diff --git a/CHANGELOG.md b/CHANGELOG.md index 905c05b..fda8ebf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ - Available storage is less than the remaining flash space on IDF v5.0. If you can not map model partition successfully, please check the left free storage by `spi_flash_mmap_get_free_pages(ESP_PARTITION_MMAP_DATA)` or update IDF to v5.1 or later. +## 1.9.4 +- Fix bugs when using C++ to compile +- Add more new wake words + ## 1.9.3 - Fix nsnet2 crash - Add esp32p4 ci test diff --git a/Kconfig.projbuild b/Kconfig.projbuild index f446721..81b5d07 100644 --- a/Kconfig.projbuild +++ b/Kconfig.projbuild @@ -257,12 +257,12 @@ menu "Load Multiple Wake Words" config SR_WN_WN9_HEYWANDA_TTS_MULTI - bool "Hey,Wanda (wn9_heywanda_tts)" - depends on IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32P4 + bool "Hey,Wanda (wn9_heywanda_tts)" + depends on IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32P4 config SR_WN_WN9_HIMIAOMIAO_TTS_MULTI - bool "Hi,喵喵 (wn9_himiaomiao_tts)" - depends on IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32P4 + bool "Hi,喵喵 (wn9_himiaomiao_tts)" + depends on IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32P4 config SR_WN_WN9_MYCROFT_TTS_MULTI diff --git a/esp-tts/esp_tts_chinese/include/esp_tts.h b/esp-tts/esp_tts_chinese/include/esp_tts.h index 99a0801..67f8f92 100644 --- a/esp-tts/esp_tts_chinese/include/esp_tts.h +++ b/esp-tts/esp_tts_chinese/include/esp_tts.h @@ -40,7 +40,7 @@ typedef void * esp_tts_handle_t; * - NULL: Init failed * - Others: The instance of voice set */ -esp_tts_voice_t *esp_tts_voice_set_init(const esp_tts_voice_t *template, void *data); +esp_tts_voice_t *esp_tts_voice_set_init(const esp_tts_voice_t *voice_template, void *data); /** * @brief Init an instance of the TTS voice set structure. diff --git a/esp-tts/esp_tts_chinese/include/esp_tts_parser.h b/esp-tts/esp_tts_chinese/include/esp_tts_parser.h index ce71b04..334e507 100644 --- a/esp-tts/esp_tts_chinese/include/esp_tts_parser.h +++ b/esp-tts/esp_tts_chinese/include/esp_tts_parser.h @@ -4,7 +4,9 @@ #include "stdlib.h" #include "esp_tts_voice.h" - +#ifdef __cplusplus +extern "C" { +#endif typedef struct { int *syll_idx; int syll_num; @@ -22,4 +24,8 @@ esp_tts_utt_t* esp_tts_utt_alloc(int syll_num, esp_tts_voice_t *voice); void esp_tts_utt_free(esp_tts_utt_t *utt); +#ifdef __cplusplus +} +#endif + #endif \ No newline at end of file diff --git a/esp-tts/esp_tts_chinese/include/esp_tts_voice.h b/esp-tts/esp_tts_chinese/include/esp_tts_voice.h index 77f263e..40f55cd 100644 --- a/esp-tts/esp_tts_chinese/include/esp_tts_voice.h +++ b/esp-tts/esp_tts_chinese/include/esp_tts_voice.h @@ -1,6 +1,10 @@ #ifndef _ESP_TTS_VOICE_H_ #define _ESP_TTS_VOICE_H_ +#ifdef __cplusplus +extern "C" { +#endif + typedef struct { char *voice_name; // voice set name char *format; // the format of voice data, currently support pcm and amrwb @@ -16,5 +20,7 @@ typedef struct { unsigned char *data; // the audio data of all syllables } esp_tts_voice_t; - +#ifdef __cplusplus +} +#endif #endif \ No newline at end of file diff --git a/idf_component.yml b/idf_component.yml index 48961cf..23e6873 100644 --- a/idf_component.yml +++ b/idf_component.yml @@ -1,4 +1,4 @@ -version: "1.9.3" +version: "1.9.4" description: esp_sr provides basic algorithms for Speech Recognition applications url: https://github.com/espressif/esp-sr dependencies: diff --git a/include/esp32/esp_afe_config.h b/include/esp32/esp_afe_config.h index e4c681e..702d859 100644 --- a/include/esp32/esp_afe_config.h +++ b/include/esp32/esp_afe_config.h @@ -113,10 +113,12 @@ typedef struct { .memory_alloc_mode = AFE_MEMORY_ALLOC_INTERNAL_PSRAM_BALANCE, \ .afe_linear_gain = 1.0, \ .agc_mode = AFE_MN_PEAK_AGC_MODE_2, \ - .pcm_config.total_ch_num = 2, \ - .pcm_config.mic_num = 1, \ - .pcm_config.ref_num = 1, \ - .pcm_config.sample_rate = 16000, \ + .pcm_config = { \ + .total_ch_num = 2, \ + .mic_num = 1, \ + .ref_num = 1, \ + .sample_rate = 16000, \ + }, \ .debug_init = false, \ .debug_hook = {{AFE_DEBUG_HOOK_MASE_TASK_IN, NULL}, {AFE_DEBUG_HOOK_FETCH_TASK_IN, NULL}}, \ .afe_ns_mode = NS_MODE_SSP, \ @@ -142,10 +144,12 @@ typedef struct { .memory_alloc_mode = AFE_MEMORY_ALLOC_MORE_PSRAM, \ .afe_linear_gain = 1.0, \ .agc_mode = AFE_MN_PEAK_AGC_MODE_2, \ - .pcm_config.total_ch_num = 3, \ - .pcm_config.mic_num = 2, \ - .pcm_config.ref_num = 1, \ - .pcm_config.sample_rate = 16000, \ + .pcm_config = { \ + .total_ch_num = 3, \ + .mic_num = 2, \ + .ref_num = 1, \ + .sample_rate = 16000, \ + }, \ .debug_init = false, \ .debug_hook = {{AFE_DEBUG_HOOK_MASE_TASK_IN, NULL}, {AFE_DEBUG_HOOK_FETCH_TASK_IN, NULL}}, \ .afe_ns_mode = NS_MODE_SSP, \ @@ -155,4 +159,4 @@ typedef struct { #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/include/esp32/esp_mn_iface.h b/include/esp32/esp_mn_iface.h index 20f96d8..a1ef049 100644 --- a/include/esp32/esp_mn_iface.h +++ b/include/esp32/esp_mn_iface.h @@ -198,7 +198,7 @@ typedef void (*esp_mn_iface_op_print_active_speech_commands)(model_iface_data_t * @param model_data The model object to query * @param str The input string */ -typedef int (*esp_mn_iface_op_check_speech_command)(model_iface_data_t *model_data, char *str); +typedef int (*esp_mn_iface_op_check_speech_command)(model_iface_data_t *model_data, const char *str); typedef struct { esp_mn_iface_op_create_t create; diff --git a/include/esp32/flite_g2p.h b/include/esp32/flite_g2p.h index 0d081cd..55aeaa6 100644 --- a/include/esp32/flite_g2p.h +++ b/include/esp32/flite_g2p.h @@ -15,6 +15,6 @@ void flite_g2p_result_print_string(flite_g2p_result *result, int map_phonemes); char *flite_g2p_result_get_string(flite_g2p_result *result, int map_phonemes); -char *flite_g2p(char *graphemes, int map_phonemes); +char *flite_g2p(const char *graphemes, int map_phonemes); #endif \ No newline at end of file diff --git a/include/esp32p4/esp_afe_config.h b/include/esp32p4/esp_afe_config.h index ff04665..6cac4c6 100644 --- a/include/esp32p4/esp_afe_config.h +++ b/include/esp32p4/esp_afe_config.h @@ -115,10 +115,12 @@ typedef struct { .memory_alloc_mode = AFE_MEMORY_ALLOC_INTERNAL_PSRAM_BALANCE, \ .afe_linear_gain = 1.0, \ .agc_mode = AFE_MN_PEAK_AGC_MODE_2, \ - .pcm_config.total_ch_num = 2, \ - .pcm_config.mic_num = 1, \ - .pcm_config.ref_num = 1, \ - .pcm_config.sample_rate = 16000, \ + .pcm_config = { \ + .total_ch_num = 2, \ + .mic_num = 1, \ + .ref_num = 1, \ + .sample_rate = 16000, \ + }, \ .debug_init = false, \ .debug_hook = {{AFE_DEBUG_HOOK_MASE_TASK_IN, NULL}, {AFE_DEBUG_HOOK_FETCH_TASK_IN, NULL}}, \ .afe_ns_mode = NS_MODE_SSP, \ @@ -145,10 +147,12 @@ typedef struct { .memory_alloc_mode = AFE_MEMORY_ALLOC_MORE_PSRAM, \ .afe_linear_gain = 1.0, \ .agc_mode = AFE_MN_PEAK_AGC_MODE_2, \ - .pcm_config.total_ch_num = 2, \ - .pcm_config.mic_num = 1, \ - .pcm_config.ref_num = 1, \ - .pcm_config.sample_rate = 16000, \ + .pcm_config = { \ + .total_ch_num = 2, \ + .mic_num = 1, \ + .ref_num = 1, \ + .sample_rate = 16000, \ + }, \ .debug_init = false, \ .debug_hook = {{AFE_DEBUG_HOOK_MASE_TASK_IN, NULL}, {AFE_DEBUG_HOOK_FETCH_TASK_IN, NULL}}, \ .afe_ns_mode = NS_MODE_SSP, \ @@ -175,10 +179,12 @@ typedef struct { .memory_alloc_mode = AFE_MEMORY_ALLOC_MORE_PSRAM, \ .afe_linear_gain = 1.0, \ .agc_mode = AFE_MN_PEAK_AGC_MODE_2, \ - .pcm_config.total_ch_num = 3, \ - .pcm_config.mic_num = 2, \ - .pcm_config.ref_num = 1, \ - .pcm_config.sample_rate = 16000, \ + .pcm_config = { \ + .total_ch_num = 3, \ + .mic_num = 2, \ + .ref_num = 1, \ + .sample_rate = 16000, \ + }, \ .debug_init = false, \ .debug_hook = {{AFE_DEBUG_HOOK_MASE_TASK_IN, NULL}, {AFE_DEBUG_HOOK_FETCH_TASK_IN, NULL}}, \ .afe_ns_mode = NS_MODE_SSP, \ diff --git a/include/esp32p4/esp_afe_sr_iface.h b/include/esp32p4/esp_afe_sr_iface.h index daf5b92..0b52ea4 100644 --- a/include/esp32p4/esp_afe_sr_iface.h +++ b/include/esp32p4/esp_afe_sr_iface.h @@ -112,7 +112,7 @@ typedef afe_fetch_result_t* (*esp_afe_sr_iface_op_fetch_t)(esp_afe_sr_data_t *af * @brief reset ringbuf of AFE. * * @param afe The AFE_SR object to query - * @return -1: fail, 0: success + * @return -1: fail, 1: success */ typedef int (*esp_afe_sr_iface_op_reset_buffer_t)(esp_afe_sr_data_t *afe); @@ -122,7 +122,7 @@ typedef int (*esp_afe_sr_iface_op_reset_buffer_t)(esp_afe_sr_data_t *afe); * * @param afe The AFE_SR object to query * @param wakenet_word The wakenet word, should be DEFAULT_WAKE_WORD or EXTRA_WAKE_WORD - * @return 0: fail, 1: success + * @return -1: fail, 1: success */ typedef int (*esp_afe_sr_iface_op_set_wakenet_t)(esp_afe_sr_data_t *afe, char* model_name); @@ -130,7 +130,7 @@ typedef int (*esp_afe_sr_iface_op_set_wakenet_t)(esp_afe_sr_data_t *afe, char* m * @brief Disable wakenet model. * * @param afe The AFE_SR object to query - * @return 0: fail, 1: success + * @return -1: fail, 0: disabled, 1: enabled */ typedef int (*esp_afe_sr_iface_op_disable_wakenet_t)(esp_afe_sr_data_t *afe); @@ -138,7 +138,7 @@ typedef int (*esp_afe_sr_iface_op_disable_wakenet_t)(esp_afe_sr_data_t *afe); * @brief Enable wakenet model. * * @param afe The AFE_SR object to query - * @return 0: fail, 1: success + * @return -1: fail, 0: disabled, 1: enabled */ typedef int (*esp_afe_sr_iface_op_enable_wakenet_t)(esp_afe_sr_data_t *afe); @@ -146,7 +146,7 @@ typedef int (*esp_afe_sr_iface_op_enable_wakenet_t)(esp_afe_sr_data_t *afe); * @brief Disable AEC algorithm. * * @param afe The AFE_SR object to query - * @return 0: fail, 1: success + * @return -1: fail, 0: disabled, 1: enabled */ typedef int (*esp_afe_sr_iface_op_disable_aec_t)(esp_afe_sr_data_t *afe); @@ -154,7 +154,7 @@ typedef int (*esp_afe_sr_iface_op_disable_aec_t)(esp_afe_sr_data_t *afe); * @brief Enable AEC algorithm. * * @param afe The AFE_SR object to query - * @return 0: fail, 1: success + * @return -1: fail, 0: disabled, 1: enabled */ typedef int (*esp_afe_sr_iface_op_enable_aec_t)(esp_afe_sr_data_t *afe); @@ -162,7 +162,7 @@ typedef int (*esp_afe_sr_iface_op_enable_aec_t)(esp_afe_sr_data_t *afe); * @brief Disable SE algorithm. * * @param afe The AFE_SR object to query - * @return 0: fail, 1: success + * @return -1: fail, 0: disabled, 1: enabled */ typedef int (*esp_afe_sr_iface_op_disable_se_t)(esp_afe_sr_data_t *afe); @@ -170,7 +170,7 @@ typedef int (*esp_afe_sr_iface_op_disable_se_t)(esp_afe_sr_data_t *afe); * @brief Enable SE algorithm. * * @param afe The AFE_SR object to query - * @return 0: fail, 1: success + * @return -1: fail, 0: disabled, 1: enabled */ typedef int (*esp_afe_sr_iface_op_enable_se_t)(esp_afe_sr_data_t *afe); diff --git a/include/esp32p4/esp_mn_iface.h b/include/esp32p4/esp_mn_iface.h index 20f96d8..a1ef049 100644 --- a/include/esp32p4/esp_mn_iface.h +++ b/include/esp32p4/esp_mn_iface.h @@ -198,7 +198,7 @@ typedef void (*esp_mn_iface_op_print_active_speech_commands)(model_iface_data_t * @param model_data The model object to query * @param str The input string */ -typedef int (*esp_mn_iface_op_check_speech_command)(model_iface_data_t *model_data, char *str); +typedef int (*esp_mn_iface_op_check_speech_command)(model_iface_data_t *model_data, const char *str); typedef struct { esp_mn_iface_op_create_t create; diff --git a/include/esp32p4/flite_g2p.h b/include/esp32p4/flite_g2p.h index 0d081cd..e91425e 100644 --- a/include/esp32p4/flite_g2p.h +++ b/include/esp32p4/flite_g2p.h @@ -9,12 +9,12 @@ typedef struct { void flite_g2p_result_free(flite_g2p_result *result); -flite_g2p_result *flite_g2p_get_result(char *grapheme); +flite_g2p_result *flite_g2p_get_result(const char *grapheme); void flite_g2p_result_print_string(flite_g2p_result *result, int map_phonemes); char *flite_g2p_result_get_string(flite_g2p_result *result, int map_phonemes); -char *flite_g2p(char *graphemes, int map_phonemes); +char *flite_g2p(const char *graphemes, int map_phonemes); #endif \ No newline at end of file diff --git a/include/esp32s3/esp_afe_config.h b/include/esp32s3/esp_afe_config.h index ff04665..6cac4c6 100644 --- a/include/esp32s3/esp_afe_config.h +++ b/include/esp32s3/esp_afe_config.h @@ -115,10 +115,12 @@ typedef struct { .memory_alloc_mode = AFE_MEMORY_ALLOC_INTERNAL_PSRAM_BALANCE, \ .afe_linear_gain = 1.0, \ .agc_mode = AFE_MN_PEAK_AGC_MODE_2, \ - .pcm_config.total_ch_num = 2, \ - .pcm_config.mic_num = 1, \ - .pcm_config.ref_num = 1, \ - .pcm_config.sample_rate = 16000, \ + .pcm_config = { \ + .total_ch_num = 2, \ + .mic_num = 1, \ + .ref_num = 1, \ + .sample_rate = 16000, \ + }, \ .debug_init = false, \ .debug_hook = {{AFE_DEBUG_HOOK_MASE_TASK_IN, NULL}, {AFE_DEBUG_HOOK_FETCH_TASK_IN, NULL}}, \ .afe_ns_mode = NS_MODE_SSP, \ @@ -145,10 +147,12 @@ typedef struct { .memory_alloc_mode = AFE_MEMORY_ALLOC_MORE_PSRAM, \ .afe_linear_gain = 1.0, \ .agc_mode = AFE_MN_PEAK_AGC_MODE_2, \ - .pcm_config.total_ch_num = 2, \ - .pcm_config.mic_num = 1, \ - .pcm_config.ref_num = 1, \ - .pcm_config.sample_rate = 16000, \ + .pcm_config = { \ + .total_ch_num = 2, \ + .mic_num = 1, \ + .ref_num = 1, \ + .sample_rate = 16000, \ + }, \ .debug_init = false, \ .debug_hook = {{AFE_DEBUG_HOOK_MASE_TASK_IN, NULL}, {AFE_DEBUG_HOOK_FETCH_TASK_IN, NULL}}, \ .afe_ns_mode = NS_MODE_SSP, \ @@ -175,10 +179,12 @@ typedef struct { .memory_alloc_mode = AFE_MEMORY_ALLOC_MORE_PSRAM, \ .afe_linear_gain = 1.0, \ .agc_mode = AFE_MN_PEAK_AGC_MODE_2, \ - .pcm_config.total_ch_num = 3, \ - .pcm_config.mic_num = 2, \ - .pcm_config.ref_num = 1, \ - .pcm_config.sample_rate = 16000, \ + .pcm_config = { \ + .total_ch_num = 3, \ + .mic_num = 2, \ + .ref_num = 1, \ + .sample_rate = 16000, \ + }, \ .debug_init = false, \ .debug_hook = {{AFE_DEBUG_HOOK_MASE_TASK_IN, NULL}, {AFE_DEBUG_HOOK_FETCH_TASK_IN, NULL}}, \ .afe_ns_mode = NS_MODE_SSP, \ diff --git a/include/esp32s3/esp_afe_sr_iface.h b/include/esp32s3/esp_afe_sr_iface.h index daf5b92..0b52ea4 100644 --- a/include/esp32s3/esp_afe_sr_iface.h +++ b/include/esp32s3/esp_afe_sr_iface.h @@ -112,7 +112,7 @@ typedef afe_fetch_result_t* (*esp_afe_sr_iface_op_fetch_t)(esp_afe_sr_data_t *af * @brief reset ringbuf of AFE. * * @param afe The AFE_SR object to query - * @return -1: fail, 0: success + * @return -1: fail, 1: success */ typedef int (*esp_afe_sr_iface_op_reset_buffer_t)(esp_afe_sr_data_t *afe); @@ -122,7 +122,7 @@ typedef int (*esp_afe_sr_iface_op_reset_buffer_t)(esp_afe_sr_data_t *afe); * * @param afe The AFE_SR object to query * @param wakenet_word The wakenet word, should be DEFAULT_WAKE_WORD or EXTRA_WAKE_WORD - * @return 0: fail, 1: success + * @return -1: fail, 1: success */ typedef int (*esp_afe_sr_iface_op_set_wakenet_t)(esp_afe_sr_data_t *afe, char* model_name); @@ -130,7 +130,7 @@ typedef int (*esp_afe_sr_iface_op_set_wakenet_t)(esp_afe_sr_data_t *afe, char* m * @brief Disable wakenet model. * * @param afe The AFE_SR object to query - * @return 0: fail, 1: success + * @return -1: fail, 0: disabled, 1: enabled */ typedef int (*esp_afe_sr_iface_op_disable_wakenet_t)(esp_afe_sr_data_t *afe); @@ -138,7 +138,7 @@ typedef int (*esp_afe_sr_iface_op_disable_wakenet_t)(esp_afe_sr_data_t *afe); * @brief Enable wakenet model. * * @param afe The AFE_SR object to query - * @return 0: fail, 1: success + * @return -1: fail, 0: disabled, 1: enabled */ typedef int (*esp_afe_sr_iface_op_enable_wakenet_t)(esp_afe_sr_data_t *afe); @@ -146,7 +146,7 @@ typedef int (*esp_afe_sr_iface_op_enable_wakenet_t)(esp_afe_sr_data_t *afe); * @brief Disable AEC algorithm. * * @param afe The AFE_SR object to query - * @return 0: fail, 1: success + * @return -1: fail, 0: disabled, 1: enabled */ typedef int (*esp_afe_sr_iface_op_disable_aec_t)(esp_afe_sr_data_t *afe); @@ -154,7 +154,7 @@ typedef int (*esp_afe_sr_iface_op_disable_aec_t)(esp_afe_sr_data_t *afe); * @brief Enable AEC algorithm. * * @param afe The AFE_SR object to query - * @return 0: fail, 1: success + * @return -1: fail, 0: disabled, 1: enabled */ typedef int (*esp_afe_sr_iface_op_enable_aec_t)(esp_afe_sr_data_t *afe); @@ -162,7 +162,7 @@ typedef int (*esp_afe_sr_iface_op_enable_aec_t)(esp_afe_sr_data_t *afe); * @brief Disable SE algorithm. * * @param afe The AFE_SR object to query - * @return 0: fail, 1: success + * @return -1: fail, 0: disabled, 1: enabled */ typedef int (*esp_afe_sr_iface_op_disable_se_t)(esp_afe_sr_data_t *afe); @@ -170,7 +170,7 @@ typedef int (*esp_afe_sr_iface_op_disable_se_t)(esp_afe_sr_data_t *afe); * @brief Enable SE algorithm. * * @param afe The AFE_SR object to query - * @return 0: fail, 1: success + * @return -1: fail, 0: disabled, 1: enabled */ typedef int (*esp_afe_sr_iface_op_enable_se_t)(esp_afe_sr_data_t *afe); diff --git a/include/esp32s3/esp_mn_iface.h b/include/esp32s3/esp_mn_iface.h index 20f96d8..a1ef049 100644 --- a/include/esp32s3/esp_mn_iface.h +++ b/include/esp32s3/esp_mn_iface.h @@ -198,7 +198,7 @@ typedef void (*esp_mn_iface_op_print_active_speech_commands)(model_iface_data_t * @param model_data The model object to query * @param str The input string */ -typedef int (*esp_mn_iface_op_check_speech_command)(model_iface_data_t *model_data, char *str); +typedef int (*esp_mn_iface_op_check_speech_command)(model_iface_data_t *model_data, const char *str); typedef struct { esp_mn_iface_op_create_t create; diff --git a/include/esp32s3/flite_g2p.h b/include/esp32s3/flite_g2p.h index 0d081cd..e91425e 100644 --- a/include/esp32s3/flite_g2p.h +++ b/include/esp32s3/flite_g2p.h @@ -9,12 +9,12 @@ typedef struct { void flite_g2p_result_free(flite_g2p_result *result); -flite_g2p_result *flite_g2p_get_result(char *grapheme); +flite_g2p_result *flite_g2p_get_result(const char *grapheme); void flite_g2p_result_print_string(flite_g2p_result *result, int map_phonemes); char *flite_g2p_result_get_string(flite_g2p_result *result, int map_phonemes); -char *flite_g2p(char *graphemes, int map_phonemes); +char *flite_g2p(const char *graphemes, int map_phonemes); #endif \ No newline at end of file diff --git a/lib/esp32p4/libc_speech_features.a b/lib/esp32p4/libc_speech_features.a index 76a9c69..0ef34d1 100644 Binary files a/lib/esp32p4/libc_speech_features.a and b/lib/esp32p4/libc_speech_features.a differ diff --git a/lib/esp32p4/libdl_lib.a b/lib/esp32p4/libdl_lib.a index f262fc6..576e891 100644 Binary files a/lib/esp32p4/libdl_lib.a and b/lib/esp32p4/libdl_lib.a differ diff --git a/lib/esp32p4/libesp_audio_front_end.a b/lib/esp32p4/libesp_audio_front_end.a index 518d753..2526180 100644 Binary files a/lib/esp32p4/libesp_audio_front_end.a and b/lib/esp32p4/libesp_audio_front_end.a differ diff --git a/lib/esp32p4/libesp_audio_processor.a b/lib/esp32p4/libesp_audio_processor.a index 70277be..33302b9 100644 Binary files a/lib/esp32p4/libesp_audio_processor.a and b/lib/esp32p4/libesp_audio_processor.a differ diff --git a/lib/esp32p4/libflite_g2p.a b/lib/esp32p4/libflite_g2p.a index 74c47b2..959bf76 100644 Binary files a/lib/esp32p4/libflite_g2p.a and b/lib/esp32p4/libflite_g2p.a differ diff --git a/lib/esp32p4/libfst.a b/lib/esp32p4/libfst.a index 670d18a..ef32581 100644 Binary files a/lib/esp32p4/libfst.a and b/lib/esp32p4/libfst.a differ diff --git a/lib/esp32p4/libhufzip.a b/lib/esp32p4/libhufzip.a index 0385219..7ed63a3 100644 Binary files a/lib/esp32p4/libhufzip.a and b/lib/esp32p4/libhufzip.a differ diff --git a/lib/esp32p4/libmultinet.a b/lib/esp32p4/libmultinet.a index 9b9ec39..f13b013 100644 Binary files a/lib/esp32p4/libmultinet.a and b/lib/esp32p4/libmultinet.a differ diff --git a/lib/esp32p4/libnsnet.a b/lib/esp32p4/libnsnet.a index aac86e4..47fc4c6 100644 Binary files a/lib/esp32p4/libnsnet.a and b/lib/esp32p4/libnsnet.a differ diff --git a/lib/esp32p4/libwakenet.a b/lib/esp32p4/libwakenet.a index 2aa5f17..91d3059 100644 Binary files a/lib/esp32p4/libwakenet.a and b/lib/esp32p4/libwakenet.a differ diff --git a/lib/esp32s3/libdl_lib.a b/lib/esp32s3/libdl_lib.a index c082693..21626fa 100644 Binary files a/lib/esp32s3/libdl_lib.a and b/lib/esp32s3/libdl_lib.a differ diff --git a/lib/esp32s3/libesp_audio_front_end.a b/lib/esp32s3/libesp_audio_front_end.a index 2d424f4..ed917cb 100644 Binary files a/lib/esp32s3/libesp_audio_front_end.a and b/lib/esp32s3/libesp_audio_front_end.a differ diff --git a/lib/esp32s3/libflite_g2p.a b/lib/esp32s3/libflite_g2p.a index 22e0f5c..76538e2 100644 Binary files a/lib/esp32s3/libflite_g2p.a and b/lib/esp32s3/libflite_g2p.a differ diff --git a/lib/esp32s3/libmultinet.a b/lib/esp32s3/libmultinet.a index eaae611..b7418f8 100644 Binary files a/lib/esp32s3/libmultinet.a and b/lib/esp32s3/libmultinet.a differ diff --git a/lib/esp32s3/libnsnet.a b/lib/esp32s3/libnsnet.a index 02f14bb..3b00050 100644 Binary files a/lib/esp32s3/libnsnet.a and b/lib/esp32s3/libnsnet.a differ diff --git a/lib/esp32s3/libwakenet.a b/lib/esp32s3/libwakenet.a index 892ad83..82c5c27 100644 Binary files a/lib/esp32s3/libwakenet.a and b/lib/esp32s3/libwakenet.a differ diff --git a/src/esp_mn_speech_commands.c b/src/esp_mn_speech_commands.c index 344b013..849fc71 100644 --- a/src/esp_mn_speech_commands.c +++ b/src/esp_mn_speech_commands.c @@ -79,7 +79,7 @@ esp_err_t esp_mn_commands_clear(void) return ESP_OK; } -esp_mn_node_t *esp_mn_command_search(char *string) +esp_mn_node_t *esp_mn_command_search(const char *string) { esp_mn_node_t *temp = esp_mn_root; if(NULL == esp_mn_root) { @@ -95,7 +95,7 @@ esp_mn_node_t *esp_mn_command_search(char *string) return NULL; } -esp_err_t esp_mn_commands_add(int command_id, char *string) +esp_err_t esp_mn_commands_add(int command_id, const char *string) { if (NULL == esp_mn_root || esp_mn_model_handle == NULL || esp_mn_model_data == NULL) { ESP_LOGE(TAG, "Please create mn model first.\n"); @@ -156,7 +156,7 @@ esp_err_t esp_mn_commands_add(int command_id, char *string) return ESP_OK; } -esp_err_t esp_mn_commands_phoneme_add(int command_id, char *string, char *phonemes) +esp_err_t esp_mn_commands_phoneme_add(int command_id, const char *string, const char *phonemes) { if (NULL == esp_mn_root || esp_mn_model_handle == NULL || esp_mn_model_data == NULL) { ESP_LOGE(TAG, "Please create mn model first.\n"); @@ -214,7 +214,7 @@ esp_err_t esp_mn_commands_phoneme_add(int command_id, char *string, char *phonem return ESP_OK; } -esp_err_t esp_mn_commands_modify(char *old_string, char *new_string) +esp_err_t esp_mn_commands_modify(const char *old_string, const char *new_string) { #ifdef CONFIG_SR_MN_EN_MULTINET7_QUANT char *phonemes = flite_g2p(new_string, 1); @@ -257,7 +257,7 @@ esp_err_t esp_mn_commands_modify(char *old_string, char *new_string) return ESP_OK; } -esp_err_t esp_mn_commands_remove(char *string) +esp_err_t esp_mn_commands_remove(const char *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"); @@ -374,7 +374,7 @@ void esp_mn_active_commands_print(void) ESP_LOGI(TAG, "---------------------------------------------------------\n"); } -esp_mn_phrase_t *esp_mn_phrase_alloc(int command_id, char *string) +esp_mn_phrase_t *esp_mn_phrase_alloc(int command_id, const char *string) { int string_len = strlen(string); diff --git a/src/include/esp_mn_speech_commands.h b/src/include/esp_mn_speech_commands.h index d643c82..615d612 100644 --- a/src/include/esp_mn_speech_commands.h +++ b/src/include/esp_mn_speech_commands.h @@ -57,7 +57,7 @@ esp_err_t esp_mn_commands_free(void); * - ESP_OK Success * - ESP_ERR_INVALID_STATE Fail */ -esp_err_t esp_mn_commands_add(int command_id, char *string); +esp_err_t esp_mn_commands_add(int command_id, const char *string); /** * @brief Add one speech commands with command string, command phonemes and command ID @@ -71,7 +71,7 @@ esp_err_t esp_mn_commands_add(int command_id, char *string); * - ESP_OK Success * - ESP_ERR_INVALID_STATE Fail */ -esp_err_t esp_mn_commands_phoneme_add(int command_id, char *string, char *phonemes); +esp_err_t esp_mn_commands_phoneme_add(int command_id, const char *string, const char *phonemes); /** * @brief Modify one speech commands with new command string @@ -83,7 +83,7 @@ esp_err_t esp_mn_commands_phoneme_add(int command_id, char *string, char *phonem * - ESP_OK Success * - ESP_ERR_INVALID_STATE Fail */ -esp_err_t esp_mn_commands_modify(char *old_string, char *new_string); +esp_err_t esp_mn_commands_modify(const char *old_string, const char *new_string); /** * @brief Remove one speech commands by command string @@ -94,7 +94,7 @@ esp_err_t esp_mn_commands_modify(char *old_string, char *new_string); * - ESP_OK Success * - ESP_ERR_INVALID_STATE Fail */ -esp_err_t esp_mn_commands_remove(char *string); +esp_err_t esp_mn_commands_remove(const char *string); /** * @brief Clear all speech commands in linked list @@ -157,7 +157,7 @@ esp_mn_error_t *esp_mn_commands_update(); * * @return the pointer of esp_mn_phrase_t */ -esp_mn_phrase_t *esp_mn_phrase_alloc(int command_id, char *string); +esp_mn_phrase_t *esp_mn_phrase_alloc(int command_id, const char *string); /** * @brief Free esp_mn_phrase_t pointer. diff --git a/test_apps/esp-sr/main/CMakeLists.txt b/test_apps/esp-sr/main/CMakeLists.txt index dfd621e..8513954 100644 --- a/test_apps/esp-sr/main/CMakeLists.txt +++ b/test_apps/esp-sr/main/CMakeLists.txt @@ -1,9 +1,9 @@ set(srcs - "test_app_main.c" - "test_wakenet.c" - "test_multinet.c" - "test_afe.c" + "app_main.cpp" + "test_wakenet.cpp" + "test_multinet.cpp" + "test_afe.cpp" ) idf_component_register(SRCS ${srcs} diff --git a/test_apps/esp-tts/main/test_app_main.c b/test_apps/esp-sr/main/app_main.cpp similarity index 97% rename from test_apps/esp-tts/main/test_app_main.c rename to test_apps/esp-sr/main/app_main.cpp index 653d6a7..3ef6613 100644 --- a/test_apps/esp-tts/main/test_app_main.c +++ b/test_apps/esp-sr/main/app_main.cpp @@ -7,12 +7,11 @@ CONDITIONS OF ANY KIND, either express or implied. */ +#include "unity.h" #include #include -#include "unity.h" - -void app_main(void) +extern "C" void app_main(void) { /* These are the different ways of running registered tests. * In practice, only one of them is usually needed. @@ -45,4 +44,4 @@ void app_main(void) * Make sure that task watchdog is disabled if you use this function. */ unity_run_menu(); -} \ No newline at end of file +} diff --git a/test_apps/esp-sr/main/test_afe.c b/test_apps/esp-sr/main/test_afe.cpp similarity index 93% rename from test_apps/esp-sr/main/test_afe.c rename to test_apps/esp-sr/main/test_afe.cpp index 1bb3033..35fa630 100644 --- a/test_apps/esp-sr/main/test_afe.c +++ b/test_apps/esp-sr/main/test_afe.cpp @@ -112,7 +112,7 @@ TEST_CASE(">>>>>>>> audio_front_end SR create/destroy API & memory leak <<<<<<<< afe_data = afe_handle->create_from_config(&afe_config); audio_chunksize = afe_handle->get_feed_chunksize(afe_data); - feed_buff = malloc(audio_chunksize * sizeof(int16_t) * afe_config.pcm_config.total_ch_num); + feed_buff = (int16_t *) malloc(audio_chunksize * sizeof(int16_t) * afe_config.pcm_config.total_ch_num); assert(feed_buff); afe_handle->feed(afe_data, feed_buff); @@ -145,7 +145,7 @@ void test_feed_Task(void *arg) esp_afe_sr_iface_t *afe_handle = (esp_afe_sr_iface_t *)arg; int feed_chunksize = afe_handle->get_feed_chunksize(afe_data); int total_nch = afe_handle->get_total_channel_num(afe_data); - int16_t *i2s_buff = malloc(feed_chunksize * sizeof(int16_t) * total_nch); + int16_t *i2s_buff = (int16_t *) malloc(feed_chunksize * sizeof(int16_t) * total_nch); assert(i2s_buff); ESP_LOGI(TAG, "feed task start\n"); // FILE *fp = fopen("/sdcard/out", "w"); @@ -169,7 +169,7 @@ void test_detect_Task(void *arg) // esp_afe_sr_iface_t *afe_handle = &ESP_AFE_SR_HANDLE; esp_afe_sr_iface_t *afe_handle = (esp_afe_sr_iface_t *)arg; int fetch_chunksize = afe_handle->get_fetch_chunksize(afe_data); - int16_t *buff = malloc(fetch_chunksize * sizeof(int16_t)); + int16_t *buff = (int16_t *) malloc(fetch_chunksize * sizeof(int16_t)); assert(buff); ESP_LOGI(TAG, "------------detect start------------\n"); @@ -208,21 +208,29 @@ esp_err_t audio_sys_get_real_time_stats(void) // Allocate array to store current task states start_array_size = uxTaskGetNumberOfTasks() + ARRAY_SIZE_OFFSET; - start_array = malloc(sizeof(TaskStatus_t) * start_array_size); + start_array = (TaskStatus_t*) malloc(sizeof(TaskStatus_t) * start_array_size); assert(start_array); // Get current task states start_array_size = uxTaskGetSystemState(start_array, start_array_size, &start_run_time); if (start_array_size == 0) { ESP_LOGE(TAG, "Insufficient array size for uxTaskGetSystemState. Trying increasing ARRAY_SIZE_OFFSET"); ret = ESP_FAIL; - goto exit; + if (start_array) { + free(start_array); + start_array = NULL; + } + if (end_array) { + free(end_array); + end_array = NULL; + } + return ret; } vTaskDelay(pdMS_TO_TICKS(AUDIO_SYS_TASKS_ELAPSED_TIME_MS)); // Allocate array to store tasks states post delay end_array_size = uxTaskGetNumberOfTasks() + ARRAY_SIZE_OFFSET; - end_array = malloc(sizeof(TaskStatus_t) * end_array_size); + end_array = (TaskStatus_t*) malloc(sizeof(TaskStatus_t) * end_array_size); assert(end_array); // Get post delay task states @@ -230,7 +238,15 @@ esp_err_t audio_sys_get_real_time_stats(void) if (end_array_size == 0) { ESP_LOGE(TAG, "Insufficient array size for uxTaskGetSystemState. Trying increasing ARRAY_SIZE_OFFSET"); ret = ESP_FAIL; - goto exit; + if (start_array) { + free(start_array); + start_array = NULL; + } + if (end_array) { + free(end_array); + end_array = NULL; + } + return ret; } // Calculate total_elapsed_time in units of run time stats clock period. @@ -238,7 +254,15 @@ esp_err_t audio_sys_get_real_time_stats(void) if (total_elapsed_time == 0) { ESP_LOGE(TAG, "Delay duration too short. Trying increasing AUDIO_SYS_TASKS_ELAPSED_TIME_MS"); ret = ESP_FAIL; - goto exit; + if (start_array) { + free(start_array); + start_array = NULL; + } + if (end_array) { + free(end_array); + end_array = NULL; + } + return ret; } ESP_LOGI(TAG, "| Task | Run Time | Per | Prio | HWM | State | CoreId | Stack "); @@ -277,15 +301,6 @@ esp_err_t audio_sys_get_real_time_stats(void) printf("\n"); ret = ESP_OK; -exit: // Common return path - if (start_array) { - free(start_array); - start_array = NULL; - } - if (end_array) { - free(end_array); - end_array = NULL; - } return ret; #else ESP_LOGW(TAG, "Please enbale `CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID` and `CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS` in menuconfig"); @@ -386,7 +401,7 @@ TEST_CASE("audio_front_end VC create/destroy API & memory leak", "[afe_vc]") afe_config.se_init = se_init; afe_config.vad_init = vad_init; afe_config.voice_communication_agc_init = voice_communication_agc_init; - afe_config.afe_ns_mode = afe_ns_mode; + afe_config.afe_ns_mode = (afe_ns_mode_t)afe_ns_mode; //start_total_mem_size = heap_caps_get_free_size(MALLOC_CAP_8BIT); //start_internal_mem_size = heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); @@ -412,7 +427,7 @@ TEST_CASE("audio_front_end VC create/destroy API & memory leak", "[afe_vc]") } audio_chunksize = afe_handle->get_feed_chunksize(afe_data); - feed_buff = malloc(audio_chunksize * sizeof(int16_t) * afe_config.pcm_config.total_ch_num); + feed_buff = (int16_t *) malloc(audio_chunksize * sizeof(int16_t) * afe_config.pcm_config.total_ch_num); assert(feed_buff); afe_handle->feed(afe_data, feed_buff); diff --git a/test_apps/esp-sr/main/test_multinet.c b/test_apps/esp-sr/main/test_multinet.cpp similarity index 99% rename from test_apps/esp-sr/main/test_multinet.c rename to test_apps/esp-sr/main/test_multinet.cpp index e14802f..369e23a 100644 --- a/test_apps/esp-sr/main/test_multinet.c +++ b/test_apps/esp-sr/main/test_multinet.cpp @@ -88,7 +88,7 @@ TEST_CASE("multinet cpu loading", "[mn]") printf("commands: da kai kong tiao, size:%d\n", data_size); } - int16_t *buffer = malloc(audio_chunksize); + int16_t *buffer = (int16_t *) malloc(audio_chunksize); int chunks = 0; struct timeval tv_start, tv_end; gettimeofday(&tv_start, NULL); diff --git a/test_apps/esp-sr/main/test_wakenet.c b/test_apps/esp-sr/main/test_wakenet.cpp similarity index 97% rename from test_apps/esp-sr/main/test_wakenet.c rename to test_apps/esp-sr/main/test_wakenet.cpp index fdb05eb..25fc537 100644 --- a/test_apps/esp-sr/main/test_wakenet.c +++ b/test_apps/esp-sr/main/test_wakenet.cpp @@ -65,7 +65,7 @@ TEST_CASE("wakenet create/destroy API & memory leak", "[wn]") // DET_MODE_3CH_90 = 4, // DET_MODE_3CH_95 = 5, // } det_mode_t; - model_data = wakenet->create(model_name, i); + model_data = wakenet->create(model_name, (det_mode_t)i); printf("destroy ...\n"); wakenet->destroy(model_data); @@ -89,7 +89,7 @@ TEST_CASE("wakenet detect API & cpu loading", "[wn]") model_iface_data_t *model_data = wakenet->create(model_name, DET_MODE_95); int frequency = wakenet->get_samp_rate(model_data); int audio_chunksize = wakenet->get_samp_chunksize(model_data) * sizeof(int16_t); - int16_t *buffer = malloc(audio_chunksize); + int16_t *buffer = (int16_t *) malloc(audio_chunksize); int chunks = 0; int detected = 0; struct timeval tv_start, tv_end; diff --git a/test_apps/esp-tts/main/CMakeLists.txt b/test_apps/esp-tts/main/CMakeLists.txt index 1cf2f9e..3ee65fd 100644 --- a/test_apps/esp-tts/main/CMakeLists.txt +++ b/test_apps/esp-tts/main/CMakeLists.txt @@ -1,7 +1,7 @@ set(srcs - "test_app_main.c" - "test_chinese_tts.c" + "app_main.cpp" + "test_chinese_tts.cpp" ) idf_component_register(SRCS ${srcs} diff --git a/test_apps/esp-sr/main/test_app_main.c b/test_apps/esp-tts/main/app_main.cpp similarity index 97% rename from test_apps/esp-sr/main/test_app_main.c rename to test_apps/esp-tts/main/app_main.cpp index 653d6a7..3ef6613 100644 --- a/test_apps/esp-sr/main/test_app_main.c +++ b/test_apps/esp-tts/main/app_main.cpp @@ -7,12 +7,11 @@ CONDITIONS OF ANY KIND, either express or implied. */ +#include "unity.h" #include #include -#include "unity.h" - -void app_main(void) +extern "C" void app_main(void) { /* These are the different ways of running registered tests. * In practice, only one of them is usually needed. @@ -45,4 +44,4 @@ void app_main(void) * Make sure that task watchdog is disabled if you use this function. */ unity_run_menu(); -} \ No newline at end of file +} diff --git a/test_apps/esp-tts/main/test_chinese_tts.cpp b/test_apps/esp-tts/main/test_chinese_tts.cpp new file mode 100644 index 0000000..cec2fa8 --- /dev/null +++ b/test_apps/esp-tts/main/test_chinese_tts.cpp @@ -0,0 +1,96 @@ +/* test_mean.c: Implementation of a testable component. + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include +#include "string.h" +#include +#include "unity.h" +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "esp_tts.h" +#include "esp_tts_voice_xiaole.h" +#include "esp_tts_voice_template.h" +#include "esp_tts_player.h" +#include "esp_partition.h" +#include "esp_idf_version.h" + +TEST_CASE("chinese tts create/destroy API & memory leak", "[tts]") +{ + int start_size = heap_caps_get_free_size(MALLOC_CAP_8BIT); + int start_internal_size = heap_caps_get_free_size(MALLOC_CAP_INTERNAL); + /*** 1. create esp tts handle ***/ + const void* voicedata; + const esp_partition_t* partition=esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, "voice_data"); + assert(partition != NULL); +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) + esp_partition_mmap_handle_t mmap_handle; + ESP_ERROR_CHECK(esp_partition_mmap(partition, 0, partition->size, ESP_PARTITION_MMAP_DATA, &voicedata, &mmap_handle)); +#else + spi_flash_mmap_handle_t mmap_handle; + ESP_ERROR_CHECK(esp_partition_mmap(partition, 0, partition->size, SPI_FLASH_MMAP_DATA, &voicedata, &mmap_handle)); +#endif + + // test model loading time + struct timeval tv_start, tv_end; + gettimeofday(&tv_start, NULL); + esp_tts_voice_t *voice=esp_tts_voice_set_init(&esp_tts_voice_template, (int16_t*)voicedata); + esp_tts_handle_t *tts_handle=(esp_tts_handle_t *)esp_tts_create(voice); + gettimeofday(&tv_end, NULL); + int tv_ms = (tv_end.tv_sec - tv_start.tv_sec) * 1000 + (tv_end.tv_usec - tv_start.tv_usec) / 1000; + printf("create latency:%d ms\n", tv_ms); + + // test model memory concumption + int create_size = start_size - heap_caps_get_free_size(MALLOC_CAP_8BIT); + int create_internal_size = start_internal_size - heap_caps_get_free_size(MALLOC_CAP_INTERNAL); + printf("Internal RAM: %d, PSRAM:%d\n", create_internal_size, create_size - create_internal_size); + + // test memory leak + esp_tts_voice_set_free(voice); + esp_tts_destroy(tts_handle); +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) + esp_partition_munmap(mmap_handle); // support esp-idf v5 +#else + spi_flash_munmap(mmap_handle); // support esp-idf v4 +#endif + int first_end_size = heap_caps_get_free_size(MALLOC_CAP_8BIT); + int last_end_size = first_end_size; + int mem_leak = start_size - last_end_size; + printf("create&destroy times:%d, memory leak:%d\n", 1, mem_leak); + + for (int i = 0; i < 6; i++) { + printf("init partition ...\n"); + partition=esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, "voice_data"); + assert(partition != NULL); +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) + ESP_ERROR_CHECK(esp_partition_mmap(partition, 0, partition->size, ESP_PARTITION_MMAP_DATA, &voicedata, &mmap_handle)); +#else + ESP_ERROR_CHECK(esp_partition_mmap(partition, 0, partition->size, SPI_FLASH_MMAP_DATA, &voicedata, &mmap_handle)); +#endif + + printf("create ...\n"); + voice=esp_tts_voice_set_init(&esp_tts_voice_template, (int16_t*)voicedata); + tts_handle=(esp_tts_handle_t *)esp_tts_create(voice); + + printf("destroy ...\n"); + esp_tts_voice_set_free(voice); + esp_tts_destroy(tts_handle); +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) + esp_partition_munmap(mmap_handle); // support esp-idf v5 +#else + spi_flash_munmap(mmap_handle); // support esp-idf v4 +#endif + last_end_size = heap_caps_get_free_size(MALLOC_CAP_8BIT); + mem_leak = start_size - last_end_size; + printf("create&destroy times:%d, memory leak:%d\n", i + 2, mem_leak); + } + + TEST_ASSERT_EQUAL(true, (mem_leak) < 1000 && last_end_size == first_end_size); +} \ No newline at end of file