Eu tenho um pequeno aplicativo no estilo karaokê, em que um usuário canta 4 linhas de uma música, com um intervalo de um segundo entre cada linha. Não há música de fundo, por isso é apenas voz, espero tornar o problema mais fácil de resolver.
Estou procurando a maneira mais robusta de detectar exatamente onde, na minha gravação, o usuário inicia e termina a linha 1, inicia e termina a linha 2, etc.
Criei um algoritmo simplista que funciona quando há muito pouco ruído de fundo na gravação (como quando isso acontece?), Mas cai em pedaços na presença do menor ruído.
Alguém pode me apontar para algo mais robusto?
audio
signal-detection
Mike Hogan
fonte
fonte
Respostas:
Se o ruído de fundo for esbranquiçado, você poderá medir o nivelamento espectral e considerá-lo voz quando a amplitude estiver acima de algum limite e o nivelamento espectral estiver abaixo de algum limite.
Basicamente, você apenas pega um FFT de um pedaço do sinal e depois divide a média geométrica da magnitude do espectro pela média aritmética.
Você também pode usar um filtro passa-banda para enfatizar apenas as regiões de frequência em que a voz humana geralmente fica (tão simples quanto definir as regiões indesejadas da FFT para 0 antes de medir o nivelamento espectral)
fonte
Eu usei fluxo espectral no passado e parece funcionar bem. A idéia básica é criar um espectrograma do seu sinal através das bandas de que você gosta. Vamos supor que sua frequência esteja no eixo y e seu tempo no eixo x, assim .
Isso significa que seu espectrograma é uma matriz. Cada coluna representa o valor absoluto da FFT de um snap-shot no tempo do seu sinal e cada linha representa como a energia de uma banda muda ao longo do tempo.
Agora, basta considerar a diferença de colunas. Ou seja, pegue uma coluna e subtraia dela a coluna anterior e faça para todas as colunas. (Deixando as colunas de início sozinhas, obviamente). Em seguida, some todas as bandas. Ou seja, basta somar todas as linhas.
Você terminará com um sinal 1-D que codifica seu sinal inicializado . Isso lhe dirá onde sua voz começa.
EDITAR:
Agora que você detectou os onets, se deseja detectar o oposto (ou seja, quando um sinal passa de atividade para nenhum), o fluxo espectral realmente fornece essas informações. Onde quer que você comece, você terá um pico positivo e, onde quer que tenha um 'deset' (por falta de uma palavra melhor), terá um pico negativo.
Eu simplesmente pegaria o primeiro pico positivo e o último pico negativo para marcar o tempo total de início e parada do meu sinal.
fonte
Da minha experiência, eu tentaria analisar os coeficientes de frequência de mel-cefstro (MFCCs) . Os MFCCs são bastante fáceis de implementar se você tiver um FFT disponível e for usado com bastante frequência no processamento de voz.
Com os MFCCs, você deve conseguir distinguir dados de voz reais de ruídos.
fonte
" Fluxo espectral " (também conhecido como "diferença espectral") é um método comum para "detecção de início". Basicamente, você captura FFTs seqüenciais do sinal e soma as magnitudes das diferenças dos baldes de FFT de uma amostra para a seguinte. O "início" geralmente será representado por um "salto" substancial nesse valor.
Google "detecção de onset" para outras idéias.
fonte
Usar o fluxo espectral sozinho pode produzir falsos positivos para certos ruídos, além de detectar uma voz cantada.
Cantar normalmente implica um conteúdo de sinal contendo um tom, então você pode usar um detector ou estimador de tom (cepstrum, etc.). Você pode verificar a fração de energia detectada como afinada versus a energia total do sinal e se a afinação estimada está dentro do alcance da voz humana. Isso reduziria a taxa de falsos positivos para ruídos não lançados, bem como para sons musicais fora do alcance vocal normal.
fonte