第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > ESP32使用百度语音合成 实现文字转语音播放

ESP32使用百度语音合成 实现文字转语音播放

时间:2023-04-17 03:54:41

相关推荐

ESP32使用百度语音合成 实现文字转语音播放

esp32 播放多个音频源的音频,例如播放本地flash的mp3,http或者蓝牙传来的音频流等。

文章目录

一,简介二,播放器初始化三,播放音频3.1 播放本地音频3.2 使用百度语音合成 实现文字转语音四,小结

一,简介

本次例程介绍更加简单的播放器初始化,并在播放器中添加http_streamflash_tone_stream等输入流来实现百度语音合成播放本地音频的效果。

二,播放器初始化

esp-idf提供了一套更加便捷的创建pipeline管道的api函数,接口在esp_audio.h中定义。使用这套api能更快的初始化一个音频处理管道。

一个音频管道就是三四个部分组成,输入流->编解码->适配->输出流,而esp_audio.h中提供了几个重要的函数来实现以上:其中必须要有的element就是输入,编解码,输出。

几个比较重要的函数:

1,添加音频输入源,这里添加了http和flash_tone

esp_audio_input_stream_add(player, http_stream_reader);

2,添加音频输出源,这里添加了i2s流,输出到ac101播放音频

esp_audio_output_stream_add(player, i2s_stream_writer);

3,添加音频编解码仓库

esp_audio_codec_lib_add(player, AUDIO_CODEC_TYPE_DECODER, mp3_decoder_init(&mp3_dec_cfg));

具体使用的流程:

/*板子音频芯片初始化 音频引脚初始化 更换芯片或者板子时要注意*/esp_audio_cfg_t cfg = DEFAULT_ESP_AUDIO_CONFIG();ESP_LOGI(TAG, "audio_board_init");//音频硬件初始化audio_board_handle_t board_handle = audio_board_init();cfg.vol_handle = board_handle->audio_hal;cfg.prefer_type = ESP_AUDIO_PREFER_MEM;ESP_LOGI(TAG, "create player");//!对于我们的开发板,要使用48k才能正常说话(喇叭)cfg.resample_rate = 48000; player = esp_audio_create(&cfg);//音频编解码芯片ac101初始化ESP_LOGI(TAG, "init codec");audio_hal_ctrl_codec(board_handle->audio_hal, AUDIO_HAL_CODEC_MODE_BOTH, AUDIO_HAL_CTRL_START);//创建http流ESP_LOGI(TAG, "[2.1] Create http stream to read data");http_stream_cfg_t http_cfg = HTTP_STREAM_CFG_DEFAULT();//设置http回调函数http_cfg.event_handle = _http_stream_event_handle;http_cfg.type = AUDIO_STREAM_READER;audio_element_handle_t http_stream_reader = http_stream_init(&http_cfg);esp_audio_input_stream_add(player, http_stream_reader); //创建flash_tone流ESP_LOGI(TAG, "create flash tone stream reader");tone_stream_cfg_t tone_cfg = TONE_STREAM_CFG_DEFAULT();tone_cfg.type = AUDIO_STREAM_READER;ESP_LOGI(TAG, "add stream reader to player");esp_audio_input_stream_add(player, tone_stream_init(&tone_cfg));//mp3解码ESP_LOGI(TAG, "create mp3 decoder and add to player");mp3_decoder_cfg_t mp3_dec_cfg = DEFAULT_MP3_DECODER_CONFIG();esp_audio_codec_lib_add(player, AUDIO_CODEC_TYPE_DECODER, mp3_decoder_init(&mp3_dec_cfg));//创建i2s writer并添加到player的输出源ESP_LOGI(TAG, "create i2s writer and add to player");i2s_stream_cfg_t i2s_writer = I2S_STREAM_CFG_DEFAULT();//!注意要和player的采样率48000相同i2s_writer.i2s_config.sample_rate = 48000; //右声道i2s_writer.i2s_config.channel_format = I2S_CHANNEL_FMT_ALL_RIGHT; i2s_writer.type = AUDIO_STREAM_WRITER;audio_element_handle_t i2s_stream_writer = i2s_stream_init(&i2s_writer);esp_audio_output_stream_add(player, i2s_stream_writer);ESP_LOGI(TAG, "http_stream_reader->mp3decode->player->i2s->ac101");ESP_LOGI(TAG, "flash_stream_reader->mp3decode->player->i2s->ac101");esp_audio_vol_set(player, 80);

三,播放音频

3.1 播放本地音频

之前介绍过esp32 播放本地flash中的mp3,没看过的朋友可以参考一下:ESP32 ADF 离线播放mp3 mp3烧录flash;

3.2 使用百度语音合成 实现文字转语音

语音合成是将中文合成音频,然后播放出来。

本例程使用的是百度AI开放平台的语音合成API,具体的接口文档参考百度AI开放平台的详细介绍。百度语音合成文档

使用百度的API需要先获得token,然后发送GET或者POST请求,请求中写入要合成的中文字符串,获取http音频流,将http音频流添加到以上的player中播放。

ADF为我们提供了获取百度token的代码,在ADF目录下components/adf_utils/cloud_services/baidu_access_token.c中,使用baidu_get_access_token()可以获取百度token。

调用以下函数实现语音播放,该函数会调用_http_stream_event_handle()回调函数,该函数负责处理这次http连接的所有操作。包括请求前的参数准备,请求开始,接收数据,断开连接等。如果成功返回http音频流,则会在player中播放

esp_audio_sync_play(player,"/text2audio", 0);

在这个回调函数中我们主要处理的是http请求前的参数设置。包括token的获取,设置POST的body参数。其中text是一个全局变量,存放即将转成语音的字符串。

/** http stream回调函数* 调用esp_audio_sync_play(player,BAIDU_TTS_URL, 0)会调用此回调函数*/int _http_stream_event_handle(http_stream_event_msg_t *msg){esp_http_client_handle_t http_client = (esp_http_client_handle_t)msg->http_client;switch(msg->event_id){case HTTP_STREAM_PRE_REQUEST://准备请求数据 检查tokenESP_LOGI(TAG, "HTTP_STREAM_PRE_REQUEST");if (baidu_access_token == NULL) {// Must freed `baidu_access_token` after used 获得tokenESP_LOGI(TAG, "try to get token");baidu_access_token = baidu_get_access_token(BAIDU_ACCESS_KEY, BAIDU_SECRET_KEY);}if (baidu_access_token == NULL) {ESP_LOGE(TAG, "Error issuing access token");return ESP_FAIL;}/* 组装body参数:lan:语言;cuid:设备id;ctp:...;aue:文件格式;spd:语速;pit:音调;vol:音量;per:人声*/int data_len = snprintf(request_data, 1024, "lan=zh&cuid=ppp&ctp=2&aue=3&spd=4&pit=5&vol=5&per=0&tok=%s&tex=%s", baidu_access_token, text);//将token装填进http请求体esp_http_client_set_post_field(http_client, request_data, data_len);//postesp_http_client_set_method(http_client, 1);break;case HTTP_STREAM_ON_REQUEST:ESP_LOGI(TAG, "HTTP_STREAM_ON_REQUEST");break;case HTTP_STREAM_ON_RESPONSE:ESP_LOGI(TAG, "HTTP_STREAM_ON_RESPONSE");break;case HTTP_STREAM_POST_REQUEST:ESP_LOGI(TAG, "HTTP_STREAM_POST_REQUEST");break;case HTTP_STREAM_FINISH_REQUEST:ESP_LOGI(TAG, "HTTP_STREAM_FINISH_REQUEST");break; case HTTP_STREAM_RESOLVE_ALL_TRACKS:ESP_LOGI(TAG, "HTTP_STREAM_RESOLVE_ALL_TRACKS");break;case HTTP_STREAM_FINISH_TRACK:ESP_LOGI(TAG, "HTTP_STREAM_FINISH_TRACK");break;case HTTP_STREAM_FINISH_PLAYLIST:ESP_LOGI(TAG, "HTTP_STREAM_FINISH_PLAYLIST");break; }return ESP_OK;}

四,小结

http stream的播放并不复杂,主要的工作就是设置好http请求头,获取http流。

但不得不夸一下百度,他的语音合成速度非常快,实用性非常高

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。