linux_sound.cc (speech_tools-2.4-release) | : | linux_sound.cc (speech_tools-2.5.0-release) | ||
---|---|---|---|---|
skipping to change at line 399 | skipping to change at line 399 | |||
/* Based on the alsa support in Flite provided by Lukas Loehrer */ | /* Based on the alsa support in Flite provided by Lukas Loehrer */ | |||
/* */ | /* */ | |||
/*=======================================================================*/ | /*=======================================================================*/ | |||
#ifdef SUPPORT_ALSALINUX | #ifdef SUPPORT_ALSALINUX | |||
#include <sys/ioctl.h> | #include <sys/ioctl.h> | |||
#include <alsa/asoundlib.h> | #include <alsa/asoundlib.h> | |||
#include <sys/types.h> | #include <sys/types.h> | |||
#include <sys/stat.h> | #include <sys/stat.h> | |||
#include <fcntl.h> | #include <fcntl.h> | |||
static const char *aud_sys_name = "ALSALINUX"; | #define aud_sys_name "ALSALINUX" | |||
// Code to block signals while sound is playing. | // Code to block signals while sound is playing. | |||
// Needed inside Java on (at least some) linux systems | // Needed inside Java on (at least some) linux systems | |||
// as scheduling interrupts seem to break the writes. | // as scheduling interrupts seem to break the writes. | |||
int linux16_supported = TRUE; | int linux16_supported = TRUE; | |||
int freebsd16_supported = FALSE; | int freebsd16_supported = FALSE; | |||
#ifdef THREAD_SAFETY | #ifdef THREAD_SAFETY | |||
#include <csignal> | #include <csignal> | |||
skipping to change at line 574 | skipping to change at line 574 | |||
/* Commit hardware parameters */ | /* Commit hardware parameters */ | |||
err = snd_pcm_hw_params(pcm_handle, hwparams); | err = snd_pcm_hw_params(pcm_handle, hwparams); | |||
if (err < 0) | if (err < 0) | |||
{ | { | |||
snd_pcm_close(pcm_handle); | snd_pcm_close(pcm_handle); | |||
EST_warning("audio_open_alsa: failed to set hw parameters. %s.\n", snd_st rerror(err)); | EST_warning("audio_open_alsa: failed to set hw parameters. %s.\n", snd_st rerror(err)); | |||
return NULL; | return NULL; | |||
} | } | |||
/* Make sure the device is ready to accept data */ | /* There doesn't seem to be another way to set the latency -- if done | |||
here, it works, if not, it looses the first 2s or so */ | ||||
snd_pcm_set_params(pcm_handle, | ||||
format, | ||||
SND_PCM_ACCESS_RW_INTERLEAVED, | ||||
1, | ||||
real_rate, | ||||
1, | ||||
50000); | ||||
/* Make sure the device is ready to accept data */ | ||||
assert(snd_pcm_state(pcm_handle) == SND_PCM_STATE_PREPARED); | assert(snd_pcm_state(pcm_handle) == SND_PCM_STATE_PREPARED); | |||
/* Write hardware parameters to flite audio device data structure */ | /* Write hardware parameters to flite audio device data structure */ | |||
ad = walloc(cst_audiodev, 1); | ad = walloc(cst_audiodev, 1); | |||
assert(ad != NULL); | assert(ad != NULL); | |||
ad->real_sps = ad->sps = sps; | ad->real_sps = ad->sps = sps; | |||
ad->real_channels = ad->channels = channels; | ad->real_channels = ad->channels = channels; | |||
ad->real_fmt = ad->fmt = fmt; | ad->real_fmt = ad->fmt = fmt; | |||
ad->platform_data = (void *) pcm_handle; | ad->platform_data = (void *) pcm_handle; | |||
skipping to change at line 650 | skipping to change at line 660 | |||
{ | { | |||
/* Unknown failure */ | /* Unknown failure */ | |||
EST_warning("audio_recover_from_write_error: %s.\n", snd_strerror(res)); | EST_warning("audio_recover_from_write_error: %s.\n", snd_strerror(res)); | |||
return res; | return res; | |||
} | } | |||
return 0; | return 0; | |||
} | } | |||
int audio_write_alsa(cst_audiodev *ad, void *samples, int num_bytes) | int audio_write_alsa(cst_audiodev *ad, void *samples, int num_bytes) | |||
{ | { | |||
size_t frame_size; | size_t frame_size; | |||
ssize_t num_frames, res; | ssize_t num_frames, res; | |||
snd_pcm_t *pcm_handle; | snd_pcm_t *pcm_handle; | |||
char *buf = (char *) samples; | char *buf = (char *) samples; | |||
/* Determine frame size in bytes */ | ||||
frame_size = audio_bps(ad->real_fmt) * ad->real_channels; | ||||
/* Require that only complete frames are handed in */ | ||||
assert((num_bytes % frame_size) == 0); | ||||
num_frames = num_bytes / frame_size; | ||||
pcm_handle = (snd_pcm_t *) ad->platform_data; | ||||
/* Determine frame size in bytes */ | while (num_frames > 0) | |||
frame_size = audio_bps(ad->real_fmt) * ad->real_channels; | { | |||
/* Require that only complete frames are handed in */ | ||||
assert((num_bytes % frame_size) == 0); | ||||
num_frames = num_bytes / frame_size; | ||||
pcm_handle = (snd_pcm_t *) ad->platform_data; | ||||
while (num_frames > 0) | ||||
{ | ||||
res = snd_pcm_writei(pcm_handle, buf, num_frames); | res = snd_pcm_writei(pcm_handle, buf, num_frames); | |||
if (res != num_frames) | if (res != num_frames) | |||
{ | { | |||
if (res == -EAGAIN || (res > 0 && res < num_frames)) | if (res == -EAGAIN || (res > 0 && res < num_frames)) | |||
{ | { | |||
snd_pcm_wait(pcm_handle, 100); | snd_pcm_wait(pcm_handle, 100); | |||
} | } | |||
else if (recover_from_error(pcm_handle, res) < 0) | else if (recover_from_error(pcm_handle, res) < 0) | |||
{ | { | |||
return -1; | return -1; | |||
} | } | |||
} | } | |||
if (res >0) | if (res >0) | |||
{ | { | |||
num_frames -= res; | num_frames -= res; | |||
buf += res * frame_size; | buf += res * frame_size; | |||
} | } | |||
} | } | |||
return num_bytes; | return num_bytes; | |||
} | } | |||
int audio_flush_alsa(cst_audiodev *ad) | int audio_flush_alsa(cst_audiodev *ad) | |||
{ | { | |||
int result; | int result; | |||
result = snd_pcm_drain((snd_pcm_t *) ad->platform_data); | result = snd_pcm_drain((snd_pcm_t *) ad->platform_data); | |||
if (result < 0) | if (result < 0) | |||
{ | { | |||
EST_warning("audio_flush_alsa: Error: %s.\n", snd_strerror(result)); | EST_warning("audio_flush_alsa: Error: %s.\n", snd_strerror(result)); | |||
} | } | |||
/* Prepare device for more data */ | /* Prepare device for more data */ | |||
result = snd_pcm_prepare((snd_pcm_t *) ad->platform_data); | result = snd_pcm_prepare((snd_pcm_t *) ad->platform_data); | |||
if (result < 0) | if (result < 0) | |||
{ | { | |||
EST_warning("audio_flush_alsa: Error: %s.\n", snd_strerror(result)); | EST_warning("audio_flush_alsa: Error: %s.\n", snd_strerror(result)); | |||
} | } | |||
return result; | return result; | |||
} | } | |||
int audio_drain_alsa(cst_audiodev *ad) | int audio_drain_alsa(cst_audiodev *ad) | |||
{ | { | |||
int result; | int result; | |||
result = snd_pcm_drop((snd_pcm_t *) ad->platform_data); | result = snd_pcm_drop((snd_pcm_t *) ad->platform_data); | |||
if (result < 0) | if (result < 0) | |||
{ | { | |||
EST_warning("audio_drain_alsa: Error: %s.\n", snd_strerror(result)); | EST_warning("audio_drain_alsa: Error: %s.\n", snd_strerror(result)); | |||
} | } | |||
/* Prepare device for more data */ | /* Prepare device for more data */ | |||
result = snd_pcm_prepare((snd_pcm_t *) ad->platform_data); | result = snd_pcm_prepare((snd_pcm_t *) ad->platform_data); | |||
if (result < 0) | if (result < 0) | |||
{ | { | |||
EST_warning("audio_drain_alsa: Error: %s.\n", snd_strerror(result)); | EST_warning("audio_drain_alsa: Error: %s.\n", snd_strerror(result)); | |||
} | } | |||
return result; | return result; | |||
} | } | |||
#define AUDIOBUFFSIZE 256 | #define AUDIOBUFFSIZE 256 | |||
// #define AUDIOBUFFSIZE 20480 | // #define AUDIOBUFFSIZE 20480 | |||
int play_linux_wave(EST_Wave &inwave, EST_Option &al) | int play_linux_wave(EST_Wave &inwave, EST_Option &al) | |||
{ | { | |||
int sample_rate; | int sample_rate; | |||
short *waveform; | short *waveform; | |||
int num_samples; | int num_samples; | |||
const char *audiodevice; | ||||
cst_audiodev *ad; | cst_audiodev *ad; | |||
#if 0 | ||||
const char *audiodevice; | ||||
if (al.present("-audiodevice")) | if (al.present("-audiodevice")) | |||
audiodevice = al.val("-audiodevice"); | audiodevice = al.val("-audiodevice"); | |||
else | else | |||
audiodevice = "/dev/dsp"; | audiodevice = "/dev/dsp"; | |||
#endif | ||||
waveform = inwave.values().memory(); | waveform = inwave.values().memory(); | |||
num_samples = inwave.num_samples(); | num_samples = inwave.num_samples(); | |||
sample_rate = inwave.sample_rate(); | sample_rate = inwave.sample_rate(); | |||
ad = audio_open_alsa(sample_rate,1,CST_AUDIO_LINEAR16); | ad = audio_open_alsa(sample_rate,1,CST_AUDIO_LINEAR16); | |||
THREAD_DECS(); | THREAD_DECS(); | |||
THREAD_PROTECT(); | THREAD_PROTECT(); | |||
End of changes. 18 change blocks. | ||||
48 lines changed or deleted | 60 lines changed or added |