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.
fuente
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
fuente
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.
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.
fuente