mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
examples: improve the ringbuffer example a little
Write the remaining samples in the ringbuffer and fill up the rest with silence. Add some more comments.
This commit is contained in:
parent
ca488a5dcc
commit
e095a1c4ac
1 changed files with 23 additions and 17 deletions
|
|
@ -55,6 +55,8 @@ static void fill_f32(struct data *d, uint32_t offset, int n_frames)
|
|||
}
|
||||
}
|
||||
|
||||
/* this is called from the main-thread when we need to fill up the ringbuffer
|
||||
* with more data */
|
||||
static void do_refill(void *userdata, uint64_t count)
|
||||
{
|
||||
struct data *data = userdata;
|
||||
|
|
@ -84,6 +86,8 @@ static void do_refill(void *userdata, uint64_t count)
|
|||
* b = pw_stream_dequeue_buffer(stream);
|
||||
*
|
||||
* .. generate stuff in the buffer ...
|
||||
* In this case we read samples from a ringbuffer. The ringbuffer is
|
||||
* filled up by another thread.
|
||||
*
|
||||
* pw_stream_queue_buffer(stream, b);
|
||||
*/
|
||||
|
|
@ -92,10 +96,9 @@ static void on_process(void *userdata)
|
|||
struct data *data = userdata;
|
||||
struct pw_buffer *b;
|
||||
struct spa_buffer *buf;
|
||||
int n_frames, stride;
|
||||
uint8_t *p;
|
||||
uint32_t index;
|
||||
int32_t avail;
|
||||
uint32_t index, to_read, to_silence;
|
||||
int32_t avail, n_frames, stride;
|
||||
|
||||
if ((b = pw_stream_dequeue_buffer(data->stream)) == NULL) {
|
||||
pw_log_warn("out of buffers: %m");
|
||||
|
|
@ -112,32 +115,35 @@ static void on_process(void *userdata)
|
|||
stride = sizeof(float) * DEFAULT_CHANNELS;
|
||||
n_frames = buf->datas[0].maxsize / stride;
|
||||
if (b->requested)
|
||||
n_frames = SPA_MIN((int)b->requested, n_frames);
|
||||
n_frames = SPA_MIN((int32_t)b->requested, n_frames);
|
||||
|
||||
if (avail < (int32_t)n_frames) {
|
||||
/* there is not enough data available in the ringbuffer,
|
||||
* fill with silence and hope it will be filled next time */
|
||||
memset(p, 0, n_frames * stride);
|
||||
pw_log_warn("underrun");
|
||||
} else {
|
||||
/* enough data in the ringbuffer, copy it into the buffer data.
|
||||
* We use the number of samples as the read/write counters so we
|
||||
* need to multiply with the stride to get the byte offsets. */
|
||||
/* we can read if there is something available */
|
||||
to_read = avail > 0 ? SPA_MIN(avail, n_frames) : 0;
|
||||
/* and fill the remainder with silence */
|
||||
to_silence = n_frames - to_read;
|
||||
|
||||
if (to_read > 0) {
|
||||
/* read data into the buffer */
|
||||
spa_ringbuffer_read_data(&data->ring,
|
||||
data->buffer, BUFFER_SIZE * stride,
|
||||
(index % BUFFER_SIZE) * stride,
|
||||
p, n_frames * stride);
|
||||
p, to_read * stride);
|
||||
/* update the read pointer */
|
||||
spa_ringbuffer_read_update(&data->ring, index + n_frames);
|
||||
|
||||
spa_ringbuffer_read_update(&data->ring, index + to_read);
|
||||
}
|
||||
if (to_silence > 0)
|
||||
/* set the rest of the buffer to silence */
|
||||
memset(SPA_PTROFF(p, to_read * stride, void), 0, to_silence * stride);
|
||||
|
||||
buf->datas[0].chunk->offset = 0;
|
||||
buf->datas[0].chunk->stride = stride;
|
||||
buf->datas[0].chunk->size = n_frames * stride;
|
||||
|
||||
pw_stream_queue_buffer(data->stream, b);
|
||||
|
||||
/* signal the main thread to fill the ringbuffer */
|
||||
/* signal the main thread to fill the ringbuffer, we can only do this, for
|
||||
* example when the available ringbuffer space falls below a certain
|
||||
* level. */
|
||||
pw_loop_signal_event(data->loop, data->refill_event);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue