Merge branch 'bugfix/c++' into 'master'

Bugfix/c++

See merge request speech-recognition-framework/esp-sr!120
This commit is contained in:
Sun Xiang Yu 2024-11-06 11:24:05 +08:00
commit c74b3b32e2
43 changed files with 253 additions and 112 deletions

View File

@ -4,6 +4,10 @@
- Available storage is less than the remaining flash space on IDF v5.0. - 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. 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 ## 1.9.3
- Fix nsnet2 crash - Fix nsnet2 crash
- Add esp32p4 ci test - Add esp32p4 ci test

View File

@ -257,12 +257,12 @@ menu "Load Multiple Wake Words"
config SR_WN_WN9_HEYWANDA_TTS_MULTI config SR_WN_WN9_HEYWANDA_TTS_MULTI
bool "Hey,Wanda (wn9_heywanda_tts)" bool "Hey,Wanda (wn9_heywanda_tts)"
depends on IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32P4 depends on IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32P4
config SR_WN_WN9_HIMIAOMIAO_TTS_MULTI config SR_WN_WN9_HIMIAOMIAO_TTS_MULTI
bool "Hi,喵喵 (wn9_himiaomiao_tts)" bool "Hi,喵喵 (wn9_himiaomiao_tts)"
depends on IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32P4 depends on IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32P4
config SR_WN_WN9_MYCROFT_TTS_MULTI config SR_WN_WN9_MYCROFT_TTS_MULTI

View File

@ -40,7 +40,7 @@ typedef void * esp_tts_handle_t;
* - NULL: Init failed * - NULL: Init failed
* - Others: The instance of voice set * - 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. * @brief Init an instance of the TTS voice set structure.

View File

@ -4,7 +4,9 @@
#include "stdlib.h" #include "stdlib.h"
#include "esp_tts_voice.h" #include "esp_tts_voice.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct { typedef struct {
int *syll_idx; int *syll_idx;
int syll_num; 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); void esp_tts_utt_free(esp_tts_utt_t *utt);
#ifdef __cplusplus
}
#endif
#endif #endif

View File

@ -1,6 +1,10 @@
#ifndef _ESP_TTS_VOICE_H_ #ifndef _ESP_TTS_VOICE_H_
#define _ESP_TTS_VOICE_H_ #define _ESP_TTS_VOICE_H_
#ifdef __cplusplus
extern "C" {
#endif
typedef struct { typedef struct {
char *voice_name; // voice set name char *voice_name; // voice set name
char *format; // the format of voice data, currently support pcm and amrwb 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 unsigned char *data; // the audio data of all syllables
} esp_tts_voice_t; } esp_tts_voice_t;
#ifdef __cplusplus
}
#endif
#endif #endif

View File

@ -1,4 +1,4 @@
version: "1.9.3" version: "1.9.4"
description: esp_sr provides basic algorithms for Speech Recognition applications description: esp_sr provides basic algorithms for Speech Recognition applications
url: https://github.com/espressif/esp-sr url: https://github.com/espressif/esp-sr
dependencies: dependencies:

View File

@ -113,10 +113,12 @@ typedef struct {
.memory_alloc_mode = AFE_MEMORY_ALLOC_INTERNAL_PSRAM_BALANCE, \ .memory_alloc_mode = AFE_MEMORY_ALLOC_INTERNAL_PSRAM_BALANCE, \
.afe_linear_gain = 1.0, \ .afe_linear_gain = 1.0, \
.agc_mode = AFE_MN_PEAK_AGC_MODE_2, \ .agc_mode = AFE_MN_PEAK_AGC_MODE_2, \
.pcm_config.total_ch_num = 2, \ .pcm_config = { \
.pcm_config.mic_num = 1, \ .total_ch_num = 2, \
.pcm_config.ref_num = 1, \ .mic_num = 1, \
.pcm_config.sample_rate = 16000, \ .ref_num = 1, \
.sample_rate = 16000, \
}, \
.debug_init = false, \ .debug_init = false, \
.debug_hook = {{AFE_DEBUG_HOOK_MASE_TASK_IN, NULL}, {AFE_DEBUG_HOOK_FETCH_TASK_IN, NULL}}, \ .debug_hook = {{AFE_DEBUG_HOOK_MASE_TASK_IN, NULL}, {AFE_DEBUG_HOOK_FETCH_TASK_IN, NULL}}, \
.afe_ns_mode = NS_MODE_SSP, \ .afe_ns_mode = NS_MODE_SSP, \
@ -142,10 +144,12 @@ typedef struct {
.memory_alloc_mode = AFE_MEMORY_ALLOC_MORE_PSRAM, \ .memory_alloc_mode = AFE_MEMORY_ALLOC_MORE_PSRAM, \
.afe_linear_gain = 1.0, \ .afe_linear_gain = 1.0, \
.agc_mode = AFE_MN_PEAK_AGC_MODE_2, \ .agc_mode = AFE_MN_PEAK_AGC_MODE_2, \
.pcm_config.total_ch_num = 3, \ .pcm_config = { \
.pcm_config.mic_num = 2, \ .total_ch_num = 3, \
.pcm_config.ref_num = 1, \ .mic_num = 2, \
.pcm_config.sample_rate = 16000, \ .ref_num = 1, \
.sample_rate = 16000, \
}, \
.debug_init = false, \ .debug_init = false, \
.debug_hook = {{AFE_DEBUG_HOOK_MASE_TASK_IN, NULL}, {AFE_DEBUG_HOOK_FETCH_TASK_IN, NULL}}, \ .debug_hook = {{AFE_DEBUG_HOOK_MASE_TASK_IN, NULL}, {AFE_DEBUG_HOOK_FETCH_TASK_IN, NULL}}, \
.afe_ns_mode = NS_MODE_SSP, \ .afe_ns_mode = NS_MODE_SSP, \
@ -155,4 +159,4 @@ typedef struct {
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -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 model_data The model object to query
* @param str The input string * @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 { typedef struct {
esp_mn_iface_op_create_t create; esp_mn_iface_op_create_t create;

View File

@ -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_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 #endif

View File

@ -115,10 +115,12 @@ typedef struct {
.memory_alloc_mode = AFE_MEMORY_ALLOC_INTERNAL_PSRAM_BALANCE, \ .memory_alloc_mode = AFE_MEMORY_ALLOC_INTERNAL_PSRAM_BALANCE, \
.afe_linear_gain = 1.0, \ .afe_linear_gain = 1.0, \
.agc_mode = AFE_MN_PEAK_AGC_MODE_2, \ .agc_mode = AFE_MN_PEAK_AGC_MODE_2, \
.pcm_config.total_ch_num = 2, \ .pcm_config = { \
.pcm_config.mic_num = 1, \ .total_ch_num = 2, \
.pcm_config.ref_num = 1, \ .mic_num = 1, \
.pcm_config.sample_rate = 16000, \ .ref_num = 1, \
.sample_rate = 16000, \
}, \
.debug_init = false, \ .debug_init = false, \
.debug_hook = {{AFE_DEBUG_HOOK_MASE_TASK_IN, NULL}, {AFE_DEBUG_HOOK_FETCH_TASK_IN, NULL}}, \ .debug_hook = {{AFE_DEBUG_HOOK_MASE_TASK_IN, NULL}, {AFE_DEBUG_HOOK_FETCH_TASK_IN, NULL}}, \
.afe_ns_mode = NS_MODE_SSP, \ .afe_ns_mode = NS_MODE_SSP, \
@ -145,10 +147,12 @@ typedef struct {
.memory_alloc_mode = AFE_MEMORY_ALLOC_MORE_PSRAM, \ .memory_alloc_mode = AFE_MEMORY_ALLOC_MORE_PSRAM, \
.afe_linear_gain = 1.0, \ .afe_linear_gain = 1.0, \
.agc_mode = AFE_MN_PEAK_AGC_MODE_2, \ .agc_mode = AFE_MN_PEAK_AGC_MODE_2, \
.pcm_config.total_ch_num = 2, \ .pcm_config = { \
.pcm_config.mic_num = 1, \ .total_ch_num = 2, \
.pcm_config.ref_num = 1, \ .mic_num = 1, \
.pcm_config.sample_rate = 16000, \ .ref_num = 1, \
.sample_rate = 16000, \
}, \
.debug_init = false, \ .debug_init = false, \
.debug_hook = {{AFE_DEBUG_HOOK_MASE_TASK_IN, NULL}, {AFE_DEBUG_HOOK_FETCH_TASK_IN, NULL}}, \ .debug_hook = {{AFE_DEBUG_HOOK_MASE_TASK_IN, NULL}, {AFE_DEBUG_HOOK_FETCH_TASK_IN, NULL}}, \
.afe_ns_mode = NS_MODE_SSP, \ .afe_ns_mode = NS_MODE_SSP, \
@ -175,10 +179,12 @@ typedef struct {
.memory_alloc_mode = AFE_MEMORY_ALLOC_MORE_PSRAM, \ .memory_alloc_mode = AFE_MEMORY_ALLOC_MORE_PSRAM, \
.afe_linear_gain = 1.0, \ .afe_linear_gain = 1.0, \
.agc_mode = AFE_MN_PEAK_AGC_MODE_2, \ .agc_mode = AFE_MN_PEAK_AGC_MODE_2, \
.pcm_config.total_ch_num = 3, \ .pcm_config = { \
.pcm_config.mic_num = 2, \ .total_ch_num = 3, \
.pcm_config.ref_num = 1, \ .mic_num = 2, \
.pcm_config.sample_rate = 16000, \ .ref_num = 1, \
.sample_rate = 16000, \
}, \
.debug_init = false, \ .debug_init = false, \
.debug_hook = {{AFE_DEBUG_HOOK_MASE_TASK_IN, NULL}, {AFE_DEBUG_HOOK_FETCH_TASK_IN, NULL}}, \ .debug_hook = {{AFE_DEBUG_HOOK_MASE_TASK_IN, NULL}, {AFE_DEBUG_HOOK_FETCH_TASK_IN, NULL}}, \
.afe_ns_mode = NS_MODE_SSP, \ .afe_ns_mode = NS_MODE_SSP, \

View File

@ -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. * @brief reset ringbuf of AFE.
* *
* @param afe The AFE_SR object to query * @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); 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 afe The AFE_SR object to query
* @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 -1: fail, 1: success
*/ */
typedef int (*esp_afe_sr_iface_op_set_wakenet_t)(esp_afe_sr_data_t *afe, char* model_name); 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. * @brief Disable wakenet model.
* *
* @param afe The AFE_SR object to query * @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); 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. * @brief Enable wakenet model.
* *
* @param afe The AFE_SR object to query * @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); 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. * @brief Disable AEC algorithm.
* *
* @param afe The AFE_SR object to query * @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); 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. * @brief Enable AEC algorithm.
* *
* @param afe The AFE_SR object to query * @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); 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. * @brief Disable SE algorithm.
* *
* @param afe The AFE_SR object to query * @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); 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. * @brief Enable SE algorithm.
* *
* @param afe The AFE_SR object to query * @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); typedef int (*esp_afe_sr_iface_op_enable_se_t)(esp_afe_sr_data_t *afe);

View File

@ -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 model_data The model object to query
* @param str The input string * @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 { typedef struct {
esp_mn_iface_op_create_t create; esp_mn_iface_op_create_t create;

View File

@ -9,12 +9,12 @@ typedef struct {
void flite_g2p_result_free(flite_g2p_result *result); 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); 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_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 #endif

View File

@ -115,10 +115,12 @@ typedef struct {
.memory_alloc_mode = AFE_MEMORY_ALLOC_INTERNAL_PSRAM_BALANCE, \ .memory_alloc_mode = AFE_MEMORY_ALLOC_INTERNAL_PSRAM_BALANCE, \
.afe_linear_gain = 1.0, \ .afe_linear_gain = 1.0, \
.agc_mode = AFE_MN_PEAK_AGC_MODE_2, \ .agc_mode = AFE_MN_PEAK_AGC_MODE_2, \
.pcm_config.total_ch_num = 2, \ .pcm_config = { \
.pcm_config.mic_num = 1, \ .total_ch_num = 2, \
.pcm_config.ref_num = 1, \ .mic_num = 1, \
.pcm_config.sample_rate = 16000, \ .ref_num = 1, \
.sample_rate = 16000, \
}, \
.debug_init = false, \ .debug_init = false, \
.debug_hook = {{AFE_DEBUG_HOOK_MASE_TASK_IN, NULL}, {AFE_DEBUG_HOOK_FETCH_TASK_IN, NULL}}, \ .debug_hook = {{AFE_DEBUG_HOOK_MASE_TASK_IN, NULL}, {AFE_DEBUG_HOOK_FETCH_TASK_IN, NULL}}, \
.afe_ns_mode = NS_MODE_SSP, \ .afe_ns_mode = NS_MODE_SSP, \
@ -145,10 +147,12 @@ typedef struct {
.memory_alloc_mode = AFE_MEMORY_ALLOC_MORE_PSRAM, \ .memory_alloc_mode = AFE_MEMORY_ALLOC_MORE_PSRAM, \
.afe_linear_gain = 1.0, \ .afe_linear_gain = 1.0, \
.agc_mode = AFE_MN_PEAK_AGC_MODE_2, \ .agc_mode = AFE_MN_PEAK_AGC_MODE_2, \
.pcm_config.total_ch_num = 2, \ .pcm_config = { \
.pcm_config.mic_num = 1, \ .total_ch_num = 2, \
.pcm_config.ref_num = 1, \ .mic_num = 1, \
.pcm_config.sample_rate = 16000, \ .ref_num = 1, \
.sample_rate = 16000, \
}, \
.debug_init = false, \ .debug_init = false, \
.debug_hook = {{AFE_DEBUG_HOOK_MASE_TASK_IN, NULL}, {AFE_DEBUG_HOOK_FETCH_TASK_IN, NULL}}, \ .debug_hook = {{AFE_DEBUG_HOOK_MASE_TASK_IN, NULL}, {AFE_DEBUG_HOOK_FETCH_TASK_IN, NULL}}, \
.afe_ns_mode = NS_MODE_SSP, \ .afe_ns_mode = NS_MODE_SSP, \
@ -175,10 +179,12 @@ typedef struct {
.memory_alloc_mode = AFE_MEMORY_ALLOC_MORE_PSRAM, \ .memory_alloc_mode = AFE_MEMORY_ALLOC_MORE_PSRAM, \
.afe_linear_gain = 1.0, \ .afe_linear_gain = 1.0, \
.agc_mode = AFE_MN_PEAK_AGC_MODE_2, \ .agc_mode = AFE_MN_PEAK_AGC_MODE_2, \
.pcm_config.total_ch_num = 3, \ .pcm_config = { \
.pcm_config.mic_num = 2, \ .total_ch_num = 3, \
.pcm_config.ref_num = 1, \ .mic_num = 2, \
.pcm_config.sample_rate = 16000, \ .ref_num = 1, \
.sample_rate = 16000, \
}, \
.debug_init = false, \ .debug_init = false, \
.debug_hook = {{AFE_DEBUG_HOOK_MASE_TASK_IN, NULL}, {AFE_DEBUG_HOOK_FETCH_TASK_IN, NULL}}, \ .debug_hook = {{AFE_DEBUG_HOOK_MASE_TASK_IN, NULL}, {AFE_DEBUG_HOOK_FETCH_TASK_IN, NULL}}, \
.afe_ns_mode = NS_MODE_SSP, \ .afe_ns_mode = NS_MODE_SSP, \

View File

@ -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. * @brief reset ringbuf of AFE.
* *
* @param afe The AFE_SR object to query * @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); 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 afe The AFE_SR object to query
* @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 -1: fail, 1: success
*/ */
typedef int (*esp_afe_sr_iface_op_set_wakenet_t)(esp_afe_sr_data_t *afe, char* model_name); 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. * @brief Disable wakenet model.
* *
* @param afe The AFE_SR object to query * @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); 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. * @brief Enable wakenet model.
* *
* @param afe The AFE_SR object to query * @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); 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. * @brief Disable AEC algorithm.
* *
* @param afe The AFE_SR object to query * @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); 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. * @brief Enable AEC algorithm.
* *
* @param afe The AFE_SR object to query * @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); 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. * @brief Disable SE algorithm.
* *
* @param afe The AFE_SR object to query * @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); 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. * @brief Enable SE algorithm.
* *
* @param afe The AFE_SR object to query * @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); typedef int (*esp_afe_sr_iface_op_enable_se_t)(esp_afe_sr_data_t *afe);

View File

@ -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 model_data The model object to query
* @param str The input string * @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 { typedef struct {
esp_mn_iface_op_create_t create; esp_mn_iface_op_create_t create;

View File

@ -9,12 +9,12 @@ typedef struct {
void flite_g2p_result_free(flite_g2p_result *result); 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); 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_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 #endif

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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

@ -79,7 +79,7 @@ esp_err_t esp_mn_commands_clear(void)
return ESP_OK; 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; esp_mn_node_t *temp = esp_mn_root;
if(NULL == esp_mn_root) { if(NULL == esp_mn_root) {
@ -95,7 +95,7 @@ esp_mn_node_t *esp_mn_command_search(char *string)
return NULL; 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) { if (NULL == esp_mn_root || esp_mn_model_handle == NULL || esp_mn_model_data == NULL) {
ESP_LOGE(TAG, "Please create mn model first.\n"); 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; 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) { if (NULL == esp_mn_root || esp_mn_model_handle == NULL || esp_mn_model_data == NULL) {
ESP_LOGE(TAG, "Please create mn model first.\n"); 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; 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 #ifdef CONFIG_SR_MN_EN_MULTINET7_QUANT
char *phonemes = flite_g2p(new_string, 1); 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; 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_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"); 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_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); int string_len = strlen(string);

View File

@ -57,7 +57,7 @@ esp_err_t esp_mn_commands_free(void);
* - ESP_OK Success * - ESP_OK Success
* - ESP_ERR_INVALID_STATE Fail * - 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 * @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_OK Success
* - ESP_ERR_INVALID_STATE Fail * - 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 * @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_OK Success
* - ESP_ERR_INVALID_STATE Fail * - 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 * @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_OK Success
* - ESP_ERR_INVALID_STATE Fail * - 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 * @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 * @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. * @brief Free esp_mn_phrase_t pointer.

View File

@ -1,9 +1,9 @@
set(srcs set(srcs
"test_app_main.c" "app_main.cpp"
"test_wakenet.c" "test_wakenet.cpp"
"test_multinet.c" "test_multinet.cpp"
"test_afe.c" "test_afe.cpp"
) )
idf_component_register(SRCS ${srcs} idf_component_register(SRCS ${srcs}

View File

@ -7,12 +7,11 @@
CONDITIONS OF ANY KIND, either express or implied. CONDITIONS OF ANY KIND, either express or implied.
*/ */
#include "unity.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "unity.h"
extern "C" void app_main(void)
void app_main(void)
{ {
/* These are the different ways of running registered tests. /* These are the different ways of running registered tests.
* In practice, only one of them is usually needed. * 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. * Make sure that task watchdog is disabled if you use this function.
*/ */
unity_run_menu(); unity_run_menu();
} }

View File

@ -112,7 +112,7 @@ TEST_CASE(">>>>>>>> audio_front_end SR create/destroy API & memory leak <<<<<<<<
afe_data = afe_handle->create_from_config(&afe_config); afe_data = afe_handle->create_from_config(&afe_config);
audio_chunksize = afe_handle->get_feed_chunksize(afe_data); 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); assert(feed_buff);
afe_handle->feed(afe_data, 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; esp_afe_sr_iface_t *afe_handle = (esp_afe_sr_iface_t *)arg;
int feed_chunksize = afe_handle->get_feed_chunksize(afe_data); int feed_chunksize = afe_handle->get_feed_chunksize(afe_data);
int total_nch = afe_handle->get_total_channel_num(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); assert(i2s_buff);
ESP_LOGI(TAG, "feed task start\n"); ESP_LOGI(TAG, "feed task start\n");
// FILE *fp = fopen("/sdcard/out", "w"); // 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_HANDLE;
esp_afe_sr_iface_t *afe_handle = (esp_afe_sr_iface_t *)arg; esp_afe_sr_iface_t *afe_handle = (esp_afe_sr_iface_t *)arg;
int fetch_chunksize = afe_handle->get_fetch_chunksize(afe_data); 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); assert(buff);
ESP_LOGI(TAG, "------------detect start------------\n"); 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 // Allocate array to store current task states
start_array_size = uxTaskGetNumberOfTasks() + ARRAY_SIZE_OFFSET; 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); assert(start_array);
// Get current task states // Get current task states
start_array_size = uxTaskGetSystemState(start_array, start_array_size, &start_run_time); start_array_size = uxTaskGetSystemState(start_array, start_array_size, &start_run_time);
if (start_array_size == 0) { if (start_array_size == 0) {
ESP_LOGE(TAG, "Insufficient array size for uxTaskGetSystemState. Trying increasing ARRAY_SIZE_OFFSET"); ESP_LOGE(TAG, "Insufficient array size for uxTaskGetSystemState. Trying increasing ARRAY_SIZE_OFFSET");
ret = ESP_FAIL; 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)); vTaskDelay(pdMS_TO_TICKS(AUDIO_SYS_TASKS_ELAPSED_TIME_MS));
// Allocate array to store tasks states post delay // Allocate array to store tasks states post delay
end_array_size = uxTaskGetNumberOfTasks() + ARRAY_SIZE_OFFSET; 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); assert(end_array);
// Get post delay task states // Get post delay task states
@ -230,7 +238,15 @@ esp_err_t audio_sys_get_real_time_stats(void)
if (end_array_size == 0) { if (end_array_size == 0) {
ESP_LOGE(TAG, "Insufficient array size for uxTaskGetSystemState. Trying increasing ARRAY_SIZE_OFFSET"); ESP_LOGE(TAG, "Insufficient array size for uxTaskGetSystemState. Trying increasing ARRAY_SIZE_OFFSET");
ret = ESP_FAIL; 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. // 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) { if (total_elapsed_time == 0) {
ESP_LOGE(TAG, "Delay duration too short. Trying increasing AUDIO_SYS_TASKS_ELAPSED_TIME_MS"); ESP_LOGE(TAG, "Delay duration too short. Trying increasing AUDIO_SYS_TASKS_ELAPSED_TIME_MS");
ret = ESP_FAIL; 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 "); 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"); printf("\n");
ret = ESP_OK; 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; return ret;
#else #else
ESP_LOGW(TAG, "Please enbale `CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID` and `CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS` in menuconfig"); 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.se_init = se_init;
afe_config.vad_init = vad_init; afe_config.vad_init = vad_init;
afe_config.voice_communication_agc_init = voice_communication_agc_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_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); //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); 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); assert(feed_buff);
afe_handle->feed(afe_data, feed_buff); afe_handle->feed(afe_data, feed_buff);

View File

@ -88,7 +88,7 @@ TEST_CASE("multinet cpu loading", "[mn]")
printf("commands: da kai kong tiao, size:%d\n", data_size); 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; int chunks = 0;
struct timeval tv_start, tv_end; struct timeval tv_start, tv_end;
gettimeofday(&tv_start, NULL); gettimeofday(&tv_start, NULL);

View File

@ -65,7 +65,7 @@ TEST_CASE("wakenet create/destroy API & memory leak", "[wn]")
// DET_MODE_3CH_90 = 4, // DET_MODE_3CH_90 = 4,
// DET_MODE_3CH_95 = 5, // DET_MODE_3CH_95 = 5,
// } det_mode_t; // } det_mode_t;
model_data = wakenet->create(model_name, i); model_data = wakenet->create(model_name, (det_mode_t)i);
printf("destroy ...\n"); printf("destroy ...\n");
wakenet->destroy(model_data); 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); model_iface_data_t *model_data = wakenet->create(model_name, DET_MODE_95);
int frequency = wakenet->get_samp_rate(model_data); int frequency = wakenet->get_samp_rate(model_data);
int audio_chunksize = wakenet->get_samp_chunksize(model_data) * sizeof(int16_t); 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 chunks = 0;
int detected = 0; int detected = 0;
struct timeval tv_start, tv_end; struct timeval tv_start, tv_end;

View File

@ -1,7 +1,7 @@
set(srcs set(srcs
"test_app_main.c" "app_main.cpp"
"test_chinese_tts.c" "test_chinese_tts.cpp"
) )
idf_component_register(SRCS ${srcs} idf_component_register(SRCS ${srcs}

View File

@ -7,12 +7,11 @@
CONDITIONS OF ANY KIND, either express or implied. CONDITIONS OF ANY KIND, either express or implied.
*/ */
#include "unity.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "unity.h"
extern "C" void app_main(void)
void app_main(void)
{ {
/* These are the different ways of running registered tests. /* These are the different ways of running registered tests.
* In practice, only one of them is usually needed. * 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. * Make sure that task watchdog is disabled if you use this function.
*/ */
unity_run_menu(); unity_run_menu();
} }

View File

@ -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 <stdio.h>
#include <stdlib.h>
#include "string.h"
#include <limits.h>
#include "unity.h"
#include <sys/time.h>
#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);
}