Mobile native

Voice control: Recognizing Voice Commands

This tutorial demonstrates how you can register voice commands, which trigger a callback when the user speaks them.

This feature is supported in mobile applications only.

Warm-up

Become familiar with the Voice control API basics by learning about:

Initializing the Voice Control

To initialize and prepare the voice control for use:

  1. To use the functions and data types of the Voice control API, include the <voice_control.h> header file in your application:
    #include <voice_control.h>
  2. Initialize the voice control with the vc_initialize() function:
    void 
    initialize_voice_control()
    {
       int ret;
       ret = vc_initialize();
       if (VC_ERROR_NONE != result)
       {
          // Error handling
       }
    }
    

    If the function call is successful, the voice control state changes to VC_STATE_INITIALIZED.

    Note
    The voice control feature is not thread safe and depends on the ecore main loop. Implement voice control within the ecore main loop and do not use it in a thread.
  3. Prepare the Voice control service with the vc_prepare() function, which connects the background Voice control daemon. The daemon records and recognizes audio data and converts sound to text.

    The vc_prepare() function is asynchronous, and when the preparation succeeds, the voice control state changes from VC_STATE_INITIALIZED to VC_STATE_READY. If the vc_prepare() function fails, the error callback is triggered.

    void 
    prepare_vc()
    {
       int ret;
       ret = vc_prepare();
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
    }
    
  4. When voice control is no longer needed, unprepare and deinitialize it:
    void 
    unprepared_vc()
    {
       int ret;
       ret = vc_unprepare();
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
    }
    
    void 
    deinitialize_voice_control()
    {
       int ret;
       ret = vc_deinitialize(); 
       if (VC_ERROR_NONE != result)
       {
          // Error handling
       }
    }
    

    When the vc_unprepare() function succeeds, the voice control state changes from VC_STATE_READY to VC_STATE_INITIALIZED.

    Note
    Do not call the vc_deinitialize() function in a callback function. Within a callback function, the vc_deinitialize() function fails and returns VC_ERROR_OPERATION_FAILED.

Managing Callbacks

The callback functions are defined in the voice_control_common.h header file, where you can find more information about them.

To set and unset callbacks to get notifications about recognition results, state changes, and errors:

Note
Set and unset all callbacks when the voice control state is VC_STATE_INITIALIZED.
  • Set the state change callback to be invoked when the voice control state changes:
    void 
    state_changed_cb(vc_state_e previous, vc_state_e current, void* user_data)
    { 
       // Your code
    }
    
    void 
    set_state_changed_cb()
    {
       int ret;
       ret = vc_set_state_changed_cb(state_changed_cb, NULL);
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
    }
    void 
    unset_state_changed_cb()
    {
       int ret;
       ret = vc_unset_state_changed_cb();
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
    }
    
  • Set the service state change callback to be invoked when the Voice control service state changes:
    void 
    __service_state_changed_cb(vc_service_state_e previous, vc_service_state_e current, void* user_data)
    { 
       // Your code
    }
    
    void 
    set_service_state_changed_cb()
    {
       int ret;
       ret = vc_set_service_state_changed_cb(__service_state_changed_cb, NULL);
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
    }
    
    void 
    unset_service_state_changed_cb()
    {
       int ret;
       ret = vc_unset_service_state_changed_cb();
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
    }
    
  • Set the current language change callback to be invoked when the system or application language changes:
    void 
    __current_language_changed_cb(const char* previous, const char* current, void* user_data)
    {
       // Your code
    }
    
    void 
    set_current_language_changed_cb()
    {
       int ret;
       ret = vc_set_current_language_changed_cb(__current_language_changed_cb, NULL);
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
    }
    
    void 
    unset_current_language_changed_cb()
    {
       int ret;
       ret = vc_unset_current_language_changed_cb();
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
    }
    
  • Set the recognition result callback to be invoked when a voice command is recognized.
    Note
    If the recognition result produces a reject event, the Voice control service has rejected the recognized command. Make sure that the command does not conflict with other commands and there are not duplicated commands.

    To get the command, use the Voice control APIs with the vc_cmd_list parameter, which is a list of recognized commands. The result parameter contains the recognized text.

    void 
    __result_cb(vc_result_event_e event, vc_cmd_list_h vc_cmd_list, const char* result, void* user_data)
    {
       int ret = -1;
       int count = 0;
       ret = vc_cmd_list_get_count(vc_cmd_list, &count);
       if (VC_ERROR_NONE != ret) 
       {
          // No result
    
          return;
       }
    	
       vc_cmd_list_first(vc_cmd_list);
    
       int i = 0;
       int type = 0;
       char* cmd = NULL;
       vc_cmd_h result_command = NULL;
       for (i = 0; i < count; i++) 
       {
          result_command = NULL;
          ret = vc_cmd_list_get_current(vc_cmd_list, &result_command);
          if (0 == ret && NULL != result_command) 
          {
             cmd = NULL;
             type = 0;
             vc_cmd_get_command(result_command, &cmd);
             vc_cmd_get_type(result_command, &type);
             // Check command and type
          }
       }
    
       return;
    }
    
    void 
    set_result_cb()
    {
       int ret;
       ret = vc_set_result_cb(__result_cb, NULL);
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
    }
    
    void 
    unset_result_cb()
    {
       int ret;
       ret = vc_unset_result_cb();
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
    }
    
  • Set the error callback to be invoked when an error occurs in the voice control process:
    void 
    __error_cb(vc_error_e reason, void* user_data)
    {
       // Your code
    }
    
    void 
    set_error_cb(vc_h vc)
    {
       int ret;
       ret = vc_set_error_cb(__error_cb, NULL);
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
    }
    
    void 
    unset_error_cb(vc_h vc)
    {
       int ret;
       ret = vc_unset_error_cb();
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
    }
    

Retrieving Voice Control Information

To get information about the current states, and current and supported languages:

  • Get the current voice control state using the vc_get_state() function.

    The voice control state changes according to function calls when the voice control is, for example, initialized and prepared.

    void 
    get_state()
    {
       vc_state_e current_state;
       int ret;
       ret = vc_get_state(&current_state);
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
    }
    
  • Get the current voice control service state using the vc_get_service_state() function.

    The user controls the voice control service state. In a general scenario:

    1. The user starts recording for recognition by using a voice application, button, or voice trigger. If the start is successful, the voice control service state changes to VC_SERVICE_STATE_RECORDING.
    2. After recording, the service state changes to VC_SERVICE_STATE_PROCESSING for recognition processing.
    3. After recognition is completed, the service state returns to VC_SERVICE_STATE_READY.

    If the application uses continuous recognition, the voice control service state can be changed from VC_SERVICE_STATE_PROCESSING directly to VC_SERVICE_STATE_RECORDING.

    void 
    get_state(vc_h vc)
    {
       vc_service_state_e service_state;
       int ret;
       ret = vc_get_service_state(&service_state);
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
    }
    
  • Get the supported languages with a callback function that runs for each language separately.

    The callback cannot be unset: as long as it returns true, it continues to loop over the supported languages.

    bool 
    supported_language_cb(const char* language, void* user_data)
    {
       return true; // To continue to get the next language
    
       return false; // To stop
    }
    
    void 
    get_supported_language()
    {
       int ret;
       ret = vc_foreach_supported_languages(supported_language_cb, NULL);
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
    }
    
  • Get the current language with the vc_get_current_language() function. The voice control recognition works for the current (default) language. Use the language change callback to be notified of language changes.
    void 
    get_current_language()
    {
       int ret;
       char* current_lang = NULL;
       ret = vc_get_current_language(&current_lang);
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
    }
    

Managing Commands

To create a command list and commands:

  1. Create a command list with a command list handle.

    The command list can include many commands, which have a command text and type. The list can have both the VC_COMMAND_TYPE_FOREGROUND and VC_COMMAND_TYPE_BACKGROUND type commands. The foreground commands are valid when the application is in a visible state and the background commands are valid when the application is in a visible or invisible state.

    You can access the command list after you set it to the voice control and when you get the recognition result.

    void 
    create_command_list()
    {
       int ret;
       vc_cmd_list_h vc_cmd_list;
       ret = vc_cmd_list_create(&vc_cmd_list);
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
    }
    
  2. Create a command.

    First create a command handle, and then define the command and type.

    void 
    create_command()
    {
       int ret;
       vc_cmd_h vc_cmd = NULL;
       ret = vc_cmd_create(&vc_cmd);
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
    
       ret = vc_cmd_set_command(vc_cmd, "open");
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
       ret = vc_cmd_set_type(vc_cmd, VC_COMMAND_TYPE_FOREGROUND);
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
    }
    
  3. Add the command to the command list.

    If necessary, you can also remove commands from the command list. After you remove the command, if you no longer use it, destroy the command handle with the vc_cmd_destroy() function.

    void 
    add_command(vc_cmd_list_h vc_cmd_list, vc_cmd_h vc_cmd)
    {
       int ret;
       ret = vc_cmd_list_add(vc_cmd_list, vc_cmd);
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
    }
    
    void 
    remove_command(vc_cmd_list_h vc_cmd_list, vc_cmd_h vc_cmd)
    {
       int ret;
       ret = vc_cmd_list_remove(vc_cmd_list, vc_cmd);
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
       // Destroy the command if no longer needed
       ret = vc_cmd_destroy(vc_cmd);
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
    }
    

    To get the commands you have added to the command list, use the vc_cmd_list_foreach_commands() function to get all commands with a callback function at once, or the vc_cmd_list_get_current() function to retrieve the commands without a callback function.

    Note
    When you get the command handle with the vc_cmd_list_get_current() function, do not release the command handle. To release the command handle, call the vc_cmd_list_remove() function before the vc_cmd_destroy() function.
    bool 
    __vc_get_command_cb(vc_cmd_h vc_command, void* user_data)
    {
       // Your code
    	
       return true;
    }
    
    void 
    foreach_command(vc_cmd_list_h vc_cmd_list)
    {
       int ret;
       vc_cmd_h vc_cmd;
       ret = vc_cmd_list_foreach_commands(vc_cmd_list, __vc_get_command_cb, NULL);
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
    }
    
    void 
    get_commands(vc_cmd_list_h vc_cmd_list)
    {
       int i;
       int ret;
       int count;
       vc_cmd_h vc_cmd;
       char* command = NULL;
       int type = 0;
    
       ret = vc_cmd_list_get_count(vc_cmd_list, &count);
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
    
       if (0 >= count) 
       {
          // Error handling
    		
          return;
       }
    
       ret = vc_cmd_list_first(vc_cmd_list);
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
    	
       do 
       {
          ret = vc_cmd_list_get_current(vc_cmd_list, &vc_cmd);
          if (VC_ERROR_NONE == ret) 
          {
             ret = vc_cmd_get_command(vc_cmd, &command);
             if (VC_ERROR_NONE != ret) 
             {
                // Error handling
             }
             if (NULL != command) 
             {
                // Command must be released
                free(command);
             }
    
             ret = vc_cmd_get_type(vc_cmd, &type);
             if (VC_ERROR_NONE != ret) 
             {
                // Error handling
             }
             // Do not release the command handle
          }
    
          ret = vc_cmd_list_next(vc_cmd_list);
       } while (VC_ERROR_ITERATION_END != ret);
    }
    
  4. Register the commands for recognition by setting the command list to the voice control.

    If you want to update registered commands, set the command list again with the updated commands.

    void 
    set_command(vc_cmd_list_h vc_cmd_list, int type)
    {
       int ret;
       ret = vc_set_command_list(vc_cmd_list, type); 
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
    }
    
  5. When no longer needed, unset the command list, and destroy the command and command list handles.

    When you destroy the command list, all the commands in the command list are not automatically released. If you no longer need the commands, set the second parameter of the vc_cmd_list_destroy() function to true.

    void 
    unset_command(int type)
    {
       int ret;
       ret = vc_unset_command_list(type); 
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
    }
    
    void 
    destroy_command(vc_cmd_h vc_cmd)
    {
       int ret;
       ret = vc_cmd_destroy(vc_cmd);
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
    }
    
    void 
    destroy_command_list(vc_cmd_list_h vc_cmd_list)
    {
       int ret;
       ret = vc_cmd_list_destroy(vc_cmd_list, true); // true destroys all commands
       if (VC_ERROR_NONE != ret) 
       {
          // Error handling
       }
    }
    
Go to top