be.tarsos.dsp.pitch.AMDF Maven / Gradle / Ivy
/*
* _______ _____ _____ _____
* |__ __| | __ \ / ____| __ \
* | | __ _ _ __ ___ ___ ___| | | | (___ | |__) |
* | |/ _` | '__/ __|/ _ \/ __| | | |\___ \| ___/
* | | (_| | | \__ \ (_) \__ \ |__| |____) | |
* |_|\__,_|_| |___/\___/|___/_____/|_____/|_|
*
* -------------------------------------------------------------
*
* TarsosDSP is developed by Joren Six at IPEM, University Ghent
*
* -------------------------------------------------------------
*
* Info: http://0110.be/tag/TarsosDSP
* Github: https://github.com/JorenSix/TarsosDSP
* Releases: http://0110.be/releases/TarsosDSP/
*
* TarsosDSP includes modified source code by various authors,
* for credits and info, see README.
*
*/
package be.tarsos.dsp.pitch;
/**
*
* A pitch extractor that extracts the Average Magnitude Difference (AMDF) from
* an audio buffer. This is a good measure of the Pitch (f0) of a signal.
*
*
* AMDF is calculated by the the difference between the waveform summing a
* lagged version of itself.
*
*
* The main bulk of the code is written by Eder de Souza for the jAudio framework. Adapted for TarsosDSP by
* Joren Six.
*
*
* @author Eder Souza (ederwander on github)
* @author Joren Six
*/
public class AMDF implements PitchDetector{
private static final double DEFAULT_MIN_FREQUENCY = 82.0;
private static final double DEFAULT_MAX_FREQUENCY = 1000.0;
private static final double DEFAULT_RATIO = 5.0;
private static final double DEFAULT_SENSITIVITY = 0.1;
private final float sampleRate;
private final double[] amd;
private final long maxPeriod;
private final long minPeriod;
private final double ratio;
private final double sensitivity;
/**
* The result of the pitch detection iteration.
*/
private final PitchDetectionResult result;
public AMDF(float sampleRate, int bufferSize) {
this(sampleRate,bufferSize,DEFAULT_MIN_FREQUENCY,DEFAULT_MAX_FREQUENCY);
}
public AMDF(float sampleRate, int bufferSize,double minFrequency,double maxFrequency) {
this.sampleRate = sampleRate;
amd = new double[bufferSize];
this.ratio = DEFAULT_RATIO;
this.sensitivity = DEFAULT_SENSITIVITY;
this.maxPeriod = Math.round(sampleRate / minFrequency + 0.5);
this.minPeriod = Math.round(sampleRate / maxFrequency + 0.5);
result = new PitchDetectionResult();
}
@Override
public PitchDetectionResult getPitch(float[] audioBuffer) {
int t = 0;
float f0 = -1;
double minval = Double.POSITIVE_INFINITY;
double maxval = Double.NEGATIVE_INFINITY;
double[] frames1 = new double[0];
double[] frames2 = new double[0];
double[] calcSub = new double[0];
int maxShift = audioBuffer.length;
for (int i = 0; i < maxShift; i++) {
frames1 = new double[maxShift - i + 1];
frames2 = new double[maxShift - i + 1];
t = 0;
for (int aux1 = 0; aux1 < maxShift - i; aux1++) {
t = t + 1;
frames1[t] = audioBuffer[aux1];
}
t = 0;
for (int aux2 = i; aux2 < maxShift; aux2++) {
t = t + 1;
frames2[t] = audioBuffer[aux2];
}
int frameLength = frames1.length;
calcSub = new double[frameLength];
for (int u = 0; u < frameLength; u++) {
calcSub[u] = frames1[u] - frames2[u];
}
double summation = 0;
for (int l = 0; l < frameLength; l++) {
summation += Math.abs(calcSub[l]);
}
amd[i] = summation;
}
for (int j = (int)minPeriod; j < (int)maxPeriod; j++){
if(amd[j] < minval){
minval = amd[j];
}
if(amd[j] > maxval) {
maxval = amd[j];
}
}
int cutoff = (int) Math.round((sensitivity * (maxval - minval)) + minval);
int j=(int)minPeriod;
while(j<=(int)maxPeriod && (amd[j] > cutoff)){
j=j+1;
}
double search_length = minPeriod / 2;
minval = amd[j];
int minpos = j;
int i=j;
while((i
© 2015 - 2024 Weber Informatics LLC | Privacy Policy