2009-09-21 26 views
21

Con recursos limitados como CPU más lentas, tamaño de código y RAM, ¿cuál es la mejor manera de detectar el tono de una nota musical, similar a lo que haría un sintonizador electrónico o de software?Reconocimiento de tono de notas musicales en un teléfono inteligente

¿Debo usar:

  • FFT beso
  • FFTW
  • Discrete Wavelet Transform
  • autocorrelación
  • cero de análisis de cruce
  • filtros de octava a espacio

otros?

En pocas palabras, lo que estoy tratando de hacer es reconocer una sola nota musical, dos octavas por debajo del Do medio a dos octavas por encima, jugó en cualquier instrumento (razonable). Me gustaría estar dentro del 20% del semitono; en otras palabras, si el usuario juega demasiado plano o demasiado agudo, necesito distinguirlo. Sin embargo, no necesitaré la precisión requerida para sintonizar.

Respuesta

14

Si no es necesario que gran precisión, una FFT podría ser suficiente . Window el fragmento de audio primero para que pueda obtener picos bien definidos, luego encuentre el primer pico significativo.

anchura Bin = tasa de muestreo/tamaño de FFT:

Fundamentos range from 20 Hz a 7 kHz, por lo que una frecuencia de muestreo de 14 kHz sería suficiente. La siguiente tasa de muestreo "estándar" es 22050 Hz.

El tamaño de FFT viene determinado por la precisión que desea. La salida de FFT es de frecuencia lineal, mientras que los tonos musicales son de frecuencia logarítmica, por lo que la peor de las situaciones será a bajas frecuencias. Para el 20% de un semitono a 20 Hz, necesita un ancho de 1.2 Hz, lo que significa una longitud de FFT de 18545. La siguiente potencia de dos es 2 = 32768. Esto es 1.5 segundos de datos, y toma el procesador de mi computadora portátil 3 ms para calcular.

Esto no funcionará con las señales que tienen un "missing fundamental", y encontrar el pico "primero significativo" es algo difícil (desde harmonics are often higher than the fundamental), pero puede encontrar una manera que se adapte a su situación.

Autocorrelation and harmonic product spectrum son mejores en la búsqueda de la verdad fundamental de una ola en lugar de uno de los armónicos, pero no creo que se ocupan, así como con inharmonicity, y la mayoría de instrumentos como el piano o la guitarra son inarmónicos (armónicos son ligeramente picante de lo que deberían ser). Sin embargo, realmente depende de tus circunstancias.

Además, puede ahorrar aún más ciclos de procesador calculando solo dentro de una banda de frecuencia específica de interés, utilizando el Chirp-Z transform.

He escrito a few different methods in Python con fines comparativos.

+1

Esto es muy informativo. Gracias. Creo que por ahora solo me interesarán 4 octavas, con media octava en cada lado, para un total de 5 octavas. Dado lo que me dices, podría hacer 6 u 8 sin ningún problema. – mahboudz

+2

¿La respuesta del endolito no subestima groseramente la cantidad de contenedores requeridos? La frecuencia es * lineal * en frecuencia, ¿verdad? Por lo tanto, para obtener un 20% de precisión de un semitono en el extremo inferior del espectro, digamos 100Hz, se requeriría un ancho de frecuencia de bin alrededor de un hercio. cuatro octavas por encima de 100 Hz es 1600Hz, por lo que necesitaría 1500 bins. ¿O me estoy perdiendo algo, completamente posible ...? – tml

+0

@tml Uhhhh, sí. ¿Cómo cometí un error tan tonto y todavía obtuve tantos votos ascendentes? – endolith

5

En mi proyecto danstuner, tomé el código de Audacity. Básicamente tomó una FFT, luego encontró la potencia máxima al poner una curva cúbica en la FFT y encontrar el pico de esa curva. Funciona bastante bien, aunque tuve que protegerme contra el salto de octavas.

Ver Spectrum.cpp.

+0

Audacity podría tener algo más resbaladizo ahora, eso fue hace bastante tiempo. – dfrankow

+0

En realidad, creo que el código tomó la autocorrelación usando la FFT. Wow, ha pasado mucho tiempo. – dfrankow

13

Si desea realizar el reconocimiento de tono en tiempo real (y con una precisión de 1/100 de un semitono), su única esperanza real es el enfoque de cruce por cero. Y es una débil esperanza, siento decirlo. El cruce por cero puede estimar el tono desde solo un par de longitudes de onda de datos, y puede hacerse con la potencia de procesamiento de un teléfono inteligente, pero no es especialmente preciso, ya que pequeños errores en la medición de las longitudes de onda resultan en errores grandes en la frecuencia estimada. Dispositivos como los sintetizadores de guitarra (que deducen el tono de una cuerda de guitarra con solo un par de longitudes de onda) funcionan cuantificando las medidas a las notas de la escala. Esto puede funcionar para sus propósitos, pero tenga en cuenta que el cruce por cero funciona muy bien con formas de onda simples, pero tiende a funcionar cada vez menos bien con sonidos de instrumentos más complejos.

En mi aplicación (un sintetizador de software que se ejecuta en teléfonos inteligentes) utilizo grabaciones de notas de instrumentos individuales como materia prima para la síntesis wavetable, y para producir notas en un tono particular, necesito saber el tono fundamental de una grabación, con precisión de 1/1000 de un semitono (realmente solo necesito 1/100 de precisión, pero soy TOC sobre esto). El enfoque de cruce por cero es mucho demasiado impreciso para esto, y los enfoques basados ​​en FFT son demasiado imprecisos o demasiado lentos (o ambos a veces).

El mejor enfoque que he encontrado en este caso es utilizar la autocorrelación. Con la autocorrelación, básicamente adivina el tono y luego mide la autocorrelación de la muestra en esa longitud de onda correspondiente. Al escanear el rango de tonos plausibles (por ejemplo, A = 55 Hz hasta A = 880 Hz) por semitonos, ubico el tono más correlacionado, luego realizo un escaneo más fino en las cercanías de ese tono para obtener un valor más preciso.

El enfoque mejor para usted depende totalmente de lo que está tratando de utilizar esto para.

+1

Interesante respuesta. Sin embargo, una cosa me confunde ... ¿no es la autocorrelación O (N^2) y la FFT O (NlogN), es decir, para tomar una autocorrelación rápida, las personas a menudo usan una FFT como primer paso, entonces, ¿cómo es la FFT? ¿demasiado lento e inexacto mientras funciona la autocorrelación? ¿Esto se debe a que puede usar efectivamente un segmento más corto de datos con la autocorrelación? – tom10

+1

@ tom10: generalmente los cálculos relativos de rendimiento son para aplicaciones no musicales. Para la detección de tono, puede aprovechar el hecho de que el tono es * probablemente * en el rango de 55-880 Hz, en lugar de 0-44100 Hz, por lo que no tiene que escanear/autocorrelacionar a través del rango teórico completo. Además, hay un truco matemático simple que puedes hacer que hace que un conjunto de escaneos tome mucho menos tiempo cuando se realizan juntos que la suma de veces si se realizan individualmente. – MusiGenesis

+0

* Puede * usar FFT para ubicarse cerca del elemento fundamental y luego escanear/autocorrelacionar para obtener una medición más precisa. Hasta ahora, he encontrado que mi método (autocorrelación pura) es ligeramente más rápido, pero recientemente tuve una idea (gracias a una pregunta de SO) sobre la forma de acelerar mi código FFT, por lo que puedo pasar a este enfoque pronto. . En última instancia, sin embargo, hay una curva definida para el enfoque de FFT donde la velocidad disminuye a medida que aumenta la precisión, por lo que la autocorrelación tiene que estar involucrada en algún momento. – MusiGenesis

5

paso por cero no funcionará porque tiene un sonido típico de los armónicos y cruces por cero mucho más que la frecuencia base.

Algo he experimentado con (como un proyecto conjunto local) fue la siguiente:

  1. Muestra el sonido con ADC en cualquier frecuencia de muestreo que necesita.
  2. Detecta los niveles de los picos positivos y negativos a corto plazo de la forma de onda (ventana deslizante o similar). Es decir. un detector de envolvente
  3. Haz una onda cuadrada que sube cuando la forma de onda va dentro del 90% (más o menos) de la envolvente positiva, y baja cuando la forma de onda va dentro del 90% de la envolvente negativa. Es decir. una onda cuadrada de seguimiento con histéresis.
  4. Mida la frecuencia de esa onda cuadrada con cálculos simples de recuento/tiempo, usando tantas muestras como necesite para obtener la precisión requerida.

Sin embargo, encontré que con las entradas de mi teclado electrónico, para algunos sonidos de instrumento, logró recoger 2 veces la frecuencia base (siguiente octava). Este fue un proyecto paralelo y nunca llegué a implementar una solución antes de pasar a otras cosas. Pero pensé que era prometedor ya que era mucho menos carga de CPU que FFT.

6

No conozco todos los métodos que menciona, pero lo que elija dependerá principalmente de la naturaleza de sus datos de entrada. ¿Estás analizando tonos puros o tu fuente de entrada tiene múltiples notas? ¿El habla es una característica de tu entrada? ¿Hay alguna limitación en el tiempo que tiene para muestrear la entrada? ¿Puedes intercambiar algo de precisión por velocidad?

Hasta cierto punto, lo que elija también depende de si desea realizar sus cálculos en time o en frequency space. La conversión de un time series a una representación de frecuencia lleva tiempo, pero en mi experiencia tiende a dar mejores resultados.

Autocorrelation compara dos señales en el dominio del tiempo. Una implementación ingenua es simple pero relativamente caro de calcular, ya que requiere de pares de diferenciación entre todos los puntos en las señales originales y desplazados en el tiempo, seguido de la diferenciación para identificar puntos de inflexión en la función de autocorrelación, y entonces la selección del mínimo correspondiente a la frecuencia fundamental. Hay métodos alternativos. Por ejemplo, Average Magnitude Differencing es una forma muy barata de autocorrelación, pero la precisión sufre. Todas las técnicas de autocorrelación corren el riesgo de errores de octava, ya que existen picos distintos del fundamental en la función.

La medición de zero-crossing points es simple y directa, pero puede tener problemas si tiene múltiples formas de onda presentes en la señal.

En el espacio de frecuencia, las técnicas basadas en FFT pueden ser lo suficientemente eficientes para sus propósitos. Un ejemplo es la técnica de espectro de producto armónico, que compara el espectro de potencia de la señal con versiones reducidas de muestreo en cada armónico, e identifica el tono multiplicando los espectros para producir un pico claro.

Como siempre, no hay sustituto para probar y perfilar varias técnicas, para determinar empíricamente qué funcionará mejor para su problema y sus limitaciones.

Una respuesta como esta solo puede arañar la superficie de este tema. Además de los enlaces anteriores, aquí hay algunas referencias relevantes para lecturas adicionales.

+0

En pocas palabras, lo que estoy tratando de hacer es reconocer una sola nota musical, tocada en cualquier instrumento (razonable). Me gustaría estar dentro del 20% del semitono; en otras palabras, si el usuario juega demasiado plano o demasiado agudo, necesito distinguirlo. Sin embargo, no necesitaré la precisión requerida para sintonizar. – mahboudz

Cuestiones relacionadas