Browse
 
Tools
Rss Categories

Decoding

Reference Number: AA-00607 Views: 10497 0 Rating/ Voters

Once you have activated your grammars and sent audio to a channel on the speech port, you can begin decoding. The decode process sends audio and grammars to the Engine to be decoded for meaning.

Batched Audio

When using audio that is sent directly into a speech port's voice channel, you can explicitly call Decode, and wait for results to come back:

C Code

  1. HPORT hport;

  2. // If you wish to use the LumenVox Semantic Interpretation process
  3. // this flag needs to be present.
  4. unsigned long flags = LV_DECODE_SEMANTIC_INTERPRETATION;

  5. // voice_channel is wherever you loaded the audio
  6. int voice_channel = 1;

  7. // You should use the LV_ACTIVE_GRAMMAR_SET if you are using SRGS grammars.
  8. // It is the grammar set that holds all of your active grammars.
  9. int grammar_set = LV_ACTIVE_GRAMMAR_SET;

  10. // Wait a max of 3 seconds before abandoning hope for the Engine to return an answer
  11. int timeout = 3000;

  12. LV_SRE_Decode(hport, voice_channel, grammar_set, flags);

  13. int code = LV_SRE_WaitForEngineToIdle(hport,timeout,voice_channel);

  14. if (code == LV_TIME_OUT)
    {
  15. // Do some clean up and exit
  16. }
    else
    {
  17. // Process the answers contained in the voice channel
  18. }

C++ Code

  1. LVSpeechPort port;

  2. unsigned long flags = LV_DECODE_SEMANTIC_INTERPRETATION;
  3. int voice_channel = 1;
  4. int grammar_set = LV_ACTIVE_GRAMMAR_SET;
  5. int timeout = 3000;

  6. port.Decode(voice_channel, grammar_set, flags);
  7. int code = port.WaitForEngineToIdle(timeout,voice_channel);

  8. if (code == LV_TIME_OUT)
    {
  9. // Do some clean up and exit
    }
  10. else
    {
  11. // Process the answers contained in the voice channel
  12. }

If you are streaming the audio into the speech port, you can elect to have the speech port handle the decode process automatically, as we did in the section on adding audio when we wrote the line:

port.SetStreamParameter(STREAM_PARM_AUTO_DECODE,1);

In order to wait for the Engine to return with results, we need to modify the callback function:

C++ Code

  1. void ProcessResults(SimpleRecognizer* reco)
  2. {
  3. reco -> audio.StopStream();
  4. int code = reco -> port.WaitForEngineToIdle(3000, voice_channel);

  5. if (code == LV_TIME_OUT)
    {
  6. // Do some clean up and exit
  7. }
    else
    {
  8. // Process the answers contained in the voice channel
  9. }
  10. }

  11. static void PortCB(int new_state, unsigned int total_bytes,
  12. unsigned int recorded_bytes, void* user_data)
  13. {
  14. SimpleRecognizer* self = (SimpleRecognizer*)user_data;
  15. switch (new_state)
  16. {
  17. case STREAM_STATUS_READY:
  18. self -> audio.StartStream(AudioCB,self);
  19. break;
  20. case STREAM_STATUS_STOPPED:
  21. case STREAM_STATUS_END_SPEECH:
  22. ProcessResults(self);
  23. break;
  24. case STREAM_STATUS_BARGE_IN:
  25. //Stop playing prompt
  26. break;
  27. }
  28. }

Getting The Return Value

When WaitForEngineToIdle returns successfully, you can get answers out of the port. If you are using semantic interpretation inside of your grammar, you retrieve LVInterpretation objects (see Using the Interpretation Object).

The decode results will remain available for a given channel until another interaction occurs with the audio in that channel.

C Code

  1. if (code == LV_TIME_OUT)
    {
  2. // Do some clean up and exit
  3. }
  4. else
  5. {
  6. int num_interp = LV_SRE_GetNumberOfInterpretations(hport,voice_channel);
  7. for (int i = 0; i < num_interp; ++i)
  8. {
  9. printf("interpretation %i: \n", i);
  10. H_SI interp = LV_SRE_CreateInterpretation(hport,voice_channel, i);

  11. const char* grammar = LVInterpretation_GetGrammarLabel(interp);
  12. int score = LVInterpretation_GetScore(interp);

  13. printf("utterance matched grammar %s with confidence %i \n", grammar,
  14. score);

  15. // See "Using the Interpretation Object" for an example of how to
  16. // handle the semantic data contained in this interpretation object

  17. // Release the interpretation handle when finished with it
  18. }
  19. }

C++ Code

  1. if (code == LV_TIME_OUT)
    {
  2. // Do some clean up and exit
  3. }
  4. else
  5. {
  6. int num_interp = port.GetNumberOfInterpretations(voice_channel);
  7. for (int i = 0; i < num_interp; ++i)
  8. {
  9. std::cout << "interpretation " << i << ":" << std::endl;
  10. LVInterpretation interp = port.GetInterpretation(voice_channel, i);

  11. const char* grammar = interp.GrammarLabel();
  12. int score = interp.Score();

  13. std::cout << "utterance matched grammar " << grammar <<
    " with confidence " << score << std::endl;

    // See "Using the Interpretation Object" to see how to handle the
    // semantic data contained in this interpretation object by example
    }
    }

If you are not using semantic interpretation, you can receive LVParseTree objects from the Engine (see Using the Parse Tree).

C Code

  1. if (code == LV_TIME_OUT)
    {
  2. // Do some clean up and exit
  3. }
  4. else
  5. {
  6. int num_parses = LV_SRE_GetNumberOfParses(hport,voice_channel);
  7. for (int i = 0; i < num_parses; ++i)
  8. {
  9. printf("interpretation %i: \n", i);
  10. H_PARSE_TREE parse = LV_SRE_CreateParseTree(hport,voice_channel, i);

  11. // See "Using the Parse Tree" to see how to handle
  12. // the parse tree by example

  13. // Release the parse tree when finished with it
  14. }
  15. }

C++ Code

  1. if (code == LV_TIME_OUT)
    {
  2. // Do some clean up and exit
  3. }
  4. else
  5. {
  6. int num_parses = port.GetNumberOfParses(voice_channel);
  7. for (int i = 0; i < num_parses; ++i)
  8. {
  9. std::cout << "interpretation" << i << ":" << std::endl;
  10. LVParseTree parse = port.GetParseTree(voice_channel, i);

  11. // See "Using the Parse Tree" to see how to handle
  12. // the parse tree by example
  13. }
  14. }

See Also