Descrição do Problema
Estou querendo usar o reconhecimento de voz como parte de um projeto de hardware, que gostaria de ser completamente independente (estou usando pequenos dispositivos de baixa potência e baixa velocidade, como Arduino e Raspberry Pi, Kinects etc., nenhum computador tradicional com um sistema operacional envolvido, portanto, um projeto fechado / autocontido).
O reconhecimento de voz pode ser muito complicado, dependendo do nível de sofisticação que você deseja. Eu tenho o que acredito ser um conjunto relativamente simples de requisitos. Eu só quero reconhecer minha própria voz e tenho um pequeno dicionário de 20 ou mais palavras que gostaria de reconhecer. Portanto, não preciso de bibliotecas complexas de reconhecimento de voz e texto ou de qualquer um dos excelentes softwares de terceiros que encontro pelos mecanismos de pesquisa da Internet (não há falta deles!). Acredito que meus requisitos sejam "simples o suficiente" (dentro do razoável) para que eu possa codificar minha própria solução. Eu estou querendo saber se alguém escreveu seu próprio processo como este, e meu método é massivamente falho? Existe uma maneira melhor de fazer isso sem exigir um alto nível de matemática ou ter que escrever um algoritmo complexo? Essa é a solução que tentei pensar abaixo.
Descrição da solução
Escreverei isso em C, mas desejo discutir um processo agnóstico da linguagem, concentrando-se no próprio processo. Então, vamos ignorar isso, se pudermos.
1 Pré-gravarei meu dicionário de palavras para corresponder às que estão sendo faladas. Podemos imaginar que tenho 20 gravações de minhas 20 palavras diferentes, ou talvez frases curtas ou sentenças de duas ou três palavras. Eu acredito que isso facilita o processo de comparar dois arquivos de gravação do que converter o áudio em texto e comparar duas strings.
2) Um microfone está conectado ao meu dispositivo de hardware executando meu código. [1] O código está continuamente colhendo amostras de comprimento fixo, digamos 10 ms, por exemplo, e armazenando 10 amostras consecutivas, por exemplo, em um estilo de registro circular. [2] (Estou inventando essas figuras de cima para baixo, para que sejam apenas exemplos para descrever o processo).
[1] Isso provavelmente seria conectado através de um filtro passa-banda e amplificador operacional, como seriam feitas as gravações do dicionário, para manter menores as amostras de áudio armazenadas e coletadas.
[2] Não sei exatamente como vou colher uma amostra, preciso elaborar um método, embora produzisse uma figura numérica (número inteiro / número flutuante / duplo) que represente o áudio de uma amostra de 10 ms (talvez um valor CRC ou soma MD5 da amostra de áudio) ou um fluxo de figuras (talvez um fluxo de leituras de áudio de frequências). Por fim, uma "amostra" será uma ou mais figuras numéricas. Esta parte terá muito mais hardware envolvido, portanto não será realmente discutida aqui.
3) O código examina 10 amostras consecutivas armazenadas e procura um aumento de volume para indicar que uma palavra ou frase está sendo dita (uma pausa do silêncio) e depois aumenta a coleta de amostras consecutivas para dizer 500 amostras, por exemplo. Isso significa que ele captura 5 segundos de áudio em amostras de 10 ms.
São essas amostras ou "fatias" que são comparadas entre o som armazenado e o som capturado. Se uma porcentagem suficientemente alta de amostras capturadas corresponder às armazenadas equivalentes, o código assumirá a mesma palavra.
The start of a store recording of the world "hello" for example,
stored words are split into 10 msec samples also
Stored Sample No | 1| 2| 3| 4| 5| 6| 7| 8|
Stored Sample Value |27|38|41|16|59|77|200|78|
Incoming audio (me saying "hello") with some "blank" samples
at the start to symbolise silence
Incoming Sample No | 1| 2| 3| 4| 5| 6| 7| 8| 9|10| 11|12|
Incoming Sample Value | | | |20|27|38|46|16|59|77|200|78|
4) Depois que o código coleta um fluxo de amostra completo, ele retira as amostras em branco no início para produzir a seguinte gravação de áudio. Também poderia mover a amostra para trás e para frente alguns lugares para melhor alinhar com a amostra armazenada.
Isso produz um conjunto de amostras como o abaixo:
Stored Sample No | 1| 2| 3| 4| 5| 6| 7| 8|
Stored Sample Value |27|38|41|16|59|77|200|78|
Incoming Sample No |-1| 1| 2| 3| 4| 5| 6| 7| 8|
Incoming Sample Value |20|27|38|46|16|59|81|201|78|
5) Acredito que, ao ter um valor percentual de quão próxima cada amostra deve estar, a amostra 7 difere por um valor 1 menor que% 1 e um valor percentual para o número total de amostras que devem estar dentro da porcentagem correspondente da amostra , o código tem um nível de precisão facilmente ajustável.
Eu nunca fiz nada assim com áudio antes, poderia ser um monte de trabalho. É por isso que estou fazendo esta pergunta, se você talvez já saiba que a resposta a esta pergunta é óbvia (qualquer que seja essa resposta). Espero que isso não seja uma tarefa computacionalmente massiva, pois parte do hardware que utilizarei será de baixo nível. Nas centenas de Megahertz (talvez 1 Ghz usando um Rasp Pi com clock excessivo). Portanto, essa é uma maneira bastante grosseira de combinar amostras de áudio usando menor poder computacional. Não estou buscando resultados instantâneos, mas menos de 30 segundos para uma prova de conceito decente.
PS Não tenho o representante para marcar isso com uma nova tag como "áudio", "reconhecimento de áudio", "voz", "reconhecimento de voz" etc.