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
Initialize and prepare the voice control for use.
-
Managing Callbacks
Set and unset callbacks to get notifications about recognition results, state changes, and errors.
-
Retrieving Voice Control Information
Get information about the current states, and current and supported languages.
-
Managing Commands
Create a command list and commands.
Initializing the Voice Control
To initialize and prepare the voice control for use:
- 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>
- 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. - 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 } }
- 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(¤t_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:
- 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.
- After recording, the service state changes to VC_SERVICE_STATE_PROCESSING for recognition processing.
- 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(¤t_lang); if (VC_ERROR_NONE != ret) { // Error handling } }
Managing Commands
To create a command list and commands:
- 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 } }
- 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 } }
- 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); }
- 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 } }
- 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 } }