These calls are used to pre-emptively exit when writing audio data. This is also handled within dispatch_audio. The difference is that this callback could allow espeak to cancel quicker. In practice it does not make much difference.master
| return -1; | return -1; | ||||
| } | } | ||||
| #ifdef USE_ASYNC | #ifdef USE_ASYNC | ||||
| if ((my_mode & ENOUTPUT_MODE_SYNCHRONOUS) == 0) { | |||||
| wave_set_callback_is_output_enabled(fifo_is_command_enabled); | |||||
| if ((my_mode & ENOUTPUT_MODE_SYNCHRONOUS) == 0) | |||||
| event_init(); | event_init(); | ||||
| } | |||||
| #endif | #endif | ||||
| } | } | ||||
| } | } |
| int wave_port_is_busy(void *theHandler); | int wave_port_is_busy(void *theHandler); | ||||
| void wave_port_terminate(); | void wave_port_terminate(); | ||||
| void wave_port_flush(void *theHandler); | void wave_port_flush(void *theHandler); | ||||
| void wave_port_set_callback_is_output_enabled(t_wave_callback *cb); | |||||
| void *wave_port_test_get_write_buffer(); | void *wave_port_test_get_write_buffer(); | ||||
| // wave_pulse.cpp | // wave_pulse.cpp | ||||
| int wave_pulse_is_busy(void *theHandler); | int wave_pulse_is_busy(void *theHandler); | ||||
| void wave_pulse_terminate(); | void wave_pulse_terminate(); | ||||
| void wave_pulse_flush(void *theHandler); | void wave_pulse_flush(void *theHandler); | ||||
| void wave_pulse_set_callback_is_output_enabled(t_wave_callback *cb); | |||||
| void *wave_pulse_test_get_write_buffer(); | void *wave_pulse_test_get_write_buffer(); | ||||
| // wrappers | // wrappers | ||||
| wave_port_flush(theHandler); | wave_port_flush(theHandler); | ||||
| } | } | ||||
| void wave_set_callback_is_output_enabled(t_wave_callback *cb) | |||||
| { | |||||
| if (pulse_running) | |||||
| wave_pulse_set_callback_is_output_enabled(cb); | |||||
| else | |||||
| wave_port_set_callback_is_output_enabled(cb); | |||||
| } | |||||
| // rename functions to be wrapped | // rename functions to be wrapped | ||||
| #define wave_open wave_port_open | #define wave_open wave_port_open | ||||
| #define wave_write wave_port_write | #define wave_write wave_port_write | ||||
| #define wave_is_busy wave_port_is_busy | #define wave_is_busy wave_port_is_busy | ||||
| #define wave_terminate wave_port_terminate | #define wave_terminate wave_port_terminate | ||||
| #define wave_flush wave_port_flush | #define wave_flush wave_port_flush | ||||
| #define wave_set_callback_is_output_enabled wave_port_set_callback_is_output_enabled | |||||
| #endif | #endif | ||||
| static t_wave_callback *my_callback_is_output_enabled = NULL; | |||||
| #define MAX_SAMPLE_RATE 22050 | #define MAX_SAMPLE_RATE 22050 | ||||
| #define FRAMES_PER_BUFFER 512 | #define FRAMES_PER_BUFFER 512 | ||||
| #define BUFFER_LENGTH (MAX_SAMPLE_RATE*2*sizeof(uint16_t)) | #define BUFFER_LENGTH (MAX_SAMPLE_RATE*2*sizeof(uint16_t)) | ||||
| return selectedDeviceInfo; | return selectedDeviceInfo; | ||||
| } | } | ||||
| void wave_set_callback_is_output_enabled(t_wave_callback *cb) | |||||
| { | |||||
| my_callback_is_output_enabled = cb; | |||||
| } | |||||
| void *wave_open(int srate, const char *device) | void *wave_open(int srate, const char *device) | ||||
| { | { | ||||
| PaError err; | PaError err; | ||||
| char *aRead; | char *aRead; | ||||
| while (1) { | while (1) { | ||||
| if (my_callback_is_output_enabled && (0 == my_callback_is_output_enabled())) | |||||
| return 0; | |||||
| aRead = myRead; | aRead = myRead; | ||||
| // write pointer is before read pointer? | // write pointer is before read pointer? | ||||
| (void)theHandler; // unused | (void)theHandler; // unused | ||||
| } | } | ||||
| void wave_set_callback_is_output_enabled(t_wave_callback *cb) | |||||
| { | |||||
| (void)cb; // unused | |||||
| } | |||||
| #endif | #endif |
| extern int wave_is_busy(void *theHandler); | extern int wave_is_busy(void *theHandler); | ||||
| extern void wave_terminate(); | extern void wave_terminate(); | ||||
| // set the callback which informs if the output is still enabled. | |||||
| // Helpful if a new sample is waiting for free space whereas sound must be stopped. | |||||
| typedef int (t_wave_callback)(void); | |||||
| extern void wave_set_callback_is_output_enabled(t_wave_callback *cb); | |||||
| // general functions | // general functions | ||||
| extern void clock_gettime2(struct timespec *ts); | extern void clock_gettime2(struct timespec *ts); | ||||
| extern void add_time_in_ms(struct timespec *ts, int time_in_ms); | extern void add_time_in_ms(struct timespec *ts, int time_in_ms); |
| #ifdef USE_PULSEAUDIO | #ifdef USE_PULSEAUDIO | ||||
| static t_wave_callback *my_callback_is_output_enabled = NULL; | |||||
| #define SAMPLE_RATE 22050 | #define SAMPLE_RATE 22050 | ||||
| #define ESPEAK_FORMAT PA_SAMPLE_S16LE | #define ESPEAK_FORMAT PA_SAMPLE_S16LE | ||||
| #define ESPEAK_CHANNEL 1 | #define ESPEAK_CHANNEL 1 | ||||
| #define wave_is_busy wave_pulse_is_busy | #define wave_is_busy wave_pulse_is_busy | ||||
| #define wave_terminate wave_pulse_terminate | #define wave_terminate wave_pulse_terminate | ||||
| #define wave_flush wave_pulse_flush | #define wave_flush wave_pulse_flush | ||||
| #define wave_set_callback_is_output_enabled wave_pulse_set_callback_is_output_enabled | |||||
| // check whether we can connect to PulseAudio | // check whether we can connect to PulseAudio | ||||
| #include <pulse/simple.h> | #include <pulse/simple.h> | ||||
| (void)theHandler; // unused | (void)theHandler; // unused | ||||
| } | } | ||||
| void wave_set_callback_is_output_enabled(t_wave_callback *cb) | |||||
| { | |||||
| my_callback_is_output_enabled = cb; | |||||
| } | |||||
| void *wave_open(int srate, const char *device) | void *wave_open(int srate, const char *device) | ||||
| { | { | ||||
| stream = NULL; | stream = NULL; | ||||
| pthread_mutex_lock(&pulse_mutex); | pthread_mutex_lock(&pulse_mutex); | ||||
| while (1) { | while (1) { | ||||
| if (my_callback_is_output_enabled | |||||
| && (0 == my_callback_is_output_enabled())) { | |||||
| theSize = 0; | |||||
| goto terminate; | |||||
| } | |||||
| aTotalFreeMem = pulse_free(); | aTotalFreeMem = pulse_free(); | ||||
| if (aTotalFreeMem >= bytes_to_write) | if (aTotalFreeMem >= bytes_to_write) | ||||
| break; | break; |
| #ifdef USE_SADA | #ifdef USE_SADA | ||||
| static t_wave_callback *my_callback_is_output_enabled = NULL; | |||||
| static const char *sun_audio_device = "/dev/audio"; | static const char *sun_audio_device = "/dev/audio"; | ||||
| static int sun_audio_fd = -1; | static int sun_audio_fd = -1; | ||||
| size_t theSize) | size_t theSize) | ||||
| { | { | ||||
| size_t num; | size_t num; | ||||
| if (my_callback_is_output_enabled && (0 == my_callback_is_output_enabled())) | |||||
| return 0; | |||||
| #if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN | #if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN | ||||
| // BIG-ENDIAN, swap the order of bytes in each sound sample | // BIG-ENDIAN, swap the order of bytes in each sound sample | ||||
| (void)theHandler; // unused | (void)theHandler; // unused | ||||
| } | } | ||||
| // wave_set_callback_is_output_enabled | |||||
| // | |||||
| // DESCRIPTION: | |||||
| // | |||||
| // Sets the callback to call from wave_write before it sends data to | |||||
| // be played. It helps wave_write determine if the data should be | |||||
| // thrown away or not. | |||||
| // | |||||
| // PARAMETERS: | |||||
| // | |||||
| // cb: the callback to call from wave_write | |||||
| // | |||||
| void wave_set_callback_is_output_enabled(t_wave_callback *cb) | |||||
| { | |||||
| my_callback_is_output_enabled = cb; | |||||
| } | |||||
| // wave_get_remaining_time | // wave_get_remaining_time | ||||
| // | // | ||||
| // DESCRIPTION: | // DESCRIPTION: |