Problemas para calcular la respuesta de frecuencia de barridos sinusoidales.

Actualmente estoy tratando de calcular la respuesta de frecuencia de ida y vuelta del altavoz / micrófono del iPhone. Realizo un barrido sinusoidal en el altavoz, lo grabo por el micrófono y trato de get la respuesta de frecuencia de eso. El objective final es poder multiplicar el FR a cualquier sonido dado para que suene como el altavoz / micrófono de iphones.

Mi código hasta ahora:

//apply window function vDSP_vmul(sineSweepMic,1,hammingWindow,1,sineSweepMic,1,n); vDSP_vmul(sineSweepFile,1,hammingWindow,1,sineSweepFile,1,n); //put both signals in complex arrays vDSP_ctoz((DSPComplex *)sineSweepMic, 2, &fftSineSweepMic, 1, nOver2); vDSP_ctoz((DSPComplex *)sineSweepFile, 2, &fftSineSweepFile, 1, nOver2); //fft of both file and mic sweeps vDSP_fft_zrip(fftSetup, &fftSineSweepFile, 1, log2n, FFT_FORWARD); vDSP_fft_zrip(fftSetup, &fftSineSweepMic, 1, log2n, FFT_FORWARD); //back to interleaved vDSP_ztoc(&fftSineSweepFile, 1, (COMPLEX *)sineSweepFile, 2, nOver2); vDSP_ztoc(&fftSineSweepMic, 1, (COMPLEX *)sineSweepMic, 2, nOver2); //divide mic-sweep by file-sweep to create frequency response vDSP_vdiv(sineSweepFile, 1, sineSweepMic, 1, frequencyResponse, 1, n); 

esto funciona hasta ahora y cuando multiplico el FR con el barrido de file inicial suena como el barrido de micrófonos.

Mi problema: esto solo funciona para el file exacto (barrido) del que se genera FR. Tan pronto como uso el FR para modificar otros sonidos, la música, por ejemplo, solo sale ruido.

Utilizo el FR de esta manera (tanto en el dominio de la frecuencia, intercalado, no complejo, incluso la misma longitud):

  vDSP_vmul(soundToModify, 1, frequencyResponse, 1, soundToModify, 1, n); 

Mi sine-sweep del file jugado en el altavoz: introduzca la descripción de la imagen aquí

Mi logging sinusoidal (bajas frecuencias atenuadas visibles): introduzca la descripción de la imagen aquí

Mi file sine-sweep se multiplica en el dominio de la frecuencia con el FR generado como se indica arriba en el código: introduzca la descripción de la imagen aquí

Mi objective: en mi opinión, la respuesta de frecuencia es la información sobre cada frecuencia, cuánto es atenuado o amplificado por el sistema (en mi ejemplo no es capaz de reproducir frecuencias bajas). Para get este tipo de información, genero un sonido que contiene todas las frecuencias deseadas (sinusoidal) y lo analizo de cómo se modifica cada frecuencia dividiendo barrido / barrido de files (split en código).

Multiplicando este FR en el dominio de la frecuencia a cualquier sonido debería modificar las amplitudes de frecuencia para imitar una reproducción en mi sistema, ¿verdad?

¡Gracias!


ACTUALIZACIÓN: al final, la falla era la compleja aritmética que faltaba y, tanto el barrido de senos como el ruido rosa funcionaron bastante bien como un impulso para recuperar la respuesta al impulso.

para get el código de trabajo simplemente complejo: divida los datos de barrido fft registrados por los datos de barrido inicial fft.

Si desea recrear el sonido del altavoz / micrófono del iPhone, lo ideal sería encontrar la respuesta de impulso del sistema.

Lo que está haciendo mal: encontrar el FFT de un barrido sinusoidal no tiene sentido, ya que la frecuencia de input es algo que cambia (lineal o exponencialmente u otro) para comenzar, antes de que el sistema imponga su propia respuesta de frecuencia además de eso. Como Paul R sugirió anteriormente, encontrar FFT de ruido blanco tiene más sentido, ya que el promedio de frecuencias de input estadísticamente planas le dará la respuesta de frecuencia real del sistema.

Sin embargo, si su objective es recrear el sonido del sistema, también debe encargarse de la fase, que no se realiza en ninguno de los methods anteriores. La forma "ideal" de hacerlo sería capturar la respuesta del altavoz / sistema del micrófono del iPhone a un "impulso" en un entorno perfectamente silencioso y seco (sin reflections). Hay 3 forms de hacerlo: 1. Use un sonido de globo pop o un sonido de impulso creado sintéticamente para hacerlo. 2. Use los códigos Golay, que es una manera más simple de promediar muchas mediciones de respuesta al impulso 3. Utilice barridos de seno, pero luego use la correlación para encontrar la respuesta de impulso.

Referencia: https://ccrma.stanford.edu/realsimple/imp_meas/imp_meas.pdf

Una vez que obtiene la medición de la respuesta al impulso, convolucione esto con la señal que está tratando de "colorear", o tome el FFT de ambas señales, multiplíquelo en el dominio de la frecuencia y luego tome el FFT inverso para get la señal de color.

Explicación: Trataré de explicarlo a mi mejor saber: – Cuando tomas el FR de una respuesta de impulso, tomas la magnitud de su FFT, tirando los datos de fase. Por lo tanto, hay muchos filters (sistemas) con la misma magnitud FR que le darán salidas radicalmente diferentes. El caso en cuestión será Filtros de Allpass: todos tienen un FR plano, pero si los impulsas, puedes recuperar un barrido sinusoidal, según los parameters del filter. Claramente, esto debería apuntar al hecho de que a pesar de que siempre puedes ir de un IR a un FR, retroceder en la dirección opuesta significa que estás haciendo una elección arbitraria. Por lo tanto, no puede descartar la fase, incluso para estimaciones aproximadas. El hecho de que no podamos escuchar la fase significa que podemos mirar el FR para get información sobre el sistema, pero no nos permite ignorar la fase en la modelación del sistema. ¿Espero que tenga sentido? Para usar un barrido sinusoidal, haga lo siguiente: si s (t) = sin (A (t)) y A (t) = integral [0 a t] (w (t) dt), correlacione la señal e (t) = corr (v (t), sin (A (t)) donde v (t) = 2 * abs (dw / dt) producirá un impulso. Por lo tanto, si reemplaza el barrido senoidal en esa correlación con la señal medida, deberías get su respuesta de impulso. ¡Espero que eso sea útil! Disculpa que sea tan matemático.