Salida FFT con buffer de flotador AudioUnit

Tengo un problema con el uso y la configuration de vDSP_zrip & AudioUnit. De hecho, configuré AudioUnit para save los datos empaquetados como flotante. Creo un búfer circular y cuando este búfer está lleno, calculo un fft. Tengo un resultado, pero no entiendo por qué fft ouput es malo (cf figura)

Configuración AudioUnit:

// describe format AudioStreamBasicDescription audioFormat; audioFormat.mSampleRate = 44100; audioFormat.mFormatID = kAudioFormatLinearPCM; audioFormat.mFormatFlags = kAudioFormatFlagsNativeEndian|kAudioFormatFlagIsPacked|kAudioFormatFlagIsFloat|kAudioFormatFlagIsNonInterleaved; audioFormat.mFramesPerPacket = 1; audioFormat.mChannelsPerFrame = 1; // mono audioFormat.mBitsPerChannel = sizeof(float) * 8; audioFormat.mBytesPerFrame = audioFormat.mChannelsPerFrame * sizeof(float); audioFormat.mBytesPerPacket = audioFormat.mFramesPerPacket * audioFormat.mBytesPerFrame; 

Búfer circular:

 _audioSample = new AudioSample(8192, 44100); // in recording callback : for(int i = 0; i < bufferList.mNumberBuffers; ++i) { if(!status) { if(_sample->needData()) _sample->put((float*)bufferList.mBuffers[i].mData, bufferList.mBuffers[i].mDataByteSize); [...] } } 

llamada vDSP:

  // get a split complex vector (real signal divided into an even-odd config vDSP_ctoz((COMPLEX *)sample.get(), 2, &_complex, 1, _fftsize); vDSP_fft_zrip(_fftsetup, &_complex, 1, _log2n, kFFTDirection_Forward); // scale (from vDSP reference) float scale = 1.0 / (2.0 * _samples); vDSP_vsmul(_complex.realp, 1, &scale, _complex.realp, 1, _fftsize); vDSP_vsmul(_complex.imagp, 1, &scale, _complex.imagp, 1, _fftsize); _complex.imagp[0] = 0.0; 

donde _fftsize = _audioSample.capacity()/2

figura

Su resultado se ve bastante razonable, así que voy a interpretar su pregunta como un "¿Cómo puedo limpiar estos resultados?"

1) Probablemente uses una window rectangular

Esto significa que no está haciendo windows , lo que introducirá cierto ruido en sus resultados. vDSP viene con algunas funciones para realizar windows, que puede usar así:

 // N = number of samples in your buffer int N = _audioSample.capacity(); // allocate space for a hamming window float * hammingWindow = (float *) malloc(sizeof(float) * N); // generate the window values and store them in the hamming window buffer vDSP_hamm_window(hammingWindow, N, 0); 

Luego, cada vez que esté a punto de hacer su FFT, muestre primero sus muestras (como en, haga esto antes de su llamada vDSP_ctoz):

  vDSP_vmul(sample.get(), 1, hammingWindow, 1, sample.get(), 1, N); 

2) Es posible que desee ejecutar una function de magnitud en sus resultados

Esto le dará resultados similares a los que vería en un visualizador de música de charts de barras FFT estándar. Haga esto después de la FFT:

 vDSP_zvmags(&_complex, 1, &_complex.realp, 1, _fftsize); 

Después de eso, _complex.realp será una matriz de valores de flotación que representan la magnitud de cada contenedor FFT.