mirror of
https://github.com/Ryujinx/libsoundio.git
synced 2024-12-22 21:55:36 +00:00
ALSA implement clear buffer
This commit is contained in:
parent
ab8a2c2ffe
commit
5906bc93d9
|
@ -242,6 +242,9 @@ view `coverage/index.html` in a browser.
|
|||
0. Figure out a way to test prebuf. I suspect prebuf not working for ALSA
|
||||
which is why we have to pre-fill the ring buffer with silence for
|
||||
the microphone example.
|
||||
0. In ALSA do we need to wake up the poll when destroying the in or out stream?
|
||||
0. Create a test for clearing the playback buffer.
|
||||
0. Create a test for pausing and resuming input and output streams.
|
||||
0. implement ASIO (Windows) backend, get examples working
|
||||
0. clean up API and improve documentation
|
||||
- make sure every function which can return an error documents which errors
|
||||
|
|
34
src/alsa.cpp
34
src/alsa.cpp
|
@ -909,7 +909,6 @@ static void outstream_destroy_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate *
|
|||
|
||||
if (osa->thread) {
|
||||
osa->thread_exit_flag.clear();
|
||||
// TODO wake up poll
|
||||
soundio_os_thread_destroy(osa->thread);
|
||||
}
|
||||
|
||||
|
@ -1007,8 +1006,6 @@ void outstream_thread_run(void *arg) {
|
|||
for (;;) {
|
||||
snd_pcm_state_t state = snd_pcm_state(osa->handle);
|
||||
switch (state) {
|
||||
case SND_PCM_STATE_OPEN:
|
||||
soundio_panic("TODO open");
|
||||
case SND_PCM_STATE_SETUP:
|
||||
if ((err = snd_pcm_prepare(osa->handle)) < 0) {
|
||||
outstream->error_callback(outstream, SoundIoErrorStreaming);
|
||||
|
@ -1050,18 +1047,18 @@ void outstream_thread_run(void *arg) {
|
|||
return;
|
||||
}
|
||||
continue;
|
||||
case SND_PCM_STATE_DRAINING:
|
||||
soundio_panic("TODO draining");
|
||||
case SND_PCM_STATE_PAUSED:
|
||||
soundio_panic("TODO paused");
|
||||
case SND_PCM_STATE_SUSPENDED:
|
||||
if ((err = xrun_recovery(os, -ESTRPIPE)) < 0) {
|
||||
outstream->error_callback(outstream, SoundIoErrorStreaming);
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
case SND_PCM_STATE_OPEN:
|
||||
case SND_PCM_STATE_DRAINING:
|
||||
case SND_PCM_STATE_PAUSED:
|
||||
case SND_PCM_STATE_DISCONNECTED:
|
||||
soundio_panic("TODO disconnected");
|
||||
outstream->error_callback(outstream, SoundIoErrorStreaming);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1076,8 +1073,6 @@ static void instream_thread_run(void *arg) {
|
|||
for (;;) {
|
||||
snd_pcm_state_t state = snd_pcm_state(osa->handle);
|
||||
switch (state) {
|
||||
case SND_PCM_STATE_OPEN:
|
||||
soundio_panic("TODO open");
|
||||
case SND_PCM_STATE_SETUP:
|
||||
if ((err = snd_pcm_prepare(osa->handle)) < 0) {
|
||||
instream->error_callback(instream, SoundIoErrorStreaming);
|
||||
|
@ -1119,18 +1114,18 @@ static void instream_thread_run(void *arg) {
|
|||
return;
|
||||
}
|
||||
continue;
|
||||
case SND_PCM_STATE_DRAINING:
|
||||
soundio_panic("TODO draining");
|
||||
case SND_PCM_STATE_PAUSED:
|
||||
soundio_panic("TODO paused");
|
||||
case SND_PCM_STATE_SUSPENDED:
|
||||
if ((err = instream_xrun_recovery(is, -ESTRPIPE)) < 0) {
|
||||
instream->error_callback(instream, SoundIoErrorStreaming);
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
case SND_PCM_STATE_OPEN:
|
||||
case SND_PCM_STATE_DRAINING:
|
||||
case SND_PCM_STATE_PAUSED:
|
||||
case SND_PCM_STATE_DISCONNECTED:
|
||||
soundio_panic("TODO disconnected");
|
||||
instream->error_callback(instream, SoundIoErrorStreaming);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1395,10 +1390,14 @@ static int outstream_end_write_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void outstream_clear_buffer_alsa(SoundIoPrivate *si,
|
||||
static int outstream_clear_buffer_alsa(SoundIoPrivate *si,
|
||||
SoundIoOutStreamPrivate *os)
|
||||
{
|
||||
soundio_panic("TODO");
|
||||
SoundIoOutStreamAlsa *osa = (SoundIoOutStreamAlsa *) os->backend_data;
|
||||
int err;
|
||||
if ((err = snd_pcm_reset(osa->handle)) < 0)
|
||||
return SoundIoErrorStreaming;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int outstream_pause_alsa(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, bool pause) {
|
||||
|
@ -1416,7 +1415,6 @@ static void instream_destroy_alsa(SoundIoPrivate *si, SoundIoInStreamPrivate *is
|
|||
|
||||
if (isa->thread) {
|
||||
isa->thread_exit_flag.clear();
|
||||
// TODO wake up poll
|
||||
soundio_os_thread_destroy(isa->thread);
|
||||
}
|
||||
|
||||
|
|
|
@ -290,9 +290,11 @@ static int outstream_end_write_dummy(SoundIoPrivate *si, SoundIoOutStreamPrivate
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void outstream_clear_buffer_dummy(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) {
|
||||
static int outstream_clear_buffer_dummy(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) {
|
||||
SoundIoOutStreamDummy *osd = (SoundIoOutStreamDummy *)os->backend_data;
|
||||
soundio_ring_buffer_clear(&osd->ring_buffer);
|
||||
osd->prebuf_frames_left = osd->prebuf_frame_count;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void instream_destroy_dummy(SoundIoPrivate *si, SoundIoInStreamPrivate *is) {
|
||||
|
|
|
@ -782,7 +782,7 @@ static int outstream_end_write_pa(SoundIoPrivate *si, SoundIoOutStreamPrivate *o
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void outstream_clear_buffer_pa(SoundIoPrivate *si,
|
||||
static int outstream_clear_buffer_pa(SoundIoPrivate *si,
|
||||
SoundIoOutStreamPrivate *os)
|
||||
{
|
||||
SoundIoOutStreamPulseAudio *ospa = (SoundIoOutStreamPulseAudio *)os->backend_data;
|
||||
|
@ -791,9 +791,10 @@ static void outstream_clear_buffer_pa(SoundIoPrivate *si,
|
|||
pa_threaded_mainloop_lock(sipa->main_loop);
|
||||
pa_operation *op = pa_stream_flush(stream, NULL, NULL);
|
||||
if (!op)
|
||||
soundio_panic("pa_stream_flush failed: %s", pa_strerror(pa_context_errno(sipa->pulse_context)));
|
||||
return SoundIoErrorStreaming;
|
||||
pa_operation_unref(op);
|
||||
pa_threaded_mainloop_unlock(sipa->main_loop);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int outstream_pause_pa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os, bool pause) {
|
||||
|
|
|
@ -340,14 +340,14 @@ struct SoundIoOutStream {
|
|||
// This optional callback happens when the sound device runs out of buffered
|
||||
// audio data to play. After this occurs, the outstream waits until the
|
||||
// buffer is full to resume playback.
|
||||
// This callback is called in the same thread context as `write_callback`.
|
||||
// This is called from the `write_callback` thread context.
|
||||
void (*underflow_callback)(struct SoundIoOutStream *);
|
||||
// Optional callback. `err` is always SoundIoErrorStreaming.
|
||||
// SoundIoErrorStreaming is an unrecoverable error. The stream is in an
|
||||
// invalid state and must be destroyed.
|
||||
// If you do not supply `error_callback`, the default callback will print
|
||||
// a message to stderr and then call `abort`.
|
||||
// This callback is called in the same thread context as `write_callback`.
|
||||
// This is called fram the `write_callback` thread context.
|
||||
void (*error_callback)(struct SoundIoOutStream *, int err);
|
||||
|
||||
// Name of the stream. This is used by PulseAudio. Defaults to "SoundIo".
|
||||
|
@ -398,7 +398,7 @@ struct SoundIoInStream {
|
|||
// invalid state and must be destroyed.
|
||||
// If you do not supply `error_callback`, the default callback will print
|
||||
// a message to stderr and then abort().
|
||||
// This is called from the same thread context as `read_callback`.
|
||||
// This is called from the `read_callback` thread context.
|
||||
void (*error_callback)(struct SoundIoInStream *, int err);
|
||||
|
||||
// Name of the stream. This is used by PulseAudio. Defaults to "SoundIo".
|
||||
|
@ -555,7 +555,7 @@ struct SoundIoOutStream *soundio_outstream_create(struct SoundIoDevice *device);
|
|||
|
||||
int soundio_outstream_open(struct SoundIoOutStream *outstream);
|
||||
|
||||
// You may not call this function from `write_callback`.
|
||||
// You may not call this function from the `write_callback` thread context.
|
||||
void soundio_outstream_destroy(struct SoundIoOutStream *outstream);
|
||||
|
||||
int soundio_outstream_start(struct SoundIoOutStream *outstream);
|
||||
|
@ -569,21 +569,23 @@ int soundio_outstream_start(struct SoundIoOutStream *outstream);
|
|||
// It is your responsibility to call this function no more and no fewer than the
|
||||
// correct number of times as determined by `requested_frame_count` from
|
||||
// `write_callback`. See sine.c for an example.
|
||||
// You must call this function only from `write_callback`. After calling this
|
||||
// function, write data to `areas` and then call `soundio_outstream_end_write`.
|
||||
// You must call this function only from the `write_callback` thread context.
|
||||
// After calling this function, write data to `areas` and then call `soundio_outstream_end_write`.
|
||||
int soundio_outstream_begin_write(struct SoundIoOutStream *outstream,
|
||||
struct SoundIoChannelArea **areas, int *frame_count);
|
||||
|
||||
// Commits the write that you began with `soundio_outstream_begin_write`.
|
||||
// You must call this function only from `write_callback`.
|
||||
// You must call this function only from the `write_callback` thread context.
|
||||
int soundio_outstream_end_write(struct SoundIoOutStream *outstream, int frame_count);
|
||||
|
||||
void soundio_outstream_clear_buffer(struct SoundIoOutStream *outstream);
|
||||
// Clears the output stream buffer and the stream goes into prebuffering mode.
|
||||
// You must call this function only from the `write_callback` thread context.
|
||||
int soundio_outstream_clear_buffer(struct SoundIoOutStream *outstream);
|
||||
|
||||
// If the underyling device supports pausing, this pauses the stream and
|
||||
// prevents `write_callback` from being called. Otherwise this returns
|
||||
// `SoundIoErrorIncompatibleDevice`.
|
||||
// You must call this function only from `write_callback`.
|
||||
// You must call this function only from the `write_callback` thread context.
|
||||
int soundio_outstream_pause(struct SoundIoOutStream *outstream, bool pause);
|
||||
|
||||
|
||||
|
@ -613,7 +615,7 @@ int soundio_instream_start(struct SoundIoInStream *instream);
|
|||
// It is your responsibility to call this function no more and no fewer than the
|
||||
// correct number of times as determined by `available_frame_count` from
|
||||
// `read_callback`. See microphone.c for an example.
|
||||
// You must call this function only from `read_callback`.
|
||||
// You must call this function only from the `read_callback` thread context.
|
||||
// After calling this function, read data from `areas` and then use
|
||||
// `soundio_instream_end_read` to actually remove the data from the buffer
|
||||
// and move the read index forward. `soundio_instream_end_read` should not be
|
||||
|
@ -623,14 +625,15 @@ int soundio_instream_begin_read(struct SoundIoInStream *instream,
|
|||
struct SoundIoChannelArea **areas, int *frame_count);
|
||||
// This will drop all of the frames from when you called
|
||||
// `soundio_instream_begin_read`.
|
||||
// You must call this function only from `read_callback` after a successful
|
||||
// call to `soundio_instream_begin_read`.
|
||||
// You must call this function only from the `read_callback` thread context.
|
||||
// You must call this function only after a successful call to
|
||||
// `soundio_instream_begin_read`.
|
||||
int soundio_instream_end_read(struct SoundIoInStream *instream);
|
||||
|
||||
// If the underyling device supports pausing, this pauses the stream and
|
||||
// prevents `read_callback` from being called. Otherwise this returns
|
||||
// `SoundIoErrorIncompatibleDevice`.
|
||||
// You must call this function only from `read_callback`.
|
||||
// You must call this function only from the `read_callback` thread context.
|
||||
int soundio_instream_pause(struct SoundIoInStream *instream, bool pause);
|
||||
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ struct SoundIoPrivate {
|
|||
int (*outstream_begin_write)(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *,
|
||||
SoundIoChannelArea **out_areas, int *frame_count);
|
||||
int (*outstream_end_write)(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *, int frame_count);
|
||||
void (*outstream_clear_buffer)(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *);
|
||||
int (*outstream_clear_buffer)(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *);
|
||||
int (*outstream_pause)(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *, bool pause);
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue