On 27/01/2026 18:24, [email protected] wrote:

From: Marc-AndrĂ© Lureau <[email protected]>

Migrate the DirectSound audio backend from the legacy driver init/fini
callbacks to proper QOM realize and finalize methods.

The dsound struct fields are now embedded directly in the AudioDsound
QOM object instead of being allocated separately as drv_opaque. This
allows accessing the backend state through proper QOM type casting
with AUDIO_DSOUND() rather than casting drv_opaque pointers.

The DirectSound and DirectSoundCapture COM objects are now managed
through the QOM lifecycle, with initialization in realize and cleanup
in finalize.

Signed-off-by: Marc-AndrĂ© Lureau <[email protected]>
---
  audio/dsound_template.h |  9 ++---
  audio/dsoundaudio.c     | 87 +++++++++++++++++++----------------------
  2 files changed, 45 insertions(+), 51 deletions(-)

diff --git a/audio/dsound_template.h b/audio/dsound_template.h
index 0678f2de38b..7979773eb86 100644
--- a/audio/dsound_template.h
+++ b/audio/dsound_template.h
@@ -72,7 +72,7 @@ static int glue (dsound_lock_, TYPE) (
      DWORD *blen1p,
      DWORD *blen2p,
      int entire,
-    dsound *s
+    AudioDsound *s
      )
  {
      HRESULT hr;
@@ -166,7 +166,7 @@ static int dsound_init_out(HWVoiceOut *hw, struct 
audsettings *as,
  {
      int err;
      HRESULT hr;
-    dsound *s = drv_opaque;
+    AudioDsound *s = AUDIO_DSOUND(hw->s);
      WAVEFORMATEX wfx;
      struct audsettings obt_as;
  #ifdef DSBTYPE_IN
@@ -174,13 +174,13 @@ static int dsound_init_out(HWVoiceOut *hw, struct 
audsettings *as,
      DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
      DSCBUFFERDESC bd;
      DSCBCAPS bc;
-    AudiodevPerDirectionOptions *pdo = s->dev->u.dsound.in;
+    AudiodevPerDirectionOptions *pdo = hw->s->dev->u.dsound.in;
  #else
      const char *typ = "DAC";
      DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
      DSBUFFERDESC bd;
      DSBCAPS bc;
-    AudiodevPerDirectionOptions *pdo = s->dev->u.dsound.out;
+    AudiodevPerDirectionOptions *pdo = hw->s->dev->u.dsound.out;
  #endif
if (!s->FIELD2) {
@@ -256,7 +256,6 @@ static int dsound_init_out(HWVoiceOut *hw, struct 
audsettings *as,
      }
      hw->size_emul = bc.dwBufferBytes;
      hw->samples = bc.dwBufferBytes / hw->info.bytes_per_frame;
-    ds->s = s;
#ifdef DEBUG_DSOUND
      dolog ("caps %ld, desc %ld\n",
diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c
index 3de6a3dee9c..4ecf2ade003 100644
--- a/audio/dsoundaudio.c
+++ b/audio/dsoundaudio.c
@@ -45,40 +45,30 @@
  #define TYPE_AUDIO_DSOUND "audio-dsound"
  OBJECT_DECLARE_SIMPLE_TYPE(AudioDsound, AUDIO_DSOUND)
+static AudioBackendClass *audio_dsound_parent_class;
+
  struct AudioDsound {
      AudioMixengBackend parent;
+
+    LPDIRECTSOUND dsound;
+    LPDIRECTSOUNDCAPTURE dsound_capture;
+    struct audsettings settings;
  };
static struct audio_driver dsound_audio_driver; -static void audio_dsound_class_init(ObjectClass *klass, const void *data)
-{
-    AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_CLASS(klass);
-
-    k->driver = &dsound_audio_driver;
-}
-
  /* #define DEBUG_DSOUND */
-typedef struct {
-    LPDIRECTSOUND dsound;
-    LPDIRECTSOUNDCAPTURE dsound_capture;
-    struct audsettings settings;
-    Audiodev *dev;
-} dsound;
-
  typedef struct {
      HWVoiceOut hw;
      LPDIRECTSOUNDBUFFER dsound_buffer;
      bool first_time;
-    dsound *s;
  } DSoundVoiceOut;
typedef struct {
      HWVoiceIn hw;
      LPDIRECTSOUNDCAPTUREBUFFER dsound_capture_buffer;
      bool first_time;
-    dsound *s;
  } DSoundVoiceIn;
static const char *dserror(HRESULT hr)
@@ -276,7 +266,7 @@ static void print_wave_format (WAVEFORMATEX *wfx)
  }
  #endif
-static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb, dsound *s)
+static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb, AudioDsound *s)
  {
      HRESULT hr;
@@ -295,7 +285,7 @@ static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb, dsound *s)
  #undef DSBTYPE_IN
static int dsound_get_status_out (LPDIRECTSOUNDBUFFER dsb, DWORD *statusp,
-                                  dsound *s)
+                                  AudioDsound *s)
  {
      HRESULT hr;
@@ -328,7 +318,7 @@ static int dsound_get_status_in (LPDIRECTSOUNDCAPTUREBUFFER dscb,
  }
static void dsound_clear_sample (HWVoiceOut *hw, LPDIRECTSOUNDBUFFER dsb,
-                                 dsound *s)
+                                 AudioDsound *s)
  {
      int err;
      LPVOID p1, p2;
@@ -372,9 +362,9 @@ static void dsound_enable_out(HWVoiceOut *hw, bool enable)
  {
      HRESULT hr;
      DWORD status;
+    AudioDsound *s = AUDIO_DSOUND(hw->s);
      DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
      LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer;
-    dsound *s = ds->s;
if (!dsb) {
          dolog ("Attempt to control voice without a buffer\n");
@@ -450,7 +440,7 @@ static void *dsound_get_buffer_out(HWVoiceOut *hw, size_t 
*size)
      assert(req_size > 0);
err = dsound_lock_out(dsb, &hw->info, hw->pos_emul, req_size, &ret, NULL,
-                          &act_size, NULL, false, ds->s);
+                          &act_size, NULL, false, AUDIO_DSOUND(hw->s));
      if (err) {
          dolog("Failed to lock buffer\n");
          *size = 0;
@@ -553,7 +543,7 @@ static void *dsound_get_buffer_in(HWVoiceIn *hw, size_t 
*size)
      }
err = dsound_lock_in(dscb, &hw->info, hw->pos_emul, req_size, &ret, NULL,
-                         &act_size, NULL, false, ds->s);
+                         &act_size, NULL, false, AUDIO_DSOUND(hw->s));
      if (err) {
          dolog("Failed to lock buffer\n");
          *size = 0;
@@ -577,13 +567,12 @@ static void dsound_put_buffer_in(HWVoiceIn *hw, void 
*buf, size_t len)
      hw->pos_emul = (hw->pos_emul + len) % hw->size_emul;
  }
-static void dsound_audio_fini (void *opaque)
+static void audio_dsound_finalize(Object *obj)
  {
+    AudioDsound *s = AUDIO_DSOUND(obj);
      HRESULT hr;
-    dsound *s = opaque;
if (!s->dsound) {
-        g_free(s);
          return;
      }
@@ -594,7 +583,6 @@ static void dsound_audio_fini (void *opaque)
      s->dsound = NULL;
if (!s->dsound_capture) {
-        g_free(s);
          return;
      }
@@ -603,18 +591,21 @@ static void dsound_audio_fini (void *opaque)
          dsound_logerr (hr, "Could not release DirectSoundCapture\n");
      }
      s->dsound_capture = NULL;
-
-    g_free(s);
  }
-static void *dsound_audio_init(Audiodev *dev, Error **errp)
+static bool
+audio_dsound_realize(AudioBackend *abe, Audiodev *dev, Error **errp)
  {
+    AudioDsound *s = AUDIO_DSOUND(abe);
      HRESULT hr;
-    dsound *s = g_new0(dsound, 1);
      AudiodevDsoundOptions *dso;
assert(dev->driver == AUDIODEV_DRIVER_DSOUND);
-    s->dev = dev;
+
+    if (!audio_dsound_parent_class->realize(abe, dev, errp)) {
+        return false;
+    }
+
      dso = &dev->u.dsound;
if (!dso->has_latency) {
@@ -625,8 +616,7 @@ static void *dsound_audio_init(Audiodev *dev, Error **errp)
      hr = CoInitialize (NULL);
      if (FAILED (hr)) {
          dserror_set(errp, hr, "Could not initialize COM");
-        dsound_audio_fini(s);
-        return NULL;
+        return false;
      }
hr = CoCreateInstance (
@@ -638,15 +628,13 @@ static void *dsound_audio_init(Audiodev *dev, Error 
**errp)
          );
      if (FAILED (hr)) {
          dserror_set(errp, hr, "Could not create DirectSound instance");
-        dsound_audio_fini(s);
-        return NULL;
+        return false;
      }
hr = IDirectSound_Initialize (s->dsound, NULL);
      if (FAILED (hr)) {
          dserror_set(errp, hr, "Could not initialize DirectSound");
-        dsound_audio_fini(s);
-        return NULL;
+        return false;
      }
hr = CoCreateInstance (
@@ -658,15 +646,13 @@ static void *dsound_audio_init(Audiodev *dev, Error 
**errp)
          );
      if (FAILED (hr)) {
          dserror_set(errp, hr, "Could not create DirectSoundCapture instance");
-        dsound_audio_fini(s);
-        return NULL;
+        return false;
      }
hr = IDirectSoundCapture_Initialize (s->dsound_capture, NULL);
      if (FAILED(hr)) {
          dserror_set(errp, hr, "Could not initialize DirectSoundCapture");
-        dsound_audio_fini(s);
-        return NULL;
+        return false;
      }
hr = IDirectSound_SetCooperativeLevel (
@@ -676,11 +662,10 @@ static void *dsound_audio_init(Audiodev *dev, Error 
**errp)
      );
      if (FAILED(hr)) {
          dserror_set(errp, hr, "Could not set cooperative level");
-        dsound_audio_fini(s);
-        return NULL;
+        return false;
      }
- return s;
+    return true;
  }
static struct audio_pcm_ops dsound_pcm_ops = {
@@ -702,8 +687,6 @@ static struct audio_pcm_ops dsound_pcm_ops = {
static struct audio_driver dsound_audio_driver = {
      .name           = "dsound",
-    .init           = dsound_audio_init,
-    .fini           = dsound_audio_fini,
      .pcm_ops        = &dsound_pcm_ops,
      .max_voices_out = INT_MAX,
      .max_voices_in  = 1,
@@ -711,11 +694,23 @@ static struct audio_driver dsound_audio_driver = {
      .voice_size_in  = sizeof (DSoundVoiceIn)
  };
+static void audio_dsound_class_init(ObjectClass *klass, const void *data)
+{
+    AudioBackendClass *b = AUDIO_BACKEND_CLASS(klass);
+    AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_CLASS(klass);
+
+    audio_dsound_parent_class = 
AUDIO_BACKEND_CLASS(object_class_get_parent(klass));
+
+    b->realize = audio_dsound_realize;
+    k->driver = &dsound_audio_driver;
+}
+
  static const TypeInfo audio_dsound_info = {
      .name = TYPE_AUDIO_DSOUND,
      .parent = TYPE_AUDIO_MIXENG_BACKEND,
      .instance_size = sizeof(AudioDsound),
      .class_init = audio_dsound_class_init,
+    .instance_finalize = audio_dsound_finalize,
  };
static void register_audio_dsound(void)

Reviewed-by: Mark Cave-Ayland <[email protected]>


ATB,

Mark.


Reply via email to