//FIXME:initialize shutdown #include "speech.h" #include #include"string.h" #include #include"wave.h" #include"ao/ao.h" #include"debug.h" #define BLOCK_SIZE 512 static t_wave_callback* my_callback_is_output_enabled=NULL; static int requested_sample_rate = 0; static size_t total_samples_sent = 0; static ao_device* ao_dev = NULL; void wave_init(int samplerate) { ENTER("wave_init"); ao_initialize(); requested_sample_rate = samplerate; ao_sample_format format; bzero(&format, sizeof(ao_sample_format)); const int default_driver = ao_default_driver_id(); format.bits = 16; format.channels = 1; format.rate = samplerate; format.byte_format = AO_FMT_LITTLE; ao_dev = ao_open_live(default_driver, &format, NULL); if (ao_dev == NULL) { SHOW("ERROR:wave_init() cannot create proper libao device for audio output with sample rate %u\n", samplerate); return; } SHOW("libao audio device was successfully created for sample rate %u\n", samplerate); } // TBD: the arg could be "alsa", "oss",... void* wave_open(const char* the_api) { ENTER("wave_open"); return ao_dev; } size_t wave_write(void* theHandler, char* theMono16BitsWaveBuffer, size_t theSize) { ENTER("wave_write"); //FIXME:big endian; if (theHandler == NULL) return 0; if (my_callback_is_output_enabled && (0==my_callback_is_output_enabled())) { SHOW_TIME("wave_write > my_callback_is_output_enabled: no!"); return 0; } SHOW("ao:requested playback of %uk of audio data\n", theSize / 1024); size_t played = 0; while (played < theSize) { size_t pos, len; if (theSize - played > BLOCK_SIZE) { pos = played; len = BLOCK_SIZE; } else { pos = played; len = theSize - played; } ao_device* device = (ao_device*)theHandler; const int res = ao_play(device, &theMono16BitsWaveBuffer[pos], len); SHOW("ao:ao_play() has returned %u to playback request of %u bytes of data", res, len); if (res == 0) { SHOW("ao_play has returned an error exit code on operation to play %u bytes of data\n", theSize); return 0; } played += len; } total_samples_sent += theSize / 2; SHOW("%u samples were successfully played by ao_play()", theSize); return theSize; } int wave_close(void* theHandler) { //FIXME: return 0; } void wave_flush(void* theHandler) { //FIXME: } int wave_is_busy(void* theHandler) { //FIXME: return 0; } void wave_terminate() { //FIXME: } uint32_t wave_get_read_position(void* theHandler) { //FIXME: return 0; } uint32_t wave_get_write_position(void* theHandler) { //FIXME: return 0; } // Supply the remaining time in ms before the sample is played // (or 0 if the event has been already played). // sample: sample identifier // time: supplied value in ms // // return 0 if ok or -1 otherwise (stream not opened). int wave_get_remaining_time(uint32_t sample, uint32_t* time) { //FIXME: return 0; } // 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. void wave_set_callback_is_output_enabled(t_wave_callback* cb) { //FIXME: } // general functions void clock_gettime2(struct timespec *ts) { //FIXME: } void add_time_in_ms(struct timespec *ts, int time_in_ms) { //FIXME: } // for tests void *wave_test_get_write_buffer() { //FIXME: return NULL; }