diff --git a/audio/dsound_template.h b/audio/dsound_template.h
index 98276fb..85ba858 100644
--- a/audio/dsound_template.h
+++ b/audio/dsound_template.h
@@ -67,7 +67,8 @@ static int glue (dsound_lock_, TYPE) (
     LPVOID *p2p,
     DWORD *blen1p,
     DWORD *blen2p,
-    int entire
+    int entire,
+    dsound *s
     )
 {
     HRESULT hr;
@@ -75,13 +76,14 @@ static int glue (dsound_lock_, TYPE) (
     LPVOID p1 = NULL, p2 = NULL;
     DWORD blen1 = 0, blen2 = 0;
     DWORD flag;
+    DSoundConf *conf = &s->conf;
 
 #ifdef DSBTYPE_IN
     flag = entire ? DSCBLOCK_ENTIREBUFFER : 0;
 #else
     flag = entire ? DSBLOCK_ENTIREBUFFER : 0;
 #endif
-    for (i = 0; i < conf.lock_retries; ++i) {
+    for (i = 0; i < conf->lock_retries; ++i) {
         hr = glue (IFACE, _Lock) (
             buf,
             pos,
@@ -96,7 +98,7 @@ static int glue (dsound_lock_, TYPE) (
         if (FAILED (hr)) {
 #ifndef DSBTYPE_IN
             if (hr == DSERR_BUFFERLOST) {
-                if (glue (dsound_restore_, TYPE) (buf)) {
+                if (glue (dsound_restore_, TYPE) (buf, s)) {
                     dsound_logerr (hr, "Could not lock " NAME "\n");
                     goto fail;
                 }
@@ -110,7 +112,7 @@ static int glue (dsound_lock_, TYPE) (
         break;
     }
 
-    if (i == conf.lock_retries) {
+    if (i == conf->lock_retries) {
         dolog ("%d attempts to lock " NAME " failed\n", i);
         goto fail;
     }
@@ -183,9 +185,10 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
 {
     int err;
     HRESULT hr;
-    dsound *s = &glob_dsound;
+    dsound *s = drv_opaque;
     WAVEFORMATEX wfx;
     struct audsettings obt_as;
+    DSoundConf *conf = &s->conf;
 #ifdef DSBTYPE_IN
     const char *typ = "ADC";
     DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
@@ -212,7 +215,7 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
     bd.dwSize = sizeof (bd);
     bd.lpwfxFormat = &wfx;
 #ifdef DSBTYPE_IN
-    bd.dwBufferBytes = conf.bufsize_in;
+    bd.dwBufferBytes = conf->bufsize_in;
     hr = IDirectSoundCapture_CreateCaptureBuffer (
         s->dsound_capture,
         &bd,
@@ -221,7 +224,7 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
         );
 #else
     bd.dwFlags = DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2;
-    bd.dwBufferBytes = conf.bufsize_out;
+    bd.dwBufferBytes = conf->bufsize_out;
     hr = IDirectSound_CreateSoundBuffer (
         s->dsound,
         &bd,
@@ -271,6 +274,7 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
             );
     }
     hw->samples = bc.dwBufferBytes >> hw->info.shift;
+    ds->s = s;
 
 #ifdef DEBUG_DSOUND
     dolog ("caps %ld, desc %ld\n",
diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c
index e2d89fd..c8b09e2 100644
--- a/audio/dsoundaudio.c
+++ b/audio/dsoundaudio.c
@@ -41,7 +41,7 @@
 
 /* #define DEBUG_DSOUND */
 
-static struct {
+typedef struct {
     int lock_retries;
     int restore_retries;
     int getstatus_retries;
@@ -50,33 +50,22 @@ static struct {
     int bufsize_out;
     struct audsettings settings;
     int latency_millis;
-} conf = {
-    .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
-};
+} DSoundConf;
 
 typedef struct {
     LPDIRECTSOUND dsound;
     LPDIRECTSOUNDCAPTURE dsound_capture;
     LPDIRECTSOUNDBUFFER dsound_primary_buffer;
     struct audsettings settings;
+    DSoundConf conf;
 } dsound;
 
-static dsound glob_dsound;
-
 typedef struct {
     HWVoiceOut hw;
     LPDIRECTSOUNDBUFFER dsound_buffer;
     DWORD old_pos;
     int first_time;
+    dsound *s;
 #ifdef DEBUG_DSOUND
     DWORD old_ppos;
     DWORD played;
@@ -88,6 +77,7 @@ typedef struct {
     HWVoiceIn hw;
     int first_time;
     LPDIRECTSOUNDCAPTUREBUFFER dsound_capture_buffer;
+    dsound *s;
 } DSoundVoiceIn;
 
 static void dsound_log_hresult (HRESULT hr)
@@ -281,12 +271,12 @@ static void print_wave_format (WAVEFORMATEX *wfx)
 }
 #endif
 
-static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb)
+static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb, dsound *s)
 {
     HRESULT hr;
     int i;
 
-    for (i = 0; i < conf.restore_retries; ++i) {
+    for (i = 0; i < s->conf.restore_retries; ++i) {
         hr = IDirectSoundBuffer_Restore (dsb);
 
         switch (hr) {
@@ -311,12 +301,13 @@ static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb)
 #include "dsound_template.h"
 #undef DSBTYPE_IN
 
-static int dsound_get_status_out (LPDIRECTSOUNDBUFFER dsb, DWORD *statusp)
+static int dsound_get_status_out (LPDIRECTSOUNDBUFFER dsb, DWORD *statusp,
+                                  dsound *s)
 {
     HRESULT hr;
     int i;
 
-    for (i = 0; i < conf.getstatus_retries; ++i) {
+    for (i = 0; i < s->conf.getstatus_retries; ++i) {
         hr = IDirectSoundBuffer_GetStatus (dsb, statusp);
         if (FAILED (hr)) {
             dsound_logerr (hr, "Could not get playback buffer status\n");
@@ -324,7 +315,7 @@ static int dsound_get_status_out (LPDIRECTSOUNDBUFFER dsb, DWORD *statusp)
         }
 
         if (*statusp & DSERR_BUFFERLOST) {
-            if (dsound_restore_out (dsb)) {
+            if (dsound_restore_out (dsb, s)) {
                 return -1;
             }
             continue;
@@ -376,7 +367,8 @@ static void dsound_write_sample (HWVoiceOut *hw, uint8_t *dst, int dst_len)
     hw->rpos = pos % hw->samples;
 }
 
-static void dsound_clear_sample (HWVoiceOut *hw, LPDIRECTSOUNDBUFFER dsb)
+static void dsound_clear_sample (HWVoiceOut *hw, LPDIRECTSOUNDBUFFER dsb,
+                                 dsound *s)
 {
     int err;
     LPVOID p1, p2;
@@ -389,7 +381,8 @@ static void dsound_clear_sample (HWVoiceOut *hw, LPDIRECTSOUNDBUFFER dsb)
         hw->samples << hw->info.shift,
         &p1, &p2,
         &blen1, &blen2,
-        1
+        1,
+        s
         );
     if (err) {
         return;
@@ -435,6 +428,7 @@ static int dsound_open (dsound *s)
     WAVEFORMATEX wfx;
     DSBUFFERDESC dsbd;
     HWND hwnd;
+    DSoundConf *conf = &s->conf;
 
     hwnd = GetForegroundWindow ();
     hr = IDirectSound_SetCooperativeLevel (
@@ -449,11 +443,11 @@ static int dsound_open (dsound *s)
         return -1;
     }
 
-    if (!conf.set_primary) {
+    if (!conf->set_primary) {
         return 0;
     }
 
-    err = waveformat_from_audio_settings (&wfx, &conf.settings);
+    err = waveformat_from_audio_settings (&wfx, &conf->settings);
     if (err) {
         return -1;
     }
@@ -514,6 +508,7 @@ static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...)
     DWORD status;
     DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
     LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer;
+    dsound *s = ds->s;
 
     if (!dsb) {
         dolog ("Attempt to control voice without a buffer\n");
@@ -522,7 +517,7 @@ static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...)
 
     switch (cmd) {
     case VOICE_ENABLE:
-        if (dsound_get_status_out (dsb, &status)) {
+        if (dsound_get_status_out (dsb, &status, s)) {
             return -1;
         }
 
@@ -531,7 +526,7 @@ static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...)
             return 0;
         }
 
-        dsound_clear_sample (hw, dsb);
+        dsound_clear_sample (hw, dsb, s);
 
         hr = IDirectSoundBuffer_Play (dsb, 0, 0, DSBPLAY_LOOPING);
         if (FAILED (hr)) {
@@ -541,7 +536,7 @@ static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...)
         break;
 
     case VOICE_DISABLE:
-        if (dsound_get_status_out (dsb, &status)) {
+        if (dsound_get_status_out (dsb, &status, s)) {
             return -1;
         }
 
@@ -578,6 +573,8 @@ static int dsound_run_out (HWVoiceOut *hw, int live)
     DWORD wpos, ppos, old_pos;
     LPVOID p1, p2;
     int bufsize;
+    dsound *s = ds->s;
+    DSoundConf *conf = &s->conf;
 
     if (!dsb) {
         dolog ("Attempt to run empty with playback buffer\n");
@@ -600,14 +597,14 @@ static int dsound_run_out (HWVoiceOut *hw, int live)
     len = live << hwshift;
 
     if (ds->first_time) {
-        if (conf.latency_millis) {
+        if (conf->latency_millis) {
             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;
+                millis_to_bytes (&hw->info, conf->latency_millis) - cur_blat;
             old_pos %= bufsize;
             old_pos &= ~hw->info.align;
         }
@@ -663,7 +660,8 @@ static int dsound_run_out (HWVoiceOut *hw, int live)
         len,
         &p1, &p2,
         &blen1, &blen2,
-        0
+        0,
+        s
         );
     if (err) {
         return 0;
@@ -766,6 +764,7 @@ static int dsound_run_in (HWVoiceIn *hw)
     DWORD cpos, rpos;
     LPVOID p1, p2;
     int hwshift;
+    dsound *s = ds->s;
 
     if (!dscb) {
         dolog ("Attempt to run without capture buffer\n");
@@ -820,7 +819,8 @@ static int dsound_run_in (HWVoiceIn *hw)
         &p2,
         &blen1,
         &blen2,
-        0
+        0,
+        s
         );
     if (err) {
         return 0;
@@ -843,12 +843,26 @@ static int dsound_run_in (HWVoiceIn *hw)
     return decr;
 }
 
+static DSoundConf glob_conf = {
+    .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
+};
+
 static void dsound_audio_fini (void *opaque)
 {
     HRESULT hr;
     dsound *s = opaque;
 
     if (!s->dsound) {
+        g_free(s);
         return;
     }
 
@@ -859,6 +873,7 @@ static void dsound_audio_fini (void *opaque)
     s->dsound = NULL;
 
     if (!s->dsound_capture) {
+        g_free(s);
         return;
     }
 
@@ -867,17 +882,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 (void)
 {
     int err;
     HRESULT hr;
-    dsound *s = &glob_dsound;
+    dsound *s = g_malloc0(sizeof(dsound));
 
+    s->conf = glob_conf;
     hr = CoInitialize (NULL);
     if (FAILED (hr)) {
         dsound_logerr (hr, "Could not initialize COM\n");
+        g_free(s);
         return NULL;
     }
 
@@ -890,6 +909,7 @@ static void *dsound_audio_init (void)
         );
     if (FAILED (hr)) {
         dsound_logerr (hr, "Could not create DirectSound instance\n");
+        g_free(s);
         return NULL;
     }
 
@@ -901,7 +921,7 @@ static void *dsound_audio_init (void)
         if (FAILED (hr)) {
             dsound_logerr (hr, "Could not release DirectSound\n");
         }
-        s->dsound = NULL;
+        g_free(s);
         return NULL;
     }
 
@@ -941,61 +961,61 @@ static struct audio_option dsound_options[] = {
     {
         .name  = "LOCK_RETRIES",
         .tag   = AUD_OPT_INT,
-        .valp  = &conf.lock_retries,
+        .valp  = &glob_conf.lock_retries,
         .descr = "Number of times to attempt locking the buffer"
     },
     {
         .name  = "RESTOURE_RETRIES",
         .tag   = AUD_OPT_INT,
-        .valp  = &conf.restore_retries,
+        .valp  = &glob_conf.restore_retries,
         .descr = "Number of times to attempt restoring the buffer"
     },
     {
         .name  = "GETSTATUS_RETRIES",
         .tag   = AUD_OPT_INT,
-        .valp  = &conf.getstatus_retries,
+        .valp  = &glob_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,
+        .valp  = &glob_conf.set_primary,
         .descr = "Set the parameters of primary buffer"
     },
     {
         .name  = "LATENCY_MILLIS",
         .tag   = AUD_OPT_INT,
-        .valp  = &conf.latency_millis,
+        .valp  = &glob_conf.latency_millis,
         .descr = "(undocumented)"
     },
     {
         .name  = "PRIMARY_FREQ",
         .tag   = AUD_OPT_INT,
-        .valp  = &conf.settings.freq,
+        .valp  = &glob_conf.settings.freq,
         .descr = "Primary buffer frequency"
     },
     {
         .name  = "PRIMARY_CHANNELS",
         .tag   = AUD_OPT_INT,
-        .valp  = &conf.settings.nchannels,
+        .valp  = &glob_conf.settings.nchannels,
         .descr = "Primary buffer number of channels (1 - mono, 2 - stereo)"
     },
     {
         .name  = "PRIMARY_FMT",
         .tag   = AUD_OPT_FMT,
-        .valp  = &conf.settings.fmt,
+        .valp  = &glob_conf.settings.fmt,
         .descr = "Primary buffer format"
     },
     {
         .name  = "BUFSIZE_OUT",
         .tag   = AUD_OPT_INT,
-        .valp  = &conf.bufsize_out,
+        .valp  = &glob_conf.bufsize_out,
         .descr = "(undocumented)"
     },
     {
         .name  = "BUFSIZE_IN",
         .tag   = AUD_OPT_INT,
-        .valp  = &conf.bufsize_in,
+        .valp  = &glob_conf.bufsize_in,
         .descr = "(undocumented)"
     },
     { /* End of list */ }
