Cómo volver a muestrear audio usando FFT o DFT

12

Estoy bajando el muestreo de audio de voz al realizar primero una FFT, luego solo tomar las partes del resultado que necesito y luego realizar una FFT inversa. Sin embargo, solo funciona correctamente cuando estoy usando frecuencias que son ambas potencias de dos, digamos un muestreo descendente de 32768 a 8192. Realizo una FFT en los datos de 32k, descarto los 3/4 superiores de los datos y luego realizo un FFT inversa en el 1/4 restante.

Sin embargo, cada vez que intento hacer esto con datos que no se alinean correctamente, sucede una de dos cosas: la biblioteca de matemáticas que estoy usando (Aforge.Math) arroja un ajuste, porque mis muestras no son una potencia de dos. Si trato de poner a cero las muestras para que se conviertan en potencia de dos, el galimatías sale del otro extremo. También intenté usar un DFT en su lugar, pero termina siendo increíblemente lento (esto debe hacerse en tiempo real).

¿Cómo voy a poner a cero los datos de FFT correctamente, tanto en la FFT inicial como en la FFT inversa al final? Suponiendo que tengo una muestra a 44.1khz que necesita llegar a 16khz, actualmente intento algo como esto, la muestra tiene un tamaño de 1000.

  1. Pad datos de entrada a 1024 al final
  2. Realizar FFT
  3. Lea los primeros 512 elementos en una matriz (solo necesito los primeros 362, pero necesito ^ 2)
  4. Realizar FFT inversa
  5. Lea los primeros 362 elementos en el búfer de reproducción de audio.

De esto, saco la basura al final. Hacer lo mismo pero sin tener que rellenar los pasos 1 y 3 debido a que las muestras ya son ^ 2, da un resultado correcto.


fuente
99
FFT realmente no es la forma correcta de hacer esto. Desea un banco de filtros polifásico para obtener la máxima eficiencia, pero si solo desea resolver el problema, primero muestree en el GCD, luego pase bajo y luego reduzca la muestra.
Bjorn Roche
Hola Bjorn: ¿qué es "GCD"?
SpeedCoder5

Respuestas:

16

El primer paso es verificar que tanto su frecuencia de muestreo inicial como su frecuencia de muestreo objetivo sean números racionales . Como son enteros, son números automáticamente racionales. Si uno de ellos no fuera un número racional, aún sería posible realizar un cambio en la frecuencia de muestreo, pero es un proceso muy diferente y más difícil.

2232527227533272255

Los pasos anteriores deben realizarse sin importar cómo desee volver a muestrear los datos. Ahora hablemos sobre cómo hacerlo con FFT. El truco para volver a muestrear con FFT es elegir longitudes de FFT que hagan que todo funcione bien. Eso significa elegir una longitud FFT que sea un múltiplo de la tasa de diezmado (441, en este caso). Por el bien del ejemplo, escojamos una longitud FFT de 441, aunque podríamos haber elegido 882, o 1323, o cualquier otro múltiplo positivo de 441.

Para entender cómo funciona esto, ayuda a visualizarlo. Empiezas con una señal de audio que se ve, en el dominio de la frecuencia, como la figura de abajo. Frecuencia de muestreo de 44,1 kHz

Cuando haya terminado con su procesamiento, desea disminuir la frecuencia de muestreo a 16 kHz, pero desea la menor distorsión posible. En otras palabras, simplemente desea mantener todo desde la imagen de arriba de -8 kHz a +8 kHz y soltar todo lo demás. Eso da como resultado la imagen a continuación. ingrese la descripción de la imagen aquí

Tenga en cuenta que las frecuencias de muestreo no están a escala, solo están ahí para ilustrar los conceptos.

255

Como puede sospechar, hay un par de posibles problemas. Revisaré cada uno y explicaré cómo puedes superarlos.

  1. ¿Qué haces si tus datos no son un buen múltiplo del factor de diezmado? Puede superar esto fácilmente rellenando el final de sus datos con suficientes ceros para convertirlo en un múltiplo del factor de diezmado. Los datos se rellenan ANTES de ser FFT.

  2. ll1ceros (tenga en cuenta que el número de muestras de datos y el número de muestras de relleno deben ser AMBOS múltiplos positivos del factor de diezmado; puede aumentar la longitud del relleno para cumplir con esta restricción), FFT 'los datos rellenados, multiplicando el dominio de frecuencia datos y filtro, y luego aliasar los resultados de alta frecuencia (> 8 kHz) en los resultados de baja frecuencia (<8 kHz) antes de soltar los resultados de alta frecuencia. Desafortunadamente, dado que el filtrado en el dominio de la frecuencia es un gran tema en sí mismo, no podré entrar en más detalles en esta respuesta. Sin embargo, diré que si filtra y procesa los datos en más de un fragmento, deberá implementar Overlap-and-Add o Overlap-and-Save para que el filtrado sea continuo.

Espero que esto ayude.

EDITAR: La diferencia entre el número inicial de muestras de dominio de frecuencia y el número objetivo de muestras de dominio de frecuencia debe ser uniforme para que pueda eliminar el mismo número de muestras del lado positivo de los resultados que del lado negativo de los resultados. En el caso de nuestro ejemplo, el número inicial de muestras fue la tasa de diezmado, o 441, y el número objetivo de muestras fue la tasa de interpolación, o 160. La diferencia es 279, que no es par. La solución es duplicar la longitud de FFT a 882, lo que hace que el número objetivo de muestras también se duplique a 320. Ahora la diferencia es pareja, y puede eliminar las muestras de dominio de frecuencia apropiadas sin problemas.

Jim Clay
fuente
Muy agradable. ¿Cómo haces figuras tan bonitas sobre la marcha, Jim?
Spacey
@Mohammad, usualmente uso Powerpoint. En este caso, utilicé la versión Libre Office de Powerpoint, que creo que se llama "Impress".
Jim Clay
Hola, tengo una pregunta sobre tu punto (2). ¿Qué quiere decir exactamente en este paso: "... y luego aliasar los resultados de alta frecuencia (> 8 kHz) en los resultados de baja frecuencia (<8 kHz) antes de soltar los resultados de alta frecuencia". Entiendo los pasos antes de eso. Después de multiplicar mis datos de dominio f con el dominio f de mi filtro, ¿entonces qué? Además, ¿funciona este método si también desea muestrear sus datos? Gracias.
TheGrapeBeyond
@TheGrapeBeyond Cuando alias en el dominio del tiempo agrega todas las zonas Nyquist juntas. Los primeros elementos de todas las zonas de Nyquist se suman y se convierten en el nuevo primer elemento de la primera zona de Nyquist. El segundo elemento de todas las zonas de Nyquist se suma y se convierte en el nuevo segundo elemento de la primera zona de Nyquist, etc.
Jim Clay
Hmm, no estoy seguro de entender cómo está haciendo el remuestreo basado en FFT, porque cuando lo intento aquí obtengo resultados muy extraños. Haré una pregunta al respecto.
TheGrapeBeyond
3

Si bien la respuesta anterior es realmente completa:

Aquí está la esencia de esto:

  1. para reducir la señal de una señal, debe ser un número entero. Antes del muestreo descendente de una señal, debe FILTRAR la señal.
  2. puede lograr una disminución de la cantidad de números racional al realizar un muestreo ascendente / interpolar primero la señal.
  3. Upsampling es simplemente insertar ceros y luego FILTRAR la señal.
  4. para lograr una frecuencia de muestreo de 3/4. aumentar la muestra de la señal insertando 4 ceros entre cada muestra de señal. Aplica un filtro. Luego, FILTRAR la señal y eliminar cada 3 de cada 4 muestras de señal.

Detalles sobre esto:

http://www.ws.binghamton.edu/fowler/fowler%20personal%20page/EE523_files/Ch_14_1%20Subband%20Intro%20&%20Multirate%20(PPT).pdf

Además: a menos que sea absolutamente necesario, NO computar la FFT para luego calcular la IFFT. Es un proceso increíblemente lento y se considera inapropiado para la mayoría de las tareas de procesamiento de señales. el FFT se usa generalmente para analizar un problema o aplicar el procesamiento de señales solo en el dominio de la frecuencia.

CyberMen
fuente
1

Como decía Bjorn Roche, usar FFT para esto sería terriblemente ineficiente. Pero aquí va de una manera muy muy simple usando el método de filtro de muestra ascendente y muestra descendente en el dominio de frecuencia.

1 - Tome la señal de vector deseada de longitud N.

2 - Realizar el punto N FFT.

3 - Cero rellena el FFT con 160 * N ceros en el medio del vector FFT.

4 - Realizar IFFT

5 - Seleccione una de las 441 muestras descartando las otras 440.

Tendrás un vector de longitud N * 160/441, que será tu señal muestreada.

Como puede ver, está haciendo muchos cálculos inútiles, porque la mayoría de los resultados se descartarán. Pero si tiene acceso al código que realiza la FFT, en realidad podría modificarlo un poco para que solo calcule los resultados de IFFT con los que terminará y no los que arrojará.

Espero eso ayude.

hueso
fuente