Browse Source

Use the wave_* APIs for non-async audio.

master
Reece H. Dunn 9 years ago
parent
commit
c9c0aca34f
1 changed files with 24 additions and 58 deletions
  1. 24
    58
      src/libespeak-ng/speech.c

+ 24
- 58
src/libespeak-ng/speech.c View File

@@ -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) {

Loading…
Cancel
Save