This commit is contained in:
Demur Rumed 2025-04-19 16:15:30 +00:00
commit 7e065ac8d7
3 changed files with 52 additions and 13 deletions

View file

@ -324,7 +324,6 @@ endif()
if (ESPEAK)
add_compile_definitions(ESPEAK=1)
target_link_libraries(${PROJECT_NAME} PUBLIC espeak-ng)
endif()
target_include_directories(${PROJECT_NAME} PRIVATE assets

View file

@ -1,26 +1,49 @@
#include "ESpeakSpeechSynthesizer.h"
extern "C" {
#include <espeak-ng/speak_lib.h>
}
#include <dlfcn.h>
#include <libultraship/libultraship.h>
ESpeakSpeechSynthesizer::ESpeakSpeechSynthesizer() {
}
bool ESpeakSpeechSynthesizer::DoInit() {
return espeak_Initialize(AUDIO_OUTPUT_PLAYBACK, 100, NULL, 0) != -1;
void* espeak = dlopen("libespeak-ng.so", RTLD_LAZY | RTLD_LOCAL);
if (espeak != NULL) {
this->Initialize = (speak_Initialize)dlsym(espeak, "espeak_Initialize");
this->SetVoiceByProperties = (speak_SetVoiceByProperties)dlsym(espeak, "espeak_SetVoiceByProperties");
this->Synth = (speak_Synth)dlsym(espeak, "espeak_Synth");
this->Terminate = (speak_Terminate)dlsym(espeak, "espeak_Terminate");
if (this->Initialize == NULL || this->SetVoiceByProperties == NULL || this->Synth == NULL ||
this->Terminate == NULL) {
lusprintf(__FILE__, __LINE__, 2, "Failed to load espeak-ng");
dlclose(espeak);
return false;
} else {
this->espeak = espeak;
return this->Initialize(AUDIO_OUTPUT_PLAYBACK, 100, NULL, 0) != -1;
}
}
return true;
}
void ESpeakSpeechSynthesizer::DoUninitialize() {
espeak_Terminate();
if (this->espeak != NULL) {
this->Terminate();
dlclose(this->espeak);
this->espeak = NULL;
}
}
void ESpeakSpeechSynthesizer::Speak(const char* text, const char* language) {
if (language != this->mLanguage) {
espeak_VOICE voice = { .languages = language };
if (espeak_SetVoiceByProperties(&voice)) {
return;
if (this->espeak == NULL) {
lusprintf(__FILE__, __LINE__, 2, "Spoken Text (%s): %s", language, text);
} else {
if (language != this->mLanguage) {
espeak_VOICE voice = { .languages = language };
if (this->SetVoiceByProperties(&voice)) {
return;
}
this->mLanguage = language;
}
this->mLanguage = language;
this->Synth(text, 100, 0, POS_CHARACTER, 0, espeakCHARS_UTF8, NULL, NULL);
}
espeak_Synth(text, 100, 0, POS_CHARACTER, 0, espeakCHARS_UTF8, NULL, NULL);
}

View file

@ -2,6 +2,18 @@
#include "SpeechSynthesizer.h"
extern "C" {
#include <espeak-ng/speak_lib.h>
// C23 typeof could help here
typedef ESPEAK_API int (*speak_Initialize)(espeak_AUDIO_OUTPUT output, int buflength, const char* path, int options);
typedef ESPEAK_API espeak_ERROR (*speak_Terminate)(void);
typedef ESPEAK_API espeak_ERROR (*speak_SetVoiceByProperties)(espeak_VOICE* voice_spec);
typedef ESPEAK_API espeak_ERROR (*speak_Synth)(const void* text, size_t size, unsigned int position,
espeak_POSITION_TYPE position_type, unsigned int end_position,
unsigned int flags, unsigned int* unique_identifier, void* user_data);
}
class ESpeakSpeechSynthesizer : public SpeechSynthesizer {
public:
ESpeakSpeechSynthesizer();
@ -13,5 +25,10 @@ class ESpeakSpeechSynthesizer : public SpeechSynthesizer {
void DoUninitialize(void);
private:
const char* mLanguage;
const char* mLanguage = NULL;
void* espeak = NULL;
speak_Initialize Initialize = NULL;
speak_SetVoiceByProperties SetVoiceByProperties = NULL;
speak_Synth Synth = NULL;
speak_Terminate Terminate = NULL;
};