|
From: | Dorinda Bassey |
Subject: | Re: [PATCH v7] audio/pwaudio.c: Add Pipewire audio backend for QEMU |
Date: | Mon, 13 Mar 2023 14:11:11 +0100 |
To hear this,
start QEMU with qemu-system-x86_64 -machine pcspk-audiodev=audio0
-device ich9-intel-hda -device hda-duplex,audiodev=audio0 -audiodev
pipewire,id=audio0,out.mixing-engine=off ...
> +/* output data processing function to read stuffs from the buffer */
> +static void
> +playback_on_process(void *data)
> +{
> + PWVoice *v = (PWVoice *) data;
> + void *p;
> + struct pw_buffer *b;
> + struct spa_buffer *buf;
> + uint32_t n_frames, req, index, n_bytes;
> + int32_t avail;
> +
> + if (!v->stream) {
> + return;
> + }
> +
> + /* obtain a buffer to read from */
> + b = pw_stream_dequeue_buffer(v->stream);
> + if (b == NULL) {
> + error_report("out of buffers: %s", strerror(errno));
> + return;
> + }
> +
> + buf = b->buffer;
> + p = buf->datas[0].data;
> + if (p == NULL) {
> + return;
> + }
> + req = b->requested * v->frame_size;
> + if (req == 0) {
> + req = 4096 * v->frame_size;
> + }
> + n_frames = SPA_MIN(req, buf->datas[0].maxsize);
> + n_bytes = n_frames * v->frame_size;
> +
> + /* get no of available bytes to read data from buffer */
> +
> + avail = spa_ringbuffer_get_read_index(&v->ring, &index);
> +
> + if (!v->enabled) {
> + avail = 0;
> + }
> +
> + if (avail == 0) {
> + memset(p, 0, n_bytes);
memset() doesn't work for unsigned samples. For unsigned samples, a
stream of zeros is silence with a DC offset. When Pipewire mixes this
stream with another, the result is a clipped audio stream. To hear this,
start QEMU with qemu-system-x86_64 -machine pcspk-audiodev=audio0
-device ich9-intel-hda -device hda-duplex,audiodev=audio0 -audiodev
pipewire,id=audio0,out.mixing-engine=off ... and start playback with the
hda device.
With best regards,
Volker
> + } else {
> + if (avail < (int32_t) n_bytes) {
> + n_bytes = avail;
> + }
> +
> + spa_ringbuffer_read_data(&v->ring,
> + v->buffer, RINGBUFFER_SIZE,
> + index & RINGBUFFER_MASK, p, n_bytes);
> +
> + index += n_bytes;
> + spa_ringbuffer_read_update(&v->ring, index);
> + }
> +
> + buf->datas[0].chunk->offset = 0;
> + buf->datas[0].chunk->stride = v->frame_size;
> + buf->datas[0].chunk->size = n_bytes;
> +
> + /* queue the buffer for playback */
> + pw_stream_queue_buffer(v->stream, b);
> +}
> +
>
[Prev in Thread] | Current Thread | [Next in Thread] |