esp32 中英文语音合成
- 环境搭建
使用资源
Esp idf https://github.com/espressif/esp-idf.git
中文合成https://github.com/espressif/esp-skainet.git
英文合成https://github.com/s-macke/SAM
WIN 平台下 默认的 语音依赖文件无法通过脚本烧录
整理出一个可以的命令行指令
python.exe G:\PRJ\esp32\esp-idf\components\esptool_py\esptool\esptool.py --chip esp32 --port COM8 --baud 115200 --before default_reset --after hard_reset write_flash --flash_mode dio --flash_freq 40m --flash_size detect 0x100000 G:\PRJ\esp32\esp-skainet\components\esp-tts\esp_tts_chinese\esp_tts_voice_data_xiaole.dat
4M Flash分区表 partitions.csv
Espressif ESP32 Partition Table
Name, Type, SubType, Offset, Size
factory, app, factory, 0x010000, 0x090000
voice_data, data, fat, 0x100000, 0x300000
中文合成 必须依赖项,具体暂不清楚
中文合成sd_card_mount("/sdcard");
中文合成例子
//初始化中文语音合成
esp_tts_handle_t * zh_init() {
const esp_partition_t* part=esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, "voice_data");//寻找语音合成所需数据分区
if (part==0) {
printf("Couldn't find voice data partition!\n");
return 0;
}
spi_flash_mmap_handle_t mmap;
uint16_t* voicedata;
esp_err_t err=esp_partition_mmap(part, 0, 3*1024*1024, SPI_FLASH_MMAP_DATA, (const void**)&voicedata, &mmap);//根据分区表加载对应数据
if (err != ESP_OK) {
printf("Couldn't map voice data partition!\n");
return 0;
}
esp_tts_voice_t *voice=esp_tts_voice_set_init(&esp_tts_voice_template, voicedata); //合成语音所需数据初始化
esp_tts_handle_t *tts_handle=esp_tts_create(voice);//创建一个合成语音对象
return tts_handle;
}
//合成并播放中文语音
void play_zh(esp_tts_handle_t tts_handle,char prompt1) {
if (esp_tts_parse_chinese(tts_handle, prompt1)) {
int len[1]={0};
do {
short *pcm_data=esp_tts_stream_play(tts_handle, len, 4);
iot_dac_audio_play(pcm_data, len[0]*2, portMAX_DELAY);
printf("pcm_data=%x\n", pcm_data[0]);
printf("len=%d\n", len[0]);
} while(len[0]>0);
i2s_zero_dma_buffer(0);
}
}
//应用
int app_main() {
codec_init(); //解码器初始化
sd_card_mount("/sdcard");//挂载SD卡
i2s_set_sample_rates(0, 8000);//设置
esp_tts_handle_t *tts_handle;
tts_handle=Zh_init();
play_zh(tts_handle,"欢迎");
i2s_set_sample_rates(0, 13050);//设置i2s播放速率
return 0;
}
英文合成例子
void play_en(char *text) {
sam_main(text);
int bufferpos = GetBufferLength();
char *buffer = GetBuffer();
short pcm_dat[512];
int len = bufferpos/512/50;
for(int i=0; i<len; i++)
{
for(int n=0;n<512;n++)pcm_dat[n]=buffer[n+i*512]*0x60;
iot_dac_audio_play(pcm_dat, 512*2, portMAX_DELAY);
}
i2s_zero_dma_buffer(0);
free(buffer);
}
应用
int app_main() {
codec_init();
sd_card_mount("/sdcard");
i2s_set_sample_rates(0, 13050);
play_en("hello world");
return 0;
}