]> git.proxmox.com Git - qemu.git/blobdiff - audio/dsoundaudio.c
hw/i386/Makefile.obj: use $(PYTHON) to run .py scripts consistently
[qemu.git] / audio / dsoundaudio.c
index 64b84174d19f0a90d95650e0f71d8233eb185413..e2d89fd5d59d13c56cb14d71a99c815896493935 100644 (file)
  * SEAL 1.07 by Carlos 'pel' Hasan was used as documentation
  */
 
-#include "vl.h"
+#include "qemu-common.h"
+#include "audio.h"
 
 #define AUDIO_CAP "dsound"
 #include "audio_int.h"
 
 #include <windows.h>
+#include <mmsystem.h>
 #include <objbase.h>
 #include <dsound.h>
 
-/* #define DEBUG_DSOUND */
+#include "audio_win_int.h"
 
-struct full_fmt {
-    int freq;
-    int nchannels;
-    audfmt_e fmt;
-};
+/* #define DEBUG_DSOUND */
 
 static struct {
     int lock_retries;
@@ -50,28 +48,26 @@ static struct {
     int set_primary;
     int bufsize_in;
     int bufsize_out;
-    struct full_fmt full_fmt;
+    struct audsettings settings;
     int latency_millis;
 } conf = {
-    1,
-    1,
-    1,
-    0,
-    16384,
-    16384,
-    {
-        44100,
-        2,
-        AUD_FMT_S16
-    },
-    10
+    .lock_retries       = 1,
+    .restore_retries    = 1,
+    .getstatus_retries  = 1,
+    .set_primary        = 0,
+    .bufsize_in         = 16384,
+    .bufsize_out        = 16384,
+    .settings.freq      = 44100,
+    .settings.nchannels = 2,
+    .settings.fmt       = AUD_FMT_S16,
+    .latency_millis     = 10
 };
 
 typedef struct {
     LPDIRECTSOUND dsound;
     LPDIRECTSOUNDCAPTURE dsound_capture;
     LPDIRECTSOUNDBUFFER dsound_primary_buffer;
-    struct full_fmt fmt;
+    struct audsettings settings;
 } dsound;
 
 static dsound glob_dsound;
@@ -259,7 +255,7 @@ static void GCC_FMT_ATTR (3, 4) dsound_logerr2 (
 {
     va_list ap;
 
-    AUD_log (AUDIO_CAP, "Can not initialize %s\n", typ);
+    AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
     va_start (ap, fmt);
     AUD_vlog (AUDIO_CAP, fmt, ap);
     va_end (ap);
@@ -301,7 +297,7 @@ static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb)
             continue;
 
         default:
-            dsound_logerr (hr, "Can not restore playback buffer\n");
+            dsound_logerr (hr, "Could not restore playback buffer\n");
             return -1;
         }
     }
@@ -310,98 +306,6 @@ static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb)
     return -1;
 }
 
-static int waveformat_from_full_fmt (WAVEFORMATEX *wfx,
-                                     struct full_fmt *full_fmt)
-{
-    memset (wfx, 0, sizeof (*wfx));
-
-    wfx->wFormatTag = WAVE_FORMAT_PCM;
-    wfx->nChannels = full_fmt->nchannels;
-    wfx->nSamplesPerSec = full_fmt->freq;
-    wfx->nAvgBytesPerSec = full_fmt->freq << (full_fmt->nchannels == 2);
-    wfx->nBlockAlign = 1 << (full_fmt->nchannels == 2);
-    wfx->cbSize = 0;
-
-    switch (full_fmt->fmt) {
-    case AUD_FMT_S8:
-        wfx->wBitsPerSample = 8;
-        break;
-
-    case AUD_FMT_U8:
-        wfx->wBitsPerSample = 8;
-        break;
-
-    case AUD_FMT_S16:
-        wfx->wBitsPerSample = 16;
-        wfx->nAvgBytesPerSec <<= 1;
-        wfx->nBlockAlign <<= 1;
-        break;
-
-    case AUD_FMT_U16:
-        wfx->wBitsPerSample = 16;
-        wfx->nAvgBytesPerSec <<= 1;
-        wfx->nBlockAlign <<= 1;
-        break;
-
-    default:
-        dolog ("Internal logic error: Bad audio format %d\n",
-               full_fmt->freq);
-        return -1;
-    }
-
-    return 0;
-}
-
-static int waveformat_to_full_fmt (WAVEFORMATEX *wfx,
-                                   struct full_fmt *full_fmt)
-{
-    if (wfx->wFormatTag != WAVE_FORMAT_PCM) {
-        dolog ("Invalid wave format, tag is not PCM, but %d\n",
-               wfx->wFormatTag);
-        return -1;
-    }
-
-    if (!wfx->nSamplesPerSec) {
-        dolog ("Invalid wave format, frequency is zero\n");
-        return -1;
-    }
-    full_fmt->freq = wfx->nSamplesPerSec;
-
-    switch (wfx->nChannels) {
-    case 1:
-        full_fmt->nchannels = 1;
-        break;
-
-    case 2:
-        full_fmt->nchannels = 2;
-        break;
-
-    default:
-        dolog (
-            "Invalid wave format, number of channels is not 1 or 2, but %d\n",
-            wfx->nChannels
-            );
-        return -1;
-    }
-
-    switch (wfx->wBitsPerSample) {
-    case 8:
-        full_fmt->fmt = AUD_FMT_U8;
-        break;
-
-    case 16:
-        full_fmt->fmt = AUD_FMT_S16;
-        break;
-
-    default:
-        dolog ("Invalid wave format, bits per sample is not 8 or 16, but %d\n",
-               wfx->wBitsPerSample);
-        return -1;
-    }
-
-    return 0;
-}
-
 #include "dsound_template.h"
 #define DSBTYPE_IN
 #include "dsound_template.h"
@@ -415,7 +319,7 @@ static int dsound_get_status_out (LPDIRECTSOUNDBUFFER dsb, DWORD *statusp)
     for (i = 0; i < conf.getstatus_retries; ++i) {
         hr = IDirectSoundBuffer_GetStatus (dsb, statusp);
         if (FAILED (hr)) {
-            dsound_logerr (hr, "Can not get playback buffer status\n");
+            dsound_logerr (hr, "Could not get playback buffer status\n");
             return -1;
         }
 
@@ -438,7 +342,7 @@ static int dsound_get_status_in (LPDIRECTSOUNDCAPTUREBUFFER dscb,
 
     hr = IDirectSoundCaptureBuffer_GetStatus (dscb, statusp);
     if (FAILED (hr)) {
-        dsound_logerr (hr, "Can not get capture buffer status\n");
+        dsound_logerr (hr, "Could not get capture buffer status\n");
         return -1;
     }
 
@@ -450,8 +354,8 @@ static void dsound_write_sample (HWVoiceOut *hw, uint8_t *dst, int dst_len)
     int src_len1 = dst_len;
     int src_len2 = 0;
     int pos = hw->rpos + dst_len;
-    st_sample_t *src1 = hw->mix_buf + hw->rpos;
-    st_sample_t *src2 = NULL;
+    struct st_sample *src1 = hw->mix_buf + hw->rpos;
+    struct st_sample *src2 = NULL;
 
     if (pos > hw->samples) {
         src_len1 = hw->samples - hw->rpos;
@@ -462,13 +366,11 @@ static void dsound_write_sample (HWVoiceOut *hw, uint8_t *dst, int dst_len)
 
     if (src_len1) {
         hw->clip (dst, src1, src_len1);
-        mixeng_clear (src1, src_len1);
     }
 
     if (src_len2) {
         dst = advance (dst, src_len1 << hw->info.shift);
         hw->clip (dst, src2, src_len2);
-        mixeng_clear (src2, src_len2);
     }
 
     hw->rpos = pos % hw->samples;
@@ -520,7 +422,7 @@ static void dsound_close (dsound *s)
     if (s->dsound_primary_buffer) {
         hr = IDirectSoundBuffer_Release (s->dsound_primary_buffer);
         if (FAILED (hr)) {
-            dsound_logerr (hr, "Can not release primary buffer\n");
+            dsound_logerr (hr, "Could not release primary buffer\n");
         }
         s->dsound_primary_buffer = NULL;
     }
@@ -542,7 +444,7 @@ static int dsound_open (dsound *s)
         );
 
     if (FAILED (hr)) {
-        dsound_logerr (hr, "Can not set cooperative level for window %p\n",
+        dsound_logerr (hr, "Could not set cooperative level for window %p\n",
                        hwnd);
         return -1;
     }
@@ -551,7 +453,7 @@ static int dsound_open (dsound *s)
         return 0;
     }
 
-    err = waveformat_from_full_fmt (&wfx, &conf.full_fmt);
+    err = waveformat_from_audio_settings (&wfx, &conf.settings);
     if (err) {
         return -1;
     }
@@ -569,13 +471,13 @@ static int dsound_open (dsound *s)
         NULL
         );
     if (FAILED (hr)) {
-        dsound_logerr (hr, "Can not create primary playback buffer\n");
+        dsound_logerr (hr, "Could not create primary playback buffer\n");
         return -1;
     }
 
     hr = IDirectSoundBuffer_SetFormat (s->dsound_primary_buffer, &wfx);
     if (FAILED (hr)) {
-        dsound_logerr (hr, "Can not set primary playback buffer format\n");
+        dsound_logerr (hr, "Could not set primary playback buffer format\n");
     }
 
     hr = IDirectSoundBuffer_GetFormat (
@@ -585,7 +487,7 @@ static int dsound_open (dsound *s)
         NULL
         );
     if (FAILED (hr)) {
-        dsound_logerr (hr, "Can not get primary playback buffer format\n");
+        dsound_logerr (hr, "Could not get primary playback buffer format\n");
         goto fail0;
     }
 
@@ -594,7 +496,7 @@ static int dsound_open (dsound *s)
     print_wave_format (&wfx);
 #endif
 
-    err = waveformat_to_full_fmt (&wfx, &s->fmt);
+    err = waveformat_to_audio_settings (&wfx, &s->settings);
     if (err) {
         goto fail0;
     }
@@ -625,7 +527,7 @@ static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...)
         }
 
         if (status & DSBSTATUS_PLAYING) {
-            dolog ("warning: voice is already playing\n");
+            dolog ("warning: Voice is already playing\n");
             return 0;
         }
 
@@ -633,7 +535,7 @@ static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...)
 
         hr = IDirectSoundBuffer_Play (dsb, 0, 0, DSBPLAY_LOOPING);
         if (FAILED (hr)) {
-            dsound_logerr (hr, "Can not start playing buffer\n");
+            dsound_logerr (hr, "Could not start playing buffer\n");
             return -1;
         }
         break;
@@ -646,12 +548,12 @@ static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...)
         if (status & DSBSTATUS_PLAYING) {
             hr = IDirectSoundBuffer_Stop (dsb);
             if (FAILED (hr)) {
-                dsound_logerr (hr, "Can not stop playing buffer\n");
+                dsound_logerr (hr, "Could not stop playing buffer\n");
                 return -1;
             }
         }
         else {
-            dolog ("warning: voice is not playing\n");
+            dolog ("warning: Voice is not playing\n");
         }
         break;
     }
@@ -663,18 +565,19 @@ static int dsound_write (SWVoiceOut *sw, void *buf, int len)
     return audio_pcm_sw_write (sw, buf, len);
 }
 
-static int dsound_run_out (HWVoiceOut *hw)
+static int dsound_run_out (HWVoiceOut *hw, int live)
 {
     int err;
     HRESULT hr;
     DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
     LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer;
-    int live, len, hwshift;
+    int len, hwshift;
     DWORD blen1, blen2;
     DWORD len1, len2;
     DWORD decr;
     DWORD wpos, ppos, old_pos;
     LPVOID p1, p2;
+    int bufsize;
 
     if (!dsb) {
         dolog ("Attempt to run empty with playback buffer\n");
@@ -682,8 +585,7 @@ static int dsound_run_out (HWVoiceOut *hw)
     }
 
     hwshift = hw->info.shift;
-
-    live = audio_pcm_hw_get_live_out (hw);
+    bufsize = hw->samples << hwshift;
 
     hr = IDirectSoundBuffer_GetCurrentPosition (
         dsb,
@@ -691,7 +593,7 @@ static int dsound_run_out (HWVoiceOut *hw)
         ds->first_time ? &wpos : NULL
         );
     if (FAILED (hr)) {
-        dsound_logerr (hr, "Can not get playback buffer position\n");
+        dsound_logerr (hr, "Could not get playback buffer position\n");
         return 0;
     }
 
@@ -699,13 +601,14 @@ static int dsound_run_out (HWVoiceOut *hw)
 
     if (ds->first_time) {
         if (conf.latency_millis) {
-            DWORD cur_blat = audio_ring_dist (wpos, ppos, hw->bufsize);
+            DWORD cur_blat;
 
+            cur_blat = audio_ring_dist (wpos, ppos, bufsize);
             ds->first_time = 0;
             old_pos = wpos;
             old_pos +=
                 millis_to_bytes (&hw->info, conf.latency_millis) - cur_blat;
-            old_pos %= hw->bufsize;
+            old_pos %= bufsize;
             old_pos &= ~hw->info.align;
         }
         else {
@@ -734,14 +637,14 @@ static int dsound_run_out (HWVoiceOut *hw)
         len = ppos - old_pos;
     }
     else {
-        if ((old_pos > ppos) && ((old_pos + len) > (ppos + hw->bufsize))) {
-            len = hw->bufsize - old_pos + ppos;
+        if ((old_pos > ppos) && ((old_pos + len) > (ppos + bufsize))) {
+            len = bufsize - old_pos + ppos;
         }
     }
 
-    if (audio_bug (AUDIO_FUNC, len < 0 || len > hw->bufsize)) {
-        dolog ("len=%d hw->bufsize=%d old_pos=%ld ppos=%ld\n",
-               len, hw->bufsize, old_pos, ppos);
+    if (audio_bug (AUDIO_FUNC, len < 0 || len > bufsize)) {
+        dolog ("len=%d bufsize=%d old_pos=%ld ppos=%ld\n",
+               len, bufsize, old_pos, ppos);
         return 0;
     }
 
@@ -779,7 +682,7 @@ static int dsound_run_out (HWVoiceOut *hw)
     }
 
     dsound_unlock_out (dsb, p1, p2, blen1, blen2);
-    ds->old_pos = (old_pos + (decr << hwshift)) % hw->bufsize;
+    ds->old_pos = (old_pos + (decr << hwshift)) % bufsize;
 
 #ifdef DEBUG_DSOUND
     ds->mixed += decr << hwshift;
@@ -812,7 +715,7 @@ static int dsound_ctl_in (HWVoiceIn *hw, int cmd, ...)
         }
 
         if (status & DSCBSTATUS_CAPTURING) {
-            dolog ("warning: voice is already capturing\n");
+            dolog ("warning: Voice is already capturing\n");
             return 0;
         }
 
@@ -820,7 +723,7 @@ static int dsound_ctl_in (HWVoiceIn *hw, int cmd, ...)
 
         hr = IDirectSoundCaptureBuffer_Start (dscb, DSCBSTART_LOOPING);
         if (FAILED (hr)) {
-            dsound_logerr (hr, "Can not start capturing\n");
+            dsound_logerr (hr, "Could not start capturing\n");
             return -1;
         }
         break;
@@ -833,12 +736,12 @@ static int dsound_ctl_in (HWVoiceIn *hw, int cmd, ...)
         if (status & DSCBSTATUS_CAPTURING) {
             hr = IDirectSoundCaptureBuffer_Stop (dscb);
             if (FAILED (hr)) {
-                dsound_logerr (hr, "Can not stop capturing\n");
+                dsound_logerr (hr, "Could not stop capturing\n");
                 return -1;
             }
         }
         else {
-            dolog ("warning: voice is not capturing\n");
+            dolog ("warning: Voice is not capturing\n");
         }
         break;
     }
@@ -883,21 +786,21 @@ static int dsound_run_in (HWVoiceIn *hw)
         ds->first_time ? &rpos : NULL
         );
     if (FAILED (hr)) {
-        dsound_logerr (hr, "Can not get capture buffer position\n");
+        dsound_logerr (hr, "Could not get capture buffer position\n");
         return 0;
     }
 
     if (ds->first_time) {
         ds->first_time = 0;
         if (rpos & hw->info.align) {
-            ldebug ("warning: misaligned capture read position %ld(%d)\n",
+            ldebug ("warning: Misaligned capture read position %ld(%d)\n",
                     rpos, hw->info.align);
         }
         hw->wpos = rpos >> hwshift;
     }
 
     if (cpos & hw->info.align) {
-        ldebug ("warning: misaligned capture position %ld(%d)\n",
+        ldebug ("warning: Misaligned capture position %ld(%d)\n",
                 cpos, hw->info.align);
     }
     cpos >>= hwshift;
@@ -928,11 +831,11 @@ static int dsound_run_in (HWVoiceIn *hw)
     decr = len1 + len2;
 
     if (p1 && len1) {
-        hw->conv (hw->conv_buf + hw->wpos, p1, len1, &nominal_volume);
+        hw->conv (hw->conv_buf + hw->wpos, p1, len1);
     }
 
     if (p2 && len2) {
-        hw->conv (hw->conv_buf, p2, len2, &nominal_volume);
+        hw->conv (hw->conv_buf, p2, len2);
     }
 
     dsound_unlock_in (dscb, p1, p2, blen1, blen2);
@@ -951,7 +854,7 @@ static void dsound_audio_fini (void *opaque)
 
     hr = IDirectSound_Release (s->dsound);
     if (FAILED (hr)) {
-        dsound_logerr (hr, "Can not release DirectSound\n");
+        dsound_logerr (hr, "Could not release DirectSound\n");
     }
     s->dsound = NULL;
 
@@ -961,7 +864,7 @@ static void dsound_audio_fini (void *opaque)
 
     hr = IDirectSoundCapture_Release (s->dsound_capture);
     if (FAILED (hr)) {
-        dsound_logerr (hr, "Can not release DirectSoundCapture\n");
+        dsound_logerr (hr, "Could not release DirectSoundCapture\n");
     }
     s->dsound_capture = NULL;
 }
@@ -974,7 +877,7 @@ static void *dsound_audio_init (void)
 
     hr = CoInitialize (NULL);
     if (FAILED (hr)) {
-        dsound_logerr (hr, "Can not initialize COM\n");
+        dsound_logerr (hr, "Could not initialize COM\n");
         return NULL;
     }
 
@@ -986,13 +889,19 @@ static void *dsound_audio_init (void)
         (void **) &s->dsound
         );
     if (FAILED (hr)) {
-        dsound_logerr (hr, "Can not create DirectSound instance\n");
+        dsound_logerr (hr, "Could not create DirectSound instance\n");
         return NULL;
     }
 
     hr = IDirectSound_Initialize (s->dsound, NULL);
     if (FAILED (hr)) {
-        dsound_logerr (hr, "Can not initialize DirectSound\n");
+        dsound_logerr (hr, "Could not initialize DirectSound\n");
+
+        hr = IDirectSound_Release (s->dsound);
+        if (FAILED (hr)) {
+            dsound_logerr (hr, "Could not release DirectSound\n");
+        }
+        s->dsound = NULL;
         return NULL;
     }
 
@@ -1004,16 +913,16 @@ static void *dsound_audio_init (void)
         (void **) &s->dsound_capture
         );
     if (FAILED (hr)) {
-        dsound_logerr (hr, "Can not create DirectSoundCapture instance\n");
+        dsound_logerr (hr, "Could not create DirectSoundCapture instance\n");
     }
     else {
         hr = IDirectSoundCapture_Initialize (s->dsound_capture, NULL);
         if (FAILED (hr)) {
-            dsound_logerr (hr, "Can not initialize DirectSoundCapture\n");
+            dsound_logerr (hr, "Could not initialize DirectSoundCapture\n");
 
             hr = IDirectSoundCapture_Release (s->dsound_capture);
             if (FAILED (hr)) {
-                dsound_logerr (hr, "Can not release DirectSoundCapture\n");
+                dsound_logerr (hr, "Could not release DirectSoundCapture\n");
             }
             s->dsound_capture = NULL;
         }
@@ -1029,54 +938,93 @@ static void *dsound_audio_init (void)
 }
 
 static struct audio_option dsound_options[] = {
-    {"LOCK_RETRIES", AUD_OPT_INT, &conf.lock_retries,
-     "Number of times to attempt locking the buffer", NULL, 0},
-    {"RESTOURE_RETRIES", AUD_OPT_INT, &conf.restore_retries,
-     "Number of times to attempt restoring the buffer", NULL, 0},
-    {"GETSTATUS_RETRIES", AUD_OPT_INT, &conf.getstatus_retries,
-     "Number of times to attempt getting status of the buffer", NULL, 0},
-    {"SET_PRIMARY", AUD_OPT_BOOL, &conf.set_primary,
-     "Set the parameters of primary buffer", NULL, 0},
-    {"LATENCY_MILLIS", AUD_OPT_INT, &conf.latency_millis,
-     "(undocumented)", NULL, 0},
-    {"PRIMARY_FREQ", AUD_OPT_INT, &conf.full_fmt.freq,
-     "Primary buffer frequency", NULL, 0},
-    {"PRIMARY_CHANNELS", AUD_OPT_INT, &conf.full_fmt.nchannels,
-     "Primary buffer number of channels (1 - mono, 2 - stereo)", NULL, 0},
-    {"PRIMARY_FMT", AUD_OPT_FMT, &conf.full_fmt.fmt,
-     "Primary buffer format", NULL, 0},
-    {"BUFSIZE_OUT", AUD_OPT_INT, &conf.bufsize_out,
-     "(undocumented)", NULL, 0},
-    {"BUFSIZE_IN", AUD_OPT_INT, &conf.bufsize_in,
-     "(undocumented)", NULL, 0},
-    {NULL, 0, NULL, NULL, NULL, 0}
+    {
+        .name  = "LOCK_RETRIES",
+        .tag   = AUD_OPT_INT,
+        .valp  = &conf.lock_retries,
+        .descr = "Number of times to attempt locking the buffer"
+    },
+    {
+        .name  = "RESTOURE_RETRIES",
+        .tag   = AUD_OPT_INT,
+        .valp  = &conf.restore_retries,
+        .descr = "Number of times to attempt restoring the buffer"
+    },
+    {
+        .name  = "GETSTATUS_RETRIES",
+        .tag   = AUD_OPT_INT,
+        .valp  = &conf.getstatus_retries,
+        .descr = "Number of times to attempt getting status of the buffer"
+    },
+    {
+        .name  = "SET_PRIMARY",
+        .tag   = AUD_OPT_BOOL,
+        .valp  = &conf.set_primary,
+        .descr = "Set the parameters of primary buffer"
+    },
+    {
+        .name  = "LATENCY_MILLIS",
+        .tag   = AUD_OPT_INT,
+        .valp  = &conf.latency_millis,
+        .descr = "(undocumented)"
+    },
+    {
+        .name  = "PRIMARY_FREQ",
+        .tag   = AUD_OPT_INT,
+        .valp  = &conf.settings.freq,
+        .descr = "Primary buffer frequency"
+    },
+    {
+        .name  = "PRIMARY_CHANNELS",
+        .tag   = AUD_OPT_INT,
+        .valp  = &conf.settings.nchannels,
+        .descr = "Primary buffer number of channels (1 - mono, 2 - stereo)"
+    },
+    {
+        .name  = "PRIMARY_FMT",
+        .tag   = AUD_OPT_FMT,
+        .valp  = &conf.settings.fmt,
+        .descr = "Primary buffer format"
+    },
+    {
+        .name  = "BUFSIZE_OUT",
+        .tag   = AUD_OPT_INT,
+        .valp  = &conf.bufsize_out,
+        .descr = "(undocumented)"
+    },
+    {
+        .name  = "BUFSIZE_IN",
+        .tag   = AUD_OPT_INT,
+        .valp  = &conf.bufsize_in,
+        .descr = "(undocumented)"
+    },
+    { /* End of list */ }
 };
 
 static struct audio_pcm_ops dsound_pcm_ops = {
-    dsound_init_out,
-    dsound_fini_out,
-    dsound_run_out,
-    dsound_write,
-    dsound_ctl_out,
-
-    dsound_init_in,
-    dsound_fini_in,
-    dsound_run_in,
-    dsound_read,
-    dsound_ctl_in
+    .init_out = dsound_init_out,
+    .fini_out = dsound_fini_out,
+    .run_out  = dsound_run_out,
+    .write    = dsound_write,
+    .ctl_out  = dsound_ctl_out,
+
+    .init_in  = dsound_init_in,
+    .fini_in  = dsound_fini_in,
+    .run_in   = dsound_run_in,
+    .read     = dsound_read,
+    .ctl_in   = dsound_ctl_in
 };
 
 struct audio_driver dsound_audio_driver = {
-    INIT_FIELD (name           = ) "dsound",
-    INIT_FIELD (descr          = )
-    "DirectSound http://wikipedia.org/wiki/DirectSound",
-    INIT_FIELD (options        = ) dsound_options,
-    INIT_FIELD (init           = ) dsound_audio_init,
-    INIT_FIELD (fini           = ) dsound_audio_fini,
-    INIT_FIELD (pcm_ops        = ) &dsound_pcm_ops,
-    INIT_FIELD (can_be_default = ) 1,
-    INIT_FIELD (max_voices_out = ) INT_MAX,
-    INIT_FIELD (max_voices_in  = ) 1,
-    INIT_FIELD (voice_size_out = ) sizeof (DSoundVoiceOut),
-    INIT_FIELD (voice_size_in  = ) sizeof (DSoundVoiceIn)
+    .name           = "dsound",
+    .descr          = "DirectSound http://wikipedia.org/wiki/DirectSound",
+    .options        = dsound_options,
+    .init           = dsound_audio_init,
+    .fini           = dsound_audio_fini,
+    .pcm_ops        = &dsound_pcm_ops,
+    .can_be_default = 1,
+    .max_voices_out = INT_MAX,
+    .max_voices_in  = 1,
+    .voice_size_out = sizeof (DSoundVoiceOut),
+    .voice_size_in  = sizeof (DSoundVoiceIn)
 };