Consejos para mejorar la detección de tono

21

Estoy trabajando en una aplicación web simple que permite al usuario afinar su guitarra. Soy un verdadero principiante en el procesamiento de señales, así que no juzgues demasiado si mi pregunta es inapropiada.

Entonces, logré obtener la frecuencia fundamental usando un algoritmo FFT y en este punto la aplicación es de alguna manera funcional. Sin embargo, hay margen de mejora, ahora mismo envío pcm sin formato al algoritmo FFT, pero estaba pensando que tal vez hay algunos algoritmos / filtros previos / posteriores que pueden mejorar la detección. ¿Puedes sugerir alguna?

Mi principal problema es que cuando detecta una determinada frecuencia, muestra esa frecuencia durante 1-2 segundos y luego salta a otras frecuencias aleatorias y vuelve de nuevo, etc., incluso si el sonido es continuo.

También estoy interesado en cualquier otro tipo de optimización si uno tiene experiencia con tales cosas.

Valentin Radu
fuente

Respuestas:

20

Supongo que las otras frecuencias que obtiene son armónicos de lo fundamental. ¿Como si estuvieras jugando 100 Hz y en su lugar selecciona 200 Hz o 300 Hz? Primero, debe limitar su espacio de búsqueda a las frecuencias que probablemente tenga una guitarra. Encuentre el fundamental más alto que probablemente necesite y limítese a eso.

La autocorrelación funcionará mejor que FFT para encontrar el fundamental, si el fundamental tiene una amplitud más baja que los armónicos (o falta por completo, pero eso no es un problema con la guitarra):

ingrese la descripción de la imagen aquí

También puede intentar ponderar las frecuencias más bajas para enfatizar los fundamentales y minimizar los armónicos, o usar un algoritmo de selección de picos como este y luego simplemente elegir la frecuencia más baja.

Además, debe poner en ventana su señal antes de aplicar la FFT. Simplemente multiplíquelo por una función de ventana , que disminuye gradualmente el principio y el final de la forma de onda para hacer que el espectro de frecuencias sea más limpio. Luego obtienes picos altos y estrechos para los componentes de frecuencia en lugar de los anchos.

También puede usar la interpolación para obtener un pico más preciso. Tome el registro del espectro, luego ajuste una parábola al pico y los dos puntos vecinos, y encuentre el verdadero pico de la parábola. Sin embargo, es posible que no necesite tanta precisión.

Aquí está mi código Python de ejemplo para todo esto .

endolito
fuente
Esto es lo que estaba buscando, muy buena respuesta, ¡gracias!
Valentin Radu
2
Multiplicar por una función de ventana que se afila en realidad borrará cualquier línea espectral en su señal, haciéndolas más amplias. Sin embargo, lo que puede comprarle es un rango dinámico, que le permite identificar, por ejemplo, una línea espectral de muy baja potencia en presencia de un tono interferente de alta potencia.
Jason R
@JasonR dado el hecho de que está diseñado para funcionar en un entorno en el que la probabilidad de un tono o tonos interferentes de alta potencia es realmente baja, ¿sugiere que es mejor no usar una ventana de Hamming?
Valentin Radu
1
Puedo confirmar que usar una ventana de Hamming me acercó a mi objetivo de mantener estables las lecturas. En este momento, cuando juego un A4 obtengo 440 Hz la mayor parte del tiempo y solo muy raramente obtengo una lectura cercana como 650 Hz más o menos. Supongo que esos son armónicos? Además, no pude evitar notar que para una frecuencia más alta, la aplicación funciona sin problemas y que para una más baja comienza a fallar. ¿Probablemente porque estoy usando FTT para detectar el intervalo de frecuencia de magnitud pico y para frecuencias más bajas que no siempre es lo fundamental?
Valentin Radu
1
@mindnoise: 660 Hz no es un armónico de 440 Hz, pero es un armónico de 220 Hz, o un quinto perfecto por encima de 440. ¿Podría ser otra cuerda resonante o distorsionada o algo así? Es mucho más fácil resolver problemas como este si puede trazar el FFT y mirarlo. Sí, las bajas frecuencias pueden filtrarse y reducirse en relación con las más altas, ya sea por efectos mecánicos o por su circuito analógico.
Endolith
12

El tono no es lo mismo que el intervalo de frecuencia de magnitud pico de una FFT. El tono es un fenómeno psicoacústico humano. El sonido de tono podría tener un fundamental faltante o muy débil (común en algunos sonidos de voz, piano y guitarra) y / o muchos sobretonos potentes en su espectro que abruman la frecuencia de tono (pero un humano aún lo escuchará como esa nota de tono) . Por lo tanto, cualquier detector de frecuencia pico FFT (incluso incluyendo algunas ventanas e interpolación) no será un método robusto de estimación de tono.

Esta pregunta de stackoverflow incluye una lista de algunos métodos alternativos para estimar el tono que podrían producir mejores resultados.

AGREGADO: si está haciendo esto para los sonidos de guitarra, tenga en cuenta que las cuerdas de guitarra más bajas pueden producir sobretonos ligeramente inarmónicos, lo que dificulta aún más la estimación del tono, ya que el oído humano puede escuchar una frecuencia de tono más estrechamente relacionada con submúltiplos de los armónicos. , en lugar de la frecuencia de vibración fundamental real de la cuerda.

AGREGADO # 2: Esto se pregunta con tanta frecuencia que escribí una publicación de blog más larga sobre el tema: http://www.musingpaw.com/2012/04/musical-pitch-is-not-just-fft-frequency.html

hotpaw2
fuente
acabo de visitar (y comentar) el blog al que nos recomendó.
Robert Bristow-Johnson
5

Pasé muchos años investigando la detección de tonos en música polifónica, como detectar las notas de un solo de guitarra dentro de una grabación mp3. También escribí una sección en Wikipedia que da una breve descripción del proceso (mira la subsección "Detección de tono" en el enlace a continuación).

Cuando se presiona una sola tecla sobre un piano, lo que escuchamos no es solo una frecuencia de vibración de sonido, sino un compuesto de múltiples vibraciones de sonido que ocurren en diferentes frecuencias relacionadas matemáticamente. Los elementos de este compuesto de vibraciones a diferentes frecuencias se denominan armónicos o parciales. Por ejemplo, si presionamos la tecla C central en el piano, las frecuencias individuales de los armónicos del compuesto comenzarán a 261,6 Hz como la frecuencia fundamental, 523 Hz sería el segundo armónico, 785 Hz sería el tercer armónico, 1046 Hz sería ser el 4to armónico, etc. Los armónicos posteriores son múltiplos enteros de la frecuencia fundamental, 261.6 Hz (ej: 2 x 261.6 = 523, 3 x 261.6 = 785, 4 x 261.6 = 1046).

Utilizo una Transformación logarítmica DFT modificada para detectar primero los posibles armónicos buscando frecuencias con niveles máximos (ver diagrama a continuación). Debido a la forma en que recopilo datos para mi Log DFT modificado, NO tengo que aplicar una función de ventana a la señal, ni agregar ni superponer . Y he creado el DFT para que sus canales de frecuencia estén ubicados logarítmicamente para alinearse directamente con las frecuencias donde se crean los armónicos por las notas en una guitarra, saxofón, etc.

Ahora que estoy retirado, he decidido publicar el código fuente de mi motor de detección de tono dentro de una aplicación de demostración gratuita llamada PitchScope Player . PitchScope Player está disponible en la web, y puede descargar el ejecutable para Windows para ver mi algoritmo en funcionamiento en un archivo mp3 de su elección. El siguiente enlace a GitHub.com lo llevará a mi código fuente completo donde puede ver cómo detecto los armónicos con una transformación DFT logarítmica personalizada y luego buscar parciales (armónicos) cuyas frecuencias satisfacen la relación entera correcta que define un ' tono'.

Mi algoritmo de detección de tono es en realidad un proceso de dos etapas: a) Primero se detecta el ScalePitch ('ScalePitch' tiene 12 valores de tono posibles: {E, F, F #, G, G #, A, A #, B, C, C #, D , D #}) b) y después de que se determina ScalePitch, se calcula la octava examinando todos los armónicos para las 4 posibles notas de octava-candidato. El algoritmo está diseñado para detectar el tono más dominante (una nota musical) en cualquier momento dado dentro de un archivo MP3 polifónico. Eso generalmente corresponde a las notas de un solo instrumental. Quienes estén interesados ​​en el código fuente de C ++ para mi algoritmo de detección de tono de 2 etapas pueden comenzar en la función Estimate_ScalePitch () dentro del archivo SPitchCalc.cpp en GitHub.com.

https://github.com/CreativeDetectors/PitchScope_Player

https://en.wikipedia.org/wiki/Transcription_(music)#Pitch_detection

A continuación se muestra la imagen de un DFT logarítmico (creado por mi software C ++) durante 3 segundos de un solo de guitarra en una grabación polifónica de mp3. Muestra cómo aparecen los armónicos para notas individuales en una guitarra, mientras se toca un solo. Para cada nota en este DFT logarítmico, podemos ver sus múltiples armónicos extendiéndose verticalmente, porque cada armónico tendrá el mismo ancho de tiempo. Después de determinar la octava de la nota, entonces conocemos la frecuencia de lo fundamental.

ingrese la descripción de la imagen aquí

El diagrama a continuación muestra el algoritmo de detección de octava que desarrollé para elegir la nota correcta de octava-candidato (es decir, el fundamento correcto), una vez que se ha determinado el tono de escala para esa nota. Aquellos que deseen ver ese método en C ++ deben ir a la función Calc_Best_Octave_Candidate () dentro del archivo llamado FundCandidCalcer.cpp, que está contenido en mi código fuente en GitHub.

ingrese la descripción de la imagen aquí

James Paul Millard
fuente
James, ¿tu detector de tono DFT detecta notas con un fundamental faltante (o débil)?
robert bristow-johnson
Sí, mi algoritmo de detección de tono de 2 etapas detectará notas, incluso si la señal tiene un "fundamental faltante (o débil)", esa es una gran fortaleza de este proceso de 2 etapas. El Fundamental se determina en la segunda etapa cuando la detección de octava se realiza en los anchos de tiempo que ve para las notas en el diagrama logarítmico DFT. Dado que esta función de detección de tono funciona dentro de la confusión de una señal mp3 polifónica, detectará notas que faltan muchos armónicos, incluido el fundamental. Acabo de agregar a esta respuesta un segundo diagrama que explica mi algoritmo de detección de octava.
James Paul Millard