mirror of
https://github.com/Ryujinx/libsoundio.git
synced 2025-01-03 15:05:31 +00:00
ALSA: fix clear buffer behavior
This commit is contained in:
parent
fe4a04d93c
commit
cd72f45f06
|
@ -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
|
||||
unplug a USB microphone.
|
||||
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
|
||||
from `sio_list_devices` and make sure you hear a sine wave.
|
||||
devices, run `./sio_sine --device id --raw` (where 'id' is a device id you
|
||||
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 `./sio_microphone` and ensure that it is both recording and playing
|
||||
back correctly. If possible use the `--in-device` and `--out-device`
|
||||
|
|
|
@ -241,6 +241,8 @@ int main(int argc, char **argv) {
|
|||
} else if (c == 'c') {
|
||||
fprintf(stderr, "clear buffer result: %s\n",
|
||||
soundio_strerror(soundio_outstream_clear_buffer(outstream)));
|
||||
} else if (c == 'q') {
|
||||
break;
|
||||
} else if (c == '\r' || c == '\n') {
|
||||
// ignore
|
||||
} else {
|
||||
|
|
24
src/alsa.cpp
24
src/alsa.cpp
|
@ -1064,6 +1064,23 @@ void outstream_thread_run(void *arg) {
|
|||
}
|
||||
if (!osa->thread_exit_flag.test_and_set())
|
||||
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);
|
||||
if (avail < 0) {
|
||||
|
@ -1172,6 +1189,8 @@ static int outstream_open_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os)
|
|||
SoundIoOutStream *outstream = &os->pub;
|
||||
SoundIoDevice *device = outstream->device;
|
||||
|
||||
osa->clear_buffer_flag.test_and_set();
|
||||
|
||||
if (outstream->software_latency == 0.0)
|
||||
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)
|
||||
{
|
||||
SoundIoOutStreamAlsa *osa = &os->backend_data.alsa;
|
||||
int err;
|
||||
if ((err = snd_pcm_reset(osa->handle)) < 0)
|
||||
return SoundIoErrorStreaming;
|
||||
osa->clear_buffer_flag.clear();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1443,7 +1460,6 @@ static int outstream_pause_alsa(struct SoundIoPrivate *si, struct SoundIoOutStre
|
|||
|
||||
int err;
|
||||
if ((err = snd_pcm_pause(osa->handle, pause)) < 0) {
|
||||
fprintf(stderr, "alsa pause result: %s\n", snd_strerror(err));
|
||||
return SoundIoErrorIncompatibleDevice;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@ struct SoundIoOutStreamAlsa {
|
|||
int period_size;
|
||||
int write_frame_count;
|
||||
bool is_paused;
|
||||
atomic_flag clear_buffer_flag;
|
||||
SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS];
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue