c# .net signal-processing music frequency-analysis

c# - Biblioteca.NET para Identificar Parcelas



signal-processing music (16)

Me gustaría escribir un programa simple (preferiblemente en C #) al que canto un tono con un micrófono y el programa identifica a qué nota musical corresponde ese tono.

Muchas gracias por sus rápidas respuestas. Aclaro:

Me gustaría una biblioteca (preferiblemente .NET) que identifique las notas que canto. Me gustaría que una biblioteca así:

  1. Identifica una nota cuando canto (una nota de la escala cromática).
  2. Me dice cuánto me voy de la nota más cercana.

Tengo la intención de usar esa biblioteca para cantar una nota a la vez.



Casi todas las respuestas dicen que hacer un FFT. Yo mismo escribí este programa y descubrí que la FFT fue buena para identificar aproximadamente la frecuencia más fuerte, pero como resultado hubo algunas "manchas" - no siempre es fácil identificar con precisión pequeñas variaciones del tono objetivo utilizando una FFT, particularmente si la muestra es corta.

El enfoque de Erik Kallen parece razonable, pero hay otros enfoques. Lo que encontré funcionó bastante bien fue usar una combinación de FFT y un simple algoritmo de detección de "cruce por cero" para reducir la frecuencia exacta de la señal.

Es decir, cuente el número de veces que la señal cruza la línea cero en un intervalo dado, ajuste eso al "cubo" de frecuencia aproximada producido por la FFT, y puede obtener un resultado bastante preciso.


Como se trata de una fuente monofónica, la mayoría de los tonos detectados con una FFT deben estar relacionados armónicamente, pero en realidad no se garantiza que el fundamental sea el tono más fuerte. Para muchos instrumentos y algunos registros de voz, de hecho, probablemente no lo sea. Sin embargo, debe ser el más bajo de los tonos relacionados armónicamente (en múltiplos enteros de los fundamentales) detectados.




Está buscando una estimación de frecuencia o pitch-detection algoritmo de pitch-detection . La mayoría de las personas sugieren encontrar el valor máximo de la FFT, pero esto es demasiado simplista y no funciona tan bien como podría pensar. Si falta el fundamental (un timbal, por ejemplo), o uno de los armónicos es más grande que el fundamental (una trompeta, por ejemplo), no detectará la frecuencia correcta. Espectro de trompeta:

Espectro de trompeta http://www.eng.cam.ac.uk/DesignOffice/mdp/electric_web/AC/02284.jpg

Además, está perdiendo ciclos de procesador calculando la FFT si solo está buscando una frecuencia específica. Puede usar cosas como el algoritmo de Goertzel para encontrar tonos en una banda de frecuencia específica de manera más eficiente.

Realmente necesitas encontrar "la primera frecuencia significativa" o "la primera frecuencia con componentes armónicos fuertes", que es más ambiguo que simplemente encontrar el máximo.

Autocorrelation o el espectro de productos armónicos es mejor para encontrar el verdadero fundamento para los instrumentos reales, pero si el instrumento es inharmonic (la mayoría lo es), entonces la forma de la onda cambia con el tiempo, y sospecho que no funcionará tan bien si lo intentas para medir más de unos pocos ciclos a la vez, lo que disminuye su precisión.


Estoy sorprendido por todas las respuestas aquí que sugieren el uso de FFT, dado que FFT no es generalmente lo suficientemente precisa para la detección de tono. Puede ser, pero solo con una ventana de FFT poco grande. Por ejemplo, para determinar el fundamental con 1/100 de una precisión de semitono (que es lo que necesita para una detección de tono precisa) cuando el fundamental está alrededor del concierto A (440 Hz), necesita una ventana FFT con 524,288 elementos. 1024 es un tamaño de FFT mucho más típico: el tiempo de cálculo empeora progresivamente a medida que aumenta la ventana.

Tengo que identificar el tono fundamental de los archivos WAV en mi sintetizador de software (donde un "fallo" es inmediatamente audible como un instrumento desafinado) y he encontrado que la autocorrelación hace el mejor trabajo. Básicamente, recorro cada nota en la escala de 12 tonos en un rango de 8 octavas, calculo la frecuencia y la longitud de onda de cada nota, y luego realizo una autocorrelación utilizando esa longitud de onda como el retraso (una autocorrelación es donde se mide la correlación entre un conjunto de datos y el mismo conjunto de datos compensado por cierta cantidad de retraso).

La nota con la mayor puntuación de autocorrelación es, por lo tanto, aproximadamente el tono fundamental. Luego me "afino" en el verdadero fundamental al pasar de un semitono a un semitono por 1 / 1000ths de un semitono, para encontrar el valor de autocorrelación del pico local. Este método funciona con mucha precisión y, lo que es más importante, funciona para una amplia variedad de archivos de instrumentos (cuerdas, guitarra, voces humanas, etc.).

Sin embargo, este proceso es extremadamente lento, especialmente para archivos WAV largos, por lo que no podría usarse tal como está para una aplicación en tiempo real. Sin embargo, si usó FFT para obtener una estimación aproximada de la fundamental, y luego usó la autocorrelación para concentrarse en el valor verdadero (y se contentó con ser menos preciso que 1 / 1000o de un semitono, lo cual es absurdamente excesivo). precisa) tendría un método que era relativamente rápido y extremadamente preciso.


He hecho la pitch-detection en el pasado, y la solución simple de "tomar una FFT y mirar el pico" no funciona en absoluto para el habla. Tuve bastante buena suerte con el análisis cepstral . Se pueden encontrar muchos artículos útiles en las publications Lawrence Rabiner. Recomiendo comenzar con "Un estudio de rendimiento comparativo de varios algoritmos de detección de tono" .

Solo como advertencia, probablemente me tomó entre 30 y 40 horas de trabajo llegar al punto en el que podía enviar un archivo wav a mi programa y hacer que escupiera un número sano. También me interesaba más la frecuencia fundamental de la voz de un orador. Estoy seguro de que tratar con la música agregará muchas más arrugas.


La pieza crucial de este problema es la transformada rápida de Fourier. Este algoritmo convierte una forma de onda (su nota cantada) en una distribución de frecuencia. Una vez que haya calculado la FFT, identificará la frecuencia fundamental (por lo general, la frecuencia con la amplitud más alta en la FFT, pero esto depende en parte de la curva de respuesta de frecuencia de su micrófono y exactamente qué tipo de sonido está escuchando su micrófono).

Una vez que haya encontrado la frecuencia fundamental, necesita buscar esa frecuencia en una lista que asigna frecuencias a las notas. Aquí tendrá que lidiar con los puntos intermedios (de modo que si la frecuencia fundamental de su nota cantada es de 452 Hz, ¿a qué nota responde realmente, A o A #?).

Este tipo en CodeProject tiene un ejemplo de FFT en C #. Estoy seguro de que hay otros por ahí ...


Para convertir la señal de dominio de tiempo proveniente del micrófono, necesitará una Transformada Discreta de Fourier (DFT) o una Transformada Rápida de Fourier (FFT). La FFT funcionará más rápido pero el código será mucho más complejo (se puede hacer una DFT en 5-10 líneas de código). Una vez que haya completado esto, debe asignar las frecuencias fundamentales a las notas, desafortunadamente hay varios esquemas de mapeo dependiendo del sistema de ajuste que esté usando. El más común de estos es el temperamento igual. Las frecuencias aquí . El artículo de Wikipedia sobre Igualdad de temperamento también proporciona información sobre el temperamento igual.

Al utilizar cualquier matemática de Fourier, debe saber cómo se manejan las frecuencias y, idealmente, realizar el filtrado de suavizado antes de la transformación y también observar la reflexión de la frecuencia cuando se realiza una transformación. Debido al teorema de Nyquists, deberá probar el contenido del micrófono al menos dos veces más rápido que la frecuencia máxima, es decir. para una frecuencia máxima de 10Hz debe muestrear a 20Hz.


Por lo general, haría una transformada de Fourier en la entrada y luego identificaría la frecuencia más prominente. Sin embargo, esto podría no ser toda la historia, ya que cualquier fuente de sonido no sintética produce una serie de frecuencias (constituyen lo que se describe como "color de tono"). De todos modos, se puede hacer de manera eficiente; hay autotuners en tiempo real (no creías que la estrella del pop realmente pudiera cantar, ¿verdad?).


Querrá capturar su entrada sin procesar, acumular algunas muestras y luego hacer un FFT en ellas. La FFT convertirá sus muestras del dominio del tiempo al dominio de la frecuencia, de modo que lo que produce es un poco como un histograma de la cantidad de energía que contiene la señal en varias frecuencias.

Sin embargo, pasar de "a" la frecuencia puede ser un poco difícil, ya que una voz humana no solo contendrá una única y limpia frecuencia de sonido. En su lugar, normalmente tendrá energía en un número bastante bueno de frecuencias diferentes. Lo que normalmente hará es comenzar desde el rango de voz más bajo, y avanzar hacia arriba, buscando la primera frecuencia (la más baja) en la que la energía es significativamente más alta que el ruido de fondo.


Realizar una transformada de Fourier le dará valores para cada frecuencia encontrada en la muestra. Cuanto más prominente sea la frecuencia, mayor será el valor. Si busca el valor más grande, encontrará la frecuencia de su raíz, pero los armónicos también estarán presentes.

Si está buscando una frecuencia específica, el uso del algoritmo de Goertzel puede ser muy efectivo.


Si solo desea el resultado - i, e, para usar el software, hay un programa llamado SingAndSee que hace esto. Es alrededor de £ 25


Tal vez esta biblioteca totalmente administrada de codeplex sea adecuada para usted: Realtime C # Pitch Tracker

El autor enumera las siguientes ventajas de la autocorrelación y la implementación de su algoritmo:

  1. Rápido. Como se mencionó anteriormente, el algoritmo es bastante rápido. Puede realizar fácilmente 3000 pruebas de tono por segundo.

  2. Preciso. La desviación medida de la frecuencia real es menor que + -0.02%.

  3. Preciso en una amplia gama de niveles de entrada. Debido a que el algoritmo utiliza las proporciones de diferentes picos y no valores absolutos, se mantiene preciso en un rango muy amplio de niveles de entrada. No hay pérdida de precisión en el rango de entrada de -40dB a 0dB.

  4. Preciso en todo el rango de frecuencia. La precisión se mantiene alta en todo el rango de frecuencias detectadas, desde aproximadamente 50 Hz hasta 1.6 kHz. Esto se debe a la interpolación que se aplica al calcular muestras para las ventanas deslizantes.

  5. Preciso con cualquier tipo de forma de onda. A diferencia de muchos otros tipos de algoritmos de detección de tono, este algoritmo no se ve afectado esencialmente por formas de onda complejas. Esto significa que funciona con voces masculinas y femeninas de cualquier tipo, así como con otros instrumentos como guitarras, etc. El único requisito es que la señal sea monofónica, por lo que no se pueden detectar los acordes. Este detector de tono funcionará bien como un afinador de guitarra muy sensible.

  6. No confía en resultados anteriores. Este algoritmo es lo suficientemente preciso como para no tener que depender de resultados anteriores. Cada resultado de tono es un valor calculado completamente nuevo. Los algoritmos de tono que rastrean el tono al "bloquearse" al tono sufren el problema de que si detectan el tono incorrecto (generalmente una octava demasiado alta o baja) también continuarán equivocados en muchas pruebas posteriores.


Tienes que hacer un FFT de la muestra y luego analizar eso. Las dos cosas que complicarán tu análisis son:

  1. Overtones. Si canta / reproduce la A a 440 Hz (A4), también obtendrá un tono en A5 (880Hz), uno en E6 (1320 Hz), etc. Dependiendo de las intensidades relativas a las frecuencias, este tono podría percibirse como un A4, A5 o E6, y en detrimento del tono no se trata simplemente de dónde está la mayor intensidad, el oído humano es más complicado que eso. Sin embargo, podría suponer razonablemente bien que se percibirá como una A.

  2. La granularidad. Su FFT tendrá una granularidad que depende solo de la duración de la muestra, no de la frecuencia de muestreo. Si recuerdo correctamente, necesita una muestra de dos segundos para poder obtener una granularidad de 1 Hz, que todavía es un poco basta. Una forma de solucionar esto es tomar tres frecuencias alrededor de cada pico, aproximarse a un polinomio de segundo grado a su alrededor y luego determinar el máximo de ese polinomio. He leído un artículo afirmando que usar la fase es más preciso que la amplitud para esto, pero no recuerdo dónde, así que no puedo citarlo.