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
|
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`
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
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())
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue