/*
 * QEMU PipeWire audio driver
 *
 * Copyright (c) 2023 Red Hat Inc.
 *
 * Author: Dorinda Bassey       <dbassey@redhat.com>
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#include "qemu/osdep.h"
#include "qemu/module.h"
#include "qemu/audio.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "qom/object.h"
#include <spa/param/audio/format-utils.h>
#include <spa/utils/ringbuffer.h>
#include <spa/utils/result.h>
#include <spa/param/props.h>

#include <pipewire/pipewire.h>

#include "audio_int.h"
#include "trace.h"

#define RINGBUFFER_SIZE    (1u << 22)
#define RINGBUFFER_MASK    (RINGBUFFER_SIZE - 1)

#define TYPE_AUDIO_PW "audio-pipewire"
OBJECT_DECLARE_SIMPLE_TYPE(AudioPw, AUDIO_PW)

static AudioBackendClass *audio_pw_parent_class;

struct AudioPw {
    AudioMixengBackend parent_obj;

    struct pw_thread_loop *thread_loop;
    struct pw_context *context;

    struct pw_core *core;
    struct spa_hook core_listener;
    int last_seq, pending_seq, error;
};


typedef struct pwvolume {
    uint32_t channels;
    float values[SPA_AUDIO_MAX_CHANNELS];
} pwvolume;

typedef struct PWVoice {
    struct pw_stream *stream;
    struct spa_hook stream_listener;
    struct spa_audio_info_raw info;
    uint32_t highwater_mark;
    uint32_t frame_size, req;
    struct spa_ringbuffer ring;
    uint8_t buffer[RINGBUFFER_SIZE];

    pwvolume volume;
    bool muted;
} PWVoice;

typedef struct PWVoiceOut {
    HWVoiceOut hw;
    PWVoice v;
} PWVoiceOut;

typedef struct PWVoiceIn {
    HWVoiceIn hw;
    PWVoice v;
} PWVoiceIn;

#define PW_VOICE_IN(v) ((PWVoiceIn *)v)
#define PW_VOICE_OUT(v) ((PWVoiceOut *)v)

static void
stream_destroy(void *data)
{
    PWVoice *v = (PWVoice *) data;
    spa_hook_remove(&v->stream_listener);
    v->stream = NULL;
}

/* output data processing function to read stuffs from the buffer */
static void
playback_on_process(void *data)
{
    PWVoice *v = data;
    void *p;
    struct pw_buffer *b;
    struct spa_buffer *buf;
    uint32_t req, index, n_bytes;
    int32_t avail;

    assert(v->stream);

    /* 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;
    }
    /* calculate the total no of bytes to read data from buffer */
    req = b->requested * v->frame_size;
    if (req == 0) {
        req = v->req;
    }
    n_bytes = SPA_MIN(req, buf->datas[0].maxsize);

    /* get no of available bytes to read data from buffer */
    avail = spa_ringbuffer_get_read_index(&v->ring, &index);

    if (avail <= 0) {
        PWVoiceOut *vo = container_of(data, PWVoiceOut, v);
        audio_pcm_info_clear_buf(&vo->hw.info, p, n_bytes / v->frame_size);
    } else {
        if ((uint32_t) avail < n_bytes) {
            /*
             * PipeWire immediately calls this callback again if we provide
             * less than n_bytes. Then audio_pcm_info_clear_buf() fills the
             * rest of the buffer with silence.
             */
            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);
}

/* output data processing function to generate stuffs in the buffer */
static void
capture_on_process(void *data)
{
    PWVoice *v = (PWVoice *) data;
    void *p;
    struct pw_buffer *b;
    struct spa_buffer *buf;
    int32_t filled;
    uint32_t index, offs, n_bytes;

    assert(v->stream);

    /* obtain a buffer */
    b = pw_stream_dequeue_buffer(v->stream);
    if (b == NULL) {
        error_report("out of buffers: %s", strerror(errno));
        return;
    }

    /* Write data into buffer */
    buf = b->buffer;
    p = buf->datas[0].data;
    if (p == NULL) {
        return;
    }
    offs = SPA_MIN(buf->datas[0].chunk->offset, buf->datas[0].maxsize);
    n_bytes = SPA_MIN(buf->datas[0].chunk->size, buf->datas[0].maxsize - offs);

    filled = spa_ringbuffer_get_write_index(&v->ring, &index);


    if (filled < 0) {
        error_report("%p: underrun write:%u filled:%d", p, index, filled);
    } else {
        if ((uint32_t) filled + n_bytes > RINGBUFFER_SIZE) {
            error_report("%p: overrun write:%u filled:%d + size:%u > max:%u",
            p, index, filled, n_bytes, RINGBUFFER_SIZE);
        }
    }
    spa_ringbuffer_write_data(&v->ring,
                                v->buffer, RINGBUFFER_SIZE,
                                index & RINGBUFFER_MASK,
                                SPA_PTROFF(p, offs, void), n_bytes);
    index += n_bytes;
    spa_ringbuffer_write_update(&v->ring, index);

    /* queue the buffer for playback */
    pw_stream_queue_buffer(v->stream, b);
}

static void
on_stream_state_changed(void *data, enum pw_stream_state old,
                        enum pw_stream_state state, const char *error)
{
    PWVoice *v = (PWVoice *) data;

    trace_pw_state_changed(pw_stream_get_node_id(v->stream),
                           pw_stream_state_as_string(state));
}

static const struct pw_stream_events capture_stream_events = {
    PW_VERSION_STREAM_EVENTS,
    .destroy = stream_destroy,
    .state_changed = on_stream_state_changed,
    .process = capture_on_process
};

static const struct pw_stream_events playback_stream_events = {
    PW_VERSION_STREAM_EVENTS,
    .destroy = stream_destroy,
    .state_changed = on_stream_state_changed,
    .process = playback_on_process
};

static size_t
qpw_read(HWVoiceIn *hw, void *data, size_t len)
{
    AudioPw *c = AUDIO_PW(hw->s);
    PWVoiceIn *pw = (PWVoiceIn *) hw;
    PWVoice *v = &pw->v;
    const char *error = NULL;
    size_t l;
    int32_t avail;
    uint32_t index;

    pw_thread_loop_lock(c->thread_loop);
    if (pw_stream_get_state(v->stream, &error) != PW_STREAM_STATE_STREAMING) {
        /* wait for stream to become ready */
        l = 0;
        goto done_unlock;
    }
    /* get no of available bytes to read data from buffer */
    avail = spa_ringbuffer_get_read_index(&v->ring, &index);

    trace_pw_read(avail, index, len);

    if (avail < (int32_t) len) {
        len = avail;
    }

    spa_ringbuffer_read_data(&v->ring,
                             v->buffer, RINGBUFFER_SIZE,
                             index & RINGBUFFER_MASK, data, len);
    index += len;
    spa_ringbuffer_read_update(&v->ring, index);
    l = len;

done_unlock:
    pw_thread_loop_unlock(c->thread_loop);
    return l;
}

static size_t qpw_buffer_get_free(HWVoiceOut *hw)
{
    AudioPw *c = AUDIO_PW(hw->s);
    PWVoiceOut *pw = (PWVoiceOut *)hw;
    PWVoice *v = &pw->v;
    const char *error = NULL;
    int32_t filled, avail;
    uint32_t index;

    pw_thread_loop_lock(c->thread_loop);
    if (pw_stream_get_state(v->stream, &error) != PW_STREAM_STATE_STREAMING) {
        /* wait for stream to become ready */
        avail = 0;
        goto done_unlock;
    }

    filled = spa_ringbuffer_get_write_index(&v->ring, &index);
    avail = v->highwater_mark - filled;

done_unlock:
    pw_thread_loop_unlock(c->thread_loop);
    return avail;
}

static size_t
qpw_write(HWVoiceOut *hw, void *data, size_t len)
{
    AudioPw *c = AUDIO_PW(hw->s);
    PWVoiceOut *pw = (PWVoiceOut *) hw;
    PWVoice *v = &pw->v;
    const char *error = NULL;
    int32_t filled, avail;
    uint32_t index;

    pw_thread_loop_lock(c->thread_loop);
    if (pw_stream_get_state(v->stream, &error) != PW_STREAM_STATE_STREAMING) {
        /* wait for stream to become ready */
        len = 0;
        goto done_unlock;
    }
    filled = spa_ringbuffer_get_write_index(&v->ring, &index);
    avail = v->highwater_mark - filled;

    trace_pw_write(filled, avail, index, len);

    if (len > avail) {
        len = avail;
    }

    if (filled < 0) {
        error_report("%p: underrun write:%u filled:%d", pw, index, filled);
    } else {
        if ((uint32_t) filled + len > RINGBUFFER_SIZE) {
            error_report("%p: overrun write:%u filled:%d + size:%zu > max:%u",
            pw, index, filled, len, RINGBUFFER_SIZE);
        }
    }

    spa_ringbuffer_write_data(&v->ring,
                                v->buffer, RINGBUFFER_SIZE,
                                index & RINGBUFFER_MASK, data, len);
    index += len;
    spa_ringbuffer_write_update(&v->ring, index);

done_unlock:
    pw_thread_loop_unlock(c->thread_loop);
    return len;
}

static int
audfmt_to_pw(AudioFormat fmt, bool big_endian)
{
    int format;

    switch (fmt) {
    case AUDIO_FORMAT_S8:
        format = SPA_AUDIO_FORMAT_S8;
        break;
    case AUDIO_FORMAT_U8:
        format = SPA_AUDIO_FORMAT_U8;
        break;
    case AUDIO_FORMAT_S16:
        format = big_endian ? SPA_AUDIO_FORMAT_S16_BE : SPA_AUDIO_FORMAT_S16_LE;
        break;
    case AUDIO_FORMAT_U16:
        format = big_endian ? SPA_AUDIO_FORMAT_U16_BE : SPA_AUDIO_FORMAT_U16_LE;
        break;
    case AUDIO_FORMAT_S32:
        format = big_endian ? SPA_AUDIO_FORMAT_S32_BE : SPA_AUDIO_FORMAT_S32_LE;
        break;
    case AUDIO_FORMAT_U32:
        format = big_endian ? SPA_AUDIO_FORMAT_U32_BE : SPA_AUDIO_FORMAT_U32_LE;
        break;
    case AUDIO_FORMAT_F32:
        format = big_endian ? SPA_AUDIO_FORMAT_F32_BE : SPA_AUDIO_FORMAT_F32_LE;
        break;
    default:
        error_report("pipewire: internal logic error: bad audio format %d", fmt);
        format = SPA_AUDIO_FORMAT_U8;
        break;
    }
    return format;
}

static AudioFormat
pw_to_audfmt(enum spa_audio_format fmt, bool *big_endian,
             uint32_t *sample_size)
{
    switch (fmt) {
    case SPA_AUDIO_FORMAT_S8:
        *sample_size = 1;
        return AUDIO_FORMAT_S8;
    case SPA_AUDIO_FORMAT_U8:
        *sample_size = 1;
        return AUDIO_FORMAT_U8;
    case SPA_AUDIO_FORMAT_S16_BE:
        *sample_size = 2;
        *big_endian = true;
        return AUDIO_FORMAT_S16;
    case SPA_AUDIO_FORMAT_S16_LE:
        *sample_size = 2;
        *big_endian = false;
        return AUDIO_FORMAT_S16;
    case SPA_AUDIO_FORMAT_U16_BE:
        *sample_size = 2;
        *big_endian = true;
        return AUDIO_FORMAT_U16;
    case SPA_AUDIO_FORMAT_U16_LE:
        *sample_size = 2;
        *big_endian = false;
        return AUDIO_FORMAT_U16;
    case SPA_AUDIO_FORMAT_S32_BE:
        *sample_size = 4;
        *big_endian = true;
        return AUDIO_FORMAT_S32;
    case SPA_AUDIO_FORMAT_S32_LE:
        *sample_size = 4;
        *big_endian = false;
        return AUDIO_FORMAT_S32;
    case SPA_AUDIO_FORMAT_U32_BE:
        *sample_size = 4;
        *big_endian = true;
        return AUDIO_FORMAT_U32;
    case SPA_AUDIO_FORMAT_U32_LE:
        *sample_size = 4;
        *big_endian = false;
        return AUDIO_FORMAT_U32;
    case SPA_AUDIO_FORMAT_F32_BE:
        *sample_size = 4;
        *big_endian = true;
        return AUDIO_FORMAT_F32;
    case SPA_AUDIO_FORMAT_F32_LE:
        *sample_size = 4;
        *big_endian = false;
        return AUDIO_FORMAT_F32;
    default:
        *sample_size = 1;
        error_report("pipewire: internal logic error: bad spa_audio_format %d", fmt);
        return AUDIO_FORMAT_U8;
    }
}

static int
qpw_stream_new(AudioPw *c, PWVoice *v, const char *stream_name,
               const char *name, enum spa_direction dir)
{
    int res;
    uint32_t n_params;
    const struct spa_pod *params[2];
    uint8_t buffer[1024];
    struct spa_pod_builder b;
    uint64_t buf_samples;
    struct pw_properties *props;

    props = pw_properties_new(NULL, NULL);
    if (!props) {
        error_report("Failed to create PW properties: %s", g_strerror(errno));
        return -1;
    }

    /* 75% of the timer period for faster updates */
    buf_samples = (uint64_t)AUDIO_MIXENG_BACKEND(c)->dev->timer_period
        * v->info.rate * 3 / 4 / 1000000;
    pw_properties_setf(props, PW_KEY_NODE_LATENCY, "%" PRIu64 "/%u",
                       buf_samples, v->info.rate);

    trace_pw_period(buf_samples, v->info.rate);
    if (name) {
        pw_properties_set(props, PW_KEY_TARGET_OBJECT, name);
    }
    v->stream = pw_stream_new(c->core, stream_name, props);
    if (v->stream == NULL) {
        error_report("Failed to create PW stream: %s", g_strerror(errno));
        return -1;
    }

    if (dir == SPA_DIRECTION_INPUT) {
        pw_stream_add_listener(v->stream,
                            &v->stream_listener, &capture_stream_events, v);
    } else {
        pw_stream_add_listener(v->stream,
                            &v->stream_listener, &playback_stream_events, v);
    }

    n_params = 0;
    spa_pod_builder_init(&b, buffer, sizeof(buffer));
    params[n_params++] = spa_format_audio_raw_build(&b,
                            SPA_PARAM_EnumFormat,
                            &v->info);

    /* connect the stream to a sink or source */
    res = pw_stream_connect(v->stream,
                            dir ==
                            SPA_DIRECTION_INPUT ? PW_DIRECTION_INPUT :
                            PW_DIRECTION_OUTPUT, PW_ID_ANY,
                            PW_STREAM_FLAG_AUTOCONNECT |
                            PW_STREAM_FLAG_INACTIVE |
                            PW_STREAM_FLAG_MAP_BUFFERS |
                            PW_STREAM_FLAG_RT_PROCESS, params, n_params);
    if (res < 0) {
        error_report("Failed to connect PW stream: %s", g_strerror(errno));
        pw_stream_destroy(v->stream);
        return -1;
    }

    return 0;
}

static void
qpw_set_position(uint32_t channels, uint32_t position[SPA_AUDIO_MAX_CHANNELS])
{
    memcpy(position, (uint32_t[SPA_AUDIO_MAX_CHANNELS]) { SPA_AUDIO_CHANNEL_UNKNOWN, },
           sizeof(uint32_t) * SPA_AUDIO_MAX_CHANNELS);
    /*
     * TODO: This currently expects the only frontend supporting more than 2
     * channels is the usb-audio.  We will need some means to set channel
     * order when a new frontend gains multi-channel support.
     */
    switch (channels) {
    case 8:
        position[6] = SPA_AUDIO_CHANNEL_SL;
        position[7] = SPA_AUDIO_CHANNEL_SR;
        /* fallthrough */
    case 6:
        position[2] = SPA_AUDIO_CHANNEL_FC;
        position[3] = SPA_AUDIO_CHANNEL_LFE;
        position[4] = SPA_AUDIO_CHANNEL_RL;
        position[5] = SPA_AUDIO_CHANNEL_RR;
        /* fallthrough */
    case 2:
        position[0] = SPA_AUDIO_CHANNEL_FL;
        position[1] = SPA_AUDIO_CHANNEL_FR;
        break;
    case 1:
        position[0] = SPA_AUDIO_CHANNEL_MONO;
        break;
    default:
        error_report("pipewire: unsupported channel count %d", channels);
    }
}

static int
qpw_init_out(HWVoiceOut *hw, struct audsettings *as)
{
    AudioPw *c = AUDIO_PW(hw->s);
    PWVoiceOut *pw = (PWVoiceOut *) hw;
    PWVoice *v = &pw->v;
    struct audsettings obt_as = *as;
    AudiodevPipewireOptions *popts = &AUDIO_MIXENG_BACKEND(c)->dev->u.pipewire;
    AudiodevPipewirePerDirectionOptions *ppdo = popts->out;
    int r;

    pw_thread_loop_lock(c->thread_loop);

    v->info.format = audfmt_to_pw(as->fmt, as->big_endian);
    v->info.channels = as->nchannels;
    qpw_set_position(as->nchannels, v->info.position);
    v->info.rate = as->freq;

    obt_as.fmt =
        pw_to_audfmt(v->info.format, &obt_as.big_endian, &v->frame_size);
    v->frame_size *= as->nchannels;

    v->req = (uint64_t)AUDIO_MIXENG_BACKEND(c)->dev->timer_period * v->info.rate
        * 1 / 2 / 1000000 * v->frame_size;

    /* call the function that creates a new stream for playback */
    r = qpw_stream_new(c, v, ppdo->stream_name ?: AUDIO_MIXENG_BACKEND(c)->dev->id,
                       ppdo->name, SPA_DIRECTION_OUTPUT);
    if (r < 0) {
        pw_thread_loop_unlock(c->thread_loop);
        return -1;
    }

    /* report the audio format we support */
    audio_pcm_init_info(&hw->info, &obt_as);

    /* report the buffer size to qemu */
    hw->samples = audio_buffer_frames(
        qapi_AudiodevPipewirePerDirectionOptions_base(ppdo), &obt_as, 46440);
    v->highwater_mark = MIN(RINGBUFFER_SIZE,
                            (ppdo->has_latency ? ppdo->latency : 46440)
                            * (uint64_t)v->info.rate / 1000000 * v->frame_size);

    pw_thread_loop_unlock(c->thread_loop);
    return 0;
}

static int
qpw_init_in(HWVoiceIn *hw, struct audsettings *as)
{
    AudioPw *c = AUDIO_PW(hw->s);
    PWVoiceIn *pw = (PWVoiceIn *) hw;
    PWVoice *v = &pw->v;
    struct audsettings obt_as = *as;
    AudiodevPipewireOptions *popts = &AUDIO_MIXENG_BACKEND(c)->dev->u.pipewire;
    AudiodevPipewirePerDirectionOptions *ppdo = popts->in;
    int r;

    pw_thread_loop_lock(c->thread_loop);

    v->info.format = audfmt_to_pw(as->fmt, as->big_endian);
    v->info.channels = as->nchannels;
    qpw_set_position(as->nchannels, v->info.position);
    v->info.rate = as->freq;

    obt_as.fmt =
        pw_to_audfmt(v->info.format, &obt_as.big_endian, &v->frame_size);
    v->frame_size *= as->nchannels;

    /* call the function that creates a new stream for recording */
    r = qpw_stream_new(c, v, ppdo->stream_name ? : AUDIO_MIXENG_BACKEND(c)->dev->id,
                       ppdo->name, SPA_DIRECTION_INPUT);
    if (r < 0) {
        pw_thread_loop_unlock(c->thread_loop);
        return -1;
    }

    /* report the audio format we support */
    audio_pcm_init_info(&hw->info, &obt_as);

    /* report the buffer size to qemu */
    hw->samples = audio_buffer_frames(
        qapi_AudiodevPipewirePerDirectionOptions_base(ppdo), &obt_as, 46440);

    pw_thread_loop_unlock(c->thread_loop);
    return 0;
}

static void
qpw_voice_fini(AudioPw *c, PWVoice *v)
{
    if (!v->stream) {
        return;
    }
    pw_thread_loop_lock(c->thread_loop);
    pw_stream_destroy(v->stream);
    v->stream = NULL;
    pw_thread_loop_unlock(c->thread_loop);
}

static void
qpw_fini_out(HWVoiceOut *hw)
{
    qpw_voice_fini(AUDIO_PW(hw->s), &PW_VOICE_OUT(hw)->v);
}

static void
qpw_fini_in(HWVoiceIn *hw)
{
    qpw_voice_fini(AUDIO_PW(hw->s), &PW_VOICE_IN(hw)->v);
}

static void
qpw_voice_set_enabled(AudioPw *c, PWVoice *v, bool enable)
{
    pw_thread_loop_lock(c->thread_loop);
    pw_stream_set_active(v->stream, enable);
    pw_thread_loop_unlock(c->thread_loop);
}

static void
qpw_enable_out(HWVoiceOut *hw, bool enable)
{
    qpw_voice_set_enabled(AUDIO_PW(hw->s), &PW_VOICE_OUT(hw)->v, enable);
}

static void
qpw_enable_in(HWVoiceIn *hw, bool enable)
{
    qpw_voice_set_enabled(AUDIO_PW(hw->s), &PW_VOICE_IN(hw)->v, enable);
}

static void
qpw_voice_set_volume(AudioPw *c, PWVoice *v, Volume *vol)
{
    int i, ret;

    pw_thread_loop_lock(c->thread_loop);
    v->volume.channels = vol->channels;

    for (i = 0; i < vol->channels; ++i) {
        v->volume.values[i] = (float)vol->vol[i] / 255;
    }

    ret = pw_stream_set_control(v->stream,
        SPA_PROP_channelVolumes, v->volume.channels, v->volume.values, 0);
    trace_pw_vol(ret == 0 ? "success" : "failed");

    v->muted = vol->mute;
    float val = v->muted ? 1.f : 0.f;
    ret = pw_stream_set_control(v->stream, SPA_PROP_mute, 1, &val, 0);
    pw_thread_loop_unlock(c->thread_loop);
}

static void
qpw_volume_out(HWVoiceOut *hw, Volume *vol)
{
    qpw_voice_set_volume(AUDIO_PW(hw->s), &PW_VOICE_OUT(hw)->v, vol);
}

static void
qpw_volume_in(HWVoiceIn *hw, Volume *vol)
{
    qpw_voice_set_volume(AUDIO_PW(hw->s), &PW_VOICE_IN(hw)->v, vol);
}

static int wait_resync(AudioPw *pw)
{
    int res;
    pw->pending_seq = pw_core_sync(pw->core, PW_ID_CORE, pw->pending_seq);

    while (true) {
        pw_thread_loop_wait(pw->thread_loop);

        res = pw->error;
        if (res < 0) {
            pw->error = 0;
            return res;
        }
        if (pw->pending_seq == pw->last_seq) {
            break;
        }
    }
    return 0;
}

static void
on_core_error(void *data, uint32_t id, int seq, int res, const char *message)
{
    AudioPw *pw = data;

    error_report("error id:%u seq:%d res:%d (%s): %s",
                id, seq, res, spa_strerror(res), message);

    /* stop and exit the thread loop */
    pw_thread_loop_signal(pw->thread_loop, FALSE);
}

static void
on_core_done(void *data, uint32_t id, int seq)
{
    AudioPw *pw = data;
    assert(id == PW_ID_CORE);
    pw->last_seq = seq;
    if (pw->pending_seq == seq) {
        /* stop and exit the thread loop */
        pw_thread_loop_signal(pw->thread_loop, FALSE);
    }
}

static const struct pw_core_events core_events = {
    PW_VERSION_CORE_EVENTS,
    .done = on_core_done,
    .error = on_core_error,
};

static bool
audio_pw_realize(AudioBackend *abe, Audiodev *dev, Error **errp)
{
    AudioPw *pw = AUDIO_PW(abe);

    assert(dev->driver == AUDIODEV_DRIVER_PIPEWIRE);
    trace_pw_audio_init();

    if (!audio_pw_parent_class->realize(abe, dev, errp)) {
        return false;
    }

    pw_init(NULL, NULL);

    pw->thread_loop = pw_thread_loop_new("PipeWire thread loop", NULL);
    if (pw->thread_loop == NULL) {
        error_setg_errno(errp, errno, "Could not create PipeWire loop");
        goto fail;
    }

    pw->context =
        pw_context_new(pw_thread_loop_get_loop(pw->thread_loop), NULL, 0);
    if (pw->context == NULL) {
        error_setg_errno(errp, errno, "Could not create PipeWire context");
        goto fail;
    }

    if (pw_thread_loop_start(pw->thread_loop) < 0) {
        error_setg_errno(errp, errno, "Could not start PipeWire loop");
        goto fail;
    }

    pw_thread_loop_lock(pw->thread_loop);

    pw->core = pw_context_connect(pw->context, NULL, 0);
    if (pw->core == NULL) {
        pw_thread_loop_unlock(pw->thread_loop);
        error_setg_errno(errp, errno, "Failed to connect to PipeWire instance");
        goto fail;
    }

    if (pw_core_add_listener(pw->core, &pw->core_listener,
                             &core_events, pw) < 0) {
        pw_thread_loop_unlock(pw->thread_loop);
        error_setg(errp, "Failed to add PipeWire listener");
        goto fail;
    }
    if (wait_resync(pw) < 0) {
        pw_thread_loop_unlock(pw->thread_loop);
    }

    pw_thread_loop_unlock(pw->thread_loop);
    return true;

fail:
    if (pw->thread_loop) {
        pw_thread_loop_stop(pw->thread_loop);
    }
    g_clear_pointer(&pw->context, pw_context_destroy);
    g_clear_pointer(&pw->thread_loop, pw_thread_loop_destroy);
    return false;
}

static void
audio_pw_finalize(Object *obj)
{
    AudioPw *pw = AUDIO_PW(obj);

    if (pw->thread_loop) {
        pw_thread_loop_stop(pw->thread_loop);
    }

    if (pw->core) {
        spa_hook_remove(&pw->core_listener);
        spa_zero(pw->core_listener);
        pw_core_disconnect(pw->core);
    }

    if (pw->context) {
        pw_context_destroy(pw->context);
    }
    g_clear_pointer(&pw->thread_loop, pw_thread_loop_destroy);
}

static void audio_pw_class_init(ObjectClass *klass, const void *data)
{
    AudioBackendClass *b = AUDIO_BACKEND_CLASS(klass);
    AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_CLASS(klass);

    audio_pw_parent_class = AUDIO_BACKEND_CLASS(object_class_get_parent(klass));

    b->realize = audio_pw_realize;
    k->max_voices_out = INT_MAX;
    k->max_voices_in = INT_MAX;
    k->voice_size_out = sizeof(PWVoiceOut);
    k->voice_size_in = sizeof(PWVoiceIn);

    k->init_out = qpw_init_out;
    k->fini_out = qpw_fini_out;
    k->write = qpw_write;
    k->buffer_get_free = qpw_buffer_get_free;
    k->run_buffer_out = audio_generic_run_buffer_out;
    k->enable_out = qpw_enable_out;
    k->volume_out = qpw_volume_out;

    k->init_in = qpw_init_in;
    k->fini_in = qpw_fini_in;
    k->read = qpw_read;
    k->run_buffer_in = audio_generic_run_buffer_in;
    k->enable_in = qpw_enable_in;
    k->volume_in = qpw_volume_in;
}

static const TypeInfo audio_types[] = {
    {
        .name = TYPE_AUDIO_PW,
        .parent = TYPE_AUDIO_MIXENG_BACKEND,
        .instance_size = sizeof(AudioPw),
        .class_init = audio_pw_class_init,
        .instance_finalize = audio_pw_finalize,
    },
};

DEFINE_TYPES(audio_types)
module_obj(TYPE_AUDIO_PW);
