2015-12-08 1 views
1

J'utilise pocketsphinx pour reconnaître les mots dans l'application Android quand quelqu'un parle. Je veux mettre en œuvre des fonctionnalités pour renvoyer une amplitude maximale d'une voix que l'enregistrement de pocketsphinx. Si je parle n'importe quel mot j'ai besoin d'obtenir un niveau sonore en retour (l'un ou l'autre mot identifie ou non du décodeur). Qu'est-ce que je l'ai fait: je regarde dans le code de pocketsphinx -> SpeechRecognizer actuellement commenté dans le fichier source:Comment obtenir l'amplitude de la voix de pocketsphinx

/*    while (!interrupted() 
       && ((timeoutSamples == NO_TIMEOUT) || (remainingSamples > 0))) { 
      int nread = recorder.read(buffer, 0, buffer.length); 

      if (-1 == nread) { 
       throw new RuntimeException("error reading audio buffer"); 
      } else if (nread > 0) { 
       decoder.processRaw(buffer, nread, false, false); 

       int max = 0; 
       for (int i = 0; i < nread; i++) { 
        max = Math.max(max, Math.abs(buffer[i])); 
       }.... 

Je semble être que cette valeur max calcule à partir d'un tampon Comment puis-je calculer cela de complète enregistrement. Quelqu'un peut-il me donner un indice?

Répondre

0

Ce serait, juste faire max un champ de classe SpeechRecognizer et ne pas initialiser chaque fois, mais seulement sur la reconnaissance de départ:

class SpeechRecognizer() { 

    double maxLevel; 

    void startRecognition() { 
     maxLevel = 0.0; 
    } 

    ....   
     @Override 
     public void run() { 
       decoder.processRaw(buffer, nread, false, false); 

       double level = 0; 
       for (int i = 0; i < nread; i++) { 
        level += buffer[i] * buffer[i]; 
       } 
       level = sqrt(level/nread); 
       if (maxLevel < level) 
        maxLevel = level 
     .... 

} 

Ici, je vous recommande d'utiliser la racine carrée moyenne (RMS) au lieu de simplement max car il s'agit d'une estimation plus stable pour une amplitude maximale, il résiste à de simples rafales d'amplitude comme des clics.

Il est également recommandé de renvoyer RMS de chaque tampon avec le résultat et de mettre à jour maxLevel dans l'application, et non dans le programme de reconnaissance.

+0

Voici comment je calculais un niveau de bruit à partir d'une classe de reconnaissance vocale et renvoyais à mon service (incapable de se formater sous le code): double somme = 0, amplitudeDb = 0; pour (int i = 0; i 0) { double amplitude finale = somme/nread; amplitudeDb = (int) Math.sqrt (amplitude); MainHandler.post (nouvel AmplitudeEvent (amplitudeDb)); –

+0

Ok, ça a l'air correct –