pocketsphinx.js icon indicating copy to clipboard operation
pocketsphinx.js copied to clipboard

french model

Open vincauddu29 opened this issue 8 years ago • 17 comments

Bonjour, j'essaye de mettre en place la reconnaissance grâce au model Français en suivant https://github.com/syl22-00/pocketsphinx.js-fr_FR-lium_french_f0 mais j'obtiens le message d'erreur : Error in addWords with code [object Object]

mon code : ` var initRecognizer = function() {

    data = {command: 'load', data: ["feat.params.js", "mdef.js", "means.js", "noisedict.js", "mixture_weights", "transition_matrices.js", "variances.js"].map(function(x) {return "../assets/vendor/recognizer/fr_FR/pocketsphinx.js-fr_FR-lium_french_f0/" + x;})}

    postRecognizerJob({command: 'initialize',
                        data: [["-hmm", "assets/vendor/recognize"],
                            ["-fwdflat", "no"],
                            ["-dict", "assets/vendor/recognizer/frenchWords62K.dic"],
                            ["-lm", "assets/vendor/recognizer/fr.lm.dmp"]]
        },
        function() {
            if (recorder) recorder.consumers = [recognizer];
            feedWords(wordList);});
};`

Merci d'avance pour vos réponses. Vincauddu29

vincauddu29 avatar Feb 04 '17 14:02 vincauddu29

Loading via the .js files is an obsolete method. The docs should really be updated. Try the lazyLoad method. Here is my working example with an English model.
https://rawgit.com/Thread7/pocketsphinx.js.external/master/webapp/lazy.html If you search/replace "cmusphinx-en-us-ptm-5.2" with the name of your model it might work. But it may not too. I have tried about 10 models and only one works with the lazyLoad feature.

Thread7 avatar Feb 06 '17 17:02 Thread7

Hello, thanks for you answer, I have test your code with replace "cmu_sphinx-en-us-ptm-5.2" with "cmusphinx-fr-ptm-5.2" but i obtains

"Error: Couldn't load ../cmusphinx-fr-ptm-5.2/feat.params. Status: 0"

and

"uncaught exception: abort({}) at jsStackTrace@file:///E:/wamp64/www/test/pocketsphinx.js-master/webapp/js/pocketsphinx.js:1:3106684 stackTrace@file:///E:/wamp64/www/test/pocketsphinx.js-master/webapp/js/pocketsphinx.js:1:3106867 abort@file:///E:/wamp64/www/test/pocketsphinx.js-master/webapp/js/pocketsphinx.js:19:5309 ___syscall145@file:///E:/wamp64/www/test/pocketsphinx.js-master/webapp/js/pocketsphinx.js:1:3469534 Gw@file:///E:/wamp64/www/test/pocketsphinx.js-master/webapp/js/pocketsphinx.js:11:1 zx@file:///E:/wamp64/www/test/pocketsphinx.js-master/webapp/js/pocketsphinx.js:11:1 by@file:///E:/wamp64/www/test/pocketsphinx.js-master/webapp/js/pocketsphinx.js:10:1 fu@file:///E:/wamp64/www/test/pocketsphinx.js-master/webapp/js/pocketsphinx.js:11:1 kn@file:///E:/wamp64/www/test/pocketsphinx.js-master/webapp/js/pocketsphinx.js:9:1 yn@file:///E:/wamp64/www/test/pocketsphinx.js-master/webapp/js/pocketsphinx.js:9:1 li@file:///E:/wamp64/www/test/pocketsphinx.js-master/webapp/js/pocketsphinx.js:8:1 Li@file:///E:/wamp64/www/test/pocketsphinx.js-master/webapp/js/pocketsphinx.js:8:1 Ki@file:///E:/wamp64/www/test/pocketsphinx.js-master/webapp/js/pocketsphinx.js:8:1 Ji@file:///E:/wamp64/www/test/pocketsphinx.js-master/webapp/js/pocketsphinx.js:8:1 GJ@file:///E:/wamp64/www/test/pocketsphinx.js-master/webapp/js/pocketsphinx.js:12:1 dynCall_iii_24@file:///E:/wamp64/www/test/pocketsphinx.js-master/webapp/js/pocketsphinx.js line 1 > Function:2:12 constructor_body@file:///E:/wamp64/www/test/pocketsphinx.js-master/webapp/js/pocketsphinx.js:1:3463419 __embind_register_class/</constructor<@file:///E:/wamp64/www/test/pocketsphinx.js-master/webapp/js/pocketsphinx.js:1:3457282 Recognizer@file:///E:/wamp64/www/test/pocketsphinx.js-master/webapp/js/pocketsphinx.js line 1 > Function:2:29 initialize@file:///E:/wamp64/www/test/pocketsphinx.js-master/webapp/js/recognizer.js:130:15 @file:///E:/wamp64/www/test/pocketsphinx.js-master/webapp/js/recognizer.js:58:2

If this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information."

vincauddu29 avatar Feb 06 '17 20:02 vincauddu29

Well it may be that your model files are not liked by lazyLoad for some reason. The fix is beyond my abilities. The only thing I could think is to use a different pocketsphinx.js file. In my directory there is one named pocketsphinx-default.js. Delete or rename the current one and then name the -default to pocketsphinx.js. Then try again.

Thread7 avatar Feb 06 '17 21:02 Thread7

thank you but i obtains the same error.

vincauddu29 avatar Feb 06 '17 21:02 vincauddu29

Oh darn. I don't know what to tell you. I think most people run into a dead end with pocketsphinx.js and look to other options. If you know other programming languages you could try one of the other CMUSPhinx based gitHub repos.

Thread7 avatar Feb 06 '17 22:02 Thread7

yes but it's for a website, i go continue to search a solution. Again thank you for your answers and sorry for my english ;)

vincauddu29 avatar Feb 06 '17 22:02 vincauddu29

@Thread7 both lazyload and JavaScript compilation methods of using data files work and are documented. Also, using pocketsphinx.js only makes sense if it must run the the browser, otherwise, of course, a natively compiled version would work much faster.

@vincauddu29 can you put more details for your issue, and the steps you followed until you are blocked? Either you use the JavaScript compilation issues and use the provided compiled files or use the lazyload command and use the original binary files provided by CMU sphinx. I did try the French acoustic model compiled in JavaScript but it was too large to be usable. I am not sure it will be much better with lazyload. If possible, use a smaller model, if you find or can build one.

syl22-00 avatar Feb 07 '17 10:02 syl22-00

@syl22-00 I agree that the methods are well documented. Thanks for all your work on this. But I don't think these methods work for a majority of models. The model is either too large to compile or spawns an error like the one @vincauddu29 experienced when trying lazyLoad. What models have been successful with either method?

Thread7 avatar Feb 07 '17 19:02 Thread7

okay, sorry for the late. @syl22-00 I have just followed your post https://github.com/syl22-00/pocketsphinx.js-fr_FR-lium_french_f0. What details do you want ?

@Thread7 I have try the worker method and your method with the french model

vincauddu29 avatar Feb 12 '17 19:02 vincauddu29

cmusphinx-fr-5.2 is much better than lium-f0

nshmyrev avatar Feb 12 '17 20:02 nshmyrev

i have try also cmusphinx-fr-5.2 with the lazyload but not with syl22-00 method.

vincauddu29 avatar Feb 12 '17 20:02 vincauddu29

I think most people run into a dead end with pocketsphinx.js and look to other options.

Would it be possible to put a complied French version of pocketsphinx.js on the site for downloading? It would enabled users to get up and running without the problems of the build system making it difficult.

6gsaifulislam avatar Feb 13 '17 17:02 6gsaifulislam

@JohnAReid that would be great but unfortunately many people have reported that compiling anything larger than the rm1_200 model into pocketsphinx.js doesn't work. I think @vincauddu29 may be out of options since he has tried just about everything now.

Thread7 avatar Feb 15 '17 06:02 Thread7

@vincauddu29 this repo was part of an attempt I made a while ago to use models via bower packages. It did not go through and those packages are not up to date. Anyhow, I believe the best way to load models is to use the lazyload command and load raw files directly.

@JohnAReid compiling an acoustic model inside pocketsphinx.js is probably not a great idea. For the demo I added a small RM1 model inside, but just out of simplicity. One issue for instance is caching, any time you modify either a model or the code, the whole big compiled file will be re-downloaded instead of just the file that was modified. Also, as I just said, I think loading raw files is a better idea.

Another note is that large model files are difficult to handle memory-wise and will require more computing resources during recognition. The acoustic and language models provided by CMU Sphinx are as large as can be handled by a natively compiled application, and tend to be too large to be usable in pocketsphinx.js. So one better build (or adapt/prune from an existing one) models for his own need. It takes some effort but is is well documented on CMU Sphinx website.

syl22-00 avatar Feb 16 '17 09:02 syl22-00

@syl22-00 i have try with the raw files and lazy-load. I obtain this code but i receive again "Error in addWords with code [object Object]". I have try with french word and same thing.

`

  // This function initializes an instance of the recorder
  // it posts a message right away and calls onReady when it
  // is ready so that onmessage can be properly set
  function spawnWorker(workerURL, onReady) {
      recognizer = new Worker(workerURL);
      recognizer.onmessage = function(event) {
        console.log('line 43 recognizer message='.event);
        onReady(recognizer);
      };
      recognizer.postMessage('');

  };

  // To display the hypothesis sent by the recognizer
  function updateHyp(hyp) {
    if (outputContainer) outputContainer.innerHTML = hyp;
  };

  // This updates the UI when the app might get ready
  // Only when both recorder and recognizer are ready do we enable the buttons
  function updateUI() {
    if (isRecorderReady && isRecognizerReady) startBtn.disabled = stopBtn.disabled = false;
  };

  // This is just a logging window where we display the status
  function updateStatus(newStatus) {
    document.getElementById('current-status').innerHTML += "<br/>" + newStatus;
  };

  // A not-so-great recording indicator
  function displayRecording(display) {
    if (display) document.getElementById('recording-indicator').innerHTML = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
    else document.getElementById('recording-indicator').innerHTML = "";
  };

  // Callback function once the user authorises access to the microphone
  // in it, we instanciate the recorder
  function startUserMedia(stream) {
    var input = audioContext.createMediaStreamSource(stream);
    // Firefox hack https://support.mozilla.org/en-US/questions/984179
    window.firefox_audio_hack = input; 
    var audioRecorderConfig = {errorCallback: function(x) {updateStatus("Error from recorder: " + x);}};
    recorder = new AudioRecorder(input, audioRecorderConfig);
    // If a recognizer is ready, we pass it to the recorder
    if (recognizer) recorder.consumers = [recognizer];
    isRecorderReady = true;
    updateUI();
    updateStatus("Audio recorder ready");
  };

  // This starts recording. We first need to get the id of the grammar to use
  var startRecording = function() {
    var id = document.getElementById('grammars').value;
    if (recorder && recorder.start(id)) displayRecording(true);
  };

  // Stops recording
  var stopRecording = function() {
    recorder && recorder.stop();
    displayRecording(false);
  };

  // Called once the recognizer is ready
  // We then add the grammars to the input select tag and update the UI
  var recognizerReady = function() {
       updateGrammars();
       isRecognizerReady = true;
       updateUI();
       updateStatus("Recognizer ready");
  };

  // We get the grammars defined below and fill in the input select tag
  var updateGrammars = function() {
    var selectTag = document.getElementById('grammars');
    for (var i = 0 ; i < grammarIds.length ; i++) {
        var newElt = document.createElement('option');
        newElt.value=grammarIds[i].id;
        newElt.innerHTML = grammarIds[i].title;
        selectTag.appendChild(newElt);
    }                          
  };

  // This adds a grammar from the grammars array
  // We add them one by one and call it again as
  // a callback.
  // Once we are done adding all grammars, we can call
  // recognizerReady()
  var feedGrammar = function(g, index, id) {
    if (id && (grammarIds.length > 0)) grammarIds[0].id = id.id;
    if (index < g.length) {
      grammarIds.unshift({title: g[index].title})
  postRecognizerJob({command: 'addGrammar', data: g[index].g},
                         function(id) {feedGrammar(grammars, index + 1, {id:id});});
    } else {
      recognizerReady();
    }
  };

  // This adds words to the recognizer. When it calls back, we add grammars
  var feedWords = function(words) {
       postRecognizerJob({command: 'addWords', data: words},
                    function() {feedGrammar(grammars, 0);});
  };

  // This initializes the recognizer. When it calls back, we add words
  var initRecognizer = function() {
      // You can pass parameters to the recognizer, such as : {command: 'initialize', data: [["-hmm", "my_model"], ["-fwdflat", "no"]]}
      postRecognizerJob({command: 'initialize', data: [["-hmm", "cmusphinx-fr-ptm-5.2"], ["-fwdflat", "no"]]},
                        function() {
                                    if (recorder) recorder.consumers = [recognizer];
                                    feedWords(wordList);});
  };

  // When the page is loaded, we spawn a new recognizer worker and call getUserMedia to
  // request access to the microphone
  window.onload = function() {
    outputContainer = document.getElementById("output");
    updateStatus("Initializing web audio and speech recognizer, waiting for approval to access the microphone");
    callbackManager = new CallbackManager();
    spawnWorker("js/recognizer.js", function(worker) {
        // This is the onmessage function, once the worker is fully loaded
        worker.onmessage = function(e) {
            // This is the case when we have a callback id to be called
            if (e.data.hasOwnProperty('id')) {
              var clb = callbackManager.get(e.data['id']);
              var data = {};
              if ( e.data.hasOwnProperty('data')) data = e.data.data;
              if(clb) clb(data);
            }
            // This is a case when the recognizer has a new hypothesis
            if (e.data.hasOwnProperty('hyp')) {
              var newHyp = e.data.hyp;
              if (e.data.hasOwnProperty('final') &&  e.data.final) newHyp = "Final: " + newHyp;
              updateHyp(newHyp);
            }
            // This is the case when we have an error
            if (e.data.hasOwnProperty('status') && (e.data.status == "error")) {
              updateStatus("Error in " + e.data.command + " with code " + e.data.code);
            }
        };
        // Once the worker is fully loaded, we can call the initialize function
        initRecognizer();
    });

    // The following is to initialize Web Audio
    try {
      window.AudioContext = window.AudioContext || window.webkitAudioContext;
      navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
      window.URL = window.URL || window.webkitURL;
      audioContext = new AudioContext();
    } catch (e) {
      updateStatus("Error initializing Web Audio browser");
    }
    if (navigator.getUserMedia) navigator.getUserMedia({audio: true}, startUserMedia, function(e) {
                                    updateStatus("No live audio input in this browser");
                                });
    else updateStatus("No web audio support in this browser");
  
  // go_lazy();
  // Wiring JavaScript to the UI
  var startBtn = document.getElementById('startBtn');
  var stopBtn = document.getElementById('stopBtn');
  startBtn.disabled = true;
  stopBtn.disabled = true;
  startBtn.onclick = startRecording;
  stopBtn.onclick = stopRecording;
  };

   // This is the list of words that need to be added to the recognizer
   // This follows the CMU dictionary format
  var wordList = [["ONE", "W AH N"], ["TWO", "T UW"], ["THREE", "TH R IY"], ["FOUR", "F AO R"], ["FIVE", "F AY V"], ["SIX", "S IH K S"], ["SEVEN", "S EH V AH N"], ["EIGHT", "EY T"], ["NINE", "N AY N"], ["ZERO", "Z IH R OW"], ["NEW-YORK", "N UW Y AO R K"], ["NEW-YORK-CITY", "N UW Y AO R K S IH T IY"], ["PARIS", "P AE R IH S"] , ["PARIS(2)", "P EH R IH S"], ["SHANGHAI", "SH AE NG HH AY"], ["SAN-FRANCISCO", "S AE N F R AE N S IH S K OW"], ["LONDON", "L AH N D AH N"], ["BERLIN", "B ER L IH N"], ["SUCKS", "S AH K S"], ["ROCKS", "R AA K S"], ["IS", "IH Z"], ["NOT", "N AA T"], ["GOOD", "G IH D"], ["GOOD(2)", "G UH D"], ["GREAT", "G R EY T"], ["WINDOWS", "W IH N D OW Z"], ["LINUX", "L IH N AH K S"], ["UNIX", "Y UW N IH K S"], ["MAC", "M AE K"], ["AND", "AE N D"], ["AND(2)", "AH N D"], ["O", "OW"], ["S", "EH S"], ["X", "EH K S"]];
  // This grammar recognizes digits
  var grammarDigits = {numStates: 1, start: 0, end: 0, transitions: [{from: 0, to: 0, word: "ONE"},{from: 0, to: 0, word: "TWO"},{from: 0, to: 0, word: "THREE"},{from: 0, to: 0, word: "FOUR"},{from: 0, to: 0, word: "FIVE"},{from: 0, to: 0, word: "SIX"},{from: 0, to: 0, word: "SEVEN"},{from: 0, to: 0, word: "EIGHT"},{from: 0, to: 0, word: "NINE"},{from: 0, to: 0, word: "ZERO"}]};
  // This grammar recognizes a few cities names
  var grammarCities = {numStates: 1, start: 0, end: 0, transitions: [{from: 0, to: 0, word: "NEW-YORK"}, {from: 0, to: 0, word: "NEW-YORK-CITY"}, {from: 0, to: 0, word: "PARIS"}, {from: 0, to: 0, word: "SHANGHAI"}, {from: 0, to: 0, word: "SAN-FRANCISCO"}, {from: 0, to: 0, word: "LONDON"}, {from: 0, to: 0, word: "BERLIN"}]};
  // This is to play with beloved or belated OSes
  var grammarOses = {numStates: 7, start: 0, end: 6, transitions: [{from: 0, to: 1, word: "WINDOWS"}, {from: 0, to: 1, word: "LINUX"}, {from: 0, to: 1, word: "UNIX"}, {from: 1, to: 2, word: "IS"}, {from: 2, to: 2, word: "NOT"}, {from: 2, to: 6, word: "GOOD"}, {from: 2, to: 6, word: "GREAT"}, {from: 1, to: 6, word: "ROCKS"}, {from: 1, to: 6, word: "SUCKS"}, {from: 0, to: 4, word: "MAC"}, {from: 4, to: 5, word: "O"}, {from: 5, to: 3, word: "S"}, {from: 3, to: 1, word: "X"}, {from: 6, to: 0, word: "AND"}]};
  var grammars = [{title: "OSes", g: grammarOses}, {title: "Digits", g: grammarDigits}, {title: "Cities", g: grammarCities}];
  var grammarIds = [];
    
      function go_lazy() {
		console.log('Inside go_lazy');
	  	postRecognizerJob({command: 'lazyLoad', 
		  data: {folders: [["/", "cmusphinx-fr-ptm-5.2"]], 
		  files: [["/cmusphinx-fr-ptm-5.2", "means", "../cmusphinx-fr-ptm-5.2/means"],
                   ["/cmusphinx-fr-ptm-5.2", "variances", "../cmusphinx-fr-ptm-5.2/variances"],
                   ["/cmusphinx-fr-ptm-5.2", "transition_matrices", "../cmusphinx-fr-ptm-5.2/transition_matrices"],
                   ["/cmusphinx-fr-ptm-5.2", "sendump", "../cmusphinx-fr-ptm-5.2/sendump"],
                   ["/cmusphinx-fr-ptm-5.2", "mdef", "../cmusphinx-fr-ptm-5.2/mdef"],
                   ["/cmusphinx-fr-ptm-5.2", "feat.params", "../cmusphinx-fr-ptm-5.2/feat.params"],
                   ["/cmusphinx-fr-ptm-5.2", "mixture_weights", "../cmusphinx-fr-ptm-5.2/mixture_weights"],
                   ["/cmusphinx-fr-ptm-5.2", "noisedict", "../cmusphinx-fr-ptm-5.2/noisedict"]]}}
              ,
                   function() {
						            console.log('Lazy Callback worked');
                    });

	  
	  }  //End go_lazy	   
</script>
<!-- These are the two JavaScript files you must load in the HTML,
The recognizer is loaded through a Web Worker -->
<script src="js/audioRecorder.js"></script>
<script src="js/callbackManager.js"></script>

vincauddu29 avatar Feb 16 '17 13:02 vincauddu29

@vincauddu29 did you ever get the French model to work - I am trying the cmusphinx-fr-5.2 model as suggested by nshmyrev - and I am getting the same error as you did - it seems as though the model is not being loaded as the words cannot see the phones:

Unknown phone bb in phone string bb

6gsaifulislam avatar Mar 28 '17 19:03 6gsaifulislam

bb is from the english pronunciation dictionary use the cmu french one

example : https://github.com/batiot/pocketsphinx.js.external

batiot avatar Jun 24 '17 21:06 batiot