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

voice_samplerate = wvoice->samplerate; voice_samplerate = wvoice->samplerate;
} }


#ifdef USE_ASYNC

static int dispatch_audio(short *outbuf, int length, espeak_EVENT *event) 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) switch (my_mode)
{ {
case ENOUTPUT_MODE_SPEAK_AUDIO: case ENOUTPUT_MODE_SPEAK_AUDIO:
case ENOUTPUT_MODE_SPEAK_AUDIO | ENOUTPUT_MODE_SYNCHRONOUS:
{ {
int event_type = 0; int event_type = 0;
if (event) if (event)
err = ENS_AUDIO_ERROR; err = ENS_AUDIO_ERROR;
return -1; 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
} }
} }


wave_write(my_audio, (char *)outbuf, 2*length); wave_write(my_audio, (char *)outbuf, 2*length);
} }


#ifdef USE_ASYNC
while (event && a_wave_can_be_played) { while (event && a_wave_can_be_played) {
// TBD: some event are filtered here but some insight might be given // TBD: some event are filtered here but some insight might be given
// TBD: in synthesise.cpp for avoiding to create WORDs with size=0. // TBD: in synthesise.cpp for avoiding to create WORDs with size=0.
// TBD: the last one has its size=0. // TBD: the last one has its size=0.
if ((event->type == espeakEVENT_WORD) && (event->length == 0)) if ((event->type == espeakEVENT_WORD) && (event->length == 0))
break; 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; break;
usleep(10000);
a_wave_can_be_played = fifo_is_command_enabled();
} }
#endif
} }
break; break;
case 0: case 0:
return finished; return finished;
} }


#ifdef USE_ASYNC

int sync_espeak_terminated_msg(uint32_t unique_identifier, void *user_data) int sync_espeak_terminated_msg(uint32_t unique_identifier, void *user_data)
{ {
int finished = 0; int finished = 0;
option_waveout = 1; // inhibit portaudio callback from wavegen.cpp option_waveout = 1; // inhibit portaudio callback from wavegen.cpp
out_samplerate = 0; 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 // buflength is in mS, allocate 2 bytes per sample
if ((buffer_length == 0) || (output_mode & ENOUTPUT_MODE_SPEAK_AUDIO)) if ((buffer_length == 0) || (output_mode & ENOUTPUT_MODE_SPEAK_AUDIO))
buffer_length = 200; buffer_length = 200;
int length; int length;
int finished = 0; int finished = 0;
int count_buffers = 0; int count_buffers = 0;
#ifdef USE_ASYNC
uint32_t a_write_pos = 0; uint32_t a_write_pos = 0;
#endif


if ((outbuf == NULL) || (event_list == NULL)) if ((outbuf == NULL) || (event_list == NULL))
return ENS_NOT_INITIALIZED; return ENS_NOT_INITIALIZED;


count_samples = 0; count_samples = 0;


#ifdef USE_ASYNC
if (my_mode == ENOUTPUT_MODE_SPEAK_AUDIO) if (my_mode == ENOUTPUT_MODE_SPEAK_AUDIO)
a_write_pos = wave_get_write_position(my_audio); a_write_pos = wave_get_write_position(my_audio);
#endif


if (translator == NULL) if (translator == NULL)
espeak_SetVoiceByName("default"); espeak_SetVoiceByName("default");


SpeakNextClause(NULL, text, 0); 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 (;;) { for (;;) {
out_ptr = outbuf; out_ptr = outbuf;
out_end = &outbuf[outbuf_size]; out_end = &outbuf[outbuf_size];
event_list[event_list_ix].user_data = my_user_data; event_list[event_list_ix].user_data = my_user_data;


count_buffers++; 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); finished = create_events((short *)outbuf, length, event_list, a_write_pos);
if (finished < 0) if (finished < 0)
return ENS_AUDIO_ERROR; return ENS_AUDIO_ERROR;
#endif
} else if (synth_callback) } else if (synth_callback)
finished = synth_callback((short *)outbuf, length, event_list); finished = synth_callback((short *)outbuf, length, event_list);
if (finished) { if (finished) {

Loading…
Cancel
Save