БПФ на iPhone для игнорирования фонового шума и нахождения более низких частот

Я реализовал проект Деметри Pitch Detector для iPhone и столкнулся с двумя проблемами. 1) любой фоновый шум посылает бананы для считывания частоты и 2) звуки более низкой частоты воспроизводятся неправильно. Я попытался настроить свою гитару, и пока работали более высокие струны - тюнер не мог правильно различить низкие E.

Код определения высоты звука находится в RIOInterface.mm и выглядит примерно так ...

// get the data
AudioUnitRender(...);

// convert int16 to float
Convert(...);

// divide the signal into even-odd configuration
vDSP_ctoz((COMPLEX*)outputBuffer, 2, &A, 1, nOver2);

// apply the fft
vDSP_fft_zrip(fftSetup, &A, stride, log2n, FFT_FORWARD);

// convert split real form to split vector
vDSP_ztoc(&A, 1, (COMPLEX *)outputBuffer, 2, nOver2);

Затем Деметри идет чтобы определить «доминирующую» частоту следующим образом:

float dominantFrequency = 0;
int bin = -1;
for (int i=0; i dominantFrequency) {
        dominantFrequency = curFreq;
        bin = (i+1)/2;
    }
}
memset(outputBuffer, 0, n*sizeof(SInt16));

// Update the UI with our newly acquired frequency value.
[THIS->listener frequencyChangedWithValue:bin*(THIS->sampleRate/bufferCapacity)];

Для начала, я считаю, что мне нужно применить LOW PASS FILTER ... но я не эксперт по БПФ и не знаю, где и как это делать с данные, возвращаемые функциями vDSP. Я тоже не уверен, как повысить точность кода на низких частотах. Кажется, существуют и другие алгоритмы для определения доминирующей частоты - но опять же, поиск толчка в правильном направлении при использовании данных, возвращаемых платформой Apple Accelerate.

ОБНОВЛЕНИЕ:

Структура ускорения фактически имеет некоторые оконные функции. Я настраиваю такое базовое окно

windowSize = maxFrames;
transferBuffer = (float*)malloc(sizeof(float)*windowSize);
window = (float*)malloc(sizeof(float)*windowSize);
memset(window, 0, sizeof(float)*windowSize);
vDSP_hann_window(window, windowSize, vDSP_HANN_NORM); 

, которое затем применяю, вставляя

vDSP_vmul(outputBuffer, 1, window, 1, transferBuffer, 1, windowSize); 

перед функцией vDSP_ctoz. Затем я изменяю остальную часть кода, чтобы использовать transferBuffer вместо outputBuffer ... но до сих пор не заметил каких-либо существенных изменений в окончательном предположении о высоте тона.

7
задан finnw 13 October 2011 в 17:22
поделиться