이 프로젝트는 ESP32의 음성 합성을 보여줍니다. 이 작업을 클라우드 제공 업체에 오프로드하지 않고 CMU Flite 라이브러리를 사용하여 로컬로 합성을 수행합니다.
이 프로젝트의 경우 Flite 2.2 (Commit Hash E9880474)가 ESP-IDF 3.2.2 프레임 워크로 포팅되었으며 이제 "구성 요소"디렉토리에서 찾을 수있는 재사용 가능한 구성 요소 세트입니다.
cmu_us_kal 음성이 예로 제공됩니다. Flite와 함께 제공되는 다른 사전 정의 된 목소리는 너무 큽니다. 플래시에 맞는 경우 새로운 목소리를 별도의 구성 요소로 추가 할 수 있습니다.
이 예제는 합성 할 텍스트 요청을받는 간단한 HTTP 서버를 실행합니다. 이 프로그램은 텍스트를 종합하고 I2S를 통해 PCM 데이터를 보냅니다. I2S 수신 측면에서는 PCM5102 칩을 사용했지만 다른 칩이 작동 할 수 있습니다. 또한 I2를 ESP32 내부 8 비트 DAC로 라우팅 할 수 있습니다.
먼저 make menuconfig 사용하여 구성하십시오. Wi-Fi SSID 및 비밀번호와 I2S에 사용할 핀을 설정해야합니다. BCK = 26, WS = 25 및 데이터 = 22로 테스트했습니다.
생성 된 WAV 파일은 힙에 할당 된 다양한 PCM 값으로 저장되므로 충분한 힙 공간을 사용할 수 있어야합니다. 필요한 공간은 합성 된 텍스트의 길이에 따라 다릅니다. 따라서 4MB의 psaram을 갖는 ESP32의 Wrover 모델을 사용하는 것이 좋습니다. PSRAM은 Menuconfig에서 활성화되어야합니다. 메뉴에는 약간 숨겨져 있습니다. 구성 요소 구성 -> ESP32 외부, SPI 연결 RAM-> SPI RAM 구성에 대한 지원. 일단 활성화되면 BRE가 힙 할당 풀에 추가됩니다.
ESP32에 대한 텍스트를 Synthesize에 보내려면 쿼리 매개 s 사용하여 HTTP Get get 요청 /say Path를 보내야합니다. 이것은 웹 브라우지로 수행 할 수 있습니다. http://<ip of esp device>/say?s=This is an example text 로 찾아보십시오. 쿼리 문자열은 약 256 자로 제한되지만 이는 예제 프로그램의 인위적 제한이며 Flite 라이브러리는 한 번에 훨씬 더 긴 텍스트를 합성 할 수 있습니다.
합성 된 데이터는 청크로 스트리밍되므로 Flite가 모든 텍스트를 처리하기 전에 재생이 시작될 수 있습니다. 이것은 더 긴 텍스트의 지연을 줄이고 실시간 느낌을줍니다. 이것은 클라우드 서비스를 사용하지 않고 Flite를 사용하고 Wi-Fi를 통해 합성 된 데이터를 다운로드하는 것의 장점 중 하나입니다.
구성 요소를 프로젝트에 복사하십시오.
앱 Partiton에 최소 2MB가 있는지 확인하십시오.
factory, app, factory, 0x10000, 0x2F0000,
make menuconfig 로 구성하십시오.
그런 다음 다음 코드를 사용하십시오.
cst_voice *register_cmu_us_kal(const char *voxdir);
int i2s_stream_chunk(const cst_wave *w, int start, int size,
int last, cst_audio_streaming_info *asi)
{
// write here code that processes the wav chunk. For example send it to
// I2S, drive a DAC or send it via Wi-Fi/Bluetooth/Serial to another
// device.
}
...
/* Initialization code */
flite_init();
cst_voice *v = register_cmu_us_kal(NULL);
cst_audio_streaming_info *asi =
cst_alloc(struct cst_audio_streaming_info_struct,1);
asi->min_buffsize = 256;
asi->asc = i2s_stream_chunk;
asi->userdata = NULL;
feat_set(v->features,"streaming_info",audio_streaming_info_val(asi));
/* Synthesis Code */
cst_wave * wav = flite_text_to_wave("Replace with your text",v);
delete_wave(wav);
프로젝트에서 Flite를 사용한 경우 프로젝트에 대한 링크와 함께 풀 요청을 열면 여기에 추가하겠습니다.