mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-11-14 09:37:47 +00:00
Use the wave_* APIs for non-async audio.
This commit is contained in:
+24
-58
@@ -86,15 +86,18 @@ void WVoiceChanged(voice_t *wvoice)
|
||||
voice_samplerate = wvoice->samplerate;
|
||||
}
|
||||
|
||||
#ifdef USE_ASYNC
|
||||
|
||||
static int dispatch_audio(short *outbuf, int length, espeak_EVENT *event)
|
||||
{
|
||||
int a_wave_can_be_played = fifo_is_command_enabled();
|
||||
int a_wave_can_be_played = 1;
|
||||
#ifdef USE_ASYNC
|
||||
if ((my_mode & ENOUTPUT_MODE_SYNCHRONOUS) == 0)
|
||||
a_wave_can_be_played = fifo_is_command_enabled();
|
||||
#endif
|
||||
|
||||
switch (my_mode)
|
||||
{
|
||||
case ENOUTPUT_MODE_SPEAK_AUDIO:
|
||||
case ENOUTPUT_MODE_SPEAK_AUDIO | ENOUTPUT_MODE_SYNCHRONOUS:
|
||||
{
|
||||
int event_type = 0;
|
||||
if (event)
|
||||
@@ -115,8 +118,12 @@ static int dispatch_audio(short *outbuf, int length, espeak_EVENT *event)
|
||||
err = ENS_AUDIO_ERROR;
|
||||
return -1;
|
||||
}
|
||||
wave_set_callback_is_output_enabled(fifo_is_command_enabled);
|
||||
event_init();
|
||||
#ifdef USE_ASYNC
|
||||
if ((my_mode & ENOUTPUT_MODE_SYNCHRONOUS) == 0) {
|
||||
wave_set_callback_is_output_enabled(fifo_is_command_enabled);
|
||||
event_init();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,6 +131,7 @@ static int dispatch_audio(short *outbuf, int length, espeak_EVENT *event)
|
||||
wave_write(my_audio, (char *)outbuf, 2*length);
|
||||
}
|
||||
|
||||
#ifdef USE_ASYNC
|
||||
while (event && a_wave_can_be_played) {
|
||||
// TBD: some event are filtered here but some insight might be given
|
||||
// TBD: in synthesise.cpp for avoiding to create WORDs with size=0.
|
||||
@@ -132,12 +140,16 @@ static int dispatch_audio(short *outbuf, int length, espeak_EVENT *event)
|
||||
// TBD: the last one has its size=0.
|
||||
if ((event->type == espeakEVENT_WORD) && (event->length == 0))
|
||||
break;
|
||||
err = event_declare(event);
|
||||
if (err != ENS_EVENT_BUFFER_FULL)
|
||||
if ((my_mode & ENOUTPUT_MODE_SYNCHRONOUS) == 0) {
|
||||
err = event_declare(event);
|
||||
if (err != ENS_EVENT_BUFFER_FULL)
|
||||
break;
|
||||
usleep(10000);
|
||||
a_wave_can_be_played = fifo_is_command_enabled();
|
||||
} else
|
||||
break;
|
||||
usleep(10000);
|
||||
a_wave_can_be_played = fifo_is_command_enabled();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
@@ -175,6 +187,8 @@ static int create_events(short *outbuf, int length, espeak_EVENT *event_list, ui
|
||||
return finished;
|
||||
}
|
||||
|
||||
#ifdef USE_ASYNC
|
||||
|
||||
int sync_espeak_terminated_msg(uint32_t unique_identifier, void *user_data)
|
||||
{
|
||||
int finished = 0;
|
||||
@@ -212,15 +226,6 @@ ESPEAK_NG_API espeak_ng_STATUS espeak_ng_InitializeOutput(espeak_ng_OUTPUT_MODE
|
||||
option_waveout = 1; // inhibit portaudio callback from wavegen.cpp
|
||||
out_samplerate = 0;
|
||||
|
||||
#ifdef USE_ASYNC
|
||||
if (output_mode == (ENOUTPUT_MODE_SYNCHRONOUS | ENOUTPUT_MODE_SPEAK_AUDIO)) {
|
||||
#else
|
||||
if ((output_mode & ENOUTPUT_MODE_SPEAK_AUDIO) == ENOUTPUT_MODE_SPEAK_AUDIO) {
|
||||
#endif
|
||||
option_waveout = 0;
|
||||
WavegenInitSound();
|
||||
}
|
||||
|
||||
// buflength is in mS, allocate 2 bytes per sample
|
||||
if ((buffer_length == 0) || (output_mode & ENOUTPUT_MODE_SPEAK_AUDIO))
|
||||
buffer_length = 200;
|
||||
@@ -362,9 +367,7 @@ static espeak_ng_STATUS Synthesize(unsigned int unique_identifier, const void *t
|
||||
int length;
|
||||
int finished = 0;
|
||||
int count_buffers = 0;
|
||||
#ifdef USE_ASYNC
|
||||
uint32_t a_write_pos = 0;
|
||||
#endif
|
||||
|
||||
if ((outbuf == NULL) || (event_list == NULL))
|
||||
return ENS_NOT_INITIALIZED;
|
||||
@@ -376,49 +379,14 @@ static espeak_ng_STATUS Synthesize(unsigned int unique_identifier, const void *t
|
||||
|
||||
count_samples = 0;
|
||||
|
||||
#ifdef USE_ASYNC
|
||||
if (my_mode == ENOUTPUT_MODE_SPEAK_AUDIO)
|
||||
a_write_pos = wave_get_write_position(my_audio);
|
||||
#endif
|
||||
|
||||
if (translator == NULL)
|
||||
espeak_SetVoiceByName("default");
|
||||
|
||||
SpeakNextClause(NULL, text, 0);
|
||||
|
||||
#ifdef USE_ASYNC
|
||||
if (my_mode == (ENOUTPUT_MODE_SYNCHRONOUS | ENOUTPUT_MODE_SPEAK_AUDIO)) {
|
||||
#else
|
||||
if ((my_mode & ENOUTPUT_MODE_SPEAK_AUDIO) == ENOUTPUT_MODE_SPEAK_AUDIO) {
|
||||
#endif
|
||||
bool continue_speaking = true;
|
||||
while (continue_speaking) {
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
Sleep(300); // 0.3s
|
||||
#else
|
||||
#ifdef USE_NANOSLEEP
|
||||
struct timespec period;
|
||||
struct timespec remaining;
|
||||
period.tv_sec = 0;
|
||||
period.tv_nsec = 300000000; // 0.3 sec
|
||||
nanosleep(&period, &remaining);
|
||||
#else
|
||||
sleep(1);
|
||||
#endif
|
||||
#endif
|
||||
do {
|
||||
if (WcmdqUsed() > 0)
|
||||
WavegenOpenSound();
|
||||
|
||||
if (Generate(phoneme_list, &n_phoneme_list, 1) == 0) {
|
||||
if (SpeakNextClause(NULL, NULL, 1) == 0)
|
||||
continue_speaking = WavegenCloseSound() == 0;
|
||||
}
|
||||
} while (skipping_text);
|
||||
}
|
||||
return ENS_OK;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
out_ptr = outbuf;
|
||||
out_end = &outbuf[outbuf_size];
|
||||
@@ -432,12 +400,10 @@ static espeak_ng_STATUS Synthesize(unsigned int unique_identifier, const void *t
|
||||
event_list[event_list_ix].user_data = my_user_data;
|
||||
|
||||
count_buffers++;
|
||||
if (my_mode == ENOUTPUT_MODE_SPEAK_AUDIO) {
|
||||
#ifdef USE_ASYNC
|
||||
if ((my_mode & ENOUTPUT_MODE_SPEAK_AUDIO) == ENOUTPUT_MODE_SPEAK_AUDIO) {
|
||||
finished = create_events((short *)outbuf, length, event_list, a_write_pos);
|
||||
if (finished < 0)
|
||||
return ENS_AUDIO_ERROR;
|
||||
#endif
|
||||
} else if (synth_callback)
|
||||
finished = synth_callback((short *)outbuf, length, event_list);
|
||||
if (finished) {
|
||||
|
||||
Reference in New Issue
Block a user