Tengo una pequeña aplicación de estilo karaoke donde un usuario canta 4 líneas de una canción, con un espacio de un segundo entre cada línea. No hay música de respaldo, por lo que es solo de voz, con suerte haciendo que el problema sea más fácil de resolver.
Estoy buscando la forma más sólida de detectar exactamente dónde, en mi grabación, el usuario comienza y termina la línea de canto 1, comienza y termina la línea de canto 2, etc.
He improvisado un algoritmo simple que funciona cuando hay muy poco ruido de fondo en la grabación (¿cuándo sucede eso?), Pero se hace pedazos en presencia del más mínimo ruido.
¿Alguien puede señalarme hacia algo más robusto?
audio
signal-detection
Mike Hogan
fuente
fuente
Respuestas:
Si el ruido de fondo es blanco, puede medir la planitud espectral y considerar que es la voz cuando la amplitud está por encima de algún umbral y la planitud espectral está por debajo de algún umbral.
Básicamente, solo toma una FFT de un fragmento de la señal, luego divide la media geométrica de la magnitud del espectro por la media aritmética.
También puede usar un filtro de paso de banda para enfatizar solo las regiones de frecuencia donde la voz humana generalmente se encuentra (tan simple como establecer las regiones no deseadas de la FFT a 0 antes de medir la planitud espectral)
fuente
He usado el flujo espectral en el pasado y parece funcionar bien. La idea básica es crear un espectrograma de su señal a través de las bandas que le interesan. Supongamos que su frecuencia está en el eje y, y su tiempo está en el eje x, así .
Esto significa que su espectrograma es una matriz. Cada columna representa el valor absoluto de la FFT de una instantánea en el tiempo de su señal, y cada fila representa cómo cambia la energía de una banda con el tiempo.
Ahora, simplemente tome la diferencia de columnas. Es decir, tome una columna, reste de sí misma la columna que está delante de ella y haga para todas las columnas. (Dejando las columnas de inicio solas obviamente). Luego suma a través de todas las bandas. Es decir, solo suma todas las filas juntas.
Terminará con una señal 1-D que codifica su inicio de señal . Esto te dirá dónde comienza tu voz.
EDITAR:
Ahora que ha detectado la aparición, si desea detectar lo contrario (es decir, cuando una señal pasa de tener actividad a ninguna), el flujo espectral realmente le brinda esa información. Dondequiera que tenga un inicio, tendrá un pico positivo, y donde sea que tenga un 'deset' (a falta de una palabra mejor), tendrá un pico negativo.
Simplemente tomaría el primer pico positivo y el último pico negativo para marcar los tiempos totales de inicio y finalización de mi señal.
fuente
Desde mi experiencia, trataría de buscar en los coeficientes de frecuencia de Melps Cepstrum (MFCC) . Los MFCC son bastante fáciles de implementar si tiene una FFT disponible y se utilizan con bastante frecuencia en el procesamiento de voz.
Con los MFCC, debería poder distinguir los datos de voz reales del ruido.
fuente
El " flujo espectral " (también denominado "diferencia espectral") es un método común para la "detección de inicio". Básicamente, toma FFT secuenciales de la señal y suma las magnitudes de las diferencias de los cubos FFT de una muestra a la siguiente. El "inicio" generalmente estará representado por un "salto" sustancial en este valor.
Google "detección de inicio" para otras ideas.
fuente
El uso del flujo espectral solo puede producir falsos positivos para ciertos ruidos, así como detectar una voz que canta.
Cantar generalmente implica un contenido de señal que contiene un tono, por lo que podría usar un detector o estimador de tono (cepstrum, etc.). Podría verificar la fracción de energía que se detecta como tono versus la energía de señal total, y que el tono estimado está dentro del rango de la voz humana. Eso reduciría la tasa de falsos positivos para el ruido no emitido, así como los sonidos musicales fuera del rango vocal normal.
fuente