#include "stdio.h" #include "stdlib.h" #include "cm_fs.h" #include "cm_mem.h" #include "cm_sys.h" #include "cm_gpio.h" #include "cm_iomux.h" #include "cm_modem.h" #include "cm_audio_player.h" #include "cm_audio_recorder.h" #include "cm_local_tts.h" #include "local_tts.h" #if 1 #include "app_uart.h" #define DEBUG(fmt, args...) app_printf("[tts]" fmt, ##args) #else #define DEBUG(fmt, arg...) #endif static osMessageQueueId_t local_tts_play_queue = NULL; static osSemaphoreId_t local_tts_play_ok_sem = NULL; /* 离线TTS回调函数 */ static void __local_tts_callback(cm_local_tts_event_e event, void *param) { switch(event){ case CM_LOCAL_TTS_EVENT_SYNTH_DATA:{ // cm_local_tts_synth_data_t *data = (cm_local_tts_synth_data_t *)param; // DEBUG("[%s] SYNTH_DATA [%d] \n", data->user, data->len); //打印log操作较费时 break; } case CM_LOCAL_TTS_EVENT_SYNTH_FAIL: case CM_LOCAL_TTS_EVENT_SYNTH_INTERRUPT: case CM_LOCAL_TTS_EVENT_SYNTH_FINISH: break; case CM_LOCAL_TTS_EVENT_PLAY_FAIL: DEBUG("[%s] PLAY_FAIL\n", (char *)param); break; case CM_LOCAL_TTS_EVENT_PLAY_INTERRUPT: DEBUG("[[%s] PLAY_INTERRUPT\n", (char *)param); break; case CM_LOCAL_TTS_EVENT_PLAY_FINISH: DEBUG("[%s] PLAY_FINISH\n", (char *)param); osSemaphoreRelease(local_tts_play_ok_sem); // 释放发送成功应答信号量 break; default: break; } } // 静音 mute: 0-关闭 1-打开 void local_tts_mute(uint8_t mute){ cm_gpio_set_level(CM_GPIO_NUM_13, mute? 1 : 0); } // 音量设置 volume: 0-100 uint8_t local_tts_volume(uint8_t volume){ uint8_t ret; if(volume > 100){ volume = 100; } cm_audio_play_set_cfg(CM_AUDIO_PLAY_CFG_VOLUME, &volume); //音量设置 0-100 cm_audio_play_get_cfg(CM_AUDIO_PLAY_CFG_VOLUME, &ret); DEBUG("[AUDIO] volume:%d\n", ret); return ret; } // speed: 语速,取值范围0-15,默认为5 // volume: 音量,取值范围0-15,默认为5 // mode: 0-自动模式 1-数字模式,2-数值模式 void local_tts_set(int32_t speed, int32_t volume, cm_local_tts_digit_e mode){ cm_local_tts_deinit(); cm_local_tts_cfg_t tts_cfg = {0}; tts_cfg.speed = speed; tts_cfg.volume = volume; tts_cfg.encode = CM_LOCAL_TTS_ENCODE_TYPE_UTF8; // 离线TTS仅支持UTF8格式 tts_cfg.digit = mode; if(0 == cm_local_tts_init(&tts_cfg)){ DEBUG("tts set:speed %d,volume %d,encode %d,digit %d\n" , tts_cfg.speed, tts_cfg.volume, tts_cfg.encode, tts_cfg.digit); }else{ DEBUG("tts set error\n"); } osDelay(100/5); // 等待初始化完成 } typedef struct{ char *text; uint8_t len; }tts_play_queue_t; // 发送本地TTS播放内容 //timeout=osWaitForever时表示等待播放完成 int8_t local_tts_text_play(char *text, uint8_t len, uint32_t timeout){ tts_play_queue_t tts_play_queue = {0}; local_tts_mute(0); // 取消静音 if(0 == len || len > strlen(text)){ len = strlen(text); DEBUG("tts play text len > len:%d \n", len); } tts_play_queue.text = cm_malloc(len + 1); if(tts_play_queue.text == NULL){ DEBUG("tts play malloc error\n"); return -1; } memcpy(tts_play_queue.text, text, len); tts_play_queue.text[len] = '\0'; tts_play_queue.len = len; if(osOK != osMessageQueuePut(local_tts_play_queue, &tts_play_queue, 0, 0)){ DEBUG("tts play queue put error\n"); cm_free(tts_play_queue.text); return -1; } // 等待播放完成 osSemaphoreAcquire(local_tts_play_ok_sem, timeout); DEBUG("tts play queue put success\n"); return 0; } // 异步播放,播放完成后播放下一条 //TODO: 待优化(暂时方案,打断播放) static osThreadFunc_t local_tts_play_task(void *arg){ tts_play_queue_t tts_play_queue; while(1){ if(osOK == osMessageQueueGet(local_tts_play_queue, &tts_play_queue, NULL, osWaitForever)){ // DEBUG("tts play stop\n"); cm_local_tts_play_stop(); // 停止播放 osDelay(200/5); // 等待播放停止 if(tts_play_queue.text == NULL){ DEBUG("tts play text is null\n"); continue; } DEBUG("tts play start\n"); cm_local_tts_play(tts_play_queue.text, tts_play_queue.len, __local_tts_callback,"Chinese"); cm_free(tts_play_queue.text); tts_play_queue.text = NULL; } } return 0; } // 初始化 void local_tts_init(void){ cm_gpio_cfg_t cfg = {0}; cfg.direction = CM_GPIO_DIRECTION_OUTPUT; cfg.pull = CM_GPIO_PULL_UP; cm_iomux_set_pin_func(CM_IOMUX_PIN_77, CM_IOMUX_FUNC_FUNCTION2);//初始化之前一定要先设置引脚复用 cm_gpio_init(CM_GPIO_NUM_13, &cfg); local_tts_mute(1); // 关闭静音 local_tts_volume(100); // 设置音量为50 local_tts_set(7, 5, CM_LOCAL_TTS_DIGIT_AUTO); // 设置TTS转换参数 if(local_tts_play_queue == NULL){ local_tts_play_queue = osMessageQueueNew(10, sizeof(tts_play_queue_t), NULL); } if(local_tts_play_ok_sem == NULL){ local_tts_play_ok_sem = osSemaphoreNew(1, 0, NULL); } osThreadAttr_t local_tts_play_thread_attr = { .name = "local_tts_play_thread", .stack_size = 4096 * 4, .priority = osPriorityNormal }; osThreadNew((osThreadFunc_t)local_tts_play_task, NULL, &local_tts_play_thread_attr); }