feat: Update API for release v2.0

This commit is contained in:
sxy 2022-07-08 19:25:49 +08:00
parent f76da537fd
commit ac47452d21
21 changed files with 2101 additions and 584 deletions

File diff suppressed because it is too large Load Diff

View File

@ -246,6 +246,28 @@ void dl_dilation_layerq8_mc_steps(dl_convq8_queue_t **in, dl_convq8_queue_t **ou
void dl_convq8_queue_mc_bzero(dl_convq8_queue_t **cqm, int nch); void dl_convq8_queue_mc_bzero(dl_convq8_queue_t **cqm, int nch);
dl_convq8_queue_t *dl_convq8_queue_alloc_from_psram(int n, int c);
qtp_t *dl_dilation_layerq16_8(dl_convq_queue_t *in, dl_convq8_queue_t *out, int rate, int size,
dl_matrix2dq_t* filter_kernel, dl_matrix2dq_t* filter_bias,
dl_matrix2dq_t* gate_kernel, dl_matrix2dq_t* gate_bias, int prenum);
qtp_t *dl_dilation_layerq8(dl_convq8_queue_t *in, dl_convq8_queue_t *out, int rate, int size,
dl_matrix2dq8_t* filter_kernel, dl_matrix2dq_t* filter_bias,
dl_matrix2dq8_t* gate_kernel, dl_matrix2dq_t* gate_bias, int prenum);
dl_matrix2dq8_t *dl_convq8_lstm_layer(const dl_convq8_queue_t *in, dl_convq8_queue_t *out, dl_matrix2dq8_t *state_c,
dl_matrix2dq8_t *state_h, const dl_matrix2dq8_t *in_weight, const dl_matrix2dq8_t *h_weight,
const dl_matrix2dq_t *bias, int prenum);
qtp_t *dl_atrous_conv1dq8_16_s3(dl_convq8_queue_t *in, dl_convq_queue_t *out, int rate, int size,
dl_matrix2dq8_t* kernel, dl_matrix2dq_t* bias, int prenum);
void print_convq8(dl_convq8_queue_t *cq, int offset); void print_convq8(dl_convq8_queue_t *cq, int offset);
void print_convq(dl_convq_queue_t *cq, int offset); void print_convq(dl_convq_queue_t *cq, int offset);
void lstmq8_free(void);
#endif #endif

View File

@ -39,16 +39,17 @@ typedef struct {
bool vad_init; bool vad_init;
bool wakenet_init; bool wakenet_init;
bool voice_communication_init; bool voice_communication_init;
bool voip_agc_init; // AGC swich for voice communication
int voip_agc_gain; // AGC gain(dB) for voice communication
vad_mode_t vad_mode; // The value can be: VAD_MODE_0, VAD_MODE_1, VAD_MODE_2, VAD_MODE_3, VAD_MODE_4 vad_mode_t vad_mode; // The value can be: VAD_MODE_0, VAD_MODE_1, VAD_MODE_2, VAD_MODE_3, VAD_MODE_4
esp_wn_iface_t *wakenet_model; char *wakenet_model_name; // The model name of wakenet
void *wakenet_coeff;
det_mode_t wakenet_mode; det_mode_t wakenet_mode;
afe_sr_mode_t afe_mode; afe_sr_mode_t afe_mode;
int afe_perferred_core; int afe_perferred_core;
int afe_perferred_priority; int afe_perferred_priority;
int afe_ringbuf_size; int afe_ringbuf_size;
afe_memory_alloc_mode_t memory_alloc_mode; afe_memory_alloc_mode_t memory_alloc_mode;
afe_mn_peak_agc_mode_t agc_mode; afe_mn_peak_agc_mode_t agc_mode; // The agc mode for ASR
afe_pcm_config_t pcm_config; // Config the channel num of original data which is fed to the afe feed function. afe_pcm_config_t pcm_config; // Config the channel num of original data which is fed to the afe feed function.
} afe_config_t; } afe_config_t;
@ -60,9 +61,10 @@ typedef struct {
.vad_init = true, \ .vad_init = true, \
.wakenet_init = true, \ .wakenet_init = true, \
.voice_communication_init = false, \ .voice_communication_init = false, \
.voip_agc_init = false, \
.voip_agc_gain = 15, \
.vad_mode = VAD_MODE_3, \ .vad_mode = VAD_MODE_3, \
.wakenet_model = &WAKENET_MODEL, \ .wakenet_model_name = NULL, \
.wakenet_coeff = &WAKENET_COEFF, \
.wakenet_mode = DET_MODE_90, \ .wakenet_mode = DET_MODE_90, \
.afe_mode = SR_MODE_HIGH_PERF, \ .afe_mode = SR_MODE_HIGH_PERF, \
.afe_perferred_core = 0, \ .afe_perferred_core = 0, \
@ -81,9 +83,10 @@ typedef struct {
.vad_init = true, \ .vad_init = true, \
.wakenet_init = true, \ .wakenet_init = true, \
.voice_communication_init = false, \ .voice_communication_init = false, \
.voip_agc_init = false, \
.voip_agc_gain = 15, \
.vad_mode = VAD_MODE_3, \ .vad_mode = VAD_MODE_3, \
.wakenet_model = (esp_wn_iface_t *)&WAKENET_MODEL, \ .wakenet_model_name = NULL, \
.wakenet_coeff = (void *)&WAKENET_COEFF, \
.wakenet_mode = DET_MODE_2CH_90, \ .wakenet_mode = DET_MODE_2CH_90, \
.afe_mode = SR_MODE_LOW_COST, \ .afe_mode = SR_MODE_LOW_COST, \
.afe_perferred_core = 0, \ .afe_perferred_core = 0, \

View File

@ -1,10 +1,6 @@
#pragma once #pragma once
#include "stdint.h" #include "stdint.h"
#if CONFIG_AFE_INTERFACE_V1
#include "esp_afe_config.h" #include "esp_afe_config.h"
#else
#include "esp_afe_config.h"
#endif
//AFE: Audio Front-End //AFE: Audio Front-End
//SR: Speech Recognition //SR: Speech Recognition
@ -13,24 +9,30 @@
//Opaque AFE_SR data container //Opaque AFE_SR data container
typedef struct esp_afe_sr_data_t esp_afe_sr_data_t; typedef struct esp_afe_sr_data_t esp_afe_sr_data_t;
// the output state of fetch function /**
typedef enum { * @brief The state of vad
AFE_FETCH_ERROR = -3, // fetch empty data, retry it */
AFE_FETCH_CHANNEL_VERIFIED = -2, // wwe state: output channel is verified typedef enum
AFE_FETCH_NOISE = -1, // vad state: noise or silence {
AFE_FETCH_SPEECH = 0, // vad state: speech AFE_VAD_SILENCE = 0, // noise or silence
AFE_FETCH_WWE_DETECTED = 1 // wwe state: wake word is detected AFE_VAD_SPEECH // speech
} afe_fetch_mode_t; } afe_vad_state_t;
/** /**
* @brief Function to initialze a AFE_SR instance with a specified mode * @brief The result of fetch function
*
* @param mode The mode of AFE_SR
* @param perferred_core The perferred core to be pinned.
* If all task in AFE_SR can not run in real time by only one core, the another core would be used.
* @returns Handle to the AFE_SR data
*/ */
typedef esp_afe_sr_data_t* (*esp_afe_sr_iface_op_create_t)(afe_sr_mode_t mode, int perferred_cor); typedef struct afe_fetch_result_t
{
int16_t *data; // the data of audio.
int data_size; // the size of data. The unit is byte.
int wakeup_state; // the value is afe_wakeup_state_t
int wake_word_index; // if the wake word is detected. It will store the wake word index which start from 1.
int vad_state; // the value is afe_vad_state_t
int trigger_channel_id; // the channel index of output
int wake_word_length; // the length of wake word. It's unit is the number of samples.
int ret_value; // the return state of fetch function
void* reserved; // reserved for future use
} afe_fetch_result_t;
/** /**
* @brief Function to initialze a AFE_SR instance * @brief Function to initialze a AFE_SR instance
@ -54,37 +56,37 @@ typedef int (*esp_afe_sr_iface_op_get_samp_chunksize_t)(esp_afe_sr_data_t *afe);
/** /**
* @brief Get the total channel number which be config * @brief Get the total channel number which be config
* *
* @param afe The AFE_SR object to query * @param afe The AFE_SR object to query
* @return The amount of total channels * @return The amount of total channels
*/ */
typedef int (*esp_afe_sr_iface_op_get_total_channel_num_t)(esp_afe_sr_data_t *afe); typedef int (*esp_afe_sr_iface_op_get_total_channel_num_t)(esp_afe_sr_data_t *afe);
/** /**
* @brief Get the mic channel number which be config * @brief Get the mic channel number which be config
* *
* @param afe The AFE_SR object to query * @param afe The AFE_SR object to query
* @return The amount of mic channels * @return The amount of mic channels
*/ */
typedef int (*esp_afe_sr_iface_op_get_channel_num_t)(esp_afe_sr_data_t *afe); typedef int (*esp_afe_sr_iface_op_get_channel_num_t)(esp_afe_sr_data_t *afe);
/** /**
* @brief Get the sample rate of the samples to feed to the function * @brief Get the sample rate of the samples to feed to the function
* *
* @param afe The AFE_SR object to query * @param afe The AFE_SR object to query
* @return The sample rate, in hz * @return The sample rate, in hz
*/ */
typedef int (*esp_afe_sr_iface_op_get_samp_rate_t)(esp_afe_sr_data_t *afe); typedef int (*esp_afe_sr_iface_op_get_samp_rate_t)(esp_afe_sr_data_t *afe);
/** /**
* @brief Feed samples of an audio stream to the AFE_SR * @brief Feed samples of an audio stream to the AFE_SR
* *
* @Warning The input data should be arranged in the format of [CH0_0, CH1_0, ..., CHN_0, CH0_1, CH1_1, ..., CHN_1, ...]. * @Warning The input data should be arranged in the format of channel interleaving.
* The last channel is reference signal or far-end signal. * The last channel is reference signal if it has reference data.
* *
* @param afe The AFE_SR object to queryq * @param afe The AFE_SR object to query
* *
* @param in The input microphone signal, only support signed 16-bit @ 16 KHZ. The frame size can be queried by the * @param in The input microphone signal, only support signed 16-bit @ 16 KHZ. The frame size can be queried by the
* `get_samp_chunksize`. The channel number can be queried `get_channel_num`. * `get_feed_chunksize`.
* @return The size of input * @return The size of input
*/ */
typedef int (*esp_afe_sr_iface_op_feed_t)(esp_afe_sr_data_t *afe, const int16_t* in); typedef int (*esp_afe_sr_iface_op_feed_t)(esp_afe_sr_data_t *afe, const int16_t* in);
@ -95,10 +97,9 @@ typedef int (*esp_afe_sr_iface_op_feed_t)(esp_afe_sr_data_t *afe, const int16_t*
* @Warning The output is single channel data, no matter how many channels the input is. * @Warning The output is single channel data, no matter how many channels the input is.
* *
* @param afe The AFE_SR object to query * @param afe The AFE_SR object to query
* @param out The output enhanced signal. The frame size can be queried by the `get_samp_chunksize`. * @return The result of output, please refer to the definition of `afe_fetch_result_t`. (The frame size of output audio can be queried by the `get_fetch_chunksize`.)
* @return The state of output, please refer to the definition of `afe_fetch_mode_t`
*/ */
typedef afe_fetch_mode_t (*esp_afe_sr_iface_op_fetch_t)(esp_afe_sr_data_t *afe, int16_t* out); typedef afe_fetch_result_t* (*esp_afe_sr_iface_op_fetch_t)(esp_afe_sr_data_t *afe);
/** /**
* @brief Initial wakenet and wake words coefficient, or reset wakenet and wake words coefficient * @brief Initial wakenet and wake words coefficient, or reset wakenet and wake words coefficient
@ -108,7 +109,7 @@ typedef afe_fetch_mode_t (*esp_afe_sr_iface_op_fetch_t)(esp_afe_sr_data_t *afe,
* @param wakenet_word The wakenet word, should be DEFAULT_WAKE_WORD or EXTRA_WAKE_WORD * @param wakenet_word The wakenet word, should be DEFAULT_WAKE_WORD or EXTRA_WAKE_WORD
* @return 0: fail, 1: success * @return 0: fail, 1: success
*/ */
typedef int (*esp_afe_sr_iface_op_set_wakenet_t)(esp_afe_sr_data_t *afe, esp_wn_word_t wakenet_word); typedef int (*esp_afe_sr_iface_op_set_wakenet_t)(esp_afe_sr_data_t *afe, char* model_name);
/** /**
* @brief Disable wakenet model. * @brief Disable wakenet model.
@ -170,7 +171,6 @@ typedef void (*esp_afe_sr_iface_op_destroy_t)(esp_afe_sr_data_t *afe);
* This structure contains the functions used to do operations on a AFE_SR. * This structure contains the functions used to do operations on a AFE_SR.
*/ */
typedef struct { typedef struct {
esp_afe_sr_iface_op_create_t create;
esp_afe_sr_iface_op_create_from_config_t create_from_config; esp_afe_sr_iface_op_create_from_config_t create_from_config;
esp_afe_sr_iface_op_feed_t feed; esp_afe_sr_iface_op_feed_t feed;
esp_afe_sr_iface_op_fetch_t fetch; esp_afe_sr_iface_op_fetch_t fetch;

View File

@ -1,18 +1,27 @@
#pragma once #pragma once
#if defined CONFIG_USE_AFE #if defined CONFIG_USE_AFE
#include "esp_afe_sr_iface.h"
#if CONFIG_AFE_INTERFACE_V1 #if CONFIG_AFE_INTERFACE_V1
#include "esp_afe_sr_iface.h" extern const esp_afe_sr_iface_t esp_afe_sr_v1;
extern const esp_afe_sr_iface_t esp_afe_v1; extern const esp_afe_sr_iface_t esp_afe_voip_v1;
#define ESP_AFE_HANDLE esp_afe_v1 #define ESP_AFE_SR_HANDLE esp_afe_sr_v1
#define ESP_AFE_VOIP_HANDLE esp_afe_voip_v1
#else #else
#error No valid afe selected. #error No valid afe selected.
#endif #endif
#else #else
#include "esp_afe_sr_iface.h" #include "esp_afe_sr_iface.h"
extern const esp_afe_sr_iface_t esp_afe_v1; extern const esp_afe_sr_iface_t esp_afe_sr_v1;
#define ESP_AFE_HANDLE esp_afe_v1 extern const esp_afe_sr_iface_t esp_afe_voip_v1;
#define ESP_AFE_SR_HANDLE esp_afe_sr_v1
#define ESP_AFE_VOIP_HANDLE esp_afe_voip_v1
#endif #endif

View File

@ -1,40 +1,53 @@
#pragma once #pragma once
#include "stdint.h" #include "stdint.h"
#include "dl_lib_coefgetter_if.h"
#include "esp_wn_iface.h" #include "esp_wn_iface.h"
// Return all possible recognition results
#define ESP_MN_RESULT_MAX_NUM 5 #define ESP_MN_RESULT_MAX_NUM 5
#define ESP_MN_MAX_PHRASE_NUM 200 #define ESP_MN_MAX_PHRASE_NUM 200
#define ESP_MN_MAX_PHRASE_LEN 63
#define ESP_MN_MIN_PHRASE_LEN 2
typedef enum { typedef enum {
ESP_MN_STATE_DETECTING = 0, // detecting ESP_MN_STATE_DETECTING = 0, // detecting
ESP_MN_STATE_DETECTED = 1, // detected ESP_MN_STATE_DETECTED = 1, // detected
ESP_MN_STATE_TIMEOUT = 2, // time out ESP_MN_STATE_TIMEOUT = 2, // time out
} esp_mn_state_t; } esp_mn_state_t;
// Return all possible recognition results
typedef struct{ typedef struct{
esp_mn_state_t state; esp_mn_state_t state;
int num; // The number of phrase in list, num<=5. When num=0, no phrase is recognized. int num; // The number of phrase in list, num<=5. When num=0, no phrase is recognized.
int command_id[ESP_MN_RESULT_MAX_NUM]; // The list of command id. int command_id[ESP_MN_RESULT_MAX_NUM]; // The list of command id.
int phrase_id[ESP_MN_RESULT_MAX_NUM]; // The list of phrase id. int phrase_id[ESP_MN_RESULT_MAX_NUM]; // The list of phrase id.
float prob[ESP_MN_RESULT_MAX_NUM]; // The list of probability. float prob[ESP_MN_RESULT_MAX_NUM]; // The list of probability.
} esp_mn_results_t; } esp_mn_results_t;
typedef struct{ typedef struct{
int16_t err_id_num; int16_t num; // The number of error phrases, which can not added into model
int16_t err_id[ESP_MN_MAX_PHRASE_NUM]; int16_t phrase_idx[ESP_MN_MAX_PHRASE_NUM]; // The error phrase index in singly linked list
} esp_mn_phrase_err_id_t; } esp_mn_error_t;
typedef struct {
char phoneme_string[ESP_MN_MAX_PHRASE_LEN + 1]; // phoneme string
int16_t command_id; // the command id
float threshold; // trigger threshold, default: 0
int16_t *wave; // prompt wave data of the phrase
} esp_mn_phrase_t;
typedef struct _mn_node_ {
esp_mn_phrase_t *phrase;
struct _mn_node_ *next;
} esp_mn_node_t;
/** /**
* @brief Initialze a model instance with specified model coefficient. * @brief Initialze a model instance with specified model name.
* *
* @param coeff The wakenet model coefficient. * @param model_name The wakenet model name.
* @param duration The duration (ms) to trigger the timeout * @param duration The duration (ms) to trigger the timeout
* @parm sample_length Audio length for speech recognition, in ms. *
* @returns Handle to the model data. * @returns Handle to the model data.
*/ */
typedef model_iface_data_t* (*esp_mn_iface_op_create_t)(const model_coeff_getter_t *coeff, int duration); typedef model_iface_data_t* (*esp_mn_iface_op_create_t)(const char *model_name, int duration);
/** /**
* @brief Callback function type to fetch the amount of samples that need to be passed to the detect function * @brief Callback function type to fetch the amount of samples that need to be passed to the detect function
@ -62,24 +75,6 @@ typedef int (*esp_mn_iface_op_get_samp_chunknum_t)(model_iface_data_t *model);
* @param det_treshold The threshold to trigger speech commands, the range of det_threshold is 0.0~0.9999 * @param det_treshold The threshold to trigger speech commands, the range of det_threshold is 0.0~0.9999
*/ */
typedef int (*esp_mn_iface_op_set_det_threshold_t)(model_iface_data_t *model, float det_threshold); typedef int (*esp_mn_iface_op_set_det_threshold_t)(model_iface_data_t *model, float det_threshold);
/**
* @brief Set the detection threshold to manually abjust the probability
*
* @param model The model object to query
* @param phrase_id The ID of speech command phrase
* @param det_treshold The threshold to trigger speech command phrases
*/
typedef void (*esp_mn_iface_op_set_command_det_threshold_t)(model_iface_data_t *model, int phrase_id, float det_threshold);
/**
* @brief Get the detection threshold by phrase ID
*
* @param model The model object to query
* @param phrase_id The ID of speech command phrase
*
* @return The threshold of speech command phrases
*/
typedef float (*esp_mn_iface_op_get_command_det_threshold_t)(model_iface_data_t *model, int phrase_id);
/** /**
* @brief Get the sample rate of the samples to feed to the detect function * @brief Get the sample rate of the samples to feed to the detect function
@ -95,18 +90,9 @@ typedef int (*esp_mn_iface_op_get_samp_rate_t)(model_iface_data_t *model);
* @param model The model object to query. * @param model The model object to query.
* @param samples An array of 16-bit signed audio samples. The array size used can be queried by the * @param samples An array of 16-bit signed audio samples. The array size used can be queried by the
* get_samp_chunksize function. * get_samp_chunksize function.
* @return The command id, return 0 if no command word is detected, * @return The state of multinet
*/ */
typedef int (*esp_mn_iface_op_detect_t)(model_iface_data_t *model, int16_t *samples); typedef esp_mn_state_t (*esp_mn_iface_op_detect_t)(model_iface_data_t *model, int16_t *samples);
/**
* @brief Get the phrase if command word is detected
*
* @param model The model object to query.
*
* @return The phrase id, return the phrase if command word is detected.
*/
typedef int (*esp_mn_iface_op_get_det_phrase_id_t)(model_iface_data_t *model);
/** /**
* @brief Destroy a speech commands recognition model * @brief Destroy a speech commands recognition model
@ -115,17 +101,6 @@ typedef int (*esp_mn_iface_op_get_det_phrase_id_t)(model_iface_data_t *model);
*/ */
typedef void (*esp_mn_iface_op_destroy_t)(model_iface_data_t *model); typedef void (*esp_mn_iface_op_destroy_t)(model_iface_data_t *model);
/**
* @brief Reset the speech commands
*
* @param model_data The model object to query.
* @param command_str The string of new commands.
* @param command_id -1 means modify all commands with new command_str, 0-200 means modify the corresponding command
*
* @return The error ID structure
*/
typedef esp_mn_phrase_err_id_t* (*esp_mn_iface_op_reset_t)(model_iface_data_t *model_data, char *command_str, int command_id);
/** /**
* @brief Get recognition results * @brief Get recognition results
* *
@ -136,20 +111,21 @@ typedef esp_mn_phrase_err_id_t* (*esp_mn_iface_op_reset_t)(model_iface_data_t *m
typedef esp_mn_results_t* (*esp_mn_iface_op_get_results_t)(model_iface_data_t *model); typedef esp_mn_results_t* (*esp_mn_iface_op_get_results_t)(model_iface_data_t *model);
/** /**
* @brief Reset the speech commands recognition model * @brief Open the log print
* *
* @param model_data The model object to query. * @param model_data The model object to query.
* *
*/ */
typedef void (*esp_mn_iface_op_wakenet_reset_t)(model_iface_data_t *model_data); typedef void (*esp_mn_iface_op_open_log_t)(model_iface_data_t *model_data);
/** /**
* @brief Close the log print * @brief Set the speech commands by mn_command_root
* *
* @param model_data The model object to query. * @param model_data The model object to query.
* * @param mn_command_root The speech commands link.
* @return The error phrase id info.
*/ */
typedef void (*esp_mn_iface_op_close_log_t)(model_iface_data_t *model_data); typedef esp_mn_error_t* (*esp_wn_iface_op_set_speech_commands)(model_iface_data_t *model_data, esp_mn_node_t *mn_command_root);
typedef struct { typedef struct {
esp_mn_iface_op_create_t create; esp_mn_iface_op_create_t create;
@ -157,13 +133,9 @@ typedef struct {
esp_mn_iface_op_get_samp_chunksize_t get_samp_chunksize; esp_mn_iface_op_get_samp_chunksize_t get_samp_chunksize;
esp_mn_iface_op_get_samp_chunknum_t get_samp_chunknum; esp_mn_iface_op_get_samp_chunknum_t get_samp_chunknum;
esp_mn_iface_op_set_det_threshold_t set_det_threshold; esp_mn_iface_op_set_det_threshold_t set_det_threshold;
esp_mn_iface_op_set_command_det_threshold_t set_command_det_threshold;
esp_mn_iface_op_get_command_det_threshold_t get_command_det_threshold;
esp_mn_iface_op_get_det_phrase_id_t get_det_phrase_id;
esp_mn_iface_op_detect_t detect; esp_mn_iface_op_detect_t detect;
esp_mn_iface_op_destroy_t destroy; esp_mn_iface_op_destroy_t destroy;
esp_mn_iface_op_reset_t reset;
esp_mn_iface_op_get_results_t get_results; esp_mn_iface_op_get_results_t get_results;
esp_mn_iface_op_wakenet_reset_t wakenet_reset; esp_mn_iface_op_open_log_t open_log;
esp_mn_iface_op_close_log_t close_log; esp_wn_iface_op_set_speech_commands set_speech_commands;
} esp_mn_iface_t; } esp_mn_iface_t;

View File

@ -3,14 +3,28 @@
//Contains declarations of all available speech recognion models. Pair this up with the right coefficients and you have a model that can recognize //Contains declarations of all available speech recognion models. Pair this up with the right coefficients and you have a model that can recognize
//a specific phrase or word. //a specific phrase or word.
extern const esp_mn_iface_t esp_sr_multinet1_single_quantized_en;
extern const esp_mn_iface_t esp_sr_multinet3_single_quantized_en;
extern const esp_mn_iface_t esp_sr_multinet2_single_quantized_cn;
extern const esp_mn_iface_t esp_sr_multinet3_single_quantized_cn; #define ESP_MN_PREFIX "mn"
extern const esp_mn_iface_t esp_sr_multinet4_single_quantized_cn; #define ESP_MN_ENGLISH "en"
extern const esp_mn_iface_t esp_sr_multinet3_continuous_quantized_cn; #define ESP_MN_CHINESE "cn"
extern const esp_mn_iface_t esp_sr_multinet5_quantized;
extern const esp_mn_iface_t esp_sr_multinet5_quantized8; /**
* @brief Get the multinet handle from model name
*
* @param model_name The name of model
* @returns The handle of multinet
*/
esp_mn_iface_t *esp_mn_handle_from_name(char *model_name);
/**
* @brief Get the multinet language from model name
*
* @param model_name The name of model
* @returns The language of multinet
*/
char *esp_mn_language_from_name(char *model_name);
/* /*
Configure wake word to use based on what's selected in menuconfig. Configure wake word to use based on what's selected in menuconfig.
@ -19,42 +33,19 @@ extern const esp_mn_iface_t esp_sr_multinet5_quantized8;
#if CONFIG_SR_MN_CN_MULTINET2_SINGLE_RECOGNITION #if CONFIG_SR_MN_CN_MULTINET2_SINGLE_RECOGNITION
#include "multinet2_ch.h" #include "multinet2_ch.h"
#define MULTINET_MODEL_CN esp_sr_multinet2_single_quantized_cn
#define MULTINET_COEFF_CN get_coeff_multinet2_ch
#define MULTINET_MODEL esp_sr_multinet2_single_quantized_cn
#define MULTINET_COEFF get_coeff_multinet2_ch #define MULTINET_COEFF get_coeff_multinet2_ch
#elif CONFIG_SR_MN_CN_MULTINET4_SINGLE_RECOGNITION #define MULTINET_MODEL_NAME "mn2_cn"
#define MULTINET_MODEL_CN esp_sr_multinet4_single_quantized_cn
#define MULTINET_COEFF_CN "mn4cn"
#define MULTINET_MODEL esp_sr_multinet4_single_quantized_cn
#define MULTINET_COEFF "mn4cn"
#elif CONFIG_SR_MN_CN_MULTINET4_5_SINGLE_RECOGNITION
#define MULTINET_MODEL_CN esp_sr_multinet4_single_quantized_cn
#define MULTINET_COEFF_CN "mn4_5cn"
#define MULTINET_MODEL esp_sr_multinet4_single_quantized_cn
#define MULTINET_COEFF "mn4_5cn"
#endif
#if CONFIG_SR_MN_EN_MULTINET5_SINGLE_RECOGNITION #else
#define MULTINET_MODEL_EN esp_sr_multinet5_quantized #define MULTINET_COEFF "COEFF_NULL"
#define MULTINET_COEFF_EN "mn5en" #define MULTINET_MODEL_NAME "NULL"
#ifndef MULTINET_MODEL
#define MULTINET_MODEL esp_sr_multinet5_quantized
#define MULTINET_COEFF "mn5en"
#endif
#elif CONFIG_SR_MN_EN_MULTINET5_SINGLE_RECOGNITION_QUANT8
#define MULTINET_MODEL_EN esp_sr_multinet5_quantized8
#define MULTINET_COEFF_EN "mn5q8en"
#ifndef MULTINET_MODEL
#define MULTINET_MODEL esp_sr_multinet5_quantized8
#define MULTINET_COEFF "mn5q8en"
#endif
#endif #endif
#else #else
#define MULTINET_MODEL "NULL" #define MULTINET_COEFF "COEFF_NULL"
#define MULTINET_COEFF "NULL" #define MULTINET_MODEL_NAME "NULL"
#endif #endif
/* example /* example
static const esp_mn_iface_t *multinet = &MULTINET_MODEL; static const esp_mn_iface_t *multinet = &MULTINET_MODEL;

View File

@ -0,0 +1,158 @@
// Copyright 2015-2022 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "esp_err.h"
#include "esp_mn_iface.h"
/*
esp_mn_node_t is a singly linked list which is used to manage speech commands.
It is easy to add one speech command into linked list and remove one speech command from linked list.
*/
/**
* @brief Initialze the speech commands singly linked list.
*
* @return
* - ESP_OK Success
* - ESP_ERR_NO_MEM No memory
* - ESP_ERR_INVALID_STATE The Speech Commands link has been initialized
*/
esp_err_t esp_mn_commands_alloc(void);
/**
* @brief Clear the speech commands linked list and free root node.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_STATE The Speech Commands link has not been initialized
*/
esp_err_t esp_mn_commands_free(void);
/**
* @brief Add one speech commands with phoneme string and command ID
*
* @param command_id The command ID
* @param phoneme_string The phoneme string of the speech commands
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_STATE Fail
*/
esp_err_t esp_mn_commands_add(int command_id, char *phoneme_string);
/**
* @brief Modify one speech commands with new phoneme string
*
* @param old_phoneme_string The old phoneme string of the speech commands
* @param new_phoneme_string The new phoneme string of the speech commands
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_STATE Fail
*/
esp_err_t esp_mn_commands_modify(char *old_phoneme_string, char *new_phoneme_string);
/**
* @brief Remove one speech commands by phoneme string
*
* @param phoneme_string The phoneme string of the speech commands
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_STATE Fail
*/
esp_err_t esp_mn_commands_remove(char *phoneme_string);
/**
* @brief Clear all speech commands in linked list
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_STATE Fail
*/
esp_err_t esp_mn_commands_clear(void);
/**
* @brief Get phrase from index, which is the depth from the phrase node to root node
*
* @Warning: The first phrase index is 0, the second phrase index is 1, and so on.
*
* @return
* - esp_mn_phrase_t* Success
* - NULL Fail
*/
esp_mn_phrase_t *esp_mn_commands_get_from_index(int index);
/**
* @brief Get phrase from phoneme string
*
* @return
* - esp_mn_phrase_t* Success
* - NULL Fail
*/
esp_mn_phrase_t *esp_mn_commands_get_from_string(const char *phoneme_string);
/**
* @brief Update the speech commands of MultiNet
*
* @Warning: Must be used after [add/remove/modify/clear] function,
* otherwise the language model of multinet can not be updated.
*
* @param multinet The multinet handle
* @param model_data The model object to query
*
* @return
* - NULL Success
* - others The list of error phrase which can not be parsed by multinet.
*/
esp_mn_error_t *esp_mn_commands_update(const esp_mn_iface_t *multinet, const model_iface_data_t *model_data);
/**
* @brief Print the MultiNet Speech Commands.
*/
void esp_mn_print_commands(void);
/**
* @brief Initialze the esp_mn_phrase_t struct by command id and phoneme string .
*
* @return the pointer of esp_mn_phrase_t
*/
esp_mn_phrase_t *esp_mn_phrase_alloc(int command_id, char *phoneme_string);
/**
* @brief Free esp_mn_phrase_t pointer.
*
* @param phrase The esp_mn_phrase_t pointer
*/
void esp_mn_phrase_free(esp_mn_phrase_t *phrase);
/**
* @brief Initialze the esp_mn_node_t struct by esp_mn_phrase_t pointer.
*
* @return the pointer of esp_mn_node_t
*/
esp_mn_node_t *esp_mn_node_alloc(esp_mn_phrase_t *phrase);
/**
* @brief Free esp_mn_node_t pointer.
*
* @param node The esp_mn_node_free pointer
*/
void esp_mn_node_free(esp_mn_node_t *node);
/**
* @brief Print phrase linked list.
*/
void esp_mn_commands_print(void);

View File

@ -0,0 +1,23 @@
#pragma once
#include "esp_err.h"
#include "esp_mn_iface.h"
/**
* @brief Check chip config to ensure optimum performance
*/
void check_chip_config(void);
/**
* @brief Update the speech commands of MultiNet by menuconfig
*
* @param multinet The multinet handle
*
* @param model_data The model object to query
*
* @param langugae The language of MultiNet
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_STATE Fail
*/
esp_err_t esp_mn_commands_update_from_sdkconfig(esp_mn_iface_t *multinet, const model_iface_data_t *model_data);

View File

@ -1,10 +1,19 @@
#pragma once #pragma once
#include "stdint.h" #include "stdint.h"
#include "dl_lib_coefgetter_if.h"
//Opaque model data container //Opaque model data container
typedef struct model_iface_data_t model_iface_data_t; typedef struct model_iface_data_t model_iface_data_t;
/**
* @brief The state of wakeup
*/
typedef enum
{
WAKENET_NO_DETECT = 0, // wake word is not detected
WAKENET_CHANNEL_VERIFIED = -1, // output channel is verified
WAKENET_DETECTED = 1 // wake word is detected
} wakenet_state_t;
//Set wake words recognition operating mode //Set wake words recognition operating mode
//The probability of being wake words is increased with increasing mode, //The probability of being wake words is increased with increasing mode,
//As a consequence also the false alarm rate goes up //As a consequence also the false alarm rate goes up
@ -25,14 +34,14 @@ typedef struct {
/** /**
* @brief Easy function type to initialze a model instance with a detection mode and specified wake word coefficient * @brief Easy function type to initialze a model instance with a detection mode and specified wake word coefficient
* *
* @param model_name The specified wake word model coefficient
* @param det_mode The wake words detection mode to trigger wake words, DET_MODE_90 or DET_MODE_95 * @param det_mode The wake words detection mode to trigger wake words, DET_MODE_90 or DET_MODE_95
* @param model_coeff The specified wake word model coefficient
* @returns Handle to the model data * @returns Handle to the model data
*/ */
typedef model_iface_data_t* (*esp_wn_iface_op_create_t)(const model_coeff_getter_t *model_coeff, det_mode_t det_mode); typedef model_iface_data_t* (*esp_wn_iface_op_create_t)(const void *model_name, det_mode_t det_mode);
/** /**
* @brief Callback function type to fetch the amount of samples that need to be passed to the detect function * @brief Get the amount of samples that need to be passed to the detect function
* *
* Every speech recognition model processes a certain number of samples at the same time. This function * Every speech recognition model processes a certain number of samples at the same time. This function
* can be used to query that amount. Note that the returned amount is in 16-bit samples, not in bytes. * can be used to query that amount. Note that the returned amount is in 16-bit samples, not in bytes.
@ -43,7 +52,7 @@ typedef model_iface_data_t* (*esp_wn_iface_op_create_t)(const model_coeff_getter
typedef int (*esp_wn_iface_op_get_samp_chunksize_t)(model_iface_data_t *model); typedef int (*esp_wn_iface_op_get_samp_chunksize_t)(model_iface_data_t *model);
/** /**
* @brief Callback function type to fetch the channel number of samples that need to be passed to the detect function * @brief Get the channel number of samples that need to be passed to the detect function
* *
* Every speech recognition model processes a certain number of samples at the same time. This function * Every speech recognition model processes a certain number of samples at the same time. This function
* can be used to query that amount. Note that the returned amount is in 16-bit samples, not in bytes. * can be used to query that amount. Note that the returned amount is in 16-bit samples, not in bytes.
@ -53,6 +62,17 @@ typedef int (*esp_wn_iface_op_get_samp_chunksize_t)(model_iface_data_t *model);
*/ */
typedef int (*esp_wn_iface_op_get_channel_num_t)(model_iface_data_t *model); typedef int (*esp_wn_iface_op_get_channel_num_t)(model_iface_data_t *model);
/**
* @brief Get the start point of wake word when one wake word is detected.
*
* @Warning: This function should be called when the channel index is verified.
* The returned value is the number of samples from start point of wake word to detected point.
*
* @param model The model object to query
* @return The number of samples from start point to detected point (end point)
*/
typedef int (*esp_wn_iface_op_get_start_point_t)(model_iface_data_t *model);
/** /**
* @brief Get the sample rate of the samples to feed to the detect function * @brief Get the sample rate of the samples to feed to the detect function
@ -110,7 +130,7 @@ typedef float (*esp_wn_iface_op_get_det_threshold_t)(model_iface_data_t *model,
* get_samp_chunksize function. * get_samp_chunksize function.
* @return The index of wake words, return 0 if no wake word is detected, else the index of the wake words. * @return The index of wake words, return 0 if no wake word is detected, else the index of the wake words.
*/ */
typedef int (*esp_wn_iface_op_detect_t)(model_iface_data_t *model, int16_t *samples); typedef wakenet_state_t (*esp_wn_iface_op_detect_t)(model_iface_data_t *model, int16_t *samples);
/** /**
* @brief Get the volume gain * @brief Get the volume gain
@ -149,6 +169,7 @@ typedef void (*esp_wn_iface_op_destroy_t)(model_iface_data_t *model);
*/ */
typedef struct { typedef struct {
esp_wn_iface_op_create_t create; esp_wn_iface_op_create_t create;
esp_wn_iface_op_get_start_point_t get_start_point;
esp_wn_iface_op_get_samp_chunksize_t get_samp_chunksize; esp_wn_iface_op_get_samp_chunksize_t get_samp_chunksize;
esp_wn_iface_op_get_channel_num_t get_channel_num; esp_wn_iface_op_get_channel_num_t get_channel_num;
esp_wn_iface_op_get_samp_rate_t get_samp_rate; esp_wn_iface_op_get_samp_rate_t get_samp_rate;

View File

@ -1,141 +1,109 @@
#pragma once #pragma once
#include "esp_wn_iface.h" #include "esp_wn_iface.h"
//Contains declarations of all available speech recognion models. Pair this up with the right coefficients and you have a model that can recognize
//a specific phrase or word.
typedef enum { // The prefix of wakenet model name is used to filter all wakenet from availabel models.
FIRST_WAKE_WORD = 0, #define ESP_WN_PREFIX "wn"
SECOND_WAKE_WORD,
} esp_wn_word_t;
typedef enum { /**
NO_WAKE_WORD = -1, * @brief Get the wakenet handle from model name
CUSTOMIZED_WORD_WN7 = 0, *
XIAOAITONGXUE_WN7 = 1, * @param model_name The name of model
XIAOAITONGXUE_WN7Q8, * @returns The handle of wakenet
ALEXA_WN7, */
ALEXA_WN7Q8, const esp_wn_iface_t *esp_wn_handle_from_name(const char *model_name);
ALEXA_WN8,
HILEXIN_WN7,
HILEXIN_WN7Q8,
HILEXIN_WN8,
HIESP_WN8,
HIESP_WN8Q8,
} esp_wn_model_t;
extern const esp_wn_iface_t esp_sr_wakenet5_quantized; /**
extern const esp_wn_iface_t esp_sr_wakenet7_quantized; * @brief Get the wake word name from model name
extern const esp_wn_iface_t esp_sr_wakenet7_quantized8; *
extern const esp_wn_iface_t esp_sr_wakenet8_quantized; * @param model_name The name of model
extern const esp_wn_iface_t esp_sr_wakenet8_quantized8; * @returns The wake word name, like "alexa","hilexin","xiaoaitongxue"
*/
char* esp_wn_wakeword_from_name(const char *model_name);
// /**
// * @brief Get the model coeff from model name
// *
// * @Warning: retuen model_coeff_getter_t, when chip is ESP32,
// * return string for other chips
// *
// * @param model_name The name of model
// * @returns The handle of wakenet
// */
// void *esp_wn_coeff_from_name(char *model_name);
#if defined CONFIG_USE_WAKENET
/* /*
Configure wake word to use based on what's selected in menuconfig. Configure wake word to use based on what's selected in menuconfig.
*/ */
#if defined CONFIG_USE_WAKENET #if CONFIG_SR_WN_WN5_HILEXIN
#if CONFIG_SR_WN_WN5_HILEXIN_FIRST || CONFIG_SR_WN_WN5_HILEXIN_SECOND
#include "hilexin_wn5.h" #include "hilexin_wn5.h"
#define WAKENET_MODEL esp_sr_wakenet5_quantized #define WAKENET_MODEL_NAME "wn5_hilexin"
#define WAKENET_COEFF get_coeff_hilexin_wn5 #define WAKENET_COEFF get_coeff_hilexin_wn5
#elif CONFIG_SR_WN_WN5X2_HILEXIN_FIRST || CONFIG_SR_WN_WN5X2_HILEXIN_SECOND #elif CONFIG_SR_WN_WN5X2_HILEXIN
#include "hilexin_wn5X2.h" #include "hilexin_wn5X2.h"
#define WAKENET_MODEL esp_sr_wakenet5_quantized #define WAKENET_MODEL_NAME "wn5_hilexinX2"
#define WAKENET_COEFF get_coeff_hilexin_wn5X2 #define WAKENET_COEFF get_coeff_hilexin_wn5X2
#elif CONFIG_SR_WN_WN5X3_HILEXIN_FIRST || CONFIG_SR_WN_WN5X3_HILEXIN_SECOND
#elif CONFIG_SR_WN_WN5X3_HILEXIN
#include "hilexin_wn5X3.h" #include "hilexin_wn5X3.h"
#define WAKENET_MODEL esp_sr_wakenet5_quantized #define WAKENET_MODEL_NAME "wn5_hilexinX3"
#define WAKENET_COEFF get_coeff_hilexin_wn5X3 #define WAKENET_COEFF get_coeff_hilexin_wn5X3
#elif CONFIG_SR_WN_WN5_NIHAOXIAOZHI_FIRST || CONFIG_SR_WN_WN5_NIHAOXIAOZHI_SECOND
#elif CONFIG_SR_WN_WN5_NIHAOXIAOZHI
#include "nihaoxiaozhi_wn5.h" #include "nihaoxiaozhi_wn5.h"
#define WAKENET_MODEL esp_sr_wakenet5_quantized #define WAKENET_MODEL_NAME "wn5_nihaoxiaozhi"
#define WAKENET_COEFF get_coeff_nihaoxiaozhi_wn5 #define WAKENET_COEFF get_coeff_nihaoxiaozhi_wn5
#elif CONFIG_SR_WN_WN5X2_NIHAOXIAOZHI_FIRST || CONFIG_SR_WN_WN5X2_NIHAOXIAOZHI_SECOND
#elif CONFIG_SR_WN_WN5X2_NIHAOXIAOZHI
#include "nihaoxiaozhi_wn5X2.h" #include "nihaoxiaozhi_wn5X2.h"
#define WAKENET_MODEL esp_sr_wakenet5_quantized #define WAKENET_MODEL_NAME "wn5_nihaoxiaozhiX2"
#define WAKENET_COEFF get_coeff_nihaoxiaozhi_wn5X2 #define WAKENET_COEFF get_coeff_nihaoxiaozhi_wn5X2
#elif CONFIG_SR_WN_WN5X3_NIHAOXIAOZHI_FIRST || CONFIG_SR_WN_WN5X3_NIHAOXIAOZHI_SECOND
#elif CONFIG_SR_WN_WN5X3_NIHAOXIAOZHI
#include "nihaoxiaozhi_wn5X3.h" #include "nihaoxiaozhi_wn5X3.h"
#define WAKENET_MODEL esp_sr_wakenet5_quantized #define WAKENET_MODEL_NAME "wn5_nihaoxiaozhiX3"
#define WAKENET_COEFF get_coeff_nihaoxiaozhi_wn5X3 #define WAKENET_COEFF get_coeff_nihaoxiaozhi_wn5X3
#elif CONFIG_SR_WN_WN5X3_NIHAOXIAOXIN_FIRST || CONFIG_SR_WN_WN5X3_NIHAOXIAOXIN_SECOND
#elif CONFIG_SR_WN_WN5X3_NIHAOXIAOXIN
#include "nihaoxiaoxin_wn5X3.h" #include "nihaoxiaoxin_wn5X3.h"
#define WAKENET_MODEL esp_sr_wakenet5_quantized #define WAKENET_MODEL_NAME "wn5_nihaoxiaoxinX3"
#define WAKENET_COEFF get_coeff_nihaoxiaoxin_wn5X3 #define WAKENET_COEFF get_coeff_nihaoxiaoxin_wn5X3
#elif CONFIG_SR_WN_WN5X3_HIJESON_FIRST || CONFIG_SR_WN_WN5X3_HIJESON_SECOND
#elif CONFIG_SR_WN_WN5X3_HIJESON
#include "hijeson_wn5X3.h" #include "hijeson_wn5X3.h"
#define WAKENET_MODEL esp_sr_wakenet5_quantized #define WAKENET_MODEL_NAME "wn5_hijesonX3"
#define WAKENET_COEFF get_coeff_hijeson_wn5X3 #define WAKENET_COEFF get_coeff_hijeson_wn5X3
#elif CONFIG_SR_WN_WN5_CUSTOMIZED_WORD_FIRST || CONFIG_SR_WN_WN5_CUSTOMIZED_WORD_SECOND #elif CONFIG_SR_WN_WN5_CUSTOMIZED_WORD
#include "customized_word_wn5.h" #include "customized_word_wn5.h"
#define WAKENET_MODEL esp_sr_wakenet5_quantized #define WAKENET_MODEL_NAME "wn5_customizedword"
#define WAKENET_COEFF get_coeff_customized_word_wn5 #define WAKENET_COEFF get_coeff_customizedword_wn5
#elif CONFIG_SR_WN_WN7_CUSTOMIZED_WORD_FIRST || CONFIG_SR_WN_WN7_CUSTOMIZED_WORD_SECOND
#define WAKENET_MODEL esp_sr_wakenet7_quantized
#define WAKENET_COEFF "custom7"
#elif CONFIG_SR_WN_WN7_XIAOAITONGXUE_FIRST || CONFIG_SR_WN_WN7_XIAOAITONGXUE_SECOND
#define WAKENET_MODEL esp_sr_wakenet7_quantized
#define WAKENET_COEFF "xiaoaitongxue7"
#elif CONFIG_SR_WN_WN7Q8_XIAOAITONGXUE_FIRST || CONFIG_SR_WN_WN7Q8_XIAOAITONGXUE_SECOND
#define WAKENET_MODEL esp_sr_wakenet7_quantized8
#define WAKENET_COEFF "xiaoaitongxue7q8"
#elif CONFIG_SR_WN_WN7_HILEXIN_FIRST || CONFIG_SR_WN_WN7_HILEXIN_SECOND
#define WAKENET_MODEL esp_sr_wakenet7_quantized
#define WAKENET_COEFF "hilexin7"
#elif CONFIG_SR_WN_WN7Q8_HILEXIN_FIRST || CONFIG_SR_WN_WN7Q8_HILEXIN_SECOND
#define WAKENET_MODEL esp_sr_wakenet7_quantized8
#define WAKENET_COEFF "hilexin7q8"
#elif CONFIG_SR_WN_WN7_ALEXA_FIRST || CONFIG_SR_WN_WN7_ALEXA_SECOND
#define WAKENET_MODEL esp_sr_wakenet7_quantized
#define WAKENET_COEFF "alexa7"
#elif CONFIG_SR_WN_WN8_ALEXA_FIRST || CONFIG_SR_WN_WN8_ALEXA_SECOND
#define WAKENET_MODEL esp_sr_wakenet8_quantized
#define WAKENET_COEFF "alexa8"
#elif CONFIG_SR_WN_WN7Q8_ALEXA_FIRST || CONFIG_SR_WN_WN7Q8_ALEXA_SECOND
#define WAKENET_MODEL esp_sr_wakenet7_quantized8
#define WAKENET_COEFF "alexa7q8"
#elif CONFIG_SR_WN_WN8_HIESP_FIRST || CONFIG_SR_WN_WN8_HIESP_SECOND
#define WAKENET_MODEL esp_sr_wakenet8_quantized
#define WAKENET_COEFF "hiesp8"
#elif CONFIG_SR_WN_WN8Q8_HIESP_FIRST || CONFIG_SR_WN_WN8Q8_HIESP_SECOND
#define WAKENET_MODEL esp_sr_wakenet8_quantized8
#define WAKENET_COEFF "hiesp8q8"
#elif CONFIG_SR_WN_WN8_HILEXIN_FIRST || CONFIG_SR_WN_WN8_HILEXIN_SECOND
#define WAKENET_MODEL esp_sr_wakenet8_quantized
#define WAKENET_COEFF "hilexin8"
#else #else
#error No valid wake word selected. #define WAKENET_MODEL_NAME "NULL"
#define WAKENET_COEFF "COEFF_NULL"
#endif #endif
#else
#define WAKENET_MODEL "NULL"
#define WAKENET_COEFF "NULL"
#endif
/* example
static const sr_model_iface_t *model = &WAKENET_MODEL; #else
#define WAKENET_MODEL_NAME "NULL"
#define WAKENET_COEFF "COEFF_NULL"
#endif
/*
static const sr_model_iface_t *model = esp_wn_handle_from_name(model_name);
//Initialize wakeNet model data //Initialize wakeNet model data
static model_iface_data_t *model_data=model->create(DET_MODE_90); static model_iface_data_t *model_data=model->create(model_name, DET_MODE_90);
//Set parameters of buffer //Set parameters of buffer
int audio_chunksize=model->get_samp_chunksize(model_data); int audio_chunksize=model->get_samp_chunksize(model_data);

View File

@ -1,3 +1,74 @@
#pragma once #pragma once
char *get_model_base_path(void);
void srmodel_spiffs_init(void); typedef struct
{
char **model_name; // the name of models, like "wn9_hilexin"(wakenet9, hilexin), "mn5_en"(multinet5, english)
int num; // the number of models
} srmodel_list_t;
#define MODEL_NAME_MAX_LENGTH 64
/**
* @brief Return all avaliable models in spiffs or selected in Kconfig.
*
* @return all avaliable models in spiffs,save as srmodel_list_t.
*/
srmodel_list_t* esp_srmodel_init(void);
/**
* @brief Free srmodel_list_t and unregister SPIFFS filesystem if open SPIFFS filesystem.
*
* @param models The srmodel_list_t point allocated by esp_srmodel_init function.
*
* @return all avaliable models in spiffs,save as srmodel_list_t.
*/
void esp_srmodel_deinit(srmodel_list_t *models);
/**
* @brief Return the first model name containing the specified keywords
* If keyword is NULL, we will ignore the keyword.
*
* @param models The srmodel_list_t point allocated by esp_srmodel_init function.
* @param keyword1 The specified keyword1 , like ESP_WN_PREDIX(the prefix of wakenet),
* ESP_MN_PREFIX(the prefix of multinet),
*
* @param keyword2 The specified keyword2, like ESP_MN_ENGLISH(the english multinet)
* ESP_MN_CHINESE(the chinese multinet)
* "alexa" (the "alexa" wakenet)
* @return return model name if can find one model name containing the keywords otherwise return NULL.
*/
char *esp_srmodel_filter(srmodel_list_t *models, const char *keyword1, const char *keyword2);
/**
* @brief Check whether the specified model name exists or not.
*
* @param models The srmodel_list_t point allocated by esp_srmodel_init function.
* @param model_name The specified model name
* @return return index in models if model name exists otherwise return -1
*/
int esp_srmodel_exists(srmodel_list_t *models, char *model_name);
/**
* @brief Initialize and mount SPIFFS filesystem, return all avaliable models in spiffs.
*
* @return all avaliable models in spiffs,save as srmodel_list_t.
*/
srmodel_list_t *srmodel_spiffs_init(void);
/**
* @brief unregister SPIFFS filesystem and free srmodel_list_t.
*
* @param models The srmodel_list_t point allocated by srmodel_spiffs_init function.
*
* @return all avaliable models in spiffs,save as srmodel_list_t.
*/
void srmodel_spiffs_deinit(srmodel_list_t *models);
/**
* @brief Return base path of srmodel spiffs
*
* @return the base path od srmodel spiffs
*/
char *get_model_base_path(void);

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,242 @@
#include <stdio.h>
#include <stdlib.h>
#include "string.h"
#include "esp_log.h"
#include "esp_heap_caps.h"
#include "esp_mn_speech_commands.h"
static char *TAG = "MN_COMMAND";
static esp_mn_node_t *esp_mn_root = NULL;
#define ESP_RETURN_ON_FALSE(a, err_code, log_tag, format, ...) do { \
if (!(a)) { \
ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
return err_code; \
} \
} while(0)
esp_err_t esp_mn_commands_alloc(void)
{
ESP_RETURN_ON_FALSE(NULL == esp_mn_root, ESP_ERR_INVALID_STATE, TAG, "The mn commands already initialized");
esp_mn_root = esp_mn_node_alloc(NULL);
return ESP_OK;
}
esp_err_t esp_mn_commands_free(void)
{
esp_mn_commands_clear();
esp_mn_node_free(esp_mn_root);
esp_mn_root = NULL;
return ESP_OK;
}
int esp_mn_commands_num(void)
{
esp_mn_node_t * t = esp_mn_root;
int i = 0;
while (t->next) {
t = t->next;
i++;
}
return i;
}
esp_err_t esp_mn_commands_clear(void)
{
ESP_RETURN_ON_FALSE(NULL != esp_mn_root, ESP_ERR_INVALID_STATE, TAG, "The mn commands is not initialized");
esp_mn_node_t * t = esp_mn_root->next;
while (t) {
esp_mn_node_t *cur_node = t;
t = t->next;
esp_mn_node_free(cur_node);
}
esp_mn_root->next = NULL;
return ESP_OK;
}
esp_err_t esp_mn_commands_add(int command_id, char *phoneme_string)
{
esp_mn_node_t *temp = esp_mn_root;
ESP_RETURN_ON_FALSE(NULL != esp_mn_root, ESP_ERR_INVALID_STATE, TAG, "The mn commands is not initialized");
int last_node_elem_num = esp_mn_commands_num();
ESP_RETURN_ON_FALSE(ESP_MN_MAX_PHRASE_NUM >= last_node_elem_num, ESP_ERR_INVALID_STATE, TAG, "The number of speech commands phrase must less than 200");
esp_mn_phrase_t *phrase = esp_mn_phrase_alloc(command_id, phoneme_string);
if (phrase == NULL) return ESP_ERR_INVALID_STATE;
esp_mn_node_t *new_node = esp_mn_node_alloc(phrase);
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = new_node;
return ESP_OK;
}
esp_err_t esp_mn_commands_modify(char *old_phoneme_string, char *new_phoneme_string)
{
esp_mn_node_t *temp = esp_mn_root;
ESP_RETURN_ON_FALSE(NULL != esp_mn_root, ESP_ERR_INVALID_STATE, TAG, "The mn commands is not initialized");
// search old phoneme_string to get command id
bool flag = false;
int command_id;
while (temp->next) {
temp = temp->next;
if (strcmp(old_phoneme_string, temp->phrase->phoneme_string) == 0) {
command_id = temp->phrase->command_id;
flag = true;
break;
}
}
// replace old phrase with new phrase
if (flag) {
esp_mn_phrase_t *phrase = esp_mn_phrase_alloc(command_id, new_phoneme_string);
if (phrase == NULL) return ESP_ERR_INVALID_STATE;
esp_mn_phrase_free(temp->phrase);
temp->phrase = phrase;
} else {
ESP_LOGE(TAG, "No such speech command: \"%s\"", old_phoneme_string);
return ESP_ERR_INVALID_STATE;
}
return ESP_OK;
}
esp_err_t esp_mn_commands_remove(char *phoneme_string)
{
esp_mn_node_t *temp = esp_mn_root;
ESP_RETURN_ON_FALSE(NULL != esp_mn_root, ESP_ERR_INVALID_STATE, TAG, "The mn commands is not initialized");
// search phoneme_string to get node point
bool flag = false;
while (temp->next) {
if (strcmp(phoneme_string, temp->next->phrase->phoneme_string) == 0) {
flag = true;
break;
}
temp = temp->next;
}
if (flag) {
esp_mn_node_t *rm_node = temp->next;
temp->next = temp->next->next;
esp_mn_node_free(rm_node);
return ESP_OK;
} else {
ESP_LOGE(TAG, "No such speech command: \"%s\"", phoneme_string);
return ESP_ERR_INVALID_STATE;
}
return ESP_OK;
}
esp_mn_phrase_t *esp_mn_commands_get_from_index(int index)
{
ESP_RETURN_ON_FALSE(NULL != esp_mn_root, ESP_ERR_INVALID_STATE, TAG, "The mn commands is not initialized");
// phrase index also is phrase id, which is the depth from this phrase node to root node
esp_mn_node_t *temp = esp_mn_root;
for (int i=-1; i<index; i++) {
if (temp->next == NULL) return NULL;
temp = temp->next;
}
return temp->phrase;
}
esp_mn_phrase_t *esp_mn_commands_get_from_string(const char *phoneme_string)
{
ESP_RETURN_ON_FALSE(NULL != esp_mn_root, ESP_ERR_INVALID_STATE, TAG, "The mn commands is not initialized");
// phrase index also is phrase id, which is the depth from this phrase node to root node
esp_mn_node_t *temp = esp_mn_root;
while (temp->next) {
if (strcmp(phoneme_string, temp->next->phrase->phoneme_string) == 0) {
return temp->next->phrase;
}
temp = temp->next;
}
return NULL;
}
esp_mn_error_t *esp_mn_commands_update(const esp_mn_iface_t *multinet, const model_iface_data_t *model_data)
{
ESP_RETURN_ON_FALSE(NULL != esp_mn_root, ESP_ERR_INVALID_STATE, TAG, "The mn commands is not initialize");
esp_mn_error_t *error = multinet->set_speech_commands(model_data, esp_mn_root);
if (error->num == 0)
return NULL;
return error;
}
void esp_mn_commands_print(void)
{
ESP_LOGI(TAG, "---------------------SPEECH COMMANDS---------------------");
esp_mn_node_t* temp = esp_mn_root;
int phrase_id = 0;
while (temp->next) {
temp = temp->next;
ESP_LOGI(TAG, "Command ID%d, phrase ID%d: %s", temp->phrase->command_id, phrase_id, temp->phrase->phoneme_string);
phrase_id++;
}
ESP_LOGI(TAG, "---------------------------------------------------------\n");
}
void *_esp_mn_calloc_(int n, int size)
{
#ifdef ESP_PLATFORM
return heap_caps_calloc(n, size, MALLOC_CAP_SPIRAM);
#else
return calloc(n, size);
#endif
}
esp_mn_phrase_t *esp_mn_phrase_alloc(int command_id, char *phoneme_string)
{
int phoneme_string_len = strlen(phoneme_string);
if (phoneme_string_len > ESP_MN_MAX_PHRASE_LEN || phoneme_string_len<1) {
ESP_LOGE(TAG, "The Length of \"%s\" > ESP_MN_MAX_PHRASE_LEN", phoneme_string);
return NULL;
}
esp_mn_phrase_t *phrase = _esp_mn_calloc_(1, sizeof(esp_mn_phrase_t));
ESP_RETURN_ON_FALSE(NULL != phrase, ESP_ERR_NO_MEM, TAG, "Fail to alloc mn phrase");
phrase->command_id = command_id;
phrase->threshold = 0;
phrase->wave = NULL;
memcpy(phrase->phoneme_string, phoneme_string, phoneme_string_len);
return phrase;
}
void esp_mn_phrase_free(esp_mn_phrase_t *phrase)
{
if (phrase != NULL) {
free(phrase);
}
}
esp_mn_node_t *esp_mn_node_alloc(esp_mn_phrase_t *phrase)
{
esp_mn_node_t *node = _esp_mn_calloc_(1, sizeof(esp_mn_node_t));
ESP_RETURN_ON_FALSE(NULL != node, ESP_ERR_NO_MEM, TAG, "Fail to alloc mn node");
node->next = NULL;
node->phrase = phrase;
return node;
}
void esp_mn_node_free(esp_mn_node_t *node)
{
if (node != NULL) {
esp_mn_phrase_free(node->phrase);
free(node);
}
}

924
src/esp_process_sdkconfig.c Normal file
View File

@ -0,0 +1,924 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "sdkconfig.h"
#include "esp_log.h"
#include "esp_process_sdkconfig.h"
#include "esp_mn_speech_commands.h"
static char *TAG = "SR_SYS";
void check_chip_config(void)
{
#ifdef CONFIG_IDF_TARGET_ESP32S3
#ifndef CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240
ESP_LOGE(TAG, "CPU freq should be 240MHz");
#endif
#ifndef CONFIG_ESPTOOLPY_FLASHFREQ_80M
ESP_LOGE(TAG, "Flash freq should be 240MHz");
#endif
#ifndef CONFIG_SPIRAM_SPEED_80M
ESP_LOGE(TAG, "PSRAM freq should be 80MHz");
#endif
#ifndef CONFIG_ESP32S3_DATA_CACHE_64KB
ESP_LOGE(TAG, "Data cache should be 64KB");
#endif
#ifndef CONFIG_ESP32S3_DATA_CACHE_LINE_64B
ESP_LOGE(TAG, "Data cache line should be 64B");
#endif
#elif CONFIG_IDF_TARGET_ESP32
#ifndef CONFIG_ESP32_DEFAULT_CPU_FREQ_240
ESP_LOGE(TAG, "CPU freq should be 240MHz");
#endif
#ifndef CONFIG_SPIRAM_SPEED_80M
ESP_LOGE(TAG, "PSRAM freq should be 80MHz");
#endif
#ifndef CONFIG_ESPTOOLPY_FLASHFREQ_80M
ESP_LOGE(TAG, "Flash freq should be 80MHz");
#endif
#ifndef CONFIG_ESPTOOLPY_FLASHMODE_QIO
ESP_LOGE(TAG, "Flash mode should be QIO");
#endif
#else
ESP_LOGE(TAG, "ESP-SR-AFE only support ESP32/ESP32S3");
#endif
}
char *get_id_name_cn(int i)
{
#if defined CONFIG_USE_MULTINET
#if defined CONFIG_SR_MN_CN_MULTINET2_SINGLE_RECOGNITION || defined CONFIG_SR_MN_CN_MULTINET4_5_SINGLE_RECOGNITION || defined CONFIG_SR_MN_CN_MULTINET4_5_SINGLE_RECOGNITION_QUANT8
if (i == 0)
return CONFIG_CN_SPEECH_COMMAND_ID0;
else if (i == 1)
return CONFIG_CN_SPEECH_COMMAND_ID1;
else if (i == 2)
return CONFIG_CN_SPEECH_COMMAND_ID2;
else if (i == 3)
return CONFIG_CN_SPEECH_COMMAND_ID3;
else if (i == 4)
return CONFIG_CN_SPEECH_COMMAND_ID4;
else if (i == 5)
return CONFIG_CN_SPEECH_COMMAND_ID5;
else if (i == 6)
return CONFIG_CN_SPEECH_COMMAND_ID6;
else if (i == 7)
return CONFIG_CN_SPEECH_COMMAND_ID7;
else if (i == 8)
return CONFIG_CN_SPEECH_COMMAND_ID8;
else if (i == 9)
return CONFIG_CN_SPEECH_COMMAND_ID9;
else if (i == 10)
return CONFIG_CN_SPEECH_COMMAND_ID10;
else if (i == 11)
return CONFIG_CN_SPEECH_COMMAND_ID11;
else if (i == 12)
return CONFIG_CN_SPEECH_COMMAND_ID12;
else if (i == 13)
return CONFIG_CN_SPEECH_COMMAND_ID13;
else if (i == 14)
return CONFIG_CN_SPEECH_COMMAND_ID14;
else if (i == 15)
return CONFIG_CN_SPEECH_COMMAND_ID15;
else if (i == 16)
return CONFIG_CN_SPEECH_COMMAND_ID16;
else if (i == 17)
return CONFIG_CN_SPEECH_COMMAND_ID17;
else if (i == 18)
return CONFIG_CN_SPEECH_COMMAND_ID18;
else if (i == 19)
return CONFIG_CN_SPEECH_COMMAND_ID19;
else if (i == 20)
return CONFIG_CN_SPEECH_COMMAND_ID20;
else if (i == 21)
return CONFIG_CN_SPEECH_COMMAND_ID21;
else if (i == 22)
return CONFIG_CN_SPEECH_COMMAND_ID22;
else if (i == 23)
return CONFIG_CN_SPEECH_COMMAND_ID23;
else if (i == 24)
return CONFIG_CN_SPEECH_COMMAND_ID24;
else if (i == 25)
return CONFIG_CN_SPEECH_COMMAND_ID25;
else if (i == 26)
return CONFIG_CN_SPEECH_COMMAND_ID26;
else if (i == 27)
return CONFIG_CN_SPEECH_COMMAND_ID27;
else if (i == 28)
return CONFIG_CN_SPEECH_COMMAND_ID28;
else if (i == 29)
return CONFIG_CN_SPEECH_COMMAND_ID29;
else if (i == 30)
return CONFIG_CN_SPEECH_COMMAND_ID30;
else if (i == 31)
return CONFIG_CN_SPEECH_COMMAND_ID31;
else if (i == 32)
return CONFIG_CN_SPEECH_COMMAND_ID32;
else if (i == 33)
return CONFIG_CN_SPEECH_COMMAND_ID33;
else if (i == 34)
return CONFIG_CN_SPEECH_COMMAND_ID34;
else if (i == 35)
return CONFIG_CN_SPEECH_COMMAND_ID35;
else if (i == 36)
return CONFIG_CN_SPEECH_COMMAND_ID36;
else if (i == 37)
return CONFIG_CN_SPEECH_COMMAND_ID37;
else if (i == 38)
return CONFIG_CN_SPEECH_COMMAND_ID38;
else if (i == 39)
return CONFIG_CN_SPEECH_COMMAND_ID39;
else if (i == 40)
return CONFIG_CN_SPEECH_COMMAND_ID40;
else if (i == 41)
return CONFIG_CN_SPEECH_COMMAND_ID41;
else if (i == 42)
return CONFIG_CN_SPEECH_COMMAND_ID42;
else if (i == 43)
return CONFIG_CN_SPEECH_COMMAND_ID43;
else if (i == 44)
return CONFIG_CN_SPEECH_COMMAND_ID44;
else if (i == 45)
return CONFIG_CN_SPEECH_COMMAND_ID45;
else if (i == 46)
return CONFIG_CN_SPEECH_COMMAND_ID46;
else if (i == 47)
return CONFIG_CN_SPEECH_COMMAND_ID47;
else if (i == 48)
return CONFIG_CN_SPEECH_COMMAND_ID48;
else if (i == 49)
return CONFIG_CN_SPEECH_COMMAND_ID49;
else if (i == 50)
return CONFIG_CN_SPEECH_COMMAND_ID50;
else if (i == 51)
return CONFIG_CN_SPEECH_COMMAND_ID51;
else if (i == 52)
return CONFIG_CN_SPEECH_COMMAND_ID52;
else if (i == 53)
return CONFIG_CN_SPEECH_COMMAND_ID53;
else if (i == 54)
return CONFIG_CN_SPEECH_COMMAND_ID54;
else if (i == 55)
return CONFIG_CN_SPEECH_COMMAND_ID55;
else if (i == 56)
return CONFIG_CN_SPEECH_COMMAND_ID56;
else if (i == 57)
return CONFIG_CN_SPEECH_COMMAND_ID57;
else if (i == 58)
return CONFIG_CN_SPEECH_COMMAND_ID58;
else if (i == 59)
return CONFIG_CN_SPEECH_COMMAND_ID59;
else if (i == 60)
return CONFIG_CN_SPEECH_COMMAND_ID60;
else if (i == 61)
return CONFIG_CN_SPEECH_COMMAND_ID61;
else if (i == 62)
return CONFIG_CN_SPEECH_COMMAND_ID62;
else if (i == 63)
return CONFIG_CN_SPEECH_COMMAND_ID63;
else if (i == 64)
return CONFIG_CN_SPEECH_COMMAND_ID64;
else if (i == 65)
return CONFIG_CN_SPEECH_COMMAND_ID65;
else if (i == 66)
return CONFIG_CN_SPEECH_COMMAND_ID66;
else if (i == 67)
return CONFIG_CN_SPEECH_COMMAND_ID67;
else if (i == 68)
return CONFIG_CN_SPEECH_COMMAND_ID68;
else if (i == 69)
return CONFIG_CN_SPEECH_COMMAND_ID69;
else if (i == 70)
return CONFIG_CN_SPEECH_COMMAND_ID70;
else if (i == 71)
return CONFIG_CN_SPEECH_COMMAND_ID71;
else if (i == 72)
return CONFIG_CN_SPEECH_COMMAND_ID72;
else if (i == 73)
return CONFIG_CN_SPEECH_COMMAND_ID73;
else if (i == 74)
return CONFIG_CN_SPEECH_COMMAND_ID74;
else if (i == 75)
return CONFIG_CN_SPEECH_COMMAND_ID75;
else if (i == 76)
return CONFIG_CN_SPEECH_COMMAND_ID76;
else if (i == 77)
return CONFIG_CN_SPEECH_COMMAND_ID77;
else if (i == 78)
return CONFIG_CN_SPEECH_COMMAND_ID78;
else if (i == 79)
return CONFIG_CN_SPEECH_COMMAND_ID79;
else if (i == 80)
return CONFIG_CN_SPEECH_COMMAND_ID80;
else if (i == 81)
return CONFIG_CN_SPEECH_COMMAND_ID81;
else if (i == 82)
return CONFIG_CN_SPEECH_COMMAND_ID82;
else if (i == 83)
return CONFIG_CN_SPEECH_COMMAND_ID83;
else if (i == 84)
return CONFIG_CN_SPEECH_COMMAND_ID84;
else if (i == 85)
return CONFIG_CN_SPEECH_COMMAND_ID85;
else if (i == 86)
return CONFIG_CN_SPEECH_COMMAND_ID86;
else if (i == 87)
return CONFIG_CN_SPEECH_COMMAND_ID87;
else if (i == 88)
return CONFIG_CN_SPEECH_COMMAND_ID88;
else if (i == 89)
return CONFIG_CN_SPEECH_COMMAND_ID89;
else if (i == 90)
return CONFIG_CN_SPEECH_COMMAND_ID90;
else if (i == 91)
return CONFIG_CN_SPEECH_COMMAND_ID91;
else if (i == 92)
return CONFIG_CN_SPEECH_COMMAND_ID92;
else if (i == 93)
return CONFIG_CN_SPEECH_COMMAND_ID93;
else if (i == 94)
return CONFIG_CN_SPEECH_COMMAND_ID94;
else if (i == 95)
return CONFIG_CN_SPEECH_COMMAND_ID95;
else if (i == 96)
return CONFIG_CN_SPEECH_COMMAND_ID96;
else if (i == 97)
return CONFIG_CN_SPEECH_COMMAND_ID97;
else if (i == 98)
return CONFIG_CN_SPEECH_COMMAND_ID98;
else if (i == 99)
return CONFIG_CN_SPEECH_COMMAND_ID99;
else if (i == 100)
return CONFIG_CN_SPEECH_COMMAND_ID100;
else if (i == 101)
return CONFIG_CN_SPEECH_COMMAND_ID101;
else if (i == 102)
return CONFIG_CN_SPEECH_COMMAND_ID102;
else if (i == 103)
return CONFIG_CN_SPEECH_COMMAND_ID103;
else if (i == 104)
return CONFIG_CN_SPEECH_COMMAND_ID104;
else if (i == 105)
return CONFIG_CN_SPEECH_COMMAND_ID105;
else if (i == 106)
return CONFIG_CN_SPEECH_COMMAND_ID106;
else if (i == 107)
return CONFIG_CN_SPEECH_COMMAND_ID107;
else if (i == 108)
return CONFIG_CN_SPEECH_COMMAND_ID108;
else if (i == 109)
return CONFIG_CN_SPEECH_COMMAND_ID109;
else if (i == 110)
return CONFIG_CN_SPEECH_COMMAND_ID110;
else if (i == 111)
return CONFIG_CN_SPEECH_COMMAND_ID111;
else if (i == 112)
return CONFIG_CN_SPEECH_COMMAND_ID112;
else if (i == 113)
return CONFIG_CN_SPEECH_COMMAND_ID113;
else if (i == 114)
return CONFIG_CN_SPEECH_COMMAND_ID114;
else if (i == 115)
return CONFIG_CN_SPEECH_COMMAND_ID115;
else if (i == 116)
return CONFIG_CN_SPEECH_COMMAND_ID116;
else if (i == 117)
return CONFIG_CN_SPEECH_COMMAND_ID117;
else if (i == 118)
return CONFIG_CN_SPEECH_COMMAND_ID118;
else if (i == 119)
return CONFIG_CN_SPEECH_COMMAND_ID119;
else if (i == 120)
return CONFIG_CN_SPEECH_COMMAND_ID120;
else if (i == 121)
return CONFIG_CN_SPEECH_COMMAND_ID121;
else if (i == 122)
return CONFIG_CN_SPEECH_COMMAND_ID122;
else if (i == 123)
return CONFIG_CN_SPEECH_COMMAND_ID123;
else if (i == 124)
return CONFIG_CN_SPEECH_COMMAND_ID124;
else if (i == 125)
return CONFIG_CN_SPEECH_COMMAND_ID125;
else if (i == 126)
return CONFIG_CN_SPEECH_COMMAND_ID126;
else if (i == 127)
return CONFIG_CN_SPEECH_COMMAND_ID127;
else if (i == 128)
return CONFIG_CN_SPEECH_COMMAND_ID128;
else if (i == 129)
return CONFIG_CN_SPEECH_COMMAND_ID129;
else if (i == 130)
return CONFIG_CN_SPEECH_COMMAND_ID130;
else if (i == 131)
return CONFIG_CN_SPEECH_COMMAND_ID131;
else if (i == 132)
return CONFIG_CN_SPEECH_COMMAND_ID132;
else if (i == 133)
return CONFIG_CN_SPEECH_COMMAND_ID133;
else if (i == 134)
return CONFIG_CN_SPEECH_COMMAND_ID134;
else if (i == 135)
return CONFIG_CN_SPEECH_COMMAND_ID135;
else if (i == 136)
return CONFIG_CN_SPEECH_COMMAND_ID136;
else if (i == 137)
return CONFIG_CN_SPEECH_COMMAND_ID137;
else if (i == 138)
return CONFIG_CN_SPEECH_COMMAND_ID138;
else if (i == 139)
return CONFIG_CN_SPEECH_COMMAND_ID139;
else if (i == 140)
return CONFIG_CN_SPEECH_COMMAND_ID140;
else if (i == 141)
return CONFIG_CN_SPEECH_COMMAND_ID141;
else if (i == 142)
return CONFIG_CN_SPEECH_COMMAND_ID142;
else if (i == 143)
return CONFIG_CN_SPEECH_COMMAND_ID143;
else if (i == 144)
return CONFIG_CN_SPEECH_COMMAND_ID144;
else if (i == 145)
return CONFIG_CN_SPEECH_COMMAND_ID145;
else if (i == 146)
return CONFIG_CN_SPEECH_COMMAND_ID146;
else if (i == 147)
return CONFIG_CN_SPEECH_COMMAND_ID147;
else if (i == 148)
return CONFIG_CN_SPEECH_COMMAND_ID148;
else if (i == 149)
return CONFIG_CN_SPEECH_COMMAND_ID149;
else if (i == 150)
return CONFIG_CN_SPEECH_COMMAND_ID150;
else if (i == 151)
return CONFIG_CN_SPEECH_COMMAND_ID151;
else if (i == 152)
return CONFIG_CN_SPEECH_COMMAND_ID152;
else if (i == 153)
return CONFIG_CN_SPEECH_COMMAND_ID153;
else if (i == 154)
return CONFIG_CN_SPEECH_COMMAND_ID154;
else if (i == 155)
return CONFIG_CN_SPEECH_COMMAND_ID155;
else if (i == 156)
return CONFIG_CN_SPEECH_COMMAND_ID156;
else if (i == 157)
return CONFIG_CN_SPEECH_COMMAND_ID157;
else if (i == 158)
return CONFIG_CN_SPEECH_COMMAND_ID158;
else if (i == 159)
return CONFIG_CN_SPEECH_COMMAND_ID159;
else if (i == 160)
return CONFIG_CN_SPEECH_COMMAND_ID160;
else if (i == 161)
return CONFIG_CN_SPEECH_COMMAND_ID161;
else if (i == 162)
return CONFIG_CN_SPEECH_COMMAND_ID162;
else if (i == 163)
return CONFIG_CN_SPEECH_COMMAND_ID163;
else if (i == 164)
return CONFIG_CN_SPEECH_COMMAND_ID164;
else if (i == 165)
return CONFIG_CN_SPEECH_COMMAND_ID165;
else if (i == 166)
return CONFIG_CN_SPEECH_COMMAND_ID166;
else if (i == 167)
return CONFIG_CN_SPEECH_COMMAND_ID167;
else if (i == 168)
return CONFIG_CN_SPEECH_COMMAND_ID168;
else if (i == 169)
return CONFIG_CN_SPEECH_COMMAND_ID169;
else if (i == 170)
return CONFIG_CN_SPEECH_COMMAND_ID170;
else if (i == 171)
return CONFIG_CN_SPEECH_COMMAND_ID171;
else if (i == 172)
return CONFIG_CN_SPEECH_COMMAND_ID172;
else if (i == 173)
return CONFIG_CN_SPEECH_COMMAND_ID173;
else if (i == 174)
return CONFIG_CN_SPEECH_COMMAND_ID174;
else if (i == 175)
return CONFIG_CN_SPEECH_COMMAND_ID175;
else if (i == 176)
return CONFIG_CN_SPEECH_COMMAND_ID176;
else if (i == 177)
return CONFIG_CN_SPEECH_COMMAND_ID177;
else if (i == 178)
return CONFIG_CN_SPEECH_COMMAND_ID178;
else if (i == 179)
return CONFIG_CN_SPEECH_COMMAND_ID179;
else if (i == 180)
return CONFIG_CN_SPEECH_COMMAND_ID180;
else if (i == 181)
return CONFIG_CN_SPEECH_COMMAND_ID181;
else if (i == 182)
return CONFIG_CN_SPEECH_COMMAND_ID182;
else if (i == 183)
return CONFIG_CN_SPEECH_COMMAND_ID183;
else if (i == 184)
return CONFIG_CN_SPEECH_COMMAND_ID184;
else if (i == 185)
return CONFIG_CN_SPEECH_COMMAND_ID185;
else if (i == 186)
return CONFIG_CN_SPEECH_COMMAND_ID186;
else if (i == 187)
return CONFIG_CN_SPEECH_COMMAND_ID187;
else if (i == 188)
return CONFIG_CN_SPEECH_COMMAND_ID188;
else if (i == 189)
return CONFIG_CN_SPEECH_COMMAND_ID189;
else if (i == 190)
return CONFIG_CN_SPEECH_COMMAND_ID190;
else if (i == 191)
return CONFIG_CN_SPEECH_COMMAND_ID191;
else if (i == 192)
return CONFIG_CN_SPEECH_COMMAND_ID192;
else if (i == 193)
return CONFIG_CN_SPEECH_COMMAND_ID193;
else if (i == 194)
return CONFIG_CN_SPEECH_COMMAND_ID194;
else if (i == 195)
return CONFIG_CN_SPEECH_COMMAND_ID195;
else if (i == 196)
return CONFIG_CN_SPEECH_COMMAND_ID196;
else if (i == 197)
return CONFIG_CN_SPEECH_COMMAND_ID197;
else if (i == 198)
return CONFIG_CN_SPEECH_COMMAND_ID198;
else if (i == 199)
return CONFIG_CN_SPEECH_COMMAND_ID199;
else
return NULL;
#else
return NULL;
#endif
#else
return NULL;
#endif
}
char *get_id_name_en(int i)
{
#if defined CONFIG_USE_MULTINET && defined CONFIG_SR_MN_EN_MULTINET5_SINGLE_RECOGNITION_QUANT8
if (i == 0)
return CONFIG_EN_SPEECH_COMMAND_ID0;
else if (i == 1)
return CONFIG_EN_SPEECH_COMMAND_ID1;
else if (i == 2)
return CONFIG_EN_SPEECH_COMMAND_ID2;
else if (i == 3)
return CONFIG_EN_SPEECH_COMMAND_ID3;
else if (i == 4)
return CONFIG_EN_SPEECH_COMMAND_ID4;
else if (i == 5)
return CONFIG_EN_SPEECH_COMMAND_ID5;
else if (i == 6)
return CONFIG_EN_SPEECH_COMMAND_ID6;
else if (i == 7)
return CONFIG_EN_SPEECH_COMMAND_ID7;
else if (i == 8)
return CONFIG_EN_SPEECH_COMMAND_ID8;
else if (i == 9)
return CONFIG_EN_SPEECH_COMMAND_ID9;
else if (i == 10)
return CONFIG_EN_SPEECH_COMMAND_ID10;
else if (i == 11)
return CONFIG_EN_SPEECH_COMMAND_ID11;
else if (i == 12)
return CONFIG_EN_SPEECH_COMMAND_ID12;
else if (i == 13)
return CONFIG_EN_SPEECH_COMMAND_ID13;
else if (i == 14)
return CONFIG_EN_SPEECH_COMMAND_ID14;
else if (i == 15)
return CONFIG_EN_SPEECH_COMMAND_ID15;
else if (i == 16)
return CONFIG_EN_SPEECH_COMMAND_ID16;
else if (i == 17)
return CONFIG_EN_SPEECH_COMMAND_ID17;
else if (i == 18)
return CONFIG_EN_SPEECH_COMMAND_ID18;
else if (i == 19)
return CONFIG_EN_SPEECH_COMMAND_ID19;
else if (i == 20)
return CONFIG_EN_SPEECH_COMMAND_ID20;
else if (i == 21)
return CONFIG_EN_SPEECH_COMMAND_ID21;
else if (i == 22)
return CONFIG_EN_SPEECH_COMMAND_ID22;
else if (i == 23)
return CONFIG_EN_SPEECH_COMMAND_ID23;
else if (i == 24)
return CONFIG_EN_SPEECH_COMMAND_ID24;
else if (i == 25)
return CONFIG_EN_SPEECH_COMMAND_ID25;
else if (i == 26)
return CONFIG_EN_SPEECH_COMMAND_ID26;
else if (i == 27)
return CONFIG_EN_SPEECH_COMMAND_ID27;
else if (i == 28)
return CONFIG_EN_SPEECH_COMMAND_ID28;
else if (i == 29)
return CONFIG_EN_SPEECH_COMMAND_ID29;
else if (i == 30)
return CONFIG_EN_SPEECH_COMMAND_ID30;
else if (i == 31)
return CONFIG_EN_SPEECH_COMMAND_ID31;
else if (i == 32)
return CONFIG_EN_SPEECH_COMMAND_ID32;
else if (i == 33)
return CONFIG_EN_SPEECH_COMMAND_ID33;
else if (i == 34)
return CONFIG_EN_SPEECH_COMMAND_ID34;
else if (i == 35)
return CONFIG_EN_SPEECH_COMMAND_ID35;
else if (i == 36)
return CONFIG_EN_SPEECH_COMMAND_ID36;
else if (i == 37)
return CONFIG_EN_SPEECH_COMMAND_ID37;
else if (i == 38)
return CONFIG_EN_SPEECH_COMMAND_ID38;
else if (i == 39)
return CONFIG_EN_SPEECH_COMMAND_ID39;
else if (i == 40)
return CONFIG_EN_SPEECH_COMMAND_ID40;
else if (i == 41)
return CONFIG_EN_SPEECH_COMMAND_ID41;
else if (i == 42)
return CONFIG_EN_SPEECH_COMMAND_ID42;
else if (i == 43)
return CONFIG_EN_SPEECH_COMMAND_ID43;
else if (i == 44)
return CONFIG_EN_SPEECH_COMMAND_ID44;
else if (i == 45)
return CONFIG_EN_SPEECH_COMMAND_ID45;
else if (i == 46)
return CONFIG_EN_SPEECH_COMMAND_ID46;
else if (i == 47)
return CONFIG_EN_SPEECH_COMMAND_ID47;
else if (i == 48)
return CONFIG_EN_SPEECH_COMMAND_ID48;
else if (i == 49)
return CONFIG_EN_SPEECH_COMMAND_ID49;
else if (i == 50)
return CONFIG_EN_SPEECH_COMMAND_ID50;
else if (i == 51)
return CONFIG_EN_SPEECH_COMMAND_ID51;
else if (i == 52)
return CONFIG_EN_SPEECH_COMMAND_ID52;
else if (i == 53)
return CONFIG_EN_SPEECH_COMMAND_ID53;
else if (i == 54)
return CONFIG_EN_SPEECH_COMMAND_ID54;
else if (i == 55)
return CONFIG_EN_SPEECH_COMMAND_ID55;
else if (i == 56)
return CONFIG_EN_SPEECH_COMMAND_ID56;
else if (i == 57)
return CONFIG_EN_SPEECH_COMMAND_ID57;
else if (i == 58)
return CONFIG_EN_SPEECH_COMMAND_ID58;
else if (i == 59)
return CONFIG_EN_SPEECH_COMMAND_ID59;
else if (i == 60)
return CONFIG_EN_SPEECH_COMMAND_ID60;
else if (i == 61)
return CONFIG_EN_SPEECH_COMMAND_ID61;
else if (i == 62)
return CONFIG_EN_SPEECH_COMMAND_ID62;
else if (i == 63)
return CONFIG_EN_SPEECH_COMMAND_ID63;
else if (i == 64)
return CONFIG_EN_SPEECH_COMMAND_ID64;
else if (i == 65)
return CONFIG_EN_SPEECH_COMMAND_ID65;
else if (i == 66)
return CONFIG_EN_SPEECH_COMMAND_ID66;
else if (i == 67)
return CONFIG_EN_SPEECH_COMMAND_ID67;
else if (i == 68)
return CONFIG_EN_SPEECH_COMMAND_ID68;
else if (i == 69)
return CONFIG_EN_SPEECH_COMMAND_ID69;
else if (i == 70)
return CONFIG_EN_SPEECH_COMMAND_ID70;
else if (i == 71)
return CONFIG_EN_SPEECH_COMMAND_ID71;
else if (i == 72)
return CONFIG_EN_SPEECH_COMMAND_ID72;
else if (i == 73)
return CONFIG_EN_SPEECH_COMMAND_ID73;
else if (i == 74)
return CONFIG_EN_SPEECH_COMMAND_ID74;
else if (i == 75)
return CONFIG_EN_SPEECH_COMMAND_ID75;
else if (i == 76)
return CONFIG_EN_SPEECH_COMMAND_ID76;
else if (i == 77)
return CONFIG_EN_SPEECH_COMMAND_ID77;
else if (i == 78)
return CONFIG_EN_SPEECH_COMMAND_ID78;
else if (i == 79)
return CONFIG_EN_SPEECH_COMMAND_ID79;
else if (i == 80)
return CONFIG_EN_SPEECH_COMMAND_ID80;
else if (i == 81)
return CONFIG_EN_SPEECH_COMMAND_ID81;
else if (i == 82)
return CONFIG_EN_SPEECH_COMMAND_ID82;
else if (i == 83)
return CONFIG_EN_SPEECH_COMMAND_ID83;
else if (i == 84)
return CONFIG_EN_SPEECH_COMMAND_ID84;
else if (i == 85)
return CONFIG_EN_SPEECH_COMMAND_ID85;
else if (i == 86)
return CONFIG_EN_SPEECH_COMMAND_ID86;
else if (i == 87)
return CONFIG_EN_SPEECH_COMMAND_ID87;
else if (i == 88)
return CONFIG_EN_SPEECH_COMMAND_ID88;
else if (i == 89)
return CONFIG_EN_SPEECH_COMMAND_ID89;
else if (i == 90)
return CONFIG_EN_SPEECH_COMMAND_ID90;
else if (i == 91)
return CONFIG_EN_SPEECH_COMMAND_ID91;
else if (i == 92)
return CONFIG_EN_SPEECH_COMMAND_ID92;
else if (i == 93)
return CONFIG_EN_SPEECH_COMMAND_ID93;
else if (i == 94)
return CONFIG_EN_SPEECH_COMMAND_ID94;
else if (i == 95)
return CONFIG_EN_SPEECH_COMMAND_ID95;
else if (i == 96)
return CONFIG_EN_SPEECH_COMMAND_ID96;
else if (i == 97)
return CONFIG_EN_SPEECH_COMMAND_ID97;
else if (i == 98)
return CONFIG_EN_SPEECH_COMMAND_ID98;
else if (i == 99)
return CONFIG_EN_SPEECH_COMMAND_ID99;
else if (i == 100)
return CONFIG_EN_SPEECH_COMMAND_ID100;
else if (i == 101)
return CONFIG_EN_SPEECH_COMMAND_ID101;
else if (i == 102)
return CONFIG_EN_SPEECH_COMMAND_ID102;
else if (i == 103)
return CONFIG_EN_SPEECH_COMMAND_ID103;
else if (i == 104)
return CONFIG_EN_SPEECH_COMMAND_ID104;
else if (i == 105)
return CONFIG_EN_SPEECH_COMMAND_ID105;
else if (i == 106)
return CONFIG_EN_SPEECH_COMMAND_ID106;
else if (i == 107)
return CONFIG_EN_SPEECH_COMMAND_ID107;
else if (i == 108)
return CONFIG_EN_SPEECH_COMMAND_ID108;
else if (i == 109)
return CONFIG_EN_SPEECH_COMMAND_ID109;
else if (i == 110)
return CONFIG_EN_SPEECH_COMMAND_ID110;
else if (i == 111)
return CONFIG_EN_SPEECH_COMMAND_ID111;
else if (i == 112)
return CONFIG_EN_SPEECH_COMMAND_ID112;
else if (i == 113)
return CONFIG_EN_SPEECH_COMMAND_ID113;
else if (i == 114)
return CONFIG_EN_SPEECH_COMMAND_ID114;
else if (i == 115)
return CONFIG_EN_SPEECH_COMMAND_ID115;
else if (i == 116)
return CONFIG_EN_SPEECH_COMMAND_ID116;
else if (i == 117)
return CONFIG_EN_SPEECH_COMMAND_ID117;
else if (i == 118)
return CONFIG_EN_SPEECH_COMMAND_ID118;
else if (i == 119)
return CONFIG_EN_SPEECH_COMMAND_ID119;
else if (i == 120)
return CONFIG_EN_SPEECH_COMMAND_ID120;
else if (i == 121)
return CONFIG_EN_SPEECH_COMMAND_ID121;
else if (i == 122)
return CONFIG_EN_SPEECH_COMMAND_ID122;
else if (i == 123)
return CONFIG_EN_SPEECH_COMMAND_ID123;
else if (i == 124)
return CONFIG_EN_SPEECH_COMMAND_ID124;
else if (i == 125)
return CONFIG_EN_SPEECH_COMMAND_ID125;
else if (i == 126)
return CONFIG_EN_SPEECH_COMMAND_ID126;
else if (i == 127)
return CONFIG_EN_SPEECH_COMMAND_ID127;
else if (i == 128)
return CONFIG_EN_SPEECH_COMMAND_ID128;
else if (i == 129)
return CONFIG_EN_SPEECH_COMMAND_ID129;
else if (i == 130)
return CONFIG_EN_SPEECH_COMMAND_ID130;
else if (i == 131)
return CONFIG_EN_SPEECH_COMMAND_ID131;
else if (i == 132)
return CONFIG_EN_SPEECH_COMMAND_ID132;
else if (i == 133)
return CONFIG_EN_SPEECH_COMMAND_ID133;
else if (i == 134)
return CONFIG_EN_SPEECH_COMMAND_ID134;
else if (i == 135)
return CONFIG_EN_SPEECH_COMMAND_ID135;
else if (i == 136)
return CONFIG_EN_SPEECH_COMMAND_ID136;
else if (i == 137)
return CONFIG_EN_SPEECH_COMMAND_ID137;
else if (i == 138)
return CONFIG_EN_SPEECH_COMMAND_ID138;
else if (i == 139)
return CONFIG_EN_SPEECH_COMMAND_ID139;
else if (i == 140)
return CONFIG_EN_SPEECH_COMMAND_ID140;
else if (i == 141)
return CONFIG_EN_SPEECH_COMMAND_ID141;
else if (i == 142)
return CONFIG_EN_SPEECH_COMMAND_ID142;
else if (i == 143)
return CONFIG_EN_SPEECH_COMMAND_ID143;
else if (i == 144)
return CONFIG_EN_SPEECH_COMMAND_ID144;
else if (i == 145)
return CONFIG_EN_SPEECH_COMMAND_ID145;
else if (i == 146)
return CONFIG_EN_SPEECH_COMMAND_ID146;
else if (i == 147)
return CONFIG_EN_SPEECH_COMMAND_ID147;
else if (i == 148)
return CONFIG_EN_SPEECH_COMMAND_ID148;
else if (i == 149)
return CONFIG_EN_SPEECH_COMMAND_ID149;
else if (i == 150)
return CONFIG_EN_SPEECH_COMMAND_ID150;
else if (i == 151)
return CONFIG_EN_SPEECH_COMMAND_ID151;
else if (i == 152)
return CONFIG_EN_SPEECH_COMMAND_ID152;
else if (i == 153)
return CONFIG_EN_SPEECH_COMMAND_ID153;
else if (i == 154)
return CONFIG_EN_SPEECH_COMMAND_ID154;
else if (i == 155)
return CONFIG_EN_SPEECH_COMMAND_ID155;
else if (i == 156)
return CONFIG_EN_SPEECH_COMMAND_ID156;
else if (i == 157)
return CONFIG_EN_SPEECH_COMMAND_ID157;
else if (i == 158)
return CONFIG_EN_SPEECH_COMMAND_ID158;
else if (i == 159)
return CONFIG_EN_SPEECH_COMMAND_ID159;
else if (i == 160)
return CONFIG_EN_SPEECH_COMMAND_ID160;
else if (i == 161)
return CONFIG_EN_SPEECH_COMMAND_ID161;
else if (i == 162)
return CONFIG_EN_SPEECH_COMMAND_ID162;
else if (i == 163)
return CONFIG_EN_SPEECH_COMMAND_ID163;
else if (i == 164)
return CONFIG_EN_SPEECH_COMMAND_ID164;
else if (i == 165)
return CONFIG_EN_SPEECH_COMMAND_ID165;
else if (i == 166)
return CONFIG_EN_SPEECH_COMMAND_ID166;
else if (i == 167)
return CONFIG_EN_SPEECH_COMMAND_ID167;
else if (i == 168)
return CONFIG_EN_SPEECH_COMMAND_ID168;
else if (i == 169)
return CONFIG_EN_SPEECH_COMMAND_ID169;
else if (i == 170)
return CONFIG_EN_SPEECH_COMMAND_ID170;
else if (i == 171)
return CONFIG_EN_SPEECH_COMMAND_ID171;
else if (i == 172)
return CONFIG_EN_SPEECH_COMMAND_ID172;
else if (i == 173)
return CONFIG_EN_SPEECH_COMMAND_ID173;
else if (i == 174)
return CONFIG_EN_SPEECH_COMMAND_ID174;
else if (i == 175)
return CONFIG_EN_SPEECH_COMMAND_ID175;
else if (i == 176)
return CONFIG_EN_SPEECH_COMMAND_ID176;
else if (i == 177)
return CONFIG_EN_SPEECH_COMMAND_ID177;
else if (i == 178)
return CONFIG_EN_SPEECH_COMMAND_ID178;
else if (i == 179)
return CONFIG_EN_SPEECH_COMMAND_ID179;
else if (i == 180)
return CONFIG_EN_SPEECH_COMMAND_ID180;
else if (i == 181)
return CONFIG_EN_SPEECH_COMMAND_ID181;
else if (i == 182)
return CONFIG_EN_SPEECH_COMMAND_ID182;
else if (i == 183)
return CONFIG_EN_SPEECH_COMMAND_ID183;
else if (i == 184)
return CONFIG_EN_SPEECH_COMMAND_ID184;
else if (i == 185)
return CONFIG_EN_SPEECH_COMMAND_ID185;
else if (i == 186)
return CONFIG_EN_SPEECH_COMMAND_ID186;
else if (i == 187)
return CONFIG_EN_SPEECH_COMMAND_ID187;
else if (i == 188)
return CONFIG_EN_SPEECH_COMMAND_ID188;
else if (i == 189)
return CONFIG_EN_SPEECH_COMMAND_ID189;
else if (i == 190)
return CONFIG_EN_SPEECH_COMMAND_ID190;
else if (i == 191)
return CONFIG_EN_SPEECH_COMMAND_ID191;
else if (i == 192)
return CONFIG_EN_SPEECH_COMMAND_ID192;
else if (i == 193)
return CONFIG_EN_SPEECH_COMMAND_ID193;
else if (i == 194)
return CONFIG_EN_SPEECH_COMMAND_ID194;
else if (i == 195)
return CONFIG_EN_SPEECH_COMMAND_ID195;
else if (i == 196)
return CONFIG_EN_SPEECH_COMMAND_ID196;
else if (i == 197)
return CONFIG_EN_SPEECH_COMMAND_ID197;
else if (i == 198)
return CONFIG_EN_SPEECH_COMMAND_ID198;
else if (i == 199)
return CONFIG_EN_SPEECH_COMMAND_ID199;
else
return NULL;
#else
return NULL;
#endif
}
esp_err_t esp_mn_commands_update_from_sdkconfig(esp_mn_iface_t *multinet, const model_iface_data_t *model_data)
{
esp_mn_commands_alloc();
int total_phrase_num = 0;
for (int i = 0; i < ESP_MN_MAX_PHRASE_NUM; i++) {
char *command_str = NULL;
int command_str_len = 0;
#if defined CONFIG_SR_MN_CN_MULTINET2_SINGLE_RECOGNITION || defined CONFIG_SR_MN_CN_MULTINET4_SINGLE_RECOGNITION || defined CONFIG_SR_MN_CN_MULTINET4_5_SINGLE_RECOGNITION || defined CONFIG_SR_MN_CN_MULTINET4_5_SINGLE_RECOGNITION_QUANT8
command_str = get_id_name_cn(i);
#elif defined CONFIG_SR_MN_EN_MULTINET5_SINGLE_RECOGNITION || defined CONFIG_SR_MN_EN_MULTINET5_SINGLE_RECOGNITION_QUANT8
command_str = get_id_name_en(i);
#else
ESP_LOGE(TAG, "Incorrect language");
#endif
command_str_len = strlen(command_str);
if (command_str_len <= 0) {
continue;
}
char *command_str_temp = calloc(command_str_len + 1, 1);
memcpy(command_str_temp, command_str, command_str_len);
char *token = strtok(command_str_temp, ",");
while (token != NULL) {
int len = strlen(token);
if (total_phrase_num > ESP_MN_MAX_PHRASE_NUM) {
ESP_LOGE(TAG, "The number of speech commands phrase must less than ESP_MN_MAX_PHRASE_NUM");
free(command_str_temp);
goto end;
}
esp_mn_commands_add(i, token);
total_phrase_num++;
token = strtok(NULL, ",");
}
free(command_str_temp);
}
end:
esp_mn_commands_print();
return esp_mn_commands_update(multinet, model_data);
}

View File

@ -1,6 +1,12 @@
#include "stdio.h" #include "stdio.h"
#include "sdkconfig.h" #include "sdkconfig.h"
#include "esp_spiffs.h" #include "esp_spiffs.h"
#include <sys/stat.h>
#include <sys/dirent.h>
#include "string.h"
#include "model_path.h"
#include "esp_wn_models.h"
#include "esp_mn_models.h"
char *get_model_base_path(void) char *get_model_base_path(void)
{ {
@ -13,9 +19,60 @@ char *get_model_base_path(void)
#endif #endif
} }
void srmodel_spiffs_init(void) srmodel_list_t *read_models_form_spiffs(const char *path)
{ {
printf("Initializing SPIFFS\n"); struct dirent *ret;
DIR *dir;
dir = opendir(path);
srmodel_list_t *models = malloc(sizeof(srmodel_list_t*));
models->num = 0;
int idx = 0;
if (dir != NULL)
{
while ((ret = readdir(dir)) != NULL)
{ // NULL if reach the end of directory
if (ret->d_type == DT_DIR) // continue if d_type is not file
continue;
int len = strlen(ret->d_name);
char *suffix = ret->d_name + len - 12;
if (strcmp(suffix, "_MODEL_INFO_") == 0)
models->num ++;
}
// allocate model names
models->model_name = malloc(models->num*sizeof(char*));
for (int i=0; i<models->num; i++) {
models->model_name[i] = (char*) calloc(MODEL_NAME_MAX_LENGTH, sizeof(char));
}
dir = opendir(path);
while ((ret = readdir(dir)) != NULL)
{ // NULL if reach the end of directory
if (ret->d_type == DT_DIR) // continue if d_type is not file
continue;
int len = strlen(ret->d_name);
char *suffix = ret->d_name + len - 12;
if (strcmp(suffix, "_MODEL_INFO_") == 0)
{
memcpy(models->model_name[idx], ret->d_name, (len-13)*sizeof(char));
// models->model_name[idx][len-13] = '\0';
idx ++;
}
}
}
return models;
}
srmodel_list_t* srmodel_spiffs_init(void)
{
printf("Initializing models from SPIFFS\n");
esp_vfs_spiffs_conf_t conf = { esp_vfs_spiffs_conf_t conf = {
.base_path = "/srmodel", .base_path = "/srmodel",
@ -36,7 +93,7 @@ void srmodel_spiffs_init(void)
} else { } else {
printf("Failed to initialize SPIFFS (%s)\n", esp_err_to_name(ret)); printf("Failed to initialize SPIFFS (%s)\n", esp_err_to_name(ret));
} }
return; return NULL;
} }
size_t total = 0, used = 0; size_t total = 0, used = 0;
@ -46,4 +103,128 @@ void srmodel_spiffs_init(void)
} else { } else {
printf("Partition size: total: %d, used: %d\n", total, used); printf("Partition size: total: %d, used: %d\n", total, used);
} }
// Read all model from path
return read_models_form_spiffs(conf.base_path);
} }
void srmodel_spiffs_deinit(srmodel_list_t *models)
{
if (models != NULL) {
if (models->num>0) {
for (int i=0; i<models->num; i++) {
free(models->model_name[i]);
}
}
free(models);
}
esp_vfs_spiffs_conf_t conf = {
.base_path = "/srmodel",
.partition_label = "model",
.max_files = 5,
.format_if_mount_failed = true
};
esp_vfs_spiffs_unregister(conf.partition_label);
}
srmodel_list_t *srmodel_config_init()
{
srmodel_list_t *models = malloc(sizeof(srmodel_list_t*));
models->num = 2;
models->model_name = malloc(models->num*sizeof(char*));
for (int i=0; i<models->num; i++) {
models->model_name[i] = (char*) calloc(MODEL_NAME_MAX_LENGTH, sizeof(char));
}
// If wakenet is selected in menuconfig, load the wakenet model
if (strcmp(WAKENET_MODEL_NAME, "NULL") == 0) {
models->num --;
free(models->model_name[models->num]);
} else {
strcpy(models->model_name[0], WAKENET_MODEL_NAME);
}
// If multinet is selected in menuconfig, load the multinet model
if (strcmp(MULTINET_MODEL_NAME, "NULL") == 0) {
models->num --;
free(models->model_name[models->num]);
} else {
strcpy(models->model_name[models->num-1], MULTINET_MODEL_NAME);
}
// could not find any avaliable models, return NULL
if (models->num == 0) {
free(models);
models = NULL;
}
return models;
}
void srmodel_config_deinit(srmodel_list_t *models)
{
if (models != NULL) {
if (models->num>0) {
for (int i=0; i<models->num; i++) {
free(models->model_name[i]);
}
}
free(models);
}
}
srmodel_list_t* esp_srmodel_init()
{
#ifdef CONFIG_IDF_TARGET_ESP32
return srmodel_config_init();
#else
return srmodel_spiffs_init();
#endif
}
void esp_srmodel_deinit(srmodel_list_t *models)
{
#ifdef CONFIG_IDF_TARGET_ESP32
return srmodel_config_deinit(models);
#else
return srmodel_spiffs_deinit(models);
#endif
}
// repackage strstr function to support needle==NULL
char *_esp_strstr_(const char *haystack, const char *needle)
{
if (needle == NULL) return haystack;
else return strstr(haystack, needle);
}
char *esp_srmodel_filter(srmodel_list_t *models, const char *keyword1, const char *keyword2)
{
if (models == NULL) return NULL;
// return the first model name including specific keyword
for (int i=0; i<models->num; i++) {
if (_esp_strstr_(models->model_name[i], keyword1) != NULL) {
if (_esp_strstr_(models->model_name[i], keyword2) != NULL)
return models->model_name[i];
}
}
return NULL;
}
int esp_srmodel_exists(srmodel_list_t *models, char *model_name) {
if (models == NULL) return -1;
for (int i=0; i<models->num; i++) {
if (strcmp(models->model_name[i], model_name) == 0) {
return i;
}
}
return -1;
}