qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v7] audio/pwaudio.c: Add Pipewire audio backend for QEMU


From: Volker Rümelin
Subject: Re: [PATCH v7] audio/pwaudio.c: Add Pipewire audio backend for QEMU
Date: Mon, 13 Mar 2023 20:22:33 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.8.0

Am 13.03.23 um 14:11 schrieb Dorinda Bassey:
Hi Volker,

    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 ...

I hear the clipped audio stream with these options. IMO, I don't think memset is responsible for that behaviour, I still hear the harsh sound with "-audiodev pa". I also tried using an alternative like:

Hi Dorinda,

when you test -audiodev pa with a pulseaudio server, audio playback is fine. Audio playback with -audiodev pa with the pipewire-pulse server is clipped. This is a pipewire bug.

With best regards,
Volker


@@ -117,7 +118,7 @@ playback_on_process(void *data)
     }

     if (avail == 0) {
-        memset(p, 0, n_bytes);
+        p = g_malloc0(sizeof(n_bytes));
     } else {

The clipped audio issue is still persistent.

Thanks,
Dorinda.

On Sun, Mar 12, 2023 at 9:01 AM Volker Rümelin <vr_qemu@t-online.de> wrote:

    > +/* 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);
    > +}
    > +
    >





reply via email to

[Prev in Thread] Current Thread [Next in Thread]