Detección de tono humano en tiempo real

11

Estoy tratando de implementar un juego de canto que analizará la entrada de micrófono sin procesar y le dirá al jugador lo bueno que está cantando. Eso debe hacerse en tiempo real.

Me he encontrado con muchos hilos haciendo la misma pregunta, pero todavía no he terminado, probablemente debido a mi falta de experiencia en el campo y mi escaso conocimiento matemático. He implementado un algoritmo basado en el artículo del cambio de tono del sitio web DSPDimension: http://www.dspdimension.com/admin/pitch-shifting-using-the-ft/

Extraigo la verdadera frecuencia y magnitud tal como explica el artículo, pero no sé encontrar la frecuencia fundamental con esto. Intenté obtener el contenedor con la mayor magnitud, pero eso solo me da los resultados correctos para señales de tono más altas, no importa qué factor de sobremuestreo use, aún obtengo datos incorrectos para señales de baja frecuencia. ¿Este enfoque es completamente incorrecto o estoy en el camino correcto pero me falta algo?

Gracias por adelantado,

EDITAR: Olvidé mencionar que solo estoy interesado en la clase de lanzamiento, por lo que está bien si falta el fundamental, pero tengo un tono fuerte en la muestra.

EDIT2: Gracias a todos, acabo de terminar una versión del algoritmo que funciona de maravilla. El problema de la estimación de tono bajo se debió a mi prueba de entrada. Cuando canté la nota, coincidía correctamente. Además, estoy considerando todos los armónicos ahora, no solo el pico más alto.

Felipe Lira
fuente
Wikipedia tiene alguna información.
Emre

Respuestas:

9

Intenté obtener el contenedor con la mayor magnitud, pero eso solo me da los resultados correctos para señales de tono más altas, no importa qué factor de sobremuestreo use, aún obtengo datos incorrectos para señales de baja frecuencia.

Eso es porque los armónicos son más grandes que los fundamentales. Trace su espectro y lo verá. Un mejor método para encontrar el verdadero fundamental es la autocorrelación. Entonces estás "deslizando" la forma de onda más allá de sí misma y encontrando retrasos en los que la forma de onda se alinea consigo misma.

http://www.phon.ucl.ac.uk/courses/spsci/matlab/lect10.html

¿Realmente quieres que canten la nota exacta, o está bien si cantan una octava arriba o abajo dependiendo de su registro de voz?

endolito
fuente
Tienes razón, olvidé mencionar que solo estoy interesado en la clase de lanzamiento. Estoy usando este sitio web para probar mi herramienta: seventhstring.com/tuningfork/tuningfork.html . Para la entrada de A (220Hz), devuelve E (660Hz) como la clase de tono encontrada. Eché un vistazo al sprectum y 220Hz está allí, pero con una magnitud menor que 660Hz. Después de filtrar valores por debajo de una magnitud mínima y frecuencias de límite en mi rango deseado, el sprectum que obtengo de esto tiene 4 picos. [pico, mag] = [220, 0.0203], [618, 0.0142], [660, 0.0668], [703, 0.0497].
Felipe Lira
Acabo de hacerme pensar que tal vez debería tener en cuenta la compensación de fase al calcular la magnitud, tal como lo estoy haciendo para obtener la frecuencia real. ¿Tiene sentido? Lo que quiero decir es que, si tengo un desfase de aproximadamente 90º para un contenedor, el "pico" sería de magnitud 0, ¿no?
Felipe Lira
@elipedrl: Así que esencialmente estás escribiendo un afinador de guitarra. :) Según tengo entendido, usan un filtro de paso bajo para limpiar la forma de onda y luego cuentan los picos para obtener el tono. electronicdesign.com/article/articles/… aboutmicrocontroller.blogspot.com/2008/04/… Sin embargo, existen mejores formas, si buscas precisión en lugar de bajo costo gist.github.com/255291
endolith
@elipedrl: el desplazamiento de fase para un bin debe ser irrelevante para el tono. Cada bin es un número complejo y le interesa el valor absoluto o la magnitud de ese número. en.wikipedia.org/wiki/Absolute_value#Complex_numbers
endolith
1
y si tiene 2 FFT más cortas por alguna razón (latencia, cuantos de tiempo, etc.), un cálculo de vocoder de fase es menos cálculo que hacer otra FFT más larga e interpolar eso.
hotpaw2
6

Sí, usar un estimador de frecuencia pico para el tono es incorrecto. El tono es un fenómeno psicoacústico, por lo que la detección o estimación del tono es diferente de la estimación de frecuencia. Se han dado muchos métodos de estimación de tono en respuestas anteriores a preguntas similares aquí. Hay más de 1 para elegir.

Aquí hay uno: /programming/4227420/matlab-missing-fundamental-from-an-fft/4231322#4231322 , y otro: Consejos para mejorar la detección de tono

AGREGADO # 1: Preguntas similares a esta se hacen 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- frecuencia.html

hotpaw2
fuente
Actualicé la pregunta con la información de que solo estoy interesado en la clase de pitch. Realmente espero que FFT con un procesamiento posterior sea suficiente para esto, estoy muy retrasado y cambiar el enfoque sería horrible para mí.
Felipe Lira
@elipedrl: FFT debería funcionar entonces. Obtener varios picos y luego seleccionar inteligentemente uno de ellos debería ser lo suficientemente bueno. Recuerde que los picos válidos estarán cerca (pero no exactamente) de múltiplos enteros del fundamental, mientras que los picos espurios no lo estarán. Debe evitar seleccionar picos espurios y evitar el tercer armónico, etc., que no estén a una octava de la nota que está buscando.
endolito el
Es posible, aunque quizás improbable, que ningún pico de frecuencia esté en la frecuencia de tono musical. Algunas vocales masculinas pueden estar cerca de esto, solo quedan tonos altos después del filtrado por el formante vocal.
hotpaw2
El método del espectro de productos armónicos puede ser adecuado para encontrar una estimación del mínimo común denominador de un grupo de picos espectrales, mediante el procesamiento posterior de los resultados iniciales de FFT.
hotpaw2