--- flite-1.2-release/src/audio/au_alsa.c.alsa 2001-12-04 21:05:52 +0300 +++ flite-1.2-release/src/audio/au_alsa.c 2005-10-31 14:53:35 +0300 @@ -46,98 +46,117 @@ #include "cst_wave.h" #include "cst_audio.h" -#include +#include #include #include -static int alsa_card = 0, alsa_device = 0; +#ifndef CST_AUDIO_ALSA_DEVICE +#define CST_AUDIO_ALSA_DEVICE "default" +#endif + +#ifdef CST_AUDIO_ALSA_DEBUG +static snd_output_t *sndout; +#endif + +static int framebits; cst_audiodev *audio_open_alsa(int sps, int channels, cst_audiofmt fmt) { - snd_pcm_channel_info_t pinfo; - snd_pcm_channel_params_t params; - snd_pcm_channel_setup_t setup; snd_pcm_t *pcm; cst_audiodev *ad; + snd_pcm_hw_params_t *params; + snd_pcm_format_t format = SND_PCM_FORMAT_S16; + snd_pcm_access_t access = SND_PCM_ACCESS_RW_INTERLEAVED; + unsigned int buffer_time = 500000; /* 0.5 sec */ + unsigned int period_time = 100000; /* 0.1 sec */ + unsigned int rate = sps; int err; -#ifdef __QNXNTO__ - if (snd_pcm_open_preferred(&pcm,&alsa_card,&alsa_device,SND_PCM_OPEN_PLAYBACK) < 0) - { - cst_errmsg("alsa_audio: failed to open audio device\n"); - cst_error(); - } - if (snd_pcm_plugin_set_disable(pcm,PLUGIN_DISABLE_MMAP) < 0) - { - cst_errmsg("alsa_audio: failed to disable mmap\n"); - snd_pcm_close(pcm); - cst_error(); - } -#else - if (snd_pcm_open(&pcm,alsa_card,alsa_device,SND_PCM_OPEN_PLAYBACK) < 0) - { - cst_errmsg("alsa_audio: failed to open audio device\n"); - cst_error(); - } -#endif - - - memset(&pinfo, 0, sizeof(pinfo)); - memset(¶ms, 0, sizeof(params)); - memset(&setup, 0, sizeof(setup)); - - pinfo.channel = SND_PCM_CHANNEL_PLAYBACK; - snd_pcm_plugin_info(pcm,&pinfo); - - params.mode = SND_PCM_MODE_BLOCK; - params.channel = SND_PCM_CHANNEL_PLAYBACK; - params.start_mode = SND_PCM_START_DATA; - params.stop_mode = SND_PCM_STOP_STOP; - - params.buf.block.frag_size = pinfo.max_fragment_size; - params.buf.block.frags_max = 1; - params.buf.block.frags_min = 1; - - params.format.interleave = 1; - params.format.rate = sps; - params.format.voices = channels; - - switch (fmt) - { + switch (fmt) { case CST_AUDIO_LINEAR16: - if (CST_LITTLE_ENDIAN) - params.format.format = SND_PCM_SFMT_S16_LE; - else - params.format.format = SND_PCM_SFMT_S16_BE; - break; + if (CST_LITTLE_ENDIAN) + format = SND_PCM_FORMAT_S16_LE; + else + format = SND_PCM_FORMAT_S16_BE; + break; case CST_AUDIO_LINEAR8: - params.format.format = SND_PCM_SFMT_U8; - break; + format = SND_PCM_FORMAT_U8; + break; case CST_AUDIO_MULAW: - params.format.format = SND_PCM_SFMT_MU_LAW; - break; + format = SND_PCM_FORMAT_MU_LAW; + break; + default: + cst_errmsg("alsa_audio: unexpected format requested\n"); } - if((err = snd_pcm_plugin_params(pcm,¶ms)) < 0) - { - cst_errmsg("alsa_audio params setting failed: %s\n",snd_strerror(err)); - snd_pcm_close(pcm); - cst_error(); - } - if((err = snd_pcm_plugin_setup(pcm,SND_PCM_CHANNEL_PLAYBACK)) > 0) { - cst_errmsg("alsa_audio sound prepare setting failed: %s\n",snd_strerror(err)); - snd_pcm_close(pcm); - cst_error(); - } - if((err = snd_pcm_plugin_prepare(pcm,SND_PCM_CHANNEL_PLAYBACK)) > 0) { - cst_errmsg("alsa_audio sound prepare setting failed: %s\n",snd_strerror(err)); - snd_pcm_close(pcm); - cst_error(); - } +#ifdef CST_AUDIO_ALSA_DEBUG + if (0 > (err = snd_output_stdio_attach(&sndout, stderr, 0))) { + cst_errmsg("alsa_audio: failed to open log\n"); + cst_error(); + return NULL; + } +#endif - pinfo.channel = SND_PCM_CHANNEL_PLAYBACK; - snd_pcm_plugin_info(pcm,&pinfo); + if (0 > (err = snd_pcm_open(&pcm, CST_AUDIO_ALSA_DEVICE, SND_PCM_STREAM_PLAYBACK, 0))) { + cst_errmsg("alsa_audio: failed to open audio device: %s\n", snd_strerror(err)); + cst_error(); + return NULL; + } + + snd_pcm_hw_params_alloca(¶ms); + + if ((err = snd_pcm_hw_params_any(pcm, params)) < 0) { + cst_errmsg("alsa_audio: failed to get configuration: %s\n", snd_strerror(err)); + goto bailout; + } + + if ((err = snd_pcm_hw_params_set_access(pcm, params, access)) < 0) { + cst_errmsg("alsa_audio: failed to set access type: %s\n", snd_strerror(err)); + goto bailout; + } + + if (0 > (err = snd_pcm_hw_params_set_format (pcm, params, format))) { + cst_errmsg("alsa_audio: failed to set sample format: %s\n", snd_strerror(err)); + goto bailout; + } + + if (0 > (err = snd_pcm_hw_params_set_channels(pcm, params, channels))) { + cst_errmsg("alsa_audio: failed to set channels count %d: %s\n", channels, snd_strerror(err)); + goto bailout; + } + + if (0 > (err = snd_pcm_hw_params_set_rate(pcm, params, rate, 0))) { + cst_errmsg("alsa_audio: failed to set sample rate: %s\n", snd_strerror(err)); + goto bailout; + } + + if (0 > (err = snd_pcm_hw_params_set_buffer_time_near(pcm, params, &buffer_time, NULL))) { + cst_errmsg("alsa_audio: failed to set buffer time: %s\n", snd_strerror(err)); + goto bailout; + } + + if (0 > (err = snd_pcm_hw_params_set_period_time_near(pcm, params, &period_time, NULL))) { + cst_errmsg("alsa_audio: failed to set period time: %s\n", snd_strerror(err)); + goto bailout; + } + + if (0 > (err = snd_pcm_hw_params(pcm, params))) { + cst_errmsg("alsa_audio: failed to set hw params: %s\n", snd_strerror(err)); + goto bailout; + } + + /* FIXME */ + if (0 > (err = snd_pcm_hw_params_get_sbits(params))) { + cst_errmsg("alsa_audio: failed to get sbits: %s\n", snd_strerror(err)); + goto bailout; + } + + framebits = err * channels; + +#ifdef CST_AUDIO_ALSA_DEBUG + snd_pcm_hw_params_dump(params, sndout); +#endif ad = cst_alloc(cst_audiodev, 1); ad->platform_data = pcm; @@ -146,6 +165,16 @@ ad->fmt = ad->real_fmt = fmt; return ad; + + bailout: + +#ifdef CST_AUDIO_ALSA_DEBUG + snd_pcm_hw_params_dump(params, sndout); +#endif + snd_pcm_close(pcm); + cst_error(); + + return NULL; } int audio_close_alsa(cst_audiodev *ad) @@ -156,7 +185,7 @@ return 0; pcm = ad->platform_data; - snd_pcm_plugin_flush(pcm,0); + snd_pcm_drop(pcm); snd_pcm_close(pcm); cst_free(ad); @@ -166,21 +195,35 @@ int audio_write_alsa(cst_audiodev *ad, void *samples, int num_bytes) { snd_pcm_t *pcm = ad->platform_data; + snd_pcm_uframes_t nframes = (num_bytes << 3) / framebits; + int err; - return snd_pcm_plugin_write(pcm,samples,num_bytes); + while (nframes > 0) { + if (0 > (err = snd_pcm_writei(pcm, samples, nframes))) { + if (err == -EAGAIN) continue; + if (err == -EPIPE) { + if (snd_pcm_prepare(pcm) < 0) return 0; + else continue; + } + } + + samples += (err * framebits) >> 3; + nframes -= err; + } + + return num_bytes; } int audio_flush_alsa(cst_audiodev *ad) { snd_pcm_t *pcm = ad->platform_data; - return snd_pcm_plugin_flush(pcm,0); + return snd_pcm_drop(pcm); } int audio_drain_alsa(cst_audiodev *ad) { snd_pcm_t *pcm = ad->platform_data; - return snd_pcm_plugin_playback_drain(pcm); + return snd_pcm_drain(pcm); } - --- flite-1.2-release/configure.in.alsa 2003-02-18 03:45:45 +0300 +++ flite-1.2-release/configure.in 2005-10-31 14:50:54 +0300 @@ -131,9 +131,10 @@ AC_CHECK_HEADER(sys/audioio.h, [AUDIODRIVER="sun" AUDIODEFS=-DCST_AUDIO_SUNOS]) -AC_CHECK_HEADER(sys/asoundlib.h, +AC_CHECK_HEADER(alsa/asoundlib.h, [AUDIODRIVER="alsa" - AUDIODEFS=-DCST_AUDIO_ALSA]) + AUDIODEFS=-DCST_AUDIO_ALSA + AUDIOLIBS=-lasound]) AC_CHECK_HEADER(mmsystem.h, [AUDIODRIVER="wince" AUDIODEFS=-DCST_AUDIO_WINCE