mirror of
https://github.com/Ryujinx/libsoundio.git
synced 2024-12-23 07:35:40 +00:00
ALSA: better pause/unpause behavior
This commit is contained in:
parent
afdb8b7feb
commit
fe4a04d93c
|
@ -229,8 +229,24 @@ int main(int argc, char **argv) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;)
|
for (;;) {
|
||||||
soundio_wait_events(soundio);
|
soundio_flush_events(soundio);
|
||||||
|
int c = getc(stdin);
|
||||||
|
if (c == 'p') {
|
||||||
|
fprintf(stderr, "pausing result: %s\n",
|
||||||
|
soundio_strerror(soundio_outstream_pause(outstream, true)));
|
||||||
|
} else if (c == 'u') {
|
||||||
|
fprintf(stderr, "unpausing result: %s\n",
|
||||||
|
soundio_strerror(soundio_outstream_pause(outstream, false)));
|
||||||
|
} else if (c == 'c') {
|
||||||
|
fprintf(stderr, "clear buffer result: %s\n",
|
||||||
|
soundio_strerror(soundio_outstream_clear_buffer(outstream)));
|
||||||
|
} else if (c == '\r' || c == '\n') {
|
||||||
|
// ignore
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Unrecognized command: %c\n", c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
soundio_outstream_destroy(outstream);
|
soundio_outstream_destroy(outstream);
|
||||||
soundio_device_unref(device);
|
soundio_device_unref(device);
|
||||||
|
|
|
@ -972,23 +972,30 @@ SOUNDIO_EXPORT int soundio_outstream_begin_write(struct SoundIoOutStream *outstr
|
||||||
SOUNDIO_EXPORT int soundio_outstream_end_write(struct SoundIoOutStream *outstream);
|
SOUNDIO_EXPORT int soundio_outstream_end_write(struct SoundIoOutStream *outstream);
|
||||||
|
|
||||||
/// Clears the output stream buffer.
|
/// Clears the output stream buffer.
|
||||||
/// You must call this function only from the SoundIoOutStream::write_callback thread context.
|
/// This function can be called from any thread.
|
||||||
|
/// Some backends do not support clearing the buffer. On these backends this
|
||||||
|
/// function will return SoundIoErrorIncompatibleBackend.
|
||||||
/// Possible errors:
|
/// Possible errors:
|
||||||
///
|
///
|
||||||
/// * #SoundIoErrorStreaming
|
/// * #SoundIoErrorStreaming
|
||||||
|
/// * #SoundIoErrorIncompatibleBackend
|
||||||
SOUNDIO_EXPORT int soundio_outstream_clear_buffer(struct SoundIoOutStream *outstream);
|
SOUNDIO_EXPORT int soundio_outstream_clear_buffer(struct SoundIoOutStream *outstream);
|
||||||
|
|
||||||
/// If the underyling device supports pausing, this pauses the stream and
|
/// If the underlying device supports pausing, this pauses the stream.
|
||||||
/// prevents SoundIoOutStream::write_callback from being called. Otherwise this returns
|
/// SoundIoOutStream::write_callback may be called a few more times if the
|
||||||
/// #SoundIoErrorIncompatibleDevice.
|
/// buffer is not full.
|
||||||
/// You must call this function only from the SoundIoOutStream::write_callback thread context.
|
/// Pausing might put the hardware into a low power state which is ideal if your
|
||||||
|
/// software is silent for some time.
|
||||||
|
/// This function may be called any thread.
|
||||||
/// Pausing when already paused or unpausing when already unpaused has no
|
/// Pausing when already paused or unpausing when already unpaused has no
|
||||||
/// effect and always returns SoundIoErrorNone.
|
/// effect and always returns SoundIoErrorNone.
|
||||||
///
|
///
|
||||||
/// Possible errors:
|
/// Possible errors:
|
||||||
/// * #SoundIoErrorBackendDisconnected
|
/// * #SoundIoErrorBackendDisconnected
|
||||||
/// * #SoundIoErrorStreaming
|
/// * #SoundIoErrorStreaming
|
||||||
/// * #SoundIoErrorIncompatibleDevice - device does not support pausing/unpausing
|
/// * #SoundIoErrorIncompatibleDevice - device does not support
|
||||||
|
/// pausing/unpausing. This error code might not be returned even if the
|
||||||
|
/// device does not support pausing/unpausing.
|
||||||
SOUNDIO_EXPORT int soundio_outstream_pause(struct SoundIoOutStream *outstream, bool pause);
|
SOUNDIO_EXPORT int soundio_outstream_pause(struct SoundIoOutStream *outstream, bool pause);
|
||||||
|
|
||||||
|
|
||||||
|
|
18
src/alsa.cpp
18
src/alsa.cpp
|
@ -1054,6 +1054,7 @@ void outstream_thread_run(void *arg) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case SND_PCM_STATE_RUNNING:
|
case SND_PCM_STATE_RUNNING:
|
||||||
|
case SND_PCM_STATE_PAUSED:
|
||||||
{
|
{
|
||||||
if ((err = outstream_wait_for_poll(os)) < 0) {
|
if ((err = outstream_wait_for_poll(os)) < 0) {
|
||||||
if (!osa->thread_exit_flag.test_and_set())
|
if (!osa->thread_exit_flag.test_and_set())
|
||||||
|
@ -1090,7 +1091,6 @@ void outstream_thread_run(void *arg) {
|
||||||
continue;
|
continue;
|
||||||
case SND_PCM_STATE_OPEN:
|
case SND_PCM_STATE_OPEN:
|
||||||
case SND_PCM_STATE_DRAINING:
|
case SND_PCM_STATE_DRAINING:
|
||||||
case SND_PCM_STATE_PAUSED:
|
|
||||||
case SND_PCM_STATE_DISCONNECTED:
|
case SND_PCM_STATE_DISCONNECTED:
|
||||||
outstream->error_callback(outstream, SoundIoErrorStreaming);
|
outstream->error_callback(outstream, SoundIoErrorStreaming);
|
||||||
return;
|
return;
|
||||||
|
@ -1437,9 +1437,17 @@ static int outstream_clear_buffer_alsa(SoundIoPrivate *si,
|
||||||
|
|
||||||
static int outstream_pause_alsa(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, bool pause) {
|
static int outstream_pause_alsa(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, bool pause) {
|
||||||
SoundIoOutStreamAlsa *osa = &os->backend_data.alsa;
|
SoundIoOutStreamAlsa *osa = &os->backend_data.alsa;
|
||||||
|
|
||||||
|
if (osa->is_paused == pause)
|
||||||
|
return 0;
|
||||||
|
|
||||||
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
osa->is_paused = pause;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1701,9 +1709,15 @@ static int instream_end_read_alsa(SoundIoPrivate *si, SoundIoInStreamPrivate *is
|
||||||
|
|
||||||
static int instream_pause_alsa(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is, bool pause) {
|
static int instream_pause_alsa(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is, bool pause) {
|
||||||
SoundIoInStreamAlsa *isa = &is->backend_data.alsa;
|
SoundIoInStreamAlsa *isa = &is->backend_data.alsa;
|
||||||
|
|
||||||
|
if (isa->is_paused == pause)
|
||||||
|
return 0;
|
||||||
|
|
||||||
int err;
|
int err;
|
||||||
if ((err = snd_pcm_pause(isa->handle, pause)) < 0)
|
if ((err = snd_pcm_pause(isa->handle, pause)) < 0)
|
||||||
return SoundIoErrorIncompatibleDevice;
|
return SoundIoErrorIncompatibleDevice;
|
||||||
|
|
||||||
|
isa->is_paused = pause;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@ struct SoundIoOutStreamAlsa {
|
||||||
atomic_flag thread_exit_flag;
|
atomic_flag thread_exit_flag;
|
||||||
int period_size;
|
int period_size;
|
||||||
int write_frame_count;
|
int write_frame_count;
|
||||||
|
bool is_paused;
|
||||||
SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS];
|
SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -75,6 +76,7 @@ struct SoundIoInStreamAlsa {
|
||||||
atomic_flag thread_exit_flag;
|
atomic_flag thread_exit_flag;
|
||||||
int period_size;
|
int period_size;
|
||||||
int read_frame_count;
|
int read_frame_count;
|
||||||
|
bool is_paused;
|
||||||
SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS];
|
SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1049,7 +1049,7 @@ static int outstream_end_write_ca(struct SoundIoPrivate *si, struct SoundIoOutSt
|
||||||
}
|
}
|
||||||
|
|
||||||
static int outstream_clear_buffer_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) {
|
static int outstream_clear_buffer_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) {
|
||||||
return 0;
|
return SoundIoErrorIncompatibleBackend;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -561,7 +561,7 @@ static int outstream_end_write_jack(struct SoundIoPrivate *si, struct SoundIoOut
|
||||||
}
|
}
|
||||||
|
|
||||||
static int outstream_clear_buffer_jack(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) {
|
static int outstream_clear_buffer_jack(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) {
|
||||||
return 0;
|
return SoundIoErrorIncompatibleBackend;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue