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: |