ALSA: fix clear buffer behavior

This commit is contained in:
Andrew Kelley 2015-09-01 15:06:33 -07:00
parent fe4a04d93c
commit cd72f45f06
4 changed files with 28 additions and 6 deletions

View file

@ -252,8 +252,11 @@ For each backend, do the following:
0. Run `./sio_list_devices --watch` and make sure it detects when you plug and 0. Run `./sio_list_devices --watch` and make sure it detects when you plug and
unplug a USB microphone. unplug a USB microphone.
0. Run `./sio_sine` and make sure you hear a sine wave. For backends with raw 0. Run `./sio_sine` and make sure you hear a sine wave. For backends with raw
devices, run `./sio_sine --device id` (where 'id' is a device id you got devices, run `./sio_sine --device id --raw` (where 'id' is a device id you
from `sio_list_devices` and make sure you hear a sine wave. got from `sio_list_devices` and make sure you hear a sine wave.
- Use 'p' to test pausing, 'u' to test unpausing, 'q' to test cleanup.
- 'c' for clear buffer. Clear buffer should not pause the stream and it
should also not cause an underflow.
0. Run `./underflow` and read the testing instructions that it prints. 0. Run `./underflow` and read the testing instructions that it prints.
0. Run `./sio_microphone` and ensure that it is both recording and playing 0. Run `./sio_microphone` and ensure that it is both recording and playing
back correctly. If possible use the `--in-device` and `--out-device` back correctly. If possible use the `--in-device` and `--out-device`

View file

@ -241,6 +241,8 @@ int main(int argc, char **argv) {
} else if (c == 'c') { } else if (c == 'c') {
fprintf(stderr, "clear buffer result: %s\n", fprintf(stderr, "clear buffer result: %s\n",
soundio_strerror(soundio_outstream_clear_buffer(outstream))); soundio_strerror(soundio_outstream_clear_buffer(outstream)));
} else if (c == 'q') {
break;
} else if (c == '\r' || c == '\n') { } else if (c == '\r' || c == '\n') {
// ignore // ignore
} else { } else {

View file

@ -1064,6 +1064,23 @@ void outstream_thread_run(void *arg) {
} }
if (!osa->thread_exit_flag.test_and_set()) if (!osa->thread_exit_flag.test_and_set())
return; return;
if (!osa->clear_buffer_flag.test_and_set()) {
if ((err = snd_pcm_drop(osa->handle)) < 0) {
outstream->error_callback(outstream, SoundIoErrorStreaming);
return;
}
if ((err = snd_pcm_reset(osa->handle)) < 0) {
if (err == -EBADFD) {
// If this happens the snd_pcm_drop will have done
// the function of the reset so it's ok that this
// did not work.
} else {
outstream->error_callback(outstream, SoundIoErrorStreaming);
return;
}
}
continue;
}
snd_pcm_sframes_t avail = snd_pcm_avail_update(osa->handle); snd_pcm_sframes_t avail = snd_pcm_avail_update(osa->handle);
if (avail < 0) { if (avail < 0) {
@ -1172,6 +1189,8 @@ static int outstream_open_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os)
SoundIoOutStream *outstream = &os->pub; SoundIoOutStream *outstream = &os->pub;
SoundIoDevice *device = outstream->device; SoundIoDevice *device = outstream->device;
osa->clear_buffer_flag.test_and_set();
if (outstream->software_latency == 0.0) if (outstream->software_latency == 0.0)
outstream->software_latency = clamp(device->software_latency_min, 1.0, device->software_latency_max); outstream->software_latency = clamp(device->software_latency_min, 1.0, device->software_latency_max);
@ -1429,9 +1448,7 @@ static int outstream_clear_buffer_alsa(SoundIoPrivate *si,
SoundIoOutStreamPrivate *os) SoundIoOutStreamPrivate *os)
{ {
SoundIoOutStreamAlsa *osa = &os->backend_data.alsa; SoundIoOutStreamAlsa *osa = &os->backend_data.alsa;
int err; osa->clear_buffer_flag.clear();
if ((err = snd_pcm_reset(osa->handle)) < 0)
return SoundIoErrorStreaming;
return 0; return 0;
} }
@ -1443,7 +1460,6 @@ static int outstream_pause_alsa(struct SoundIoPrivate *si, struct SoundIoOutStre
int err; int err;
if ((err = snd_pcm_pause(osa->handle, pause)) < 0) { if ((err = snd_pcm_pause(osa->handle, pause)) < 0) {
fprintf(stderr, "alsa pause result: %s\n", snd_strerror(err));
return SoundIoErrorIncompatibleDevice; return SoundIoErrorIncompatibleDevice;
} }

View file

@ -59,6 +59,7 @@ struct SoundIoOutStreamAlsa {
int period_size; int period_size;
int write_frame_count; int write_frame_count;
bool is_paused; bool is_paused;
atomic_flag clear_buffer_flag;
SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS]; SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS];
}; };