ALSA: fix playback on raw device

This commit is contained in:
Andrew Kelley 2015-08-26 12:30:46 -07:00
parent 6019d4b964
commit 195ea59209
4 changed files with 24 additions and 12 deletions

View file

@ -274,7 +274,6 @@ Then look at `html/index.html` in a browser.
## Roadmap ## Roadmap
0. test sio_sine with ALSA raw device
0. Make sure PulseAudio can handle refresh devices crashing before 0. Make sure PulseAudio can handle refresh devices crashing before
block_until_have_devices block_until_have_devices
0. Integrate into libgroove and test with Groove Basin 0. Integrate into libgroove and test with Groove Basin

View file

@ -188,6 +188,11 @@ int main(int argc, char **argv) {
fprintf(stderr, "Output device: %s\n", device->name); fprintf(stderr, "Output device: %s\n", device->name);
if (device->probe_error) {
fprintf(stderr, "Cannot probe device: %s\n", soundio_strerror(device->probe_error));
return 1;
}
struct SoundIoOutStream *outstream = soundio_outstream_create(device); struct SoundIoOutStream *outstream = soundio_outstream_create(device);
outstream->write_callback = write_callback; outstream->write_callback = write_callback;
outstream->underflow_callback = underflow_callback; outstream->underflow_callback = underflow_callback;

View file

@ -970,6 +970,17 @@ void outstream_thread_run(void *arg) {
} }
case SND_PCM_STATE_PREPARED: case SND_PCM_STATE_PREPARED:
{ {
snd_pcm_sframes_t avail = snd_pcm_avail_update(osa->handle);
if (avail < 0) {
outstream->error_callback(outstream, SoundIoErrorStreaming);
return;
}
if ((snd_pcm_uframes_t)avail == osa->buffer_size_frames) {
outstream->write_callback(outstream, 0, avail);
continue;
}
if ((err = snd_pcm_start(osa->handle)) < 0) { if ((err = snd_pcm_start(osa->handle)) < 0) {
outstream->error_callback(outstream, SoundIoErrorStreaming); outstream->error_callback(outstream, SoundIoErrorStreaming);
return; return;
@ -1155,6 +1166,13 @@ static int outstream_open_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os)
return SoundIoErrorOpeningDevice; return SoundIoErrorOpeningDevice;
} }
osa->buffer_size_frames = ceil(outstream->software_latency * (double)outstream->sample_rate);
if ((err = snd_pcm_hw_params_set_buffer_size_near(osa->handle, hwparams, &osa->buffer_size_frames)) < 0) {
outstream_destroy_alsa(si, os);
return SoundIoErrorOpeningDevice;
}
outstream->software_latency = ((double)osa->buffer_size_frames) / (double)outstream->sample_rate;
if (device->is_raw) { if (device->is_raw) {
unsigned int microseconds; unsigned int microseconds;
@ -1172,17 +1190,6 @@ static int outstream_open_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os)
} }
} }
snd_pcm_uframes_t buffer_size_frames = ceil(outstream->software_latency * (double)outstream->sample_rate);
if ((err = snd_pcm_hw_params_set_buffer_size_near(osa->handle, hwparams, &buffer_size_frames)) < 0) {
outstream_destroy_alsa(si, os);
return SoundIoErrorOpeningDevice;
}
outstream->software_latency = ((double)buffer_size_frames) / (double)outstream->sample_rate;
snd_pcm_uframes_t period_size; snd_pcm_uframes_t period_size;
if ((snd_pcm_hw_params_get_period_size(hwparams, &period_size, nullptr)) < 0) { if ((snd_pcm_hw_params_get_period_size(hwparams, &period_size, nullptr)) < 0) {
outstream_destroy_alsa(si, os); outstream_destroy_alsa(si, os);

View file

@ -42,6 +42,7 @@ struct SoundIoOutStreamAlsa {
int chmap_size; int chmap_size;
snd_pcm_uframes_t offset; snd_pcm_uframes_t offset;
snd_pcm_access_t access; snd_pcm_access_t access;
snd_pcm_uframes_t buffer_size_frames;
int sample_buffer_size; int sample_buffer_size;
char *sample_buffer; char *sample_buffer;
int poll_fd_count; int poll_fd_count;