Hi On Wed, Feb 4, 2026 at 3:33 PM Mark Cave-Ayland <[email protected]> wrote: > > On 23/01/2026 07:49, [email protected] wrote: > > > From: Marc-André Lureau <[email protected]> > > > > Now "audio_driver" is a detail implementation of AudioMixengBackend and > > not required to implement an AudioBackend. > > > > Signed-off-by: Marc-André Lureau <[email protected]> > > --- > > include/qemu/audio.h | 1 + > > audio/audio.c | 40 ++++++++++++++++++++++++++-------------- > > 2 files changed, 27 insertions(+), 14 deletions(-) > > > > diff --git a/include/qemu/audio.h b/include/qemu/audio.h > > index 474d761f0be..1eeead2a722 100644 > > --- a/include/qemu/audio.h > > +++ b/include/qemu/audio.h > > @@ -51,6 +51,7 @@ typedef struct AudioBackend { > > typedef struct AudioBackendClass { > > ObjectClass parent_class; > > > > + bool (*realize)(AudioBackend *be, Audiodev *dev, Error **errp); > > const char *(*get_id)(AudioBackend *be); > > #ifdef CONFIG_GIO > > bool (*set_dbus_server)(AudioBackend *be, > > diff --git a/audio/audio.c b/audio/audio.c > > index 7e23a63d401..f6896229cfb 100644 > > --- a/audio/audio.c > > +++ b/audio/audio.c > > @@ -1561,24 +1561,16 @@ size_t audio_generic_read(HWVoiceIn *hw, void *buf, > > size_t size) > > return total; > > } > > > > -static AudioBackend *audio_be_new(Audiodev *dev, Error **errp) > > +static bool audio_mixeng_backend_realize(AudioBackend *abe, > > + Audiodev *dev, Error **errp) > > { > > - const char *drvname = AudiodevDriver_str(dev->driver); > > - struct audio_driver *drv = audio_driver_lookup(drvname); > > + AudioMixengBackend *be = AUDIO_MIXENG_BACKEND(abe); > > + audio_driver *drv = AUDIO_MIXENG_BACKEND_GET_CLASS(be)->driver; > > > > - if (!drv) { > > - error_setg(errp, "Unknown audio driver `%s'", drvname); > > - qapi_free_Audiodev(dev); > > - return NULL; > > - } > > - > > - AudioMixengBackend *be = > > AUDIO_MIXENG_BACKEND(object_new(TYPE_AUDIO_MIXENG_BACKEND)); > > be->dev = dev; > > - > > be->drv_opaque = drv->init(be->dev, errp); > > if (!be->drv_opaque) { > > - object_unref(OBJECT(be)); > > - return NULL; > > + return false; > > } > > > > if (!drv->pcm_ops->get_buffer_in) { > > @@ -1600,7 +1592,26 @@ static AudioBackend *audio_be_new(Audiodev *dev, > > Error **errp) > > be->period_ticks = be->dev->timer_period * (int64_t)SCALE_US; > > } > > > > - return AUDIO_BACKEND(be); > > + return true; > > +} > > + > > +static AudioBackend *audio_be_new(Audiodev *dev, Error **errp) > > +{ > > + const char *drvname = AudiodevDriver_str(dev->driver); > > + g_autofree char *type = g_strconcat("audio-", drvname, NULL); > > + AudioBackend *be = AUDIO_BACKEND(object_new(type)); > > + > > + if (!be) { > > + error_setg(errp, "Unknown audio driver `%s'", drvname); > > + return NULL; > > + } > > + > > + if (!AUDIO_BACKEND_GET_CLASS(be)->realize(be, dev, errp)) { > > + object_unref(OBJECT(be)); > > + return NULL; > > + } > > + > > + return be; > > } > > > > static void audio_vm_change_state_handler (void *opaque, bool running, > > @@ -1643,6 +1654,7 @@ static void > > audio_mixeng_backend_class_init(ObjectClass *klass, const void *data > > { > > AudioBackendClass *be = AUDIO_BACKEND_CLASS(klass); > > > > + be->realize = audio_mixeng_backend_realize; > > be->get_id = audio_mixeng_backend_get_id; > > } > > I'm wondering if an AudioBackendClass realize() method is the right way > to handle this, and if instead an object_property_set() function could > be used to set a "driver" property? >
By the end of the refactoring, "driver" is gone. Effectively, each (current) backend will inherit from AudioMixengBe.
