1. 程式人生 > 其它 >啟明智顯分享|樂鑫ESP32-S3語音--文字轉語音(TTS)

啟明智顯分享|樂鑫ESP32-S3語音--文字轉語音(TTS)

今天,我們來研究樂鑫的語音助手框架ESP-Skainet其中的中文語音合成的例程。

編譯原例程

  1. 首先需要clone例程
git clone --recursive https://github.com/espressif/esp-skainet.git

  該工程內部自帶一個idf,是執行的最佳版本,不過你任然可以使用自己的idf。

  1. 進入例程中

cd  esp-skainet/examples/chinese_tts
  1. 理論上設定好了晶片型號為esp32s3後自動呼叫sdkconfig.defaults.esp32s3配置檔案。 但是實際上好像沒有,所以這裡加一個步驟確保能使用上預設配置。

cp sdkconfig.defaults.esp32s3 sdkconfig.defaults
  1. 設定晶片為esp32s3

idf.py set-target esp32s3
  1. 進入menuconfig

idf.py menuconfig

修改Audio Media Hal -> Audio Hardware board 改成ESP32-S3-Korvo-1

  1. 編譯燒錄程式

idf.py flash monitor -p /dev/ttyUSB0

執行原例程

執行後,可以看到如下列印

歡迎使用樂鑫語音合成
I (266) tts_parser: unicode:0x6b22
-> huan1 I (266) tts_parser: unicode:0x8fce -> ying2 I (276) tts_parser: unicode:0x4f7f -> shi3 I (276) tts_parser: unicode:0x7528 -> yong4 I (286) tts_parser: unicode:0x4e50 -> le4 I (286) tts_parser: unicode:0x946b -> xin1 I (296) tts_parser: unicode:0x8bed -> yu3 I (296) tts_parser: unicode:0x97f3
-> yin1 I (306) tts_parser: unicode:0x5408 -> he2 I (306) tts_parser: unicode:0x6210 -> cheng2 請輸入短語:

簡化原例程並分析

原例程大致分為兩個功能,第一個功能是閱讀“樂鑫語音合成”這句話,還有一個功能是朗讀串列埠輸入的文字。 第二部分經常會有bug,所以咱們簡化例程,重心分析第一個功能。簡化例程如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.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_board_init.h"

int app_main()
{

    ESP_ERROR_CHECK(esp_board_init(AUDIO_HAL_16K_SAMPLES, 1, 16));     // 初始化codec晶片,配置好取樣率、聲道數、取樣大小
    esp_tts_voice_t *voice = (esp_tts_voice_t *)&esp_tts_voice_xiaole; // 配置tts的聲音配置檔案,來自libvoice_set_xiaole
    esp_tts_handle_t *tts_handle = esp_tts_create(voice);              // 建立tts物件
    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, 3); // 拼音轉換成pcm音訊
            esp_audio_play(pcm_data, len[0] * 2, portMAX_DELAY);       //播放音訊
        } while (len[0] > 0);
    }
    esp_tts_stream_reset(tts_handle); // 重置 tts 流並清除 TTS 例項的所有快取

    return 0;
}

這裡音訊的tts來自靜態庫libvoice_set_xiaole中,目前也只有這一個音色可供使用,其餘的tts相關函式則是屬於靜態庫libesp_tts_chinese。

總結

tts過度封裝化,一定程度上註定它的使用難度不高。但是依據已跑完的例程來看,音訊任然有發音聲音的問題,對於現在的一些成熟的tts方案,樂鑫的這個tts還有一定的差距,這個缺點可能導致無法應用於商業化專案中。專案中如果涉及到語音轉文字的內容,一方面可以通過雲平臺的提供的API能力傳送文字收取PCM音訊來解決。另一方面如果是有限的詞彙,也可以用語音拼接的方式,把相應的音訊存到檔案系統中,通過對映播放指定的內容並拼湊成一段完整的語句。例如:“支付寶收款”、“元”、“個”、“十”、“百”、“千”、“萬”這幾段文字的語音就基本可以通過拼湊音訊達到支付寶語音播報功能。