Я использую 32-битный звук с плавающей запятой (44,1 кГц) на своем ПК (от -1 до +1), используя Port Audio, и снимаю его с помощью fftw.
Теперь мне нужно взять 16-битный int Audio и проверить его fft. Я преобразовал образцы аудио в значения с плавающей запятой между -1 и +1. FFT работает, но пик возникает на частоте, в 2 раза превышающей ту, на которой он должен быть, и поэтому максимальное разрешение по частоте также уменьшается. Таким образом, при 44 кГц максимальный компонент, который я вижу, составляет около 10 кГц, тогда как с 32-битным int / float он составлял около 20 кГц.
Например, если я передаю сигнал 10 кГц от генератора знаков на звуковую карту, пик теперь отображается на частоте 20 кГц. А поменял только формат с paInt32 на paInt16. Он корректно работает в формате paInt32.
outputStreamParam.channelCount = 1;
outputStreamParam.device = Pa_GetDefaultOutputDevice();
outputStreamParam.sampleFormat = paInt16;
outputStreamParam.suggestedLatency = suggestedLatency;
outputStreamParam.hostApiSpecificStreamInfo = NULL;
inputStreamParam.channelCount = 1;
inputStreamParam.device = Pa_GetDefaultInputDevice();
inputStreamParam.sampleFormat = paInt16;
inputStreamParam.suggestedLatency = suggestedLatency;
inputStreamParam.hostApiSpecificStreamInfo = NULL;
Преобразование int (16 или 32) в число с плавающей запятой между -1 и +1.
int audioProcessor::processingCallback(const void *inputBuffer,
void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags)
{ unsigned int i;
framesPerBuffer = framesPerBuffer/2;
int *inint = (int*) inputBuffer;
float *out = (float*) outputBuffer;
float *in = (float*) inputBuffer;
for( i=0; i<framesPerBuffer; i++ )
{
in[i] = inint[i]/2147483647.0f;
}
Код процессора FFTW.
this->fftSize = fftSize;
cout << "Plan start " << endl;
outArraySize = fftSize/2+1;
cout << "fft Processor start \n";
fftIn = (double*) fftw_malloc(sizeof(double) * fftSize);
fftOut = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * outArraySize );
fftOutAbs = (double*) fftw_malloc(sizeof(double) * outArraySize );
// fftwPlan = fftw_plan_dft_r2c_1d(fftSize, fftIn, fftOut, FFTW_ESTIMATE);
cout << "Plan succeed " << endl;
fftwPlan = fftw_plan_dft_r2c_1d(fftSize, fftIn, fftOut, FFTW_MEASURE);
}