summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS1
-rw-r--r--audio/Makefile.objs4
-rw-r--r--audio/alsaaudio.c179
-rw-r--r--audio/audio.c35
-rw-r--r--audio/audio_int.h7
-rw-r--r--audio/audio_template.h43
-rw-r--r--audio/coreaudio.c46
-rw-r--r--audio/dsound_template.h51
-rw-r--r--audio/dsoundaudio.c238
-rw-r--r--audio/esdaudio.c557
-rw-r--r--audio/fmodaudio.c685
-rw-r--r--audio/noaudio.c4
-rw-r--r--audio/ossaudio.c126
-rw-r--r--audio/paaudio.c105
-rw-r--r--audio/sdlaudio.c10
-rw-r--r--audio/spiceaudio.c5
-rw-r--r--audio/wavaudio.c42
-rw-r--r--audio/winwaveaudio.c717
-rwxr-xr-xconfigure68
-rw-r--r--include/monitor/monitor.h1
-rw-r--r--monitor.c4
-rw-r--r--trace-events16
22 files changed, 382 insertions, 2562 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index e728d3a1d2..7ba2079c35 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -770,7 +770,6 @@ F: hw/net/rocker/
 Subsystems
 ----------
 Audio
-M: Vassili Karpov (malc) <av1474@comtv.ru>
 M: Gerd Hoffmann <kraxel@redhat.com>
 S: Maintained
 F: audio/
diff --git a/audio/Makefile.objs b/audio/Makefile.objs
index 26a0ac9507..481d1aa30e 100644
--- a/audio/Makefile.objs
+++ b/audio/Makefile.objs
@@ -5,13 +5,9 @@ common-obj-$(CONFIG_SPICE) += spiceaudio.o
 common-obj-$(CONFIG_COREAUDIO) += coreaudio.o
 common-obj-$(CONFIG_ALSA) += alsaaudio.o
 common-obj-$(CONFIG_DSOUND) += dsoundaudio.o
-common-obj-$(CONFIG_FMOD) += fmodaudio.o
-common-obj-$(CONFIG_ESD) += esdaudio.o
 common-obj-$(CONFIG_PA) += paaudio.o
-common-obj-$(CONFIG_WINWAVE) += winwaveaudio.o
 common-obj-$(CONFIG_AUDIO_PT_INT) += audio_pt_int.o
 common-obj-$(CONFIG_AUDIO_WIN_INT) += audio_win_int.o
 common-obj-y += wavcapture.o
 
-$(obj)/audio.o $(obj)/fmodaudio.o: QEMU_CFLAGS += $(FMOD_CFLAGS)
 sdlaudio.o-cflags := $(SDL_CFLAGS)
diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index ed7655de86..6315b2d746 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -25,6 +25,7 @@
 #include "qemu-common.h"
 #include "qemu/main-loop.h"
 #include "audio.h"
+#include "trace.h"
 
 #if QEMU_GNUC_PREREQ(4, 3)
 #pragma GCC diagnostic ignored "-Waddress"
@@ -33,9 +34,28 @@
 #define AUDIO_CAP "alsa"
 #include "audio_int.h"
 
+typedef struct ALSAConf {
+    int size_in_usec_in;
+    int size_in_usec_out;
+    const char *pcm_name_in;
+    const char *pcm_name_out;
+    unsigned int buffer_size_in;
+    unsigned int period_size_in;
+    unsigned int buffer_size_out;
+    unsigned int period_size_out;
+    unsigned int threshold;
+
+    int buffer_size_in_overridden;
+    int period_size_in_overridden;
+
+    int buffer_size_out_overridden;
+    int period_size_out_overridden;
+} ALSAConf;
+
 struct pollhlp {
     snd_pcm_t *handle;
     struct pollfd *pfds;
+    ALSAConf *conf;
     int count;
     int mask;
 };
@@ -56,30 +76,6 @@ typedef struct ALSAVoiceIn {
     struct pollhlp pollhlp;
 } ALSAVoiceIn;
 
-static struct {
-    int size_in_usec_in;
-    int size_in_usec_out;
-    const char *pcm_name_in;
-    const char *pcm_name_out;
-    unsigned int buffer_size_in;
-    unsigned int period_size_in;
-    unsigned int buffer_size_out;
-    unsigned int period_size_out;
-    unsigned int threshold;
-
-    int buffer_size_in_overridden;
-    int period_size_in_overridden;
-
-    int buffer_size_out_overridden;
-    int period_size_out_overridden;
-    int verbose;
-} conf = {
-    .buffer_size_out = 4096,
-    .period_size_out = 1024,
-    .pcm_name_out = "default",
-    .pcm_name_in = "default",
-};
-
 struct alsa_params_req {
     int freq;
     snd_pcm_format_t fmt;
@@ -205,9 +201,7 @@ static void alsa_poll_handler (void *opaque)
     }
 
     if (!(revents & hlp->mask)) {
-        if (conf.verbose) {
-            dolog ("revents = %d\n", revents);
-        }
+        trace_alsa_revents(revents);
         return;
     }
 
@@ -269,15 +263,10 @@ static int alsa_poll_helper (snd_pcm_t *handle, struct pollhlp *hlp, int mask)
             qemu_set_fd_handler (pfds[i].fd, alsa_poll_handler, NULL, hlp);
         }
         if (pfds[i].events & POLLOUT) {
-            if (conf.verbose) {
-                dolog ("POLLOUT %d %d\n", i, pfds[i].fd);
-            }
+            trace_alsa_pollout(i, pfds[i].fd);
             qemu_set_fd_handler (pfds[i].fd, NULL, alsa_poll_handler, hlp);
         }
-        if (conf.verbose) {
-            dolog ("Set handler events=%#x index=%d fd=%d err=%d\n",
-                   pfds[i].events, i, pfds[i].fd, err);
-        }
+        trace_alsa_set_handler(pfds[i].events, i, pfds[i].fd, err);
 
     }
     hlp->pfds = pfds;
@@ -464,14 +453,15 @@ static void alsa_set_threshold (snd_pcm_t *handle, snd_pcm_uframes_t threshold)
 }
 
 static int alsa_open (int in, struct alsa_params_req *req,
-                      struct alsa_params_obt *obt, snd_pcm_t **handlep)
+                      struct alsa_params_obt *obt, snd_pcm_t **handlep,
+                      ALSAConf *conf)
 {
     snd_pcm_t *handle;
     snd_pcm_hw_params_t *hw_params;
     int err;
     int size_in_usec;
     unsigned int freq, nchannels;
-    const char *pcm_name = in ? conf.pcm_name_in : conf.pcm_name_out;
+    const char *pcm_name = in ? conf->pcm_name_in : conf->pcm_name_out;
     snd_pcm_uframes_t obt_buffer_size;
     const char *typ = in ? "ADC" : "DAC";
     snd_pcm_format_t obtfmt;
@@ -510,7 +500,7 @@ static int alsa_open (int in, struct alsa_params_req *req,
     }
 
     err = snd_pcm_hw_params_set_format (handle, hw_params, req->fmt);
-    if (err < 0 && conf.verbose) {
+    if (err < 0) {
         alsa_logerr2 (err, typ, "Failed to set format %d\n", req->fmt);
     }
 
@@ -642,7 +632,7 @@ static int alsa_open (int in, struct alsa_params_req *req,
         goto err;
     }
 
-    if (!in && conf.threshold) {
+    if (!in && conf->threshold) {
         snd_pcm_uframes_t threshold;
         int bytes_per_sec;
 
@@ -664,7 +654,7 @@ static int alsa_open (int in, struct alsa_params_req *req,
             break;
         }
 
-        threshold = (conf.threshold * bytes_per_sec) / 1000;
+        threshold = (conf->threshold * bytes_per_sec) / 1000;
         alsa_set_threshold (handle, threshold);
     }
 
@@ -674,10 +664,9 @@ static int alsa_open (int in, struct alsa_params_req *req,
 
     *handlep = handle;
 
-    if (conf.verbose &&
-        (obtfmt != req->fmt ||
+    if (obtfmt != req->fmt ||
          obt->nchannels != req->nchannels ||
-         obt->freq != req->freq)) {
+         obt->freq != req->freq) {
         dolog ("Audio parameters for %s\n", typ);
         alsa_dump_info (req, obt, obtfmt);
     }
@@ -731,9 +720,7 @@ static void alsa_write_pending (ALSAVoiceOut *alsa)
             if (written <= 0) {
                 switch (written) {
                 case 0:
-                    if (conf.verbose) {
-                        dolog ("Failed to write %d frames (wrote zero)\n", len);
-                    }
+                    trace_alsa_wrote_zero(len);
                     return;
 
                 case -EPIPE:
@@ -742,9 +729,7 @@ static void alsa_write_pending (ALSAVoiceOut *alsa)
                                      len);
                         return;
                     }
-                    if (conf.verbose) {
-                        dolog ("Recovering from playback xrun\n");
-                    }
+                    trace_alsa_xrun_out();
                     continue;
 
                 case -ESTRPIPE:
@@ -755,9 +740,7 @@ static void alsa_write_pending (ALSAVoiceOut *alsa)
                                      len);
                         return;
                     }
-                    if (conf.verbose) {
-                        dolog ("Resuming suspended output stream\n");
-                    }
+                    trace_alsa_resume_out();
                     continue;
 
                 case -EAGAIN:
@@ -807,25 +790,27 @@ static void alsa_fini_out (HWVoiceOut *hw)
     alsa->pcm_buf = NULL;
 }
 
-static int alsa_init_out (HWVoiceOut *hw, struct audsettings *as)
+static int alsa_init_out(HWVoiceOut *hw, struct audsettings *as,
+                         void *drv_opaque)
 {
     ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
     struct alsa_params_req req;
     struct alsa_params_obt obt;
     snd_pcm_t *handle;
     struct audsettings obt_as;
+    ALSAConf *conf = drv_opaque;
 
     req.fmt = aud_to_alsafmt (as->fmt, as->endianness);
     req.freq = as->freq;
     req.nchannels = as->nchannels;
-    req.period_size = conf.period_size_out;
-    req.buffer_size = conf.buffer_size_out;
-    req.size_in_usec = conf.size_in_usec_out;
+    req.period_size = conf->period_size_out;
+    req.buffer_size = conf->buffer_size_out;
+    req.size_in_usec = conf->size_in_usec_out;
     req.override_mask =
-        (conf.period_size_out_overridden ? 1 : 0) |
-        (conf.buffer_size_out_overridden ? 2 : 0);
+        (conf->period_size_out_overridden ? 1 : 0) |
+        (conf->buffer_size_out_overridden ? 2 : 0);
 
-    if (alsa_open (0, &req, &obt, &handle)) {
+    if (alsa_open (0, &req, &obt, &handle, conf)) {
         return -1;
     }
 
@@ -846,6 +831,7 @@ static int alsa_init_out (HWVoiceOut *hw, struct audsettings *as)
     }
 
     alsa->handle = handle;
+    alsa->pollhlp.conf = conf;
     return 0;
 }
 
@@ -916,25 +902,26 @@ static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...)
     return -1;
 }
 
-static int alsa_init_in (HWVoiceIn *hw, struct audsettings *as)
+static int alsa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
 {
     ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
     struct alsa_params_req req;
     struct alsa_params_obt obt;
     snd_pcm_t *handle;
     struct audsettings obt_as;
+    ALSAConf *conf = drv_opaque;
 
     req.fmt = aud_to_alsafmt (as->fmt, as->endianness);
     req.freq = as->freq;
     req.nchannels = as->nchannels;
-    req.period_size = conf.period_size_in;
-    req.buffer_size = conf.buffer_size_in;
-    req.size_in_usec = conf.size_in_usec_in;
+    req.period_size = conf->period_size_in;
+    req.buffer_size = conf->buffer_size_in;
+    req.size_in_usec = conf->size_in_usec_in;
     req.override_mask =
-        (conf.period_size_in_overridden ? 1 : 0) |
-        (conf.buffer_size_in_overridden ? 2 : 0);
+        (conf->period_size_in_overridden ? 1 : 0) |
+        (conf->buffer_size_in_overridden ? 2 : 0);
 
-    if (alsa_open (1, &req, &obt, &handle)) {
+    if (alsa_open (1, &req, &obt, &handle, conf)) {
         return -1;
     }
 
@@ -955,6 +942,7 @@ static int alsa_init_in (HWVoiceIn *hw, struct audsettings *as)
     }
 
     alsa->handle = handle;
+    alsa->pollhlp.conf = conf;
     return 0;
 }
 
@@ -1010,14 +998,10 @@ static int alsa_run_in (HWVoiceIn *hw)
                 dolog ("Failed to resume suspended input stream\n");
                 return 0;
             }
-            if (conf.verbose) {
-                dolog ("Resuming suspended input stream\n");
-            }
+            trace_alsa_resume_in();
             break;
         default:
-            if (conf.verbose) {
-                dolog ("No frames available and ALSA state is %d\n", state);
-            }
+            trace_alsa_no_frames(state);
             return 0;
         }
     }
@@ -1052,9 +1036,7 @@ static int alsa_run_in (HWVoiceIn *hw)
             if (nread <= 0) {
                 switch (nread) {
                 case 0:
-                    if (conf.verbose) {
-                        dolog ("Failed to read %ld frames (read zero)\n", len);
-                    }
+                    trace_alsa_read_zero(len);
                     goto exit;
 
                 case -EPIPE:
@@ -1062,9 +1044,7 @@ static int alsa_run_in (HWVoiceIn *hw)
                         alsa_logerr (nread, "Failed to read %ld frames\n", len);
                         goto exit;
                     }
-                    if (conf.verbose) {
-                        dolog ("Recovering from capture xrun\n");
-                    }
+                    trace_alsa_xrun_in();
                     continue;
 
                 case -EAGAIN:
@@ -1136,82 +1116,85 @@ static int alsa_ctl_in (HWVoiceIn *hw, int cmd, ...)
     return -1;
 }
 
+static ALSAConf glob_conf = {
+    .buffer_size_out = 4096,
+    .period_size_out = 1024,
+    .pcm_name_out = "default",
+    .pcm_name_in = "default",
+};
+
 static void *alsa_audio_init (void)
 {
-    return &conf;
+    ALSAConf *conf = g_malloc(sizeof(ALSAConf));
+    *conf = glob_conf;
+    return conf;
 }
 
 static void alsa_audio_fini (void *opaque)
 {
-    (void) opaque;
+    g_free(opaque);
 }
 
 static struct audio_option alsa_options[] = {
     {
         .name        = "DAC_SIZE_IN_USEC",
         .tag         = AUD_OPT_BOOL,
-        .valp        = &conf.size_in_usec_out,
+        .valp        = &glob_conf.size_in_usec_out,
         .descr       = "DAC period/buffer size in microseconds (otherwise in frames)"
     },
     {
         .name        = "DAC_PERIOD_SIZE",
         .tag         = AUD_OPT_INT,
-        .valp        = &conf.period_size_out,
+        .valp        = &glob_conf.period_size_out,
         .descr       = "DAC period size (0 to go with system default)",
-        .overriddenp = &conf.period_size_out_overridden
+        .overriddenp = &glob_conf.period_size_out_overridden
     },
     {
         .name        = "DAC_BUFFER_SIZE",
         .tag         = AUD_OPT_INT,
-        .valp        = &conf.buffer_size_out,
+        .valp        = &glob_conf.buffer_size_out,
         .descr       = "DAC buffer size (0 to go with system default)",
-        .overriddenp = &conf.buffer_size_out_overridden
+        .overriddenp = &glob_conf.buffer_size_out_overridden
     },
     {
         .name        = "ADC_SIZE_IN_USEC",
         .tag         = AUD_OPT_BOOL,
-        .valp        = &conf.size_in_usec_in,
+        .valp        = &glob_conf.size_in_usec_in,
         .descr       =
         "ADC period/buffer size in microseconds (otherwise in frames)"
     },
     {
         .name        = "ADC_PERIOD_SIZE",
         .tag         = AUD_OPT_INT,
-        .valp        = &conf.period_size_in,
+        .valp        = &glob_conf.period_size_in,
         .descr       = "ADC period size (0 to go with system default)",
-        .overriddenp = &conf.period_size_in_overridden
+        .overriddenp = &glob_conf.period_size_in_overridden
     },
     {
         .name        = "ADC_BUFFER_SIZE",
         .tag         = AUD_OPT_INT,
-        .valp        = &conf.buffer_size_in,
+        .valp        = &glob_conf.buffer_size_in,
         .descr       = "ADC buffer size (0 to go with system default)",
-        .overriddenp = &conf.buffer_size_in_overridden
+        .overriddenp = &glob_conf.buffer_size_in_overridden
     },
     {
         .name        = "THRESHOLD",
         .tag         = AUD_OPT_INT,
-        .valp        = &conf.threshold,
+        .valp        = &glob_conf.threshold,
         .descr       = "(undocumented)"
     },
     {
         .name        = "DAC_DEV",
         .tag         = AUD_OPT_STR,
-        .valp        = &conf.pcm_name_out,
+        .valp        = &glob_conf.pcm_name_out,
         .descr       = "DAC device name (for instance dmix)"
     },
     {
         .name        = "ADC_DEV",
         .tag         = AUD_OPT_STR,
-        .valp        = &conf.pcm_name_in,
+        .valp        = &glob_conf.pcm_name_in,
         .descr       = "ADC device name"
     },
-    {
-        .name        = "VERBOSE",
-        .tag         = AUD_OPT_BOOL,
-        .valp        = &conf.verbose,
-        .descr       = "Behave in a more verbose way"
-    },
     { /* End of list */ }
 };
 
diff --git a/audio/audio.c b/audio/audio.c
index 9d018e9ded..5be4b15fcf 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -30,7 +30,6 @@
 #define AUDIO_CAP "audio"
 #include "audio_int.h"
 
-/* #define DEBUG_PLIVE */
 /* #define DEBUG_LIVE */
 /* #define DEBUG_OUT */
 /* #define DEBUG_CAPTURE */
@@ -66,8 +65,6 @@ static struct {
         int hertz;
         int64_t ticks;
     } period;
-    int plive;
-    int log_to_monitor;
     int try_poll_in;
     int try_poll_out;
 } conf = {
@@ -96,8 +93,6 @@ static struct {
     },
 
     .period = { .hertz = 100 },
-    .plive = 0,
-    .log_to_monitor = 0,
     .try_poll_in = 1,
     .try_poll_out = 1,
 };
@@ -331,20 +326,11 @@ static const char *audio_get_conf_str (const char *key,
 
 void AUD_vlog (const char *cap, const char *fmt, va_list ap)
 {
-    if (conf.log_to_monitor) {
-        if (cap) {
-            monitor_printf(default_mon, "%s: ", cap);
-        }
-
-        monitor_vprintf(default_mon, fmt, ap);
+    if (cap) {
+        fprintf(stderr, "%s: ", cap);
     }
-    else {
-        if (cap) {
-            fprintf (stderr, "%s: ", cap);
-        }
 
-        vfprintf (stderr, fmt, ap);
-    }
+    vfprintf(stderr, fmt, ap);
 }
 
 void AUD_log (const char *cap, const char *fmt, ...)
@@ -1454,9 +1440,6 @@ static void audio_run_out (AudioState *s)
             while (sw) {
                 sw1 = sw->entries.le_next;
                 if (!sw->active && !sw->callback.fn) {
-#ifdef DEBUG_PLIVE
-                    dolog ("Finishing with old voice\n");
-#endif
                     audio_close_out (sw);
                 }
                 sw = sw1;
@@ -1648,18 +1631,6 @@ static struct audio_option audio_options[] = {
         .valp  = &conf.period.hertz,
         .descr = "Timer period in HZ (0 - use lowest possible)"
     },
-    {
-        .name  = "PLIVE",
-        .tag   = AUD_OPT_BOOL,
-        .valp  = &conf.plive,
-        .descr = "(undocumented)"
-    },
-    {
-        .name  = "LOG_TO_MONITOR",
-        .tag   = AUD_OPT_BOOL,
-        .valp  = &conf.log_to_monitor,
-        .descr = "Print logging messages to monitor instead of stderr"
-    },
     { /* End of list */ }
 };
 
diff --git a/audio/audio_int.h b/audio/audio_int.h
index fd019a0fc3..566df5edf4 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -156,13 +156,13 @@ struct audio_driver {
 };
 
 struct audio_pcm_ops {
-    int  (*init_out)(HWVoiceOut *hw, struct audsettings *as);
+    int  (*init_out)(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque);
     void (*fini_out)(HWVoiceOut *hw);
     int  (*run_out) (HWVoiceOut *hw, int live);
     int  (*write)   (SWVoiceOut *sw, void *buf, int size);
     int  (*ctl_out) (HWVoiceOut *hw, int cmd, ...);
 
-    int  (*init_in) (HWVoiceIn *hw, struct audsettings *as);
+    int  (*init_in) (HWVoiceIn *hw, struct audsettings *as, void *drv_opaque);
     void (*fini_in) (HWVoiceIn *hw);
     int  (*run_in)  (HWVoiceIn *hw);
     int  (*read)    (SWVoiceIn *sw, void *buf, int size);
@@ -206,14 +206,11 @@ extern struct audio_driver no_audio_driver;
 extern struct audio_driver oss_audio_driver;
 extern struct audio_driver sdl_audio_driver;
 extern struct audio_driver wav_audio_driver;
-extern struct audio_driver fmod_audio_driver;
 extern struct audio_driver alsa_audio_driver;
 extern struct audio_driver coreaudio_audio_driver;
 extern struct audio_driver dsound_audio_driver;
-extern struct audio_driver esd_audio_driver;
 extern struct audio_driver pa_audio_driver;
 extern struct audio_driver spice_audio_driver;
-extern struct audio_driver winwave_audio_driver;
 extern const struct mixeng_volume nominal_volume;
 
 void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as);
diff --git a/audio/audio_template.h b/audio/audio_template.h
index 584e536fac..99b27b285e 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -262,7 +262,7 @@ static HW *glue (audio_pcm_hw_add_new_, TYPE) (struct audsettings *as)
 #ifdef DAC
     QLIST_INIT (&hw->cap_head);
 #endif
-    if (glue (hw->pcm_ops->init_, TYPE) (hw, as)) {
+    if (glue (hw->pcm_ops->init_, TYPE) (hw, as, s->drv_opaque)) {
         goto err0;
     }
 
@@ -398,10 +398,6 @@ SW *glue (AUD_open_, TYPE) (
     )
 {
     AudioState *s = &glob_audio_state;
-#ifdef DAC
-    int live = 0;
-    SW *old_sw = NULL;
-#endif
 
     if (audio_bug (AUDIO_FUNC, !card || !name || !callback_fn || !as)) {
         dolog ("card=%p name=%p callback_fn=%p as=%p\n",
@@ -426,29 +422,6 @@ SW *glue (AUD_open_, TYPE) (
         return sw;
     }
 
-#ifdef DAC
-    if (conf.plive && sw && (!sw->active && !sw->empty)) {
-        live = sw->total_hw_samples_mixed;
-
-#ifdef DEBUG_PLIVE
-        dolog ("Replacing voice %s with %d live samples\n", SW_NAME (sw), live);
-        dolog ("Old %s freq %d, bits %d, channels %d\n",
-               SW_NAME (sw), sw->info.freq, sw->info.bits, sw->info.nchannels);
-        dolog ("New %s freq %d, bits %d, channels %d\n",
-               name,
-               as->freq,
-               (as->fmt == AUD_FMT_S16 || as->fmt == AUD_FMT_U16) ? 16 : 8,
-               as->nchannels);
-#endif
-
-        if (live) {
-            old_sw = sw;
-            old_sw->callback.fn = NULL;
-            sw = NULL;
-        }
-    }
-#endif
-
     if (!glue (conf.fixed_, TYPE).enabled && sw) {
         glue (AUD_close_, TYPE) (card, sw);
         sw = NULL;
@@ -481,20 +454,6 @@ SW *glue (AUD_open_, TYPE) (
     sw->callback.fn = callback_fn;
     sw->callback.opaque = callback_opaque;
 
-#ifdef DAC
-    if (live) {
-        int mixed =
-            (live << old_sw->info.shift)
-            * old_sw->info.bytes_per_second
-            / sw->info.bytes_per_second;
-
-#ifdef DEBUG_PLIVE
-        dolog ("Silence will be mixed %d\n", mixed);
-#endif
-        sw->total_hw_samples_mixed += mixed;
-    }
-#endif
-
 #ifdef DEBUG_AUDIO
     dolog ("%s\n", name);
     audio_pcm_print_info ("hw", &sw->hw->info);
diff --git a/audio/coreaudio.c b/audio/coreaudio.c
index 5964c62eaf..6dfd63eb42 100644
--- a/audio/coreaudio.c
+++ b/audio/coreaudio.c
@@ -32,20 +32,16 @@
 #define AUDIO_CAP "coreaudio"
 #include "audio_int.h"
 
-struct {
+static int isAtexit;
+
+typedef struct {
     int buffer_frames;
     int nbuffers;
-    int isAtexit;
-} conf = {
-    .buffer_frames = 512,
-    .nbuffers = 4,
-    .isAtexit = 0
-};
+} CoreaudioConf;
 
 typedef struct coreaudioVoiceOut {
     HWVoiceOut hw;
     pthread_mutex_t mutex;
-    int isAtexit;
     AudioDeviceID outputDeviceID;
     UInt32 audioDevicePropertyBufferFrameSize;
     AudioStreamBasicDescription outputStreamBasicDescription;
@@ -161,7 +157,7 @@ static inline UInt32 isPlaying (AudioDeviceID outputDeviceID)
 
 static void coreaudio_atexit (void)
 {
-    conf.isAtexit = 1;
+    isAtexit = 1;
 }
 
 static int coreaudio_lock (coreaudioVoiceOut *core, const char *fn_name)
@@ -287,7 +283,8 @@ static int coreaudio_write (SWVoiceOut *sw, void *buf, int len)
     return audio_pcm_sw_write (sw, buf, len);
 }
 
-static int coreaudio_init_out (HWVoiceOut *hw, struct audsettings *as)
+static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
+                              void *drv_opaque)
 {
     OSStatus status;
     coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
@@ -295,6 +292,7 @@ static int coreaudio_init_out (HWVoiceOut *hw, struct audsettings *as)
     int err;
     const char *typ = "playback";
     AudioValueRange frameRange;
+    CoreaudioConf *conf = drv_opaque;
 
     /* create mutex */
     err = pthread_mutex_init(&core->mutex, NULL);
@@ -336,16 +334,16 @@ static int coreaudio_init_out (HWVoiceOut *hw, struct audsettings *as)
         return -1;
     }
 
-    if (frameRange.mMinimum > conf.buffer_frames) {
+    if (frameRange.mMinimum > conf->buffer_frames) {
         core->audioDevicePropertyBufferFrameSize = (UInt32) frameRange.mMinimum;
         dolog ("warning: Upsizing Buffer Frames to %f\n", frameRange.mMinimum);
     }
-    else if (frameRange.mMaximum < conf.buffer_frames) {
+    else if (frameRange.mMaximum < conf->buffer_frames) {
         core->audioDevicePropertyBufferFrameSize = (UInt32) frameRange.mMaximum;
         dolog ("warning: Downsizing Buffer Frames to %f\n", frameRange.mMaximum);
     }
     else {
-        core->audioDevicePropertyBufferFrameSize = conf.buffer_frames;
+        core->audioDevicePropertyBufferFrameSize = conf->buffer_frames;
     }
 
     /* set Buffer Frame Size */
@@ -379,7 +377,7 @@ static int coreaudio_init_out (HWVoiceOut *hw, struct audsettings *as)
                            "Could not get device buffer frame size\n");
         return -1;
     }
-    hw->samples = conf.nbuffers * core->audioDevicePropertyBufferFrameSize;
+    hw->samples = conf->nbuffers * core->audioDevicePropertyBufferFrameSize;
 
     /* get StreamFormat */
     propertySize = sizeof(core->outputStreamBasicDescription);
@@ -443,7 +441,7 @@ static void coreaudio_fini_out (HWVoiceOut *hw)
     int err;
     coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
 
-    if (!conf.isAtexit) {
+    if (!isAtexit) {
         /* stop playback */
         if (isPlaying(core->outputDeviceID)) {
             status = AudioDeviceStop(core->outputDeviceID, audioDeviceIOProc);
@@ -486,7 +484,7 @@ static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...)
 
     case VOICE_DISABLE:
         /* stop playback */
-        if (!conf.isAtexit) {
+        if (!isAtexit) {
             if (isPlaying(core->outputDeviceID)) {
                 status = AudioDeviceStop(core->outputDeviceID, audioDeviceIOProc);
                 if (status != kAudioHardwareNoError) {
@@ -499,28 +497,36 @@ static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...)
     return 0;
 }
 
+static CoreaudioConf glob_conf = {
+    .buffer_frames = 512,
+    .nbuffers = 4,
+};
+
 static void *coreaudio_audio_init (void)
 {
+    CoreaudioConf *conf = g_malloc(sizeof(CoreaudioConf));
+    *conf = glob_conf;
+
     atexit(coreaudio_atexit);
-    return &coreaudio_audio_init;
+    return conf;
 }
 
 static void coreaudio_audio_fini (void *opaque)
 {
-    (void) opaque;
+    g_free(opaque);
 }
 
 static struct audio_option coreaudio_options[] = {
     {
         .name  = "BUFFER_SIZE",
         .tag   = AUD_OPT_INT,
-        .valp  = &conf.buffer_frames,
+        .valp  = &glob_conf.buffer_frames,
         .descr = "Size of the buffer in frames"
     },
     {
         .name  = "BUFFER_COUNT",
         .tag   = AUD_OPT_INT,
-        .valp  = &conf.nbuffers,
+        .valp  = &glob_conf.nbuffers,
         .descr = "Number of buffers"
     },
     { /* End of list */ }
diff --git a/audio/dsound_template.h b/audio/dsound_template.h
index 8b37d16a8c..b439f33f58 100644
--- a/audio/dsound_template.h
+++ b/audio/dsound_template.h
@@ -67,11 +67,11 @@ static int glue (dsound_lock_, TYPE) (
     LPVOID *p2p,
     DWORD *blen1p,
     DWORD *blen2p,
-    int entire
+    int entire,
+    dsound *s
     )
 {
     HRESULT hr;
-    int i;
     LPVOID p1 = NULL, p2 = NULL;
     DWORD blen1 = 0, blen2 = 0;
     DWORD flag;
@@ -81,37 +81,18 @@ static int glue (dsound_lock_, TYPE) (
 #else
     flag = entire ? DSBLOCK_ENTIREBUFFER : 0;
 #endif
-    for (i = 0; i < conf.lock_retries; ++i) {
-        hr = glue (IFACE, _Lock) (
-            buf,
-            pos,
-            len,
-            &p1,
-            &blen1,
-            &p2,
-            &blen2,
-            flag
-            );
+    hr = glue(IFACE, _Lock)(buf, pos, len, &p1, &blen1, &p2, &blen2, flag);
 
-        if (FAILED (hr)) {
+    if (FAILED (hr)) {
 #ifndef DSBTYPE_IN
-            if (hr == DSERR_BUFFERLOST) {
-                if (glue (dsound_restore_, TYPE) (buf)) {
-                    dsound_logerr (hr, "Could not lock " NAME "\n");
-                    goto fail;
-                }
-                continue;
+        if (hr == DSERR_BUFFERLOST) {
+            if (glue (dsound_restore_, TYPE) (buf, s)) {
+                dsound_logerr (hr, "Could not lock " NAME "\n");
             }
-#endif
-            dsound_logerr (hr, "Could not lock " NAME "\n");
             goto fail;
         }
-
-        break;
-    }
-
-    if (i == conf.lock_retries) {
-        dolog ("%d attempts to lock " NAME " failed\n", i);
+#endif
+        dsound_logerr (hr, "Could not lock " NAME "\n");
         goto fail;
     }
 
@@ -174,16 +155,19 @@ static void dsound_fini_out (HWVoiceOut *hw)
 }
 
 #ifdef DSBTYPE_IN
-static int dsound_init_in (HWVoiceIn *hw, struct audsettings *as)
+static int dsound_init_in(HWVoiceIn *hw, struct audsettings *as,
+                          void *drv_opaque)
 #else
-static int dsound_init_out (HWVoiceOut *hw, struct audsettings *as)
+static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
+                           void *drv_opaque)
 #endif
 {
     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;
@@ -210,7 +194,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,
@@ -219,7 +203,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,
@@ -269,6 +253,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 e2d89fd5d5..e9472c105c 100644
--- a/audio/dsoundaudio.c
+++ b/audio/dsoundaudio.c
@@ -41,42 +41,25 @@
 
 /* #define DEBUG_DSOUND */
 
-static struct {
-    int lock_retries;
-    int restore_retries;
-    int getstatus_retries;
-    int set_primary;
+typedef struct {
     int bufsize_in;
     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 +71,7 @@ typedef struct {
     HWVoiceIn hw;
     int first_time;
     LPDIRECTSOUNDCAPTUREBUFFER dsound_capture_buffer;
+    dsound *s;
 } DSoundVoiceIn;
 
 static void dsound_log_hresult (HRESULT hr)
@@ -281,29 +265,17 @@ 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) {
-        hr = IDirectSoundBuffer_Restore (dsb);
-
-        switch (hr) {
-        case DS_OK:
-            return 0;
 
-        case DSERR_BUFFERLOST:
-            continue;
+    hr = IDirectSoundBuffer_Restore (dsb);
 
-        default:
-            dsound_logerr (hr, "Could not restore playback buffer\n");
-            return -1;
-        }
+    if (hr != DS_OK) {
+        dsound_logerr (hr, "Could not restore playback buffer\n");
+        return -1;
     }
-
-    dolog ("%d attempts to restore playback buffer failed\n", i);
-    return -1;
+    return 0;
 }
 
 #include "dsound_template.h"
@@ -311,25 +283,20 @@ 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) {
-        hr = IDirectSoundBuffer_GetStatus (dsb, statusp);
-        if (FAILED (hr)) {
-            dsound_logerr (hr, "Could not get playback buffer status\n");
-            return -1;
-        }
+    hr = IDirectSoundBuffer_GetStatus (dsb, statusp);
+    if (FAILED (hr)) {
+        dsound_logerr (hr, "Could not get playback buffer status\n");
+        return -1;
+    }
 
-        if (*statusp & DSERR_BUFFERLOST) {
-            if (dsound_restore_out (dsb)) {
-                return -1;
-            }
-            continue;
-        }
-        break;
+    if (*statusp & DSERR_BUFFERLOST) {
+        dsound_restore_out(dsb, s);
+        return -1;
     }
 
     return 0;
@@ -376,7 +343,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 +357,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;
@@ -415,25 +384,9 @@ static void dsound_clear_sample (HWVoiceOut *hw, LPDIRECTSOUNDBUFFER dsb)
     dsound_unlock_out (dsb, p1, p2, blen1, blen2);
 }
 
-static void dsound_close (dsound *s)
-{
-    HRESULT hr;
-
-    if (s->dsound_primary_buffer) {
-        hr = IDirectSoundBuffer_Release (s->dsound_primary_buffer);
-        if (FAILED (hr)) {
-            dsound_logerr (hr, "Could not release primary buffer\n");
-        }
-        s->dsound_primary_buffer = NULL;
-    }
-}
-
 static int dsound_open (dsound *s)
 {
-    int err;
     HRESULT hr;
-    WAVEFORMATEX wfx;
-    DSBUFFERDESC dsbd;
     HWND hwnd;
 
     hwnd = GetForegroundWindow ();
@@ -449,63 +402,7 @@ static int dsound_open (dsound *s)
         return -1;
     }
 
-    if (!conf.set_primary) {
-        return 0;
-    }
-
-    err = waveformat_from_audio_settings (&wfx, &conf.settings);
-    if (err) {
-        return -1;
-    }
-
-    memset (&dsbd, 0, sizeof (dsbd));
-    dsbd.dwSize = sizeof (dsbd);
-    dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;
-    dsbd.dwBufferBytes = 0;
-    dsbd.lpwfxFormat = NULL;
-
-    hr = IDirectSound_CreateSoundBuffer (
-        s->dsound,
-        &dsbd,
-        &s->dsound_primary_buffer,
-        NULL
-        );
-    if (FAILED (hr)) {
-        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, "Could not set primary playback buffer format\n");
-    }
-
-    hr = IDirectSoundBuffer_GetFormat (
-        s->dsound_primary_buffer,
-        &wfx,
-        sizeof (wfx),
-        NULL
-        );
-    if (FAILED (hr)) {
-        dsound_logerr (hr, "Could not get primary playback buffer format\n");
-        goto fail0;
-    }
-
-#ifdef DEBUG_DSOUND
-    dolog ("Primary\n");
-    print_wave_format (&wfx);
-#endif
-
-    err = waveformat_to_audio_settings (&wfx, &s->settings);
-    if (err) {
-        goto fail0;
-    }
-
     return 0;
-
- fail0:
-    dsound_close (s);
-    return -1;
 }
 
 static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...)
@@ -514,6 +411,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 +420,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 +429,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 +439,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 +476,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 +500,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 +563,8 @@ static int dsound_run_out (HWVoiceOut *hw, int live)
         len,
         &p1, &p2,
         &blen1, &blen2,
-        0
+        0,
+        s
         );
     if (err) {
         return 0;
@@ -766,6 +667,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 +722,8 @@ static int dsound_run_in (HWVoiceIn *hw)
         &p2,
         &blen1,
         &blen2,
-        0
+        0,
+        s
         );
     if (err) {
         return 0;
@@ -843,12 +746,19 @@ static int dsound_run_in (HWVoiceIn *hw)
     return decr;
 }
 
+static DSoundConf glob_conf = {
+    .bufsize_in         = 16384,
+    .bufsize_out        = 16384,
+    .latency_millis     = 10
+};
+
 static void dsound_audio_fini (void *opaque)
 {
     HRESULT hr;
     dsound *s = opaque;
 
     if (!s->dsound) {
+        g_free(s);
         return;
     }
 
@@ -859,6 +769,7 @@ static void dsound_audio_fini (void *opaque)
     s->dsound = NULL;
 
     if (!s->dsound_capture) {
+        g_free(s);
         return;
     }
 
@@ -867,17 +778,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 +805,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 +817,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;
     }
 
@@ -939,63 +855,21 @@ static void *dsound_audio_init (void)
 
 static struct audio_option dsound_options[] = {
     {
-        .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,
+        .valp  = &glob_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,
+        .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 */ }
diff --git a/audio/esdaudio.c b/audio/esdaudio.c
deleted file mode 100644
index eea9ccec0b..0000000000
--- a/audio/esdaudio.c
+++ /dev/null
@@ -1,557 +0,0 @@
-/*
- * QEMU ESD audio driver
- *
- * Copyright (c) 2006 Frederick Reeve (brushed up by malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include <esd.h>
-#include "qemu-common.h"
-#include "audio.h"
-
-#define AUDIO_CAP "esd"
-#include "audio_int.h"
-#include "audio_pt_int.h"
-
-typedef struct {
-    HWVoiceOut hw;
-    int done;
-    int live;
-    int decr;
-    int rpos;
-    void *pcm_buf;
-    int fd;
-    struct audio_pt pt;
-} ESDVoiceOut;
-
-typedef struct {
-    HWVoiceIn hw;
-    int done;
-    int dead;
-    int incr;
-    int wpos;
-    void *pcm_buf;
-    int fd;
-    struct audio_pt pt;
-} ESDVoiceIn;
-
-static struct {
-    int samples;
-    int divisor;
-    char *dac_host;
-    char *adc_host;
-} conf = {
-    .samples = 1024,
-    .divisor = 2,
-};
-
-static void GCC_FMT_ATTR (2, 3) qesd_logerr (int err, const char *fmt, ...)
-{
-    va_list ap;
-
-    va_start (ap, fmt);
-    AUD_vlog (AUDIO_CAP, fmt, ap);
-    va_end (ap);
-
-    AUD_log (AUDIO_CAP, "Reason: %s\n", strerror (err));
-}
-
-/* playback */
-static void *qesd_thread_out (void *arg)
-{
-    ESDVoiceOut *esd = arg;
-    HWVoiceOut *hw = &esd->hw;
-    int threshold;
-
-    threshold = conf.divisor ? hw->samples / conf.divisor : 0;
-
-    if (audio_pt_lock (&esd->pt, AUDIO_FUNC)) {
-        return NULL;
-    }
-
-    for (;;) {
-        int decr, to_mix, rpos;
-
-        for (;;) {
-            if (esd->done) {
-                goto exit;
-            }
-
-            if (esd->live > threshold) {
-                break;
-            }
-
-            if (audio_pt_wait (&esd->pt, AUDIO_FUNC)) {
-                goto exit;
-            }
-        }
-
-        decr = to_mix = esd->live;
-        rpos = hw->rpos;
-
-        if (audio_pt_unlock (&esd->pt, AUDIO_FUNC)) {
-            return NULL;
-        }
-
-        while (to_mix) {
-            ssize_t written;
-            int chunk = audio_MIN (to_mix, hw->samples - rpos);
-            struct st_sample *src = hw->mix_buf + rpos;
-
-            hw->clip (esd->pcm_buf, src, chunk);
-
-        again:
-            written = write (esd->fd, esd->pcm_buf, chunk << hw->info.shift);
-            if (written == -1) {
-                if (errno == EINTR || errno == EAGAIN) {
-                    goto again;
-                }
-                qesd_logerr (errno, "write failed\n");
-                return NULL;
-            }
-
-            if (written != chunk << hw->info.shift) {
-                int wsamples = written >> hw->info.shift;
-                int wbytes = wsamples << hw->info.shift;
-                if (wbytes != written) {
-                    dolog ("warning: Misaligned write %d (requested %zd), "
-                           "alignment %d\n",
-                           wbytes, written, hw->info.align + 1);
-                }
-                to_mix -= wsamples;
-                rpos = (rpos + wsamples) % hw->samples;
-                break;
-            }
-
-            rpos = (rpos + chunk) % hw->samples;
-            to_mix -= chunk;
-        }
-
-        if (audio_pt_lock (&esd->pt, AUDIO_FUNC)) {
-            return NULL;
-        }
-
-        esd->rpos = rpos;
-        esd->live -= decr;
-        esd->decr += decr;
-    }
-
- exit:
-    audio_pt_unlock (&esd->pt, AUDIO_FUNC);
-    return NULL;
-}
-
-static int qesd_run_out (HWVoiceOut *hw, int live)
-{
-    int decr;
-    ESDVoiceOut *esd = (ESDVoiceOut *) hw;
-
-    if (audio_pt_lock (&esd->pt, AUDIO_FUNC)) {
-        return 0;
-    }
-
-    decr = audio_MIN (live, esd->decr);
-    esd->decr -= decr;
-    esd->live = live - decr;
-    hw->rpos = esd->rpos;
-    if (esd->live > 0) {
-        audio_pt_unlock_and_signal (&esd->pt, AUDIO_FUNC);
-    }
-    else {
-        audio_pt_unlock (&esd->pt, AUDIO_FUNC);
-    }
-    return decr;
-}
-
-static int qesd_write (SWVoiceOut *sw, void *buf, int len)
-{
-    return audio_pcm_sw_write (sw, buf, len);
-}
-
-static int qesd_init_out (HWVoiceOut *hw, struct audsettings *as)
-{
-    ESDVoiceOut *esd = (ESDVoiceOut *) hw;
-    struct audsettings obt_as = *as;
-    int esdfmt = ESD_STREAM | ESD_PLAY;
-
-    esdfmt |= (as->nchannels == 2) ? ESD_STEREO : ESD_MONO;
-    switch (as->fmt) {
-    case AUD_FMT_S8:
-    case AUD_FMT_U8:
-        esdfmt |= ESD_BITS8;
-        obt_as.fmt = AUD_FMT_U8;
-        break;
-
-    case AUD_FMT_S32:
-    case AUD_FMT_U32:
-        dolog ("Will use 16 instead of 32 bit samples\n");
-        /* fall through */
-    case AUD_FMT_S16:
-    case AUD_FMT_U16:
-    deffmt:
-        esdfmt |= ESD_BITS16;
-        obt_as.fmt = AUD_FMT_S16;
-        break;
-
-    default:
-        dolog ("Internal logic error: Bad audio format %d\n", as->fmt);
-        goto deffmt;
-
-    }
-    obt_as.endianness = AUDIO_HOST_ENDIANNESS;
-
-    audio_pcm_init_info (&hw->info, &obt_as);
-
-    hw->samples = conf.samples;
-    esd->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
-    if (!esd->pcm_buf) {
-        dolog ("Could not allocate buffer (%d bytes)\n",
-               hw->samples << hw->info.shift);
-        return -1;
-    }
-
-    esd->fd = esd_play_stream (esdfmt, as->freq, conf.dac_host, NULL);
-    if (esd->fd < 0) {
-        qesd_logerr (errno, "esd_play_stream failed\n");
-        goto fail1;
-    }
-
-    if (audio_pt_init (&esd->pt, qesd_thread_out, esd, AUDIO_CAP, AUDIO_FUNC)) {
-        goto fail2;
-    }
-
-    return 0;
-
- fail2:
-    if (close (esd->fd)) {
-        qesd_logerr (errno, "%s: close on esd socket(%d) failed\n",
-                     AUDIO_FUNC, esd->fd);
-    }
-    esd->fd = -1;
-
- fail1:
-    g_free (esd->pcm_buf);
-    esd->pcm_buf = NULL;
-    return -1;
-}
-
-static void qesd_fini_out (HWVoiceOut *hw)
-{
-    void *ret;
-    ESDVoiceOut *esd = (ESDVoiceOut *) hw;
-
-    audio_pt_lock (&esd->pt, AUDIO_FUNC);
-    esd->done = 1;
-    audio_pt_unlock_and_signal (&esd->pt, AUDIO_FUNC);
-    audio_pt_join (&esd->pt, &ret, AUDIO_FUNC);
-
-    if (esd->fd >= 0) {
-        if (close (esd->fd)) {
-            qesd_logerr (errno, "failed to close esd socket\n");
-        }
-        esd->fd = -1;
-    }
-
-    audio_pt_fini (&esd->pt, AUDIO_FUNC);
-
-    g_free (esd->pcm_buf);
-    esd->pcm_buf = NULL;
-}
-
-static int qesd_ctl_out (HWVoiceOut *hw, int cmd, ...)
-{
-    (void) hw;
-    (void) cmd;
-    return 0;
-}
-
-/* capture */
-static void *qesd_thread_in (void *arg)
-{
-    ESDVoiceIn *esd = arg;
-    HWVoiceIn *hw = &esd->hw;
-    int threshold;
-
-    threshold = conf.divisor ? hw->samples / conf.divisor : 0;
-
-    if (audio_pt_lock (&esd->pt, AUDIO_FUNC)) {
-        return NULL;
-    }
-
-    for (;;) {
-        int incr, to_grab, wpos;
-
-        for (;;) {
-            if (esd->done) {
-                goto exit;
-            }
-
-            if (esd->dead > threshold) {
-                break;
-            }
-
-            if (audio_pt_wait (&esd->pt, AUDIO_FUNC)) {
-                goto exit;
-            }
-        }
-
-        incr = to_grab = esd->dead;
-        wpos = hw->wpos;
-
-        if (audio_pt_unlock (&esd->pt, AUDIO_FUNC)) {
-            return NULL;
-        }
-
-        while (to_grab) {
-            ssize_t nread;
-            int chunk = audio_MIN (to_grab, hw->samples - wpos);
-            void *buf = advance (esd->pcm_buf, wpos);
-
-        again:
-            nread = read (esd->fd, buf, chunk << hw->info.shift);
-            if (nread == -1) {
-                if (errno == EINTR || errno == EAGAIN) {
-                    goto again;
-                }
-                qesd_logerr (errno, "read failed\n");
-                return NULL;
-            }
-
-            if (nread != chunk << hw->info.shift) {
-                int rsamples = nread >> hw->info.shift;
-                int rbytes = rsamples << hw->info.shift;
-                if (rbytes != nread) {
-                    dolog ("warning: Misaligned write %d (requested %zd), "
-                           "alignment %d\n",
-                           rbytes, nread, hw->info.align + 1);
-                }
-                to_grab -= rsamples;
-                wpos = (wpos + rsamples) % hw->samples;
-                break;
-            }
-
-            hw->conv (hw->conv_buf + wpos, buf, nread >> hw->info.shift);
-            wpos = (wpos + chunk) % hw->samples;
-            to_grab -= chunk;
-        }
-
-        if (audio_pt_lock (&esd->pt, AUDIO_FUNC)) {
-            return NULL;
-        }
-
-        esd->wpos = wpos;
-        esd->dead -= incr;
-        esd->incr += incr;
-    }
-
- exit:
-    audio_pt_unlock (&esd->pt, AUDIO_FUNC);
-    return NULL;
-}
-
-static int qesd_run_in (HWVoiceIn *hw)
-{
-    int live, incr, dead;
-    ESDVoiceIn *esd = (ESDVoiceIn *) hw;
-
-    if (audio_pt_lock (&esd->pt, AUDIO_FUNC)) {
-        return 0;
-    }
-
-    live = audio_pcm_hw_get_live_in (hw);
-    dead = hw->samples - live;
-    incr = audio_MIN (dead, esd->incr);
-    esd->incr -= incr;
-    esd->dead = dead - incr;
-    hw->wpos = esd->wpos;
-    if (esd->dead > 0) {
-        audio_pt_unlock_and_signal (&esd->pt, AUDIO_FUNC);
-    }
-    else {
-        audio_pt_unlock (&esd->pt, AUDIO_FUNC);
-    }
-    return incr;
-}
-
-static int qesd_read (SWVoiceIn *sw, void *buf, int len)
-{
-    return audio_pcm_sw_read (sw, buf, len);
-}
-
-static int qesd_init_in (HWVoiceIn *hw, struct audsettings *as)
-{
-    ESDVoiceIn *esd = (ESDVoiceIn *) hw;
-    struct audsettings obt_as = *as;
-    int esdfmt = ESD_STREAM | ESD_RECORD;
-
-    esdfmt |= (as->nchannels == 2) ? ESD_STEREO : ESD_MONO;
-    switch (as->fmt) {
-    case AUD_FMT_S8:
-    case AUD_FMT_U8:
-        esdfmt |= ESD_BITS8;
-        obt_as.fmt = AUD_FMT_U8;
-        break;
-
-    case AUD_FMT_S16:
-    case AUD_FMT_U16:
-        esdfmt |= ESD_BITS16;
-        obt_as.fmt = AUD_FMT_S16;
-        break;
-
-    case AUD_FMT_S32:
-    case AUD_FMT_U32:
-        dolog ("Will use 16 instead of 32 bit samples\n");
-        esdfmt |= ESD_BITS16;
-        obt_as.fmt = AUD_FMT_S16;
-        break;
-    }
-    obt_as.endianness = AUDIO_HOST_ENDIANNESS;
-
-    audio_pcm_init_info (&hw->info, &obt_as);
-
-    hw->samples = conf.samples;
-    esd->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
-    if (!esd->pcm_buf) {
-        dolog ("Could not allocate buffer (%d bytes)\n",
-               hw->samples << hw->info.shift);
-        return -1;
-    }
-
-    esd->fd = esd_record_stream (esdfmt, as->freq, conf.adc_host, NULL);
-    if (esd->fd < 0) {
-        qesd_logerr (errno, "esd_record_stream failed\n");
-        goto fail1;
-    }
-
-    if (audio_pt_init (&esd->pt, qesd_thread_in, esd, AUDIO_CAP, AUDIO_FUNC)) {
-        goto fail2;
-    }
-
-    return 0;
-
- fail2:
-    if (close (esd->fd)) {
-        qesd_logerr (errno, "%s: close on esd socket(%d) failed\n",
-                     AUDIO_FUNC, esd->fd);
-    }
-    esd->fd = -1;
-
- fail1:
-    g_free (esd->pcm_buf);
-    esd->pcm_buf = NULL;
-    return -1;
-}
-
-static void qesd_fini_in (HWVoiceIn *hw)
-{
-    void *ret;
-    ESDVoiceIn *esd = (ESDVoiceIn *) hw;
-
-    audio_pt_lock (&esd->pt, AUDIO_FUNC);
-    esd->done = 1;
-    audio_pt_unlock_and_signal (&esd->pt, AUDIO_FUNC);
-    audio_pt_join (&esd->pt, &ret, AUDIO_FUNC);
-
-    if (esd->fd >= 0) {
-        if (close (esd->fd)) {
-            qesd_logerr (errno, "failed to close esd socket\n");
-        }
-        esd->fd = -1;
-    }
-
-    audio_pt_fini (&esd->pt, AUDIO_FUNC);
-
-    g_free (esd->pcm_buf);
-    esd->pcm_buf = NULL;
-}
-
-static int qesd_ctl_in (HWVoiceIn *hw, int cmd, ...)
-{
-    (void) hw;
-    (void) cmd;
-    return 0;
-}
-
-/* common */
-static void *qesd_audio_init (void)
-{
-    return &conf;
-}
-
-static void qesd_audio_fini (void *opaque)
-{
-    (void) opaque;
-    ldebug ("esd_fini");
-}
-
-struct audio_option qesd_options[] = {
-    {
-        .name  = "SAMPLES",
-        .tag   = AUD_OPT_INT,
-        .valp  = &conf.samples,
-        .descr = "buffer size in samples"
-    },
-    {
-        .name  = "DIVISOR",
-        .tag   = AUD_OPT_INT,
-        .valp  = &conf.divisor,
-        .descr = "threshold divisor"
-    },
-    {
-        .name  = "DAC_HOST",
-        .tag   = AUD_OPT_STR,
-        .valp  = &conf.dac_host,
-        .descr = "playback host"
-    },
-    {
-        .name  = "ADC_HOST",
-        .tag   = AUD_OPT_STR,
-        .valp  = &conf.adc_host,
-        .descr = "capture host"
-    },
-    { /* End of list */ }
-};
-
-static struct audio_pcm_ops qesd_pcm_ops = {
-    .init_out = qesd_init_out,
-    .fini_out = qesd_fini_out,
-    .run_out  = qesd_run_out,
-    .write    = qesd_write,
-    .ctl_out  = qesd_ctl_out,
-
-    .init_in  = qesd_init_in,
-    .fini_in  = qesd_fini_in,
-    .run_in   = qesd_run_in,
-    .read     = qesd_read,
-    .ctl_in   = qesd_ctl_in,
-};
-
-struct audio_driver esd_audio_driver = {
-    .name           = "esd",
-    .descr          = "http://en.wikipedia.org/wiki/Esound",
-    .options        = qesd_options,
-    .init           = qesd_audio_init,
-    .fini           = qesd_audio_fini,
-    .pcm_ops        = &qesd_pcm_ops,
-    .can_be_default = 0,
-    .max_voices_out = INT_MAX,
-    .max_voices_in  = INT_MAX,
-    .voice_size_out = sizeof (ESDVoiceOut),
-    .voice_size_in  = sizeof (ESDVoiceIn)
-};
diff --git a/audio/fmodaudio.c b/audio/fmodaudio.c
deleted file mode 100644
index fabf84dd3b..0000000000
--- a/audio/fmodaudio.c
+++ /dev/null
@@ -1,685 +0,0 @@
-/*
- * QEMU FMOD audio driver
- *
- * Copyright (c) 2004-2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include <fmod.h>
-#include <fmod_errors.h>
-#include "qemu-common.h"
-#include "audio.h"
-
-#define AUDIO_CAP "fmod"
-#include "audio_int.h"
-
-typedef struct FMODVoiceOut {
-    HWVoiceOut hw;
-    unsigned int old_pos;
-    FSOUND_SAMPLE *fmod_sample;
-    int channel;
-} FMODVoiceOut;
-
-typedef struct FMODVoiceIn {
-    HWVoiceIn hw;
-    FSOUND_SAMPLE *fmod_sample;
-} FMODVoiceIn;
-
-static struct {
-    const char *drvname;
-    int nb_samples;
-    int freq;
-    int nb_channels;
-    int bufsize;
-    int broken_adc;
-} conf = {
-    .nb_samples  = 2048 * 2,
-    .freq        = 44100,
-    .nb_channels = 2,
-};
-
-static void GCC_FMT_ATTR (1, 2) fmod_logerr (const char *fmt, ...)
-{
-    va_list ap;
-
-    va_start (ap, fmt);
-    AUD_vlog (AUDIO_CAP, fmt, ap);
-    va_end (ap);
-
-    AUD_log (AUDIO_CAP, "Reason: %s\n",
-             FMOD_ErrorString (FSOUND_GetError ()));
-}
-
-static void GCC_FMT_ATTR (2, 3) fmod_logerr2 (
-    const char *typ,
-    const char *fmt,
-    ...
-    )
-{
-    va_list ap;
-
-    AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
-
-    va_start (ap, fmt);
-    AUD_vlog (AUDIO_CAP, fmt, ap);
-    va_end (ap);
-
-    AUD_log (AUDIO_CAP, "Reason: %s\n",
-             FMOD_ErrorString (FSOUND_GetError ()));
-}
-
-static int fmod_write (SWVoiceOut *sw, void *buf, int len)
-{
-    return audio_pcm_sw_write (sw, buf, len);
-}
-
-static void fmod_clear_sample (FMODVoiceOut *fmd)
-{
-    HWVoiceOut *hw = &fmd->hw;
-    int status;
-    void *p1 = 0, *p2 = 0;
-    unsigned int len1 = 0, len2 = 0;
-
-    status = FSOUND_Sample_Lock (
-        fmd->fmod_sample,
-        0,
-        hw->samples << hw->info.shift,
-        &p1,
-        &p2,
-        &len1,
-        &len2
-        );
-
-    if (!status) {
-        fmod_logerr ("Failed to lock sample\n");
-        return;
-    }
-
-    if ((len1 & hw->info.align) || (len2 & hw->info.align)) {
-        dolog ("Lock returned misaligned length %d, %d, alignment %d\n",
-               len1, len2, hw->info.align + 1);
-        goto fail;
-    }
-
-    if ((len1 + len2) - (hw->samples << hw->info.shift)) {
-        dolog ("Lock returned incomplete length %d, %d\n",
-               len1 + len2, hw->samples << hw->info.shift);
-        goto fail;
-    }
-
-    audio_pcm_info_clear_buf (&hw->info, p1, hw->samples);
-
- fail:
-    status = FSOUND_Sample_Unlock (fmd->fmod_sample, p1, p2, len1, len2);
-    if (!status) {
-        fmod_logerr ("Failed to unlock sample\n");
-    }
-}
-
-static void fmod_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;
-    struct st_sample *src1 = hw->mix_buf + hw->rpos;
-    struct st_sample *src2 = NULL;
-
-    if (pos > hw->samples) {
-        src_len1 = hw->samples - hw->rpos;
-        src2 = hw->mix_buf;
-        src_len2 = dst_len - src_len1;
-        pos = src_len2;
-    }
-
-    if (src_len1) {
-        hw->clip (dst, src1, src_len1);
-    }
-
-    if (src_len2) {
-        dst = advance (dst, src_len1 << hw->info.shift);
-        hw->clip (dst, src2, src_len2);
-    }
-
-    hw->rpos = pos % hw->samples;
-}
-
-static int fmod_unlock_sample (FSOUND_SAMPLE *sample, void *p1, void *p2,
-                               unsigned int blen1, unsigned int blen2)
-{
-    int status = FSOUND_Sample_Unlock (sample, p1, p2, blen1, blen2);
-    if (!status) {
-        fmod_logerr ("Failed to unlock sample\n");
-        return -1;
-    }
-    return 0;
-}
-
-static int fmod_lock_sample (
-    FSOUND_SAMPLE *sample,
-    struct audio_pcm_info *info,
-    int pos,
-    int len,
-    void **p1,
-    void **p2,
-    unsigned int *blen1,
-    unsigned int *blen2
-    )
-{
-    int status;
-
-    status = FSOUND_Sample_Lock (
-        sample,
-        pos << info->shift,
-        len << info->shift,
-        p1,
-        p2,
-        blen1,
-        blen2
-        );
-
-    if (!status) {
-        fmod_logerr ("Failed to lock sample\n");
-        return -1;
-    }
-
-    if ((*blen1 & info->align) || (*blen2 & info->align)) {
-        dolog ("Lock returned misaligned length %d, %d, alignment %d\n",
-               *blen1, *blen2, info->align + 1);
-
-        fmod_unlock_sample (sample, *p1, *p2, *blen1, *blen2);
-
-        *p1 = NULL - 1;
-        *p2 = NULL - 1;
-        *blen1 = ~0U;
-        *blen2 = ~0U;
-        return -1;
-    }
-
-    if (!*p1 && *blen1) {
-        dolog ("warning: !p1 && blen1=%d\n", *blen1);
-        *blen1 = 0;
-    }
-
-    if (!p2 && *blen2) {
-        dolog ("warning: !p2 && blen2=%d\n", *blen2);
-        *blen2 = 0;
-    }
-
-    return 0;
-}
-
-static int fmod_run_out (HWVoiceOut *hw, int live)
-{
-    FMODVoiceOut *fmd = (FMODVoiceOut *) hw;
-    int decr;
-    void *p1 = 0, *p2 = 0;
-    unsigned int blen1 = 0, blen2 = 0;
-    unsigned int len1 = 0, len2 = 0;
-
-    if (!hw->pending_disable) {
-        return 0;
-    }
-
-    decr = live;
-
-    if (fmd->channel >= 0) {
-        int len = decr;
-        int old_pos = fmd->old_pos;
-        int ppos = FSOUND_GetCurrentPosition (fmd->channel);
-
-        if (ppos == old_pos || !ppos) {
-            return 0;
-        }
-
-        if ((old_pos < ppos) && ((old_pos + len) > ppos)) {
-            len = ppos - old_pos;
-        }
-        else {
-            if ((old_pos > ppos) && ((old_pos + len) > (ppos + hw->samples))) {
-                len = hw->samples - old_pos + ppos;
-            }
-        }
-        decr = len;
-
-        if (audio_bug (AUDIO_FUNC, decr < 0)) {
-            dolog ("decr=%d live=%d ppos=%d old_pos=%d len=%d\n",
-                   decr, live, ppos, old_pos, len);
-            return 0;
-        }
-    }
-
-
-    if (!decr) {
-        return 0;
-    }
-
-    if (fmod_lock_sample (fmd->fmod_sample, &fmd->hw.info,
-                          fmd->old_pos, decr,
-                          &p1, &p2,
-                          &blen1, &blen2)) {
-        return 0;
-    }
-
-    len1 = blen1 >> hw->info.shift;
-    len2 = blen2 >> hw->info.shift;
-    ldebug ("%p %p %d %d %d %d\n", p1, p2, len1, len2, blen1, blen2);
-    decr = len1 + len2;
-
-    if (p1 && len1) {
-        fmod_write_sample (hw, p1, len1);
-    }
-
-    if (p2 && len2) {
-        fmod_write_sample (hw, p2, len2);
-    }
-
-    fmod_unlock_sample (fmd->fmod_sample, p1, p2, blen1, blen2);
-
-    fmd->old_pos = (fmd->old_pos + decr) % hw->samples;
-    return decr;
-}
-
-static int aud_to_fmodfmt (audfmt_e fmt, int stereo)
-{
-    int mode = FSOUND_LOOP_NORMAL;
-
-    switch (fmt) {
-    case AUD_FMT_S8:
-        mode |= FSOUND_SIGNED | FSOUND_8BITS;
-        break;
-
-    case AUD_FMT_U8:
-        mode |= FSOUND_UNSIGNED | FSOUND_8BITS;
-        break;
-
-    case AUD_FMT_S16:
-        mode |= FSOUND_SIGNED | FSOUND_16BITS;
-        break;
-
-    case AUD_FMT_U16:
-        mode |= FSOUND_UNSIGNED | FSOUND_16BITS;
-        break;
-
-    default:
-        dolog ("Internal logic error: Bad audio format %d\n", fmt);
-#ifdef DEBUG_FMOD
-        abort ();
-#endif
-        mode |= FSOUND_8BITS;
-    }
-    mode |= stereo ? FSOUND_STEREO : FSOUND_MONO;
-    return mode;
-}
-
-static void fmod_fini_out (HWVoiceOut *hw)
-{
-    FMODVoiceOut *fmd = (FMODVoiceOut *) hw;
-
-    if (fmd->fmod_sample) {
-        FSOUND_Sample_Free (fmd->fmod_sample);
-        fmd->fmod_sample = 0;
-
-        if (fmd->channel >= 0) {
-            FSOUND_StopSound (fmd->channel);
-        }
-    }
-}
-
-static int fmod_init_out (HWVoiceOut *hw, struct audsettings *as)
-{
-    int mode, channel;
-    FMODVoiceOut *fmd = (FMODVoiceOut *) hw;
-    struct audsettings obt_as = *as;
-
-    mode = aud_to_fmodfmt (as->fmt, as->nchannels == 2 ? 1 : 0);
-    fmd->fmod_sample = FSOUND_Sample_Alloc (
-        FSOUND_FREE,            /* index */
-        conf.nb_samples,        /* length */
-        mode,                   /* mode */
-        as->freq,               /* freq */
-        255,                    /* volume */
-        128,                    /* pan */
-        255                     /* priority */
-        );
-
-    if (!fmd->fmod_sample) {
-        fmod_logerr2 ("DAC", "Failed to allocate FMOD sample\n");
-        return -1;
-    }
-
-    channel = FSOUND_PlaySoundEx (FSOUND_FREE, fmd->fmod_sample, 0, 1);
-    if (channel < 0) {
-        fmod_logerr2 ("DAC", "Failed to start playing sound\n");
-        FSOUND_Sample_Free (fmd->fmod_sample);
-        return -1;
-    }
-    fmd->channel = channel;
-
-    /* FMOD always operates on little endian frames? */
-    obt_as.endianness = 0;
-    audio_pcm_init_info (&hw->info, &obt_as);
-    hw->samples = conf.nb_samples;
-    return 0;
-}
-
-static int fmod_ctl_out (HWVoiceOut *hw, int cmd, ...)
-{
-    int status;
-    FMODVoiceOut *fmd = (FMODVoiceOut *) hw;
-
-    switch (cmd) {
-    case VOICE_ENABLE:
-        fmod_clear_sample (fmd);
-        status = FSOUND_SetPaused (fmd->channel, 0);
-        if (!status) {
-            fmod_logerr ("Failed to resume channel %d\n", fmd->channel);
-        }
-        break;
-
-    case VOICE_DISABLE:
-        status = FSOUND_SetPaused (fmd->channel, 1);
-        if (!status) {
-            fmod_logerr ("Failed to pause channel %d\n", fmd->channel);
-        }
-        break;
-    }
-    return 0;
-}
-
-static int fmod_init_in (HWVoiceIn *hw, struct audsettings *as)
-{
-    int mode;
-    FMODVoiceIn *fmd = (FMODVoiceIn *) hw;
-    struct audsettings obt_as = *as;
-
-    if (conf.broken_adc) {
-        return -1;
-    }
-
-    mode = aud_to_fmodfmt (as->fmt, as->nchannels == 2 ? 1 : 0);
-    fmd->fmod_sample = FSOUND_Sample_Alloc (
-        FSOUND_FREE,            /* index */
-        conf.nb_samples,        /* length */
-        mode,                   /* mode */
-        as->freq,               /* freq */
-        255,                    /* volume */
-        128,                    /* pan */
-        255                     /* priority */
-        );
-
-    if (!fmd->fmod_sample) {
-        fmod_logerr2 ("ADC", "Failed to allocate FMOD sample\n");
-        return -1;
-    }
-
-    /* FMOD always operates on little endian frames? */
-    obt_as.endianness = 0;
-    audio_pcm_init_info (&hw->info, &obt_as);
-    hw->samples = conf.nb_samples;
-    return 0;
-}
-
-static void fmod_fini_in (HWVoiceIn *hw)
-{
-    FMODVoiceIn *fmd = (FMODVoiceIn *) hw;
-
-    if (fmd->fmod_sample) {
-        FSOUND_Record_Stop ();
-        FSOUND_Sample_Free (fmd->fmod_sample);
-        fmd->fmod_sample = 0;
-    }
-}
-
-static int fmod_run_in (HWVoiceIn *hw)
-{
-    FMODVoiceIn *fmd = (FMODVoiceIn *) hw;
-    int hwshift = hw->info.shift;
-    int live, dead, new_pos, len;
-    unsigned int blen1 = 0, blen2 = 0;
-    unsigned int len1, len2;
-    unsigned int decr;
-    void *p1, *p2;
-
-    live = audio_pcm_hw_get_live_in (hw);
-    dead = hw->samples - live;
-    if (!dead) {
-        return 0;
-    }
-
-    new_pos = FSOUND_Record_GetPosition ();
-    if (new_pos < 0) {
-        fmod_logerr ("Could not get recording position\n");
-        return 0;
-    }
-
-    len = audio_ring_dist (new_pos,  hw->wpos, hw->samples);
-    if (!len) {
-        return 0;
-    }
-    len = audio_MIN (len, dead);
-
-    if (fmod_lock_sample (fmd->fmod_sample, &fmd->hw.info,
-                          hw->wpos, len,
-                          &p1, &p2,
-                          &blen1, &blen2)) {
-        return 0;
-    }
-
-    len1 = blen1 >> hwshift;
-    len2 = blen2 >> hwshift;
-    decr = len1 + len2;
-
-    if (p1 && blen1) {
-        hw->conv (hw->conv_buf + hw->wpos, p1, len1);
-    }
-    if (p2 && len2) {
-        hw->conv (hw->conv_buf, p2, len2);
-    }
-
-    fmod_unlock_sample (fmd->fmod_sample, p1, p2, blen1, blen2);
-    hw->wpos = (hw->wpos + decr) % hw->samples;
-    return decr;
-}
-
-static struct {
-    const char *name;
-    int type;
-} drvtab[] = {
-    { .name = "none",   .type = FSOUND_OUTPUT_NOSOUND },
-#ifdef _WIN32
-    { .name = "winmm",  .type = FSOUND_OUTPUT_WINMM   },
-    { .name = "dsound", .type = FSOUND_OUTPUT_DSOUND  },
-    { .name = "a3d",    .type = FSOUND_OUTPUT_A3D     },
-    { .name = "asio",   .type = FSOUND_OUTPUT_ASIO    },
-#endif
-#ifdef __linux__
-    { .name = "oss",    .type = FSOUND_OUTPUT_OSS     },
-    { .name = "alsa",   .type = FSOUND_OUTPUT_ALSA    },
-    { .name = "esd",    .type = FSOUND_OUTPUT_ESD     },
-#endif
-#ifdef __APPLE__
-    { .name = "mac",    .type = FSOUND_OUTPUT_MAC     },
-#endif
-#if 0
-    { .name = "xbox",   .type = FSOUND_OUTPUT_XBOX    },
-    { .name = "ps2",    .type = FSOUND_OUTPUT_PS2     },
-    { .name = "gcube",  .type = FSOUND_OUTPUT_GC      },
-#endif
-    { .name = "none-realtime", .type = FSOUND_OUTPUT_NOSOUND_NONREALTIME }
-};
-
-static void *fmod_audio_init (void)
-{
-    size_t i;
-    double ver;
-    int status;
-    int output_type = -1;
-    const char *drv = conf.drvname;
-
-    ver = FSOUND_GetVersion ();
-    if (ver < FMOD_VERSION) {
-        dolog ("Wrong FMOD version %f, need at least %f\n", ver, FMOD_VERSION);
-        return NULL;
-    }
-
-#ifdef __linux__
-    if (ver < 3.75) {
-        dolog ("FMOD before 3.75 has bug preventing ADC from working\n"
-               "ADC will be disabled.\n");
-        conf.broken_adc = 1;
-    }
-#endif
-
-    if (drv) {
-        int found = 0;
-        for (i = 0; i < ARRAY_SIZE (drvtab); i++) {
-            if (!strcmp (drv, drvtab[i].name)) {
-                output_type = drvtab[i].type;
-                found = 1;
-                break;
-            }
-        }
-        if (!found) {
-            dolog ("Unknown FMOD driver `%s'\n", drv);
-            dolog ("Valid drivers:\n");
-            for (i = 0; i < ARRAY_SIZE (drvtab); i++) {
-                dolog ("  %s\n", drvtab[i].name);
-            }
-        }
-    }
-
-    if (output_type != -1) {
-        status = FSOUND_SetOutput (output_type);
-        if (!status) {
-            fmod_logerr ("FSOUND_SetOutput(%d) failed\n", output_type);
-            return NULL;
-        }
-    }
-
-    if (conf.bufsize) {
-        status = FSOUND_SetBufferSize (conf.bufsize);
-        if (!status) {
-            fmod_logerr ("FSOUND_SetBufferSize (%d) failed\n", conf.bufsize);
-        }
-    }
-
-    status = FSOUND_Init (conf.freq, conf.nb_channels, 0);
-    if (!status) {
-        fmod_logerr ("FSOUND_Init failed\n");
-        return NULL;
-    }
-
-    return &conf;
-}
-
-static int fmod_read (SWVoiceIn *sw, void *buf, int size)
-{
-    return audio_pcm_sw_read (sw, buf, size);
-}
-
-static int fmod_ctl_in (HWVoiceIn *hw, int cmd, ...)
-{
-    int status;
-    FMODVoiceIn *fmd = (FMODVoiceIn *) hw;
-
-    switch (cmd) {
-    case VOICE_ENABLE:
-        status = FSOUND_Record_StartSample (fmd->fmod_sample, 1);
-        if (!status) {
-            fmod_logerr ("Failed to start recording\n");
-        }
-        break;
-
-    case VOICE_DISABLE:
-        status = FSOUND_Record_Stop ();
-        if (!status) {
-            fmod_logerr ("Failed to stop recording\n");
-        }
-        break;
-    }
-    return 0;
-}
-
-static void fmod_audio_fini (void *opaque)
-{
-    (void) opaque;
-    FSOUND_Close ();
-}
-
-static struct audio_option fmod_options[] = {
-    {
-        .name  = "DRV",
-        .tag   = AUD_OPT_STR,
-        .valp  = &conf.drvname,
-        .descr = "FMOD driver"
-    },
-    {
-        .name  = "FREQ",
-        .tag   = AUD_OPT_INT,
-        .valp  = &conf.freq,
-        .descr = "Default frequency"
-    },
-    {
-        .name  = "SAMPLES",
-        .tag   = AUD_OPT_INT,
-        .valp  = &conf.nb_samples,
-        .descr = "Buffer size in samples"
-    },
-    {
-        .name  = "CHANNELS",
-        .tag   = AUD_OPT_INT,
-        .valp  = &conf.nb_channels,
-        .descr = "Number of default channels (1 - mono, 2 - stereo)"
-    },
-    {
-        .name  = "BUFSIZE",
-        .tag   = AUD_OPT_INT,
-        .valp  = &conf.bufsize,
-        .descr = "(undocumented)"
-    },
-    { /* End of list */ }
-};
-
-static struct audio_pcm_ops fmod_pcm_ops = {
-    .init_out = fmod_init_out,
-    .fini_out = fmod_fini_out,
-    .run_out  = fmod_run_out,
-    .write    = fmod_write,
-    .ctl_out  = fmod_ctl_out,
-
-    .init_in  = fmod_init_in,
-    .fini_in  = fmod_fini_in,
-    .run_in   = fmod_run_in,
-    .read     = fmod_read,
-    .ctl_in   = fmod_ctl_in
-};
-
-struct audio_driver fmod_audio_driver = {
-    .name           = "fmod",
-    .descr          = "FMOD 3.xx http://www.fmod.org",
-    .options        = fmod_options,
-    .init           = fmod_audio_init,
-    .fini           = fmod_audio_fini,
-    .pcm_ops        = &fmod_pcm_ops,
-    .can_be_default = 1,
-    .max_voices_out = INT_MAX,
-    .max_voices_in  = INT_MAX,
-    .voice_size_out = sizeof (FMODVoiceOut),
-    .voice_size_in  = sizeof (FMODVoiceIn)
-};
diff --git a/audio/noaudio.c b/audio/noaudio.c
index cb386620ae..50db1f344b 100644
--- a/audio/noaudio.c
+++ b/audio/noaudio.c
@@ -63,7 +63,7 @@ static int no_write (SWVoiceOut *sw, void *buf, int len)
     return audio_pcm_sw_write (sw, buf, len);
 }
 
-static int no_init_out (HWVoiceOut *hw, struct audsettings *as)
+static int no_init_out(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque)
 {
     audio_pcm_init_info (&hw->info, as);
     hw->samples = 1024;
@@ -82,7 +82,7 @@ static int no_ctl_out (HWVoiceOut *hw, int cmd, ...)
     return 0;
 }
 
-static int no_init_in (HWVoiceIn *hw, struct audsettings *as)
+static int no_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
 {
     audio_pcm_init_info (&hw->info, as);
     hw->samples = 1024;
diff --git a/audio/ossaudio.c b/audio/ossaudio.c
index b9c6b30ca1..11e76a15a2 100644
--- a/audio/ossaudio.c
+++ b/audio/ossaudio.c
@@ -30,6 +30,7 @@
 #include "qemu/main-loop.h"
 #include "qemu/host-utils.h"
 #include "audio.h"
+#include "trace.h"
 
 #define AUDIO_CAP "oss"
 #include "audio_int.h"
@@ -38,6 +39,16 @@
 #define USE_DSP_POLICY
 #endif
 
+typedef struct OSSConf {
+    int try_mmap;
+    int nfrags;
+    int fragsize;
+    const char *devpath_out;
+    const char *devpath_in;
+    int exclusive;
+    int policy;
+} OSSConf;
+
 typedef struct OSSVoiceOut {
     HWVoiceOut hw;
     void *pcm_buf;
@@ -47,6 +58,7 @@ typedef struct OSSVoiceOut {
     int fragsize;
     int mmapped;
     int pending;
+    OSSConf *conf;
 } OSSVoiceOut;
 
 typedef struct OSSVoiceIn {
@@ -55,28 +67,9 @@ typedef struct OSSVoiceIn {
     int fd;
     int nfrags;
     int fragsize;
+    OSSConf *conf;
 } OSSVoiceIn;
 
-static struct {
-    int try_mmap;
-    int nfrags;
-    int fragsize;
-    const char *devpath_out;
-    const char *devpath_in;
-    int debug;
-    int exclusive;
-    int policy;
-} conf = {
-    .try_mmap = 0,
-    .nfrags = 4,
-    .fragsize = 4096,
-    .devpath_out = "/dev/dsp",
-    .devpath_in = "/dev/dsp",
-    .debug = 0,
-    .exclusive = 0,
-    .policy = 5
-};
-
 struct oss_params {
     int freq;
     audfmt_e fmt;
@@ -272,18 +265,18 @@ static int oss_get_version (int fd, int *version, const char *typ)
 #endif
 
 static int oss_open (int in, struct oss_params *req,
-                     struct oss_params *obt, int *pfd)
+                     struct oss_params *obt, int *pfd, OSSConf* conf)
 {
     int fd;
-    int oflags = conf.exclusive ? O_EXCL : 0;
+    int oflags = conf->exclusive ? O_EXCL : 0;
     audio_buf_info abinfo;
     int fmt, freq, nchannels;
     int setfragment = 1;
-    const char *dspname = in ? conf.devpath_in : conf.devpath_out;
+    const char *dspname = in ? conf->devpath_in : conf->devpath_out;
     const char *typ = in ? "ADC" : "DAC";
 
     /* Kludge needed to have working mmap on Linux */
-    oflags |= conf.try_mmap ? O_RDWR : (in ? O_RDONLY : O_WRONLY);
+    oflags |= conf->try_mmap ? O_RDWR : (in ? O_RDONLY : O_WRONLY);
 
     fd = open (dspname, oflags | O_NONBLOCK);
     if (-1 == fd) {
@@ -317,20 +310,18 @@ static int oss_open (int in, struct oss_params *req,
     }
 
 #ifdef USE_DSP_POLICY
-    if (conf.policy >= 0) {
+    if (conf->policy >= 0) {
         int version;
 
         if (!oss_get_version (fd, &version, typ)) {
-            if (conf.debug) {
-                dolog ("OSS version = %#x\n", version);
-            }
+            trace_oss_version(version);
 
             if (version >= 0x040000) {
-                int policy = conf.policy;
+                int policy = conf->policy;
                 if (ioctl (fd, SNDCTL_DSP_POLICY, &policy)) {
                     oss_logerr2 (errno, typ,
                                  "Failed to set timing policy to %d\n",
-                                 conf.policy);
+                                 conf->policy);
                     goto err;
                 }
                 setfragment = 0;
@@ -458,19 +449,12 @@ static int oss_run_out (HWVoiceOut *hw, int live)
         }
 
         if (abinfo.bytes > bufsize) {
-            if (conf.debug) {
-                dolog ("warning: Invalid available size, size=%d bufsize=%d\n"
-                       "please report your OS/audio hw to av1474@comtv.ru\n",
-                       abinfo.bytes, bufsize);
-            }
+            trace_oss_invalid_available_size(abinfo.bytes, bufsize);
             abinfo.bytes = bufsize;
         }
 
         if (abinfo.bytes < 0) {
-            if (conf.debug) {
-                dolog ("warning: Invalid available size, size=%d bufsize=%d\n",
-                       abinfo.bytes, bufsize);
-            }
+            trace_oss_invalid_available_size(abinfo.bytes, bufsize);
             return 0;
         }
 
@@ -510,7 +494,8 @@ static void oss_fini_out (HWVoiceOut *hw)
     }
 }
 
-static int oss_init_out (HWVoiceOut *hw, struct audsettings *as)
+static int oss_init_out(HWVoiceOut *hw, struct audsettings *as,
+                        void *drv_opaque)
 {
     OSSVoiceOut *oss = (OSSVoiceOut *) hw;
     struct oss_params req, obt;
@@ -519,16 +504,17 @@ static int oss_init_out (HWVoiceOut *hw, struct audsettings *as)
     int fd;
     audfmt_e effective_fmt;
     struct audsettings obt_as;
+    OSSConf *conf = drv_opaque;
 
     oss->fd = -1;
 
     req.fmt = aud_to_ossfmt (as->fmt, as->endianness);
     req.freq = as->freq;
     req.nchannels = as->nchannels;
-    req.fragsize = conf.fragsize;
-    req.nfrags = conf.nfrags;
+    req.fragsize = conf->fragsize;
+    req.nfrags = conf->nfrags;
 
-    if (oss_open (0, &req, &obt, &fd)) {
+    if (oss_open (0, &req, &obt, &fd, conf)) {
         return -1;
     }
 
@@ -555,7 +541,7 @@ static int oss_init_out (HWVoiceOut *hw, struct audsettings *as)
     hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift;
 
     oss->mmapped = 0;
-    if (conf.try_mmap) {
+    if (conf->try_mmap) {
         oss->pcm_buf = mmap (
             NULL,
             hw->samples << hw->info.shift,
@@ -615,6 +601,7 @@ static int oss_init_out (HWVoiceOut *hw, struct audsettings *as)
     }
 
     oss->fd = fd;
+    oss->conf = conf;
     return 0;
 }
 
@@ -677,7 +664,7 @@ static int oss_ctl_out (HWVoiceOut *hw, int cmd, ...)
     return 0;
 }
 
-static int oss_init_in (HWVoiceIn *hw, struct audsettings *as)
+static int oss_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
 {
     OSSVoiceIn *oss = (OSSVoiceIn *) hw;
     struct oss_params req, obt;
@@ -686,15 +673,16 @@ static int oss_init_in (HWVoiceIn *hw, struct audsettings *as)
     int fd;
     audfmt_e effective_fmt;
     struct audsettings obt_as;
+    OSSConf *conf = drv_opaque;
 
     oss->fd = -1;
 
     req.fmt = aud_to_ossfmt (as->fmt, as->endianness);
     req.freq = as->freq;
     req.nchannels = as->nchannels;
-    req.fragsize = conf.fragsize;
-    req.nfrags = conf.nfrags;
-    if (oss_open (1, &req, &obt, &fd)) {
+    req.fragsize = conf->fragsize;
+    req.nfrags = conf->nfrags;
+    if (oss_open (1, &req, &obt, &fd, conf)) {
         return -1;
     }
 
@@ -728,6 +716,7 @@ static int oss_init_in (HWVoiceIn *hw, struct audsettings *as)
     }
 
     oss->fd = fd;
+    oss->conf = conf;
     return 0;
 }
 
@@ -847,71 +836,78 @@ static int oss_ctl_in (HWVoiceIn *hw, int cmd, ...)
     return 0;
 }
 
+static OSSConf glob_conf = {
+    .try_mmap = 0,
+    .nfrags = 4,
+    .fragsize = 4096,
+    .devpath_out = "/dev/dsp",
+    .devpath_in = "/dev/dsp",
+    .exclusive = 0,
+    .policy = 5
+};
+
 static void *oss_audio_init (void)
 {
-    if (access(conf.devpath_in, R_OK | W_OK) < 0 ||
-        access(conf.devpath_out, R_OK | W_OK) < 0) {
+    OSSConf *conf = g_malloc(sizeof(OSSConf));
+    *conf = glob_conf;
+
+    if (access(conf->devpath_in, R_OK | W_OK) < 0 ||
+        access(conf->devpath_out, R_OK | W_OK) < 0) {
         return NULL;
     }
-    return &conf;
+    return conf;
 }
 
 static void oss_audio_fini (void *opaque)
 {
-    (void) opaque;
+    g_free(opaque);
 }
 
 static struct audio_option oss_options[] = {
     {
         .name  = "FRAGSIZE",
         .tag   = AUD_OPT_INT,
-        .valp  = &conf.fragsize,
+        .valp  = &glob_conf.fragsize,
         .descr = "Fragment size in bytes"
     },
     {
         .name  = "NFRAGS",
         .tag   = AUD_OPT_INT,
-        .valp  = &conf.nfrags,
+        .valp  = &glob_conf.nfrags,
         .descr = "Number of fragments"
     },
     {
         .name  = "MMAP",
         .tag   = AUD_OPT_BOOL,
-        .valp  = &conf.try_mmap,
+        .valp  = &glob_conf.try_mmap,
         .descr = "Try using memory mapped access"
     },
     {
         .name  = "DAC_DEV",
         .tag   = AUD_OPT_STR,
-        .valp  = &conf.devpath_out,
+        .valp  = &glob_conf.devpath_out,
         .descr = "Path to DAC device"
     },
     {
         .name  = "ADC_DEV",
         .tag   = AUD_OPT_STR,
-        .valp  = &conf.devpath_in,
+        .valp  = &glob_conf.devpath_in,
         .descr = "Path to ADC device"
     },
     {
         .name  = "EXCLUSIVE",
         .tag   = AUD_OPT_BOOL,
-        .valp  = &conf.exclusive,
+        .valp  = &glob_conf.exclusive,
         .descr = "Open device in exclusive mode (vmix wont work)"
     },
 #ifdef USE_DSP_POLICY
     {
         .name  = "POLICY",
         .tag   = AUD_OPT_INT,
-        .valp  = &conf.policy,
+        .valp  = &glob_conf.policy,
         .descr = "Set the timing policy of the device, -1 to use fragment mode",
     },
 #endif
-    {
-        .name  = "DEBUG",
-        .tag   = AUD_OPT_BOOL,
-        .valp  = &conf.debug,
-        .descr = "Turn on some debugging messages"
-    },
     { /* End of list */ }
 };
 
diff --git a/audio/paaudio.c b/audio/paaudio.c
index 90ff24500b..fea607166f 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -9,6 +9,19 @@
 #include "audio_pt_int.h"
 
 typedef struct {
+    int samples;
+    char *server;
+    char *sink;
+    char *source;
+} PAConf;
+
+typedef struct {
+    PAConf conf;
+    pa_threaded_mainloop *mainloop;
+    pa_context *context;
+} paaudio;
+
+typedef struct {
     HWVoiceOut hw;
     int done;
     int live;
@@ -17,6 +30,7 @@ typedef struct {
     pa_stream *stream;
     void *pcm_buf;
     struct audio_pt pt;
+    paaudio *g;
 } PAVoiceOut;
 
 typedef struct {
@@ -30,20 +44,10 @@ typedef struct {
     struct audio_pt pt;
     const void *read_data;
     size_t read_index, read_length;
+    paaudio *g;
 } PAVoiceIn;
 
-typedef struct {
-    int samples;
-    char *server;
-    char *sink;
-    char *source;
-    pa_threaded_mainloop *mainloop;
-    pa_context *context;
-} paaudio;
-
-static paaudio glob_paaudio = {
-    .samples = 4096,
-};
+static void qpa_audio_fini(void *opaque);
 
 static void GCC_FMT_ATTR (2, 3) qpa_logerr (int err, const char *fmt, ...)
 {
@@ -106,7 +110,7 @@ static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x)
 
 static int qpa_simple_read (PAVoiceIn *p, void *data, size_t length, int *rerror)
 {
-    paaudio *g = &glob_paaudio;
+    paaudio *g = p->g;
 
     pa_threaded_mainloop_lock (g->mainloop);
 
@@ -160,7 +164,7 @@ unlock_and_fail:
 
 static int qpa_simple_write (PAVoiceOut *p, const void *data, size_t length, int *rerror)
 {
-    paaudio *g = &glob_paaudio;
+    paaudio *g = p->g;
 
     pa_threaded_mainloop_lock (g->mainloop);
 
@@ -222,7 +226,7 @@ static void *qpa_thread_out (void *arg)
             }
         }
 
-        decr = to_mix = audio_MIN (pa->live, glob_paaudio.samples >> 2);
+        decr = to_mix = audio_MIN (pa->live, pa->g->conf.samples >> 2);
         rpos = pa->rpos;
 
         if (audio_pt_unlock (&pa->pt, AUDIO_FUNC)) {
@@ -314,7 +318,7 @@ static void *qpa_thread_in (void *arg)
             }
         }
 
-        incr = to_grab = audio_MIN (pa->dead, glob_paaudio.samples >> 2);
+        incr = to_grab = audio_MIN (pa->dead, pa->g->conf.samples >> 2);
         wpos = pa->wpos;
 
         if (audio_pt_unlock (&pa->pt, AUDIO_FUNC)) {
@@ -430,7 +434,7 @@ static audfmt_e pa_to_audfmt (pa_sample_format_t fmt, int *endianness)
 
 static void context_state_cb (pa_context *c, void *userdata)
 {
-    paaudio *g = &glob_paaudio;
+    paaudio *g = userdata;
 
     switch (pa_context_get_state(c)) {
     case PA_CONTEXT_READY:
@@ -449,7 +453,7 @@ static void context_state_cb (pa_context *c, void *userdata)
 
 static void stream_state_cb (pa_stream *s, void * userdata)
 {
-    paaudio *g = &glob_paaudio;
+    paaudio *g = userdata;
 
     switch (pa_stream_get_state (s)) {
 
@@ -467,23 +471,21 @@ static void stream_state_cb (pa_stream *s, void * userdata)
 
 static void stream_request_cb (pa_stream *s, size_t length, void *userdata)
 {
-    paaudio *g = &glob_paaudio;
+    paaudio *g = userdata;
 
     pa_threaded_mainloop_signal (g->mainloop, 0);
 }
 
 static pa_stream *qpa_simple_new (
-        const char *server,
+        paaudio *g,
         const char *name,
         pa_stream_direction_t dir,
         const char *dev,
-        const char *stream_name,
         const pa_sample_spec *ss,
         const pa_channel_map *map,
         const pa_buffer_attr *attr,
         int *rerror)
 {
-    paaudio *g = &glob_paaudio;
     int r;
     pa_stream *stream;
 
@@ -534,13 +536,15 @@ fail:
     return NULL;
 }
 
-static int qpa_init_out (HWVoiceOut *hw, struct audsettings *as)
+static int qpa_init_out(HWVoiceOut *hw, struct audsettings *as,
+                        void *drv_opaque)
 {
     int error;
-    static pa_sample_spec ss;
-    static pa_buffer_attr ba;
+    pa_sample_spec ss;
+    pa_buffer_attr ba;
     struct audsettings obt_as = *as;
     PAVoiceOut *pa = (PAVoiceOut *) hw;
+    paaudio *g = pa->g = drv_opaque;
 
     ss.format = audfmt_to_pa (as->fmt, as->endianness);
     ss.channels = as->nchannels;
@@ -558,11 +562,10 @@ static int qpa_init_out (HWVoiceOut *hw, struct audsettings *as)
     obt_as.fmt = pa_to_audfmt (ss.format, &obt_as.endianness);
 
     pa->stream = qpa_simple_new (
-        glob_paaudio.server,
+        g,
         "qemu",
         PA_STREAM_PLAYBACK,
-        glob_paaudio.sink,
-        "pcm.playback",
+        g->conf.sink,
         &ss,
         NULL,                   /* channel map */
         &ba,                    /* buffering attributes */
@@ -574,7 +577,7 @@ static int qpa_init_out (HWVoiceOut *hw, struct audsettings *as)
     }
 
     audio_pcm_init_info (&hw->info, &obt_as);
-    hw->samples = glob_paaudio.samples;
+    hw->samples = g->conf.samples;
     pa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
     pa->rpos = hw->rpos;
     if (!pa->pcm_buf) {
@@ -601,12 +604,13 @@ static int qpa_init_out (HWVoiceOut *hw, struct audsettings *as)
     return -1;
 }
 
-static int qpa_init_in (HWVoiceIn *hw, struct audsettings *as)
+static int qpa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
 {
     int error;
-    static pa_sample_spec ss;
+    pa_sample_spec ss;
     struct audsettings obt_as = *as;
     PAVoiceIn *pa = (PAVoiceIn *) hw;
+    paaudio *g = pa->g = drv_opaque;
 
     ss.format = audfmt_to_pa (as->fmt, as->endianness);
     ss.channels = as->nchannels;
@@ -615,11 +619,10 @@ static int qpa_init_in (HWVoiceIn *hw, struct audsettings *as)
     obt_as.fmt = pa_to_audfmt (ss.format, &obt_as.endianness);
 
     pa->stream = qpa_simple_new (
-        glob_paaudio.server,
+        g,
         "qemu",
         PA_STREAM_RECORD,
-        glob_paaudio.source,
-        "pcm.capture",
+        g->conf.source,
         &ss,
         NULL,                   /* channel map */
         NULL,                   /* buffering attributes */
@@ -631,7 +634,7 @@ static int qpa_init_in (HWVoiceIn *hw, struct audsettings *as)
     }
 
     audio_pcm_init_info (&hw->info, &obt_as);
-    hw->samples = glob_paaudio.samples;
+    hw->samples = g->conf.samples;
     pa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
     pa->wpos = hw->wpos;
     if (!pa->pcm_buf) {
@@ -703,7 +706,7 @@ static int qpa_ctl_out (HWVoiceOut *hw, int cmd, ...)
     PAVoiceOut *pa = (PAVoiceOut *) hw;
     pa_operation *op;
     pa_cvolume v;
-    paaudio *g = &glob_paaudio;
+    paaudio *g = pa->g;
 
 #ifdef PA_CHECK_VERSION    /* macro is present in 0.9.16+ */
     pa_cvolume_init (&v);  /* function is present in 0.9.13+ */
@@ -755,7 +758,7 @@ static int qpa_ctl_in (HWVoiceIn *hw, int cmd, ...)
     PAVoiceIn *pa = (PAVoiceIn *) hw;
     pa_operation *op;
     pa_cvolume v;
-    paaudio *g = &glob_paaudio;
+    paaudio *g = pa->g;
 
 #ifdef PA_CHECK_VERSION
     pa_cvolume_init (&v);
@@ -805,23 +808,31 @@ static int qpa_ctl_in (HWVoiceIn *hw, int cmd, ...)
 }
 
 /* common */
+static PAConf glob_conf = {
+    .samples = 4096,
+};
+
 static void *qpa_audio_init (void)
 {
-    paaudio *g = &glob_paaudio;
+    paaudio *g = g_malloc(sizeof(paaudio));
+    g->conf = glob_conf;
+    g->mainloop = NULL;
+    g->context = NULL;
 
     g->mainloop = pa_threaded_mainloop_new ();
     if (!g->mainloop) {
         goto fail;
     }
 
-    g->context = pa_context_new (pa_threaded_mainloop_get_api (g->mainloop), glob_paaudio.server);
+    g->context = pa_context_new (pa_threaded_mainloop_get_api (g->mainloop),
+                                 g->conf.server);
     if (!g->context) {
         goto fail;
     }
 
     pa_context_set_state_callback (g->context, context_state_cb, g);
 
-    if (pa_context_connect (g->context, glob_paaudio.server, 0, NULL) < 0) {
+    if (pa_context_connect (g->context, g->conf.server, 0, NULL) < 0) {
         qpa_logerr (pa_context_errno (g->context),
                     "pa_context_connect() failed\n");
         goto fail;
@@ -854,12 +865,13 @@ static void *qpa_audio_init (void)
 
     pa_threaded_mainloop_unlock (g->mainloop);
 
-    return &glob_paaudio;
+    return g;
 
 unlock_and_fail:
     pa_threaded_mainloop_unlock (g->mainloop);
 fail:
     AUD_log (AUDIO_CAP, "Failed to initialize PA context");
+    qpa_audio_fini(g);
     return NULL;
 }
 
@@ -874,39 +886,38 @@ static void qpa_audio_fini (void *opaque)
     if (g->context) {
         pa_context_disconnect (g->context);
         pa_context_unref (g->context);
-        g->context = NULL;
     }
 
     if (g->mainloop) {
         pa_threaded_mainloop_free (g->mainloop);
     }
 
-    g->mainloop = NULL;
+    g_free(g);
 }
 
 struct audio_option qpa_options[] = {
     {
         .name  = "SAMPLES",
         .tag   = AUD_OPT_INT,
-        .valp  = &glob_paaudio.samples,
+        .valp  = &glob_conf.samples,
         .descr = "buffer size in samples"
     },
     {
         .name  = "SERVER",
         .tag   = AUD_OPT_STR,
-        .valp  = &glob_paaudio.server,
+        .valp  = &glob_conf.server,
         .descr = "server address"
     },
     {
         .name  = "SINK",
         .tag   = AUD_OPT_STR,
-        .valp  = &glob_paaudio.sink,
+        .valp  = &glob_conf.sink,
         .descr = "sink device name"
     },
     {
         .name  = "SOURCE",
         .tag   = AUD_OPT_STR,
-        .valp  = &glob_paaudio.source,
+        .valp  = &glob_conf.source,
         .descr = "source device name"
     },
     { /* End of list */ }
diff --git a/audio/sdlaudio.c b/audio/sdlaudio.c
index d24daa5ead..1140f2ea0a 100644
--- a/audio/sdlaudio.c
+++ b/audio/sdlaudio.c
@@ -55,6 +55,7 @@ static struct SDLAudioState {
     SDL_mutex *mutex;
     SDL_sem *sem;
     int initialized;
+    bool driver_created;
 } glob_sdl;
 typedef struct SDLAudioState SDLAudioState;
 
@@ -332,7 +333,8 @@ static void sdl_fini_out (HWVoiceOut *hw)
     sdl_close (&glob_sdl);
 }
 
-static int sdl_init_out (HWVoiceOut *hw, struct audsettings *as)
+static int sdl_init_out(HWVoiceOut *hw, struct audsettings *as,
+                        void *drv_opaque)
 {
     SDLVoiceOut *sdl = (SDLVoiceOut *) hw;
     SDLAudioState *s = &glob_sdl;
@@ -392,6 +394,10 @@ static int sdl_ctl_out (HWVoiceOut *hw, int cmd, ...)
 static void *sdl_audio_init (void)
 {
     SDLAudioState *s = &glob_sdl;
+    if (s->driver_created) {
+        sdl_logerr("Can't create multiple sdl backends\n");
+        return NULL;
+    }
 
     if (SDL_InitSubSystem (SDL_INIT_AUDIO)) {
         sdl_logerr ("SDL failed to initialize audio subsystem\n");
@@ -413,6 +419,7 @@ static void *sdl_audio_init (void)
         return NULL;
     }
 
+    s->driver_created = true;
     return s;
 }
 
@@ -423,6 +430,7 @@ static void sdl_audio_fini (void *opaque)
     SDL_DestroySemaphore (s->sem);
     SDL_DestroyMutex (s->mutex);
     SDL_QuitSubSystem (SDL_INIT_AUDIO);
+    s->driver_created = false;
 }
 
 static struct audio_option sdl_options[] = {
diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c
index 7b79bedca2..5c6f726757 100644
--- a/audio/spiceaudio.c
+++ b/audio/spiceaudio.c
@@ -115,7 +115,8 @@ static int rate_get_samples (struct audio_pcm_info *info, SpiceRateCtl *rate)
 
 /* playback */
 
-static int line_out_init (HWVoiceOut *hw, struct audsettings *as)
+static int line_out_init(HWVoiceOut *hw, struct audsettings *as,
+                         void *drv_opaque)
 {
     SpiceVoiceOut *out = container_of (hw, SpiceVoiceOut, hw);
     struct audsettings settings;
@@ -243,7 +244,7 @@ static int line_out_ctl (HWVoiceOut *hw, int cmd, ...)
 
 /* record */
 
-static int line_in_init (HWVoiceIn *hw, struct audsettings *as)
+static int line_in_init(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
 {
     SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw);
     struct audsettings settings;
diff --git a/audio/wavaudio.c b/audio/wavaudio.c
index 6846a1a9f7..c586020c59 100644
--- a/audio/wavaudio.c
+++ b/audio/wavaudio.c
@@ -36,15 +36,10 @@ typedef struct WAVVoiceOut {
     int total_samples;
 } WAVVoiceOut;
 
-static struct {
+typedef struct {
     struct audsettings settings;
     const char *wav_path;
-} conf = {
-    .settings.freq      = 44100,
-    .settings.nchannels = 2,
-    .settings.fmt       = AUD_FMT_S16,
-    .wav_path           = "qemu.wav"
-};
+} WAVConf;
 
 static int wav_run_out (HWVoiceOut *hw, int live)
 {
@@ -105,7 +100,8 @@ static void le_store (uint8_t *buf, uint32_t val, int len)
     }
 }
 
-static int wav_init_out (HWVoiceOut *hw, struct audsettings *as)
+static int wav_init_out(HWVoiceOut *hw, struct audsettings *as,
+                        void *drv_opaque)
 {
     WAVVoiceOut *wav = (WAVVoiceOut *) hw;
     int bits16 = 0, stereo = 0;
@@ -115,9 +111,8 @@ static int wav_init_out (HWVoiceOut *hw, struct audsettings *as)
         0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04,
         0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00
     };
-    struct audsettings wav_as = conf.settings;
-
-    (void) as;
+    WAVConf *conf = drv_opaque;
+    struct audsettings wav_as = conf->settings;
 
     stereo = wav_as.nchannels == 2;
     switch (wav_as.fmt) {
@@ -155,10 +150,10 @@ static int wav_init_out (HWVoiceOut *hw, struct audsettings *as)
     le_store (hdr + 28, hw->info.freq << (bits16 + stereo), 4);
     le_store (hdr + 32, 1 << (bits16 + stereo), 2);
 
-    wav->f = fopen (conf.wav_path, "wb");
+    wav->f = fopen (conf->wav_path, "wb");
     if (!wav->f) {
         dolog ("Failed to open wave file `%s'\nReason: %s\n",
-               conf.wav_path, strerror (errno));
+               conf->wav_path, strerror (errno));
         g_free (wav->pcm_buf);
         wav->pcm_buf = NULL;
         return -1;
@@ -226,40 +221,49 @@ static int wav_ctl_out (HWVoiceOut *hw, int cmd, ...)
     return 0;
 }
 
+static WAVConf glob_conf = {
+    .settings.freq      = 44100,
+    .settings.nchannels = 2,
+    .settings.fmt       = AUD_FMT_S16,
+    .wav_path           = "qemu.wav"
+};
+
 static void *wav_audio_init (void)
 {
-    return &conf;
+    WAVConf *conf = g_malloc(sizeof(WAVConf));
+    *conf = glob_conf;
+    return conf;
 }
 
 static void wav_audio_fini (void *opaque)
 {
-    (void) opaque;
     ldebug ("wav_fini");
+    g_free(opaque);
 }
 
 static struct audio_option wav_options[] = {
     {
         .name  = "FREQUENCY",
         .tag   = AUD_OPT_INT,
-        .valp  = &conf.settings.freq,
+        .valp  = &glob_conf.settings.freq,
         .descr = "Frequency"
     },
     {
         .name  = "FORMAT",
         .tag   = AUD_OPT_FMT,
-        .valp  = &conf.settings.fmt,
+        .valp  = &glob_conf.settings.fmt,
         .descr = "Format"
     },
     {
         .name  = "DAC_FIXED_CHANNELS",
         .tag   = AUD_OPT_INT,
-        .valp  = &conf.settings.nchannels,
+        .valp  = &glob_conf.settings.nchannels,
         .descr = "Number of channels (1 - mono, 2 - stereo)"
     },
     {
         .name  = "PATH",
         .tag   = AUD_OPT_STR,
-        .valp  = &conf.wav_path,
+        .valp  = &glob_conf.wav_path,
         .descr = "Path to wave file"
     },
     { /* End of list */ }
diff --git a/audio/winwaveaudio.c b/audio/winwaveaudio.c
deleted file mode 100644
index 8dbd145ca1..0000000000
--- a/audio/winwaveaudio.c
+++ /dev/null
@@ -1,717 +0,0 @@
-/* public domain */
-
-#include "qemu-common.h"
-#include "sysemu/sysemu.h"
-#include "audio.h"
-
-#define AUDIO_CAP "winwave"
-#include "audio_int.h"
-
-#include <windows.h>
-#include <mmsystem.h>
-
-#include "audio_win_int.h"
-
-static struct {
-    int dac_headers;
-    int dac_samples;
-    int adc_headers;
-    int adc_samples;
-} conf = {
-    .dac_headers = 4,
-    .dac_samples = 1024,
-    .adc_headers = 4,
-    .adc_samples = 1024
-};
-
-typedef struct {
-    HWVoiceOut hw;
-    HWAVEOUT hwo;
-    WAVEHDR *hdrs;
-    HANDLE event;
-    void *pcm_buf;
-    int avail;
-    int pending;
-    int curhdr;
-    int paused;
-    CRITICAL_SECTION crit_sect;
-} WaveVoiceOut;
-
-typedef struct {
-    HWVoiceIn hw;
-    HWAVEIN hwi;
-    WAVEHDR *hdrs;
-    HANDLE event;
-    void *pcm_buf;
-    int curhdr;
-    int paused;
-    int rpos;
-    int avail;
-    CRITICAL_SECTION crit_sect;
-} WaveVoiceIn;
-
-static void winwave_log_mmresult (MMRESULT mr)
-{
-    const char *str = "BUG";
-
-    switch (mr) {
-    case MMSYSERR_NOERROR:
-        str = "Success";
-        break;
-
-    case MMSYSERR_INVALHANDLE:
-        str = "Specified device handle is invalid";
-        break;
-
-    case MMSYSERR_BADDEVICEID:
-        str = "Specified device id is out of range";
-        break;
-
-    case MMSYSERR_NODRIVER:
-        str = "No device driver is present";
-        break;
-
-    case MMSYSERR_NOMEM:
-        str = "Unable to allocate or lock memory";
-        break;
-
-    case WAVERR_SYNC:
-        str = "Device is synchronous but waveOutOpen was called "
-            "without using the WINWAVE_ALLOWSYNC flag";
-        break;
-
-    case WAVERR_UNPREPARED:
-        str = "The data block pointed to by the pwh parameter "
-            "hasn't been prepared";
-        break;
-
-    case WAVERR_STILLPLAYING:
-        str = "There are still buffers in the queue";
-        break;
-
-    default:
-        dolog ("Reason: Unknown (MMRESULT %#x)\n", mr);
-        return;
-    }
-
-    dolog ("Reason: %s\n", str);
-}
-
-static void GCC_FMT_ATTR (2, 3) winwave_logerr (
-    MMRESULT mr,
-    const char *fmt,
-    ...
-    )
-{
-    va_list ap;
-
-    va_start (ap, fmt);
-    AUD_vlog (AUDIO_CAP, fmt, ap);
-    va_end (ap);
-
-    AUD_log (NULL, " failed\n");
-    winwave_log_mmresult (mr);
-}
-
-static void winwave_anal_close_out (WaveVoiceOut *wave)
-{
-    MMRESULT mr;
-
-    mr = waveOutClose (wave->hwo);
-    if (mr != MMSYSERR_NOERROR) {
-        winwave_logerr (mr, "waveOutClose");
-    }
-    wave->hwo = NULL;
-}
-
-static void CALLBACK winwave_callback_out (
-    HWAVEOUT hwo,
-    UINT msg,
-    DWORD_PTR dwInstance,
-    DWORD_PTR dwParam1,
-    DWORD_PTR dwParam2
-    )
-{
-    WaveVoiceOut *wave = (WaveVoiceOut *) dwInstance;
-
-    switch (msg) {
-    case WOM_DONE:
-        {
-            WAVEHDR *h = (WAVEHDR *) dwParam1;
-            if (!h->dwUser) {
-                h->dwUser = 1;
-                EnterCriticalSection (&wave->crit_sect);
-                {
-                    wave->avail += conf.dac_samples;
-                }
-                LeaveCriticalSection (&wave->crit_sect);
-                if (wave->hw.poll_mode) {
-                    if (!SetEvent (wave->event)) {
-                        dolog ("DAC SetEvent failed %lx\n", GetLastError ());
-                    }
-                }
-            }
-        }
-        break;
-
-    case WOM_CLOSE:
-    case WOM_OPEN:
-        break;
-
-    default:
-        dolog ("unknown wave out callback msg %x\n", msg);
-    }
-}
-
-static int winwave_init_out (HWVoiceOut *hw, struct audsettings *as)
-{
-    int i;
-    int err;
-    MMRESULT mr;
-    WAVEFORMATEX wfx;
-    WaveVoiceOut *wave;
-
-    wave = (WaveVoiceOut *) hw;
-
-    InitializeCriticalSection (&wave->crit_sect);
-
-    err = waveformat_from_audio_settings (&wfx, as);
-    if (err) {
-        goto err0;
-    }
-
-    mr = waveOutOpen (&wave->hwo, WAVE_MAPPER, &wfx,
-                      (DWORD_PTR) winwave_callback_out,
-                      (DWORD_PTR) wave, CALLBACK_FUNCTION);
-    if (mr != MMSYSERR_NOERROR) {
-        winwave_logerr (mr, "waveOutOpen");
-        goto err1;
-    }
-
-    wave->hdrs = audio_calloc (AUDIO_FUNC, conf.dac_headers,
-                               sizeof (*wave->hdrs));
-    if (!wave->hdrs) {
-        goto err2;
-    }
-
-    audio_pcm_init_info (&hw->info, as);
-    hw->samples = conf.dac_samples * conf.dac_headers;
-    wave->avail = hw->samples;
-
-    wave->pcm_buf = audio_calloc (AUDIO_FUNC, conf.dac_samples,
-                                  conf.dac_headers << hw->info.shift);
-    if (!wave->pcm_buf) {
-        goto err3;
-    }
-
-    for (i = 0; i < conf.dac_headers; ++i) {
-        WAVEHDR *h = &wave->hdrs[i];
-
-        h->dwUser = 0;
-        h->dwBufferLength = conf.dac_samples << hw->info.shift;
-        h->lpData = advance (wave->pcm_buf, i * h->dwBufferLength);
-        h->dwFlags = 0;
-
-        mr = waveOutPrepareHeader (wave->hwo, h, sizeof (*h));
-        if (mr != MMSYSERR_NOERROR) {
-            winwave_logerr (mr, "waveOutPrepareHeader(%d)", i);
-            goto err4;
-        }
-    }
-
-    return 0;
-
- err4:
-    g_free (wave->pcm_buf);
- err3:
-    g_free (wave->hdrs);
- err2:
-    winwave_anal_close_out (wave);
- err1:
- err0:
-    return -1;
-}
-
-static int winwave_write (SWVoiceOut *sw, void *buf, int len)
-{
-    return audio_pcm_sw_write (sw, buf, len);
-}
-
-static int winwave_run_out (HWVoiceOut *hw, int live)
-{
-    WaveVoiceOut *wave = (WaveVoiceOut *) hw;
-    int decr;
-    int doreset;
-
-    EnterCriticalSection (&wave->crit_sect);
-    {
-        decr = audio_MIN (live, wave->avail);
-        decr = audio_pcm_hw_clip_out (hw, wave->pcm_buf, decr, wave->pending);
-        wave->pending += decr;
-        wave->avail -= decr;
-    }
-    LeaveCriticalSection (&wave->crit_sect);
-
-    doreset = hw->poll_mode && (wave->pending >= conf.dac_samples);
-    if (doreset && !ResetEvent (wave->event)) {
-        dolog ("DAC ResetEvent failed %lx\n", GetLastError ());
-    }
-
-    while (wave->pending >= conf.dac_samples) {
-        MMRESULT mr;
-        WAVEHDR *h = &wave->hdrs[wave->curhdr];
-
-        h->dwUser = 0;
-        mr = waveOutWrite (wave->hwo, h, sizeof (*h));
-        if (mr != MMSYSERR_NOERROR) {
-            winwave_logerr (mr, "waveOutWrite(%d)", wave->curhdr);
-            break;
-        }
-
-        wave->pending -= conf.dac_samples;
-        wave->curhdr = (wave->curhdr + 1) % conf.dac_headers;
-    }
-
-    return decr;
-}
-
-static void winwave_poll (void *opaque)
-{
-    (void) opaque;
-    audio_run ("winwave_poll");
-}
-
-static void winwave_fini_out (HWVoiceOut *hw)
-{
-    int i;
-    MMRESULT mr;
-    WaveVoiceOut *wave = (WaveVoiceOut *) hw;
-
-    mr = waveOutReset (wave->hwo);
-    if (mr != MMSYSERR_NOERROR) {
-        winwave_logerr (mr, "waveOutReset");
-    }
-
-    for (i = 0; i < conf.dac_headers; ++i) {
-        mr = waveOutUnprepareHeader (wave->hwo, &wave->hdrs[i],
-                                     sizeof (wave->hdrs[i]));
-        if (mr != MMSYSERR_NOERROR) {
-            winwave_logerr (mr, "waveOutUnprepareHeader(%d)", i);
-        }
-    }
-
-    winwave_anal_close_out (wave);
-
-    if (wave->event) {
-        qemu_del_wait_object (wave->event, winwave_poll, wave);
-        if (!CloseHandle (wave->event)) {
-            dolog ("DAC CloseHandle failed %lx\n", GetLastError ());
-        }
-        wave->event = NULL;
-    }
-
-    g_free (wave->pcm_buf);
-    wave->pcm_buf = NULL;
-
-    g_free (wave->hdrs);
-    wave->hdrs = NULL;
-}
-
-static int winwave_ctl_out (HWVoiceOut *hw, int cmd, ...)
-{
-    MMRESULT mr;
-    WaveVoiceOut *wave = (WaveVoiceOut *) hw;
-
-    switch (cmd) {
-    case VOICE_ENABLE:
-        {
-            va_list ap;
-            int poll_mode;
-
-            va_start (ap, cmd);
-            poll_mode = va_arg (ap, int);
-            va_end (ap);
-
-            if (poll_mode && !wave->event) {
-                wave->event = CreateEvent (NULL, TRUE, TRUE, NULL);
-                if (!wave->event) {
-                    dolog ("DAC CreateEvent: %lx, poll mode will be disabled\n",
-                           GetLastError ());
-                }
-            }
-
-            if (wave->event) {
-                int ret;
-
-                ret = qemu_add_wait_object (wave->event, winwave_poll, wave);
-                hw->poll_mode = (ret == 0);
-            }
-            else {
-                hw->poll_mode = 0;
-            }
-            wave->paused = 0;
-        }
-        return 0;
-
-    case VOICE_DISABLE:
-        if (!wave->paused) {
-            mr = waveOutReset (wave->hwo);
-            if (mr != MMSYSERR_NOERROR) {
-                winwave_logerr (mr, "waveOutReset");
-            }
-            else {
-                wave->paused = 1;
-            }
-        }
-        if (wave->event) {
-            qemu_del_wait_object (wave->event, winwave_poll, wave);
-        }
-        return 0;
-    }
-    return -1;
-}
-
-static void winwave_anal_close_in (WaveVoiceIn *wave)
-{
-    MMRESULT mr;
-
-    mr = waveInClose (wave->hwi);
-    if (mr != MMSYSERR_NOERROR) {
-        winwave_logerr (mr, "waveInClose");
-    }
-    wave->hwi = NULL;
-}
-
-static void CALLBACK winwave_callback_in (
-    HWAVEIN *hwi,
-    UINT msg,
-    DWORD_PTR dwInstance,
-    DWORD_PTR dwParam1,
-    DWORD_PTR dwParam2
-    )
-{
-    WaveVoiceIn *wave = (WaveVoiceIn *) dwInstance;
-
-    switch (msg) {
-    case WIM_DATA:
-        {
-            WAVEHDR *h = (WAVEHDR *) dwParam1;
-            if (!h->dwUser) {
-                h->dwUser = 1;
-                EnterCriticalSection (&wave->crit_sect);
-                {
-                    wave->avail += conf.adc_samples;
-                }
-                LeaveCriticalSection (&wave->crit_sect);
-                if (wave->hw.poll_mode) {
-                    if (!SetEvent (wave->event)) {
-                        dolog ("ADC SetEvent failed %lx\n", GetLastError ());
-                    }
-                }
-            }
-        }
-        break;
-
-    case WIM_CLOSE:
-    case WIM_OPEN:
-        break;
-
-    default:
-        dolog ("unknown wave in callback msg %x\n", msg);
-    }
-}
-
-static void winwave_add_buffers (WaveVoiceIn *wave, int samples)
-{
-    int doreset;
-
-    doreset = wave->hw.poll_mode && (samples >= conf.adc_samples);
-    if (doreset && !ResetEvent (wave->event)) {
-        dolog ("ADC ResetEvent failed %lx\n", GetLastError ());
-    }
-
-    while (samples >= conf.adc_samples) {
-        MMRESULT mr;
-        WAVEHDR *h = &wave->hdrs[wave->curhdr];
-
-        h->dwUser = 0;
-        mr = waveInAddBuffer (wave->hwi, h, sizeof (*h));
-        if (mr != MMSYSERR_NOERROR) {
-            winwave_logerr (mr, "waveInAddBuffer(%d)", wave->curhdr);
-        }
-        wave->curhdr = (wave->curhdr + 1) % conf.adc_headers;
-        samples -= conf.adc_samples;
-    }
-}
-
-static int winwave_init_in (HWVoiceIn *hw, struct audsettings *as)
-{
-    int i;
-    int err;
-    MMRESULT mr;
-    WAVEFORMATEX wfx;
-    WaveVoiceIn *wave;
-
-    wave = (WaveVoiceIn *) hw;
-
-    InitializeCriticalSection (&wave->crit_sect);
-
-    err = waveformat_from_audio_settings (&wfx, as);
-    if (err) {
-        goto err0;
-    }
-
-    mr = waveInOpen (&wave->hwi, WAVE_MAPPER, &wfx,
-                     (DWORD_PTR) winwave_callback_in,
-                     (DWORD_PTR) wave, CALLBACK_FUNCTION);
-    if (mr != MMSYSERR_NOERROR) {
-        winwave_logerr (mr, "waveInOpen");
-        goto err1;
-    }
-
-    wave->hdrs = audio_calloc (AUDIO_FUNC, conf.dac_headers,
-                               sizeof (*wave->hdrs));
-    if (!wave->hdrs) {
-        goto err2;
-    }
-
-    audio_pcm_init_info (&hw->info, as);
-    hw->samples = conf.adc_samples * conf.adc_headers;
-    wave->avail = 0;
-
-    wave->pcm_buf = audio_calloc (AUDIO_FUNC, conf.adc_samples,
-                                  conf.adc_headers << hw->info.shift);
-    if (!wave->pcm_buf) {
-        goto err3;
-    }
-
-    for (i = 0; i < conf.adc_headers; ++i) {
-        WAVEHDR *h = &wave->hdrs[i];
-
-        h->dwUser = 0;
-        h->dwBufferLength = conf.adc_samples << hw->info.shift;
-        h->lpData = advance (wave->pcm_buf, i * h->dwBufferLength);
-        h->dwFlags = 0;
-
-        mr = waveInPrepareHeader (wave->hwi, h, sizeof (*h));
-        if (mr != MMSYSERR_NOERROR) {
-            winwave_logerr (mr, "waveInPrepareHeader(%d)", i);
-            goto err4;
-        }
-    }
-
-    wave->paused = 1;
-    winwave_add_buffers (wave, hw->samples);
-    return 0;
-
- err4:
-    g_free (wave->pcm_buf);
- err3:
-    g_free (wave->hdrs);
- err2:
-    winwave_anal_close_in (wave);
- err1:
- err0:
-    return -1;
-}
-
-static void winwave_fini_in (HWVoiceIn *hw)
-{
-    int i;
-    MMRESULT mr;
-    WaveVoiceIn *wave = (WaveVoiceIn *) hw;
-
-    mr = waveInReset (wave->hwi);
-    if (mr != MMSYSERR_NOERROR) {
-        winwave_logerr (mr, "waveInReset");
-    }
-
-    for (i = 0; i < conf.adc_headers; ++i) {
-        mr = waveInUnprepareHeader (wave->hwi, &wave->hdrs[i],
-                                     sizeof (wave->hdrs[i]));
-        if (mr != MMSYSERR_NOERROR) {
-            winwave_logerr (mr, "waveInUnprepareHeader(%d)", i);
-        }
-    }
-
-    winwave_anal_close_in (wave);
-
-    if (wave->event) {
-        qemu_del_wait_object (wave->event, winwave_poll, wave);
-        if (!CloseHandle (wave->event)) {
-            dolog ("ADC CloseHandle failed %lx\n", GetLastError ());
-        }
-        wave->event = NULL;
-    }
-
-    g_free (wave->pcm_buf);
-    wave->pcm_buf = NULL;
-
-    g_free (wave->hdrs);
-    wave->hdrs = NULL;
-}
-
-static int winwave_run_in (HWVoiceIn *hw)
-{
-    WaveVoiceIn *wave = (WaveVoiceIn *) hw;
-    int live = audio_pcm_hw_get_live_in (hw);
-    int dead = hw->samples - live;
-    int decr, ret;
-
-    if (!dead) {
-        return 0;
-    }
-
-    EnterCriticalSection (&wave->crit_sect);
-    {
-        decr = audio_MIN (dead, wave->avail);
-        wave->avail -= decr;
-    }
-    LeaveCriticalSection (&wave->crit_sect);
-
-    ret = decr;
-    while (decr) {
-        int left = hw->samples - hw->wpos;
-        int conv = audio_MIN (left, decr);
-        hw->conv (hw->conv_buf + hw->wpos,
-                  advance (wave->pcm_buf, wave->rpos << hw->info.shift),
-                  conv);
-
-        wave->rpos = (wave->rpos + conv) % hw->samples;
-        hw->wpos = (hw->wpos + conv) % hw->samples;
-        decr -= conv;
-    }
-
-    winwave_add_buffers (wave, ret);
-    return ret;
-}
-
-static int winwave_read (SWVoiceIn *sw, void *buf, int size)
-{
-    return audio_pcm_sw_read (sw, buf, size);
-}
-
-static int winwave_ctl_in (HWVoiceIn *hw, int cmd, ...)
-{
-    MMRESULT mr;
-    WaveVoiceIn *wave = (WaveVoiceIn *) hw;
-
-    switch (cmd) {
-    case VOICE_ENABLE:
-        {
-            va_list ap;
-            int poll_mode;
-
-            va_start (ap, cmd);
-            poll_mode = va_arg (ap, int);
-            va_end (ap);
-
-            if (poll_mode && !wave->event) {
-                wave->event = CreateEvent (NULL, TRUE, TRUE, NULL);
-                if (!wave->event) {
-                    dolog ("ADC CreateEvent: %lx, poll mode will be disabled\n",
-                           GetLastError ());
-                }
-            }
-
-            if (wave->event) {
-                int ret;
-
-                ret = qemu_add_wait_object (wave->event, winwave_poll, wave);
-                hw->poll_mode = (ret == 0);
-            }
-            else {
-                hw->poll_mode = 0;
-            }
-            if (wave->paused) {
-                mr = waveInStart (wave->hwi);
-                if (mr != MMSYSERR_NOERROR) {
-                    winwave_logerr (mr, "waveInStart");
-                }
-                wave->paused = 0;
-            }
-        }
-        return 0;
-
-    case VOICE_DISABLE:
-        if (!wave->paused) {
-            mr = waveInStop (wave->hwi);
-            if (mr != MMSYSERR_NOERROR) {
-                winwave_logerr (mr, "waveInStop");
-            }
-            else {
-                wave->paused = 1;
-            }
-        }
-        if (wave->event) {
-            qemu_del_wait_object (wave->event, winwave_poll, wave);
-        }
-        return 0;
-    }
-    return 0;
-}
-
-static void *winwave_audio_init (void)
-{
-    return &conf;
-}
-
-static void winwave_audio_fini (void *opaque)
-{
-    (void) opaque;
-}
-
-static struct audio_option winwave_options[] = {
-    {
-        .name        = "DAC_HEADERS",
-        .tag         = AUD_OPT_INT,
-        .valp        = &conf.dac_headers,
-        .descr       = "DAC number of headers",
-    },
-    {
-        .name        = "DAC_SAMPLES",
-        .tag         = AUD_OPT_INT,
-        .valp        = &conf.dac_samples,
-        .descr       = "DAC number of samples per header",
-    },
-    {
-        .name        = "ADC_HEADERS",
-        .tag         = AUD_OPT_INT,
-        .valp        = &conf.adc_headers,
-        .descr       = "ADC number of headers",
-    },
-    {
-        .name        = "ADC_SAMPLES",
-        .tag         = AUD_OPT_INT,
-        .valp        = &conf.adc_samples,
-        .descr       = "ADC number of samples per header",
-    },
-    { /* End of list */ }
-};
-
-static struct audio_pcm_ops winwave_pcm_ops = {
-    .init_out = winwave_init_out,
-    .fini_out = winwave_fini_out,
-    .run_out  = winwave_run_out,
-    .write    = winwave_write,
-    .ctl_out  = winwave_ctl_out,
-    .init_in  = winwave_init_in,
-    .fini_in  = winwave_fini_in,
-    .run_in   = winwave_run_in,
-    .read     = winwave_read,
-    .ctl_in   = winwave_ctl_in
-};
-
-struct audio_driver winwave_audio_driver = {
-    .name           = "winwave",
-    .descr          = "Windows Waveform Audio http://msdn.microsoft.com",
-    .options        = winwave_options,
-    .init           = winwave_audio_init,
-    .fini           = winwave_audio_fini,
-    .pcm_ops        = &winwave_pcm_ops,
-    .can_be_default = 1,
-    .max_voices_out = INT_MAX,
-    .max_voices_in  = INT_MAX,
-    .voice_size_out = sizeof (WaveVoiceOut),
-    .voice_size_in  = sizeof (WaveVoiceIn)
-};
diff --git a/configure b/configure
index 409edf94fb..222694f34d 100755
--- a/configure
+++ b/configure
@@ -285,8 +285,6 @@ sysconfdir="\${prefix}/etc"
 local_statedir="\${prefix}/var"
 confsuffix="/qemu"
 slirp="yes"
-fmod_lib=""
-fmod_inc=""
 oss_lib=""
 bsd="no"
 linux="no"
@@ -437,6 +435,14 @@ EOF
   compile_object
 }
 
+check_include() {
+cat > $TMPC <<EOF
+#include <$1>
+int main(void) { return 0; }
+EOF
+  compile_object
+}
+
 write_c_skeleton() {
     cat > $TMPC <<EOF
 int main(void) { return 0; }
@@ -564,24 +570,28 @@ case $targetos in
 CYGWIN*)
   mingw32="yes"
   QEMU_CFLAGS="-mno-cygwin $QEMU_CFLAGS"
-  audio_possible_drivers="winwave sdl"
-  audio_drv_list="winwave"
+  audio_possible_drivers="sdl"
+  audio_drv_list="sdl"
 ;;
 MINGW32*)
   mingw32="yes"
-  audio_possible_drivers="winwave dsound sdl fmod"
-  audio_drv_list="winwave"
+  audio_possible_drivers="dsound sdl"
+  if check_include dsound.h; then
+    audio_drv_list="dsound"
+  else
+    audio_drv_list=""
+  fi
 ;;
 GNU/kFreeBSD)
   bsd="yes"
   audio_drv_list="oss"
-  audio_possible_drivers="oss sdl esd pa"
+  audio_possible_drivers="oss sdl pa"
 ;;
 FreeBSD)
   bsd="yes"
   make="${MAKE-gmake}"
   audio_drv_list="oss"
-  audio_possible_drivers="oss sdl esd pa"
+  audio_possible_drivers="oss sdl pa"
   # needed for kinfo_getvmmap(3) in libutil.h
   LIBS="-lutil $LIBS"
   netmap=""  # enable netmap autodetect
@@ -591,14 +601,14 @@ DragonFly)
   bsd="yes"
   make="${MAKE-gmake}"
   audio_drv_list="oss"
-  audio_possible_drivers="oss sdl esd pa"
+  audio_possible_drivers="oss sdl pa"
   HOST_VARIANT_DIR="dragonfly"
 ;;
 NetBSD)
   bsd="yes"
   make="${MAKE-gmake}"
   audio_drv_list="oss"
-  audio_possible_drivers="oss sdl esd"
+  audio_possible_drivers="oss sdl"
   oss_lib="-lossaudio"
   HOST_VARIANT_DIR="netbsd"
 ;;
@@ -606,7 +616,7 @@ OpenBSD)
   bsd="yes"
   make="${MAKE-gmake}"
   audio_drv_list="sdl"
-  audio_possible_drivers="sdl esd"
+  audio_possible_drivers="sdl"
   HOST_VARIANT_DIR="openbsd"
 ;;
 Darwin)
@@ -619,7 +629,7 @@ Darwin)
   fi
   cocoa="yes"
   audio_drv_list="coreaudio"
-  audio_possible_drivers="coreaudio sdl fmod"
+  audio_possible_drivers="coreaudio sdl"
   LDFLAGS="-framework CoreFoundation -framework IOKit $LDFLAGS"
   libs_softmmu="-F/System/Library/Frameworks -framework Cocoa -framework IOKit $libs_softmmu"
   # Disable attempts to use ObjectiveC features in os/object.h since they
@@ -674,15 +684,12 @@ Haiku)
 ;;
 *)
   audio_drv_list="oss"
-  audio_possible_drivers="oss alsa sdl esd pa"
+  audio_possible_drivers="oss alsa sdl pa"
   linux="yes"
   linux_user="yes"
   kvm="yes"
   vhost_net="yes"
   vhost_scsi="yes"
-  if [ "$cpu" = "i386" -o "$cpu" = "x86_64" -o "$cpu" = "x32" ] ; then
-    audio_possible_drivers="$audio_possible_drivers fmod"
-  fi
   QEMU_INCLUDES="-I\$(SRC_PATH)/linux-headers -I$(pwd)/linux-headers $QEMU_INCLUDES"
 ;;
 esac
@@ -847,10 +854,6 @@ for opt do
   ;;
   --enable-vnc) vnc="yes"
   ;;
-  --fmod-lib=*) fmod_lib="$optarg"
-  ;;
-  --fmod-inc=*) fmod_inc="$optarg"
-  ;;
   --oss-lib=*) oss_lib="$optarg"
   ;;
   --audio-drv-list=*) audio_drv_list="$optarg"
@@ -1349,8 +1352,6 @@ Advanced options (experts only):
   --disable-guest-base     disable GUEST_BASE support
   --enable-pie             build Position Independent Executables
   --disable-pie            do not build Position Independent Executables
-  --fmod-lib               path to FMOD library
-  --fmod-inc               path to FMOD includes
   --oss-lib                path to OSS library
   --cpu=CPU                Build for host CPU [$cpu]
   --disable-uuid           disable uuid support
@@ -2621,21 +2622,6 @@ for drv in $audio_drv_list; do
     libs_softmmu="-lasound $libs_softmmu"
     ;;
 
-    fmod)
-    if test -z $fmod_lib || test -z $fmod_inc; then
-        error_exit "You must specify path to FMOD library and headers" \
-            "Example: --fmod-inc=/path/include/fmod --fmod-lib=/path/lib/libfmod-3.74.so"
-    fi
-    audio_drv_probe $drv fmod.h $fmod_lib "return FSOUND_GetVersion();" "-I $fmod_inc"
-    libs_softmmu="$fmod_lib $libs_softmmu"
-    ;;
-
-    esd)
-    audio_drv_probe $drv esd.h -lesd 'return esd_play_stream(0, 0, "", 0);'
-    libs_softmmu="-lesd $libs_softmmu"
-    audio_pt_int="yes"
-    ;;
-
     pa)
     audio_drv_probe $drv pulse/mainloop.h "-lpulse" \
         "pa_mainloop *m = 0; pa_mainloop_free (m); return 0;"
@@ -2660,11 +2646,6 @@ for drv in $audio_drv_list; do
     # XXX: Probes for CoreAudio, DirectSound, SDL(?)
     ;;
 
-    winwave)
-      libs_softmmu="-lwinmm $libs_softmmu"
-      audio_win_int="yes"
-    ;;
-
     *)
     echo "$audio_possible_drivers" | grep -q "\<$drv\>" || {
         error_exit "Unknown driver '$drv' selected" \
@@ -4629,9 +4610,6 @@ echo "CONFIG_AUDIO_DRIVERS=$audio_drv_list" >> $config_host_mak
 for drv in $audio_drv_list; do
     def=CONFIG_`echo $drv | LC_ALL=C tr '[a-z]' '[A-Z]'`
     echo "$def=y" >> $config_host_mak
-    if test "$drv" = "fmod"; then
-        echo "FMOD_CFLAGS=-I$fmod_inc" >> $config_host_mak
-    fi
 done
 if test "$audio_pt_int" = "yes" ; then
   echo "CONFIG_AUDIO_PT_INT=y" >> $config_host_mak
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index 57f8394a94..88644ceda7 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -8,7 +8,6 @@
 #include "qemu/readline.h"
 
 extern Monitor *cur_mon;
-extern Monitor *default_mon;
 
 /* flags for monitor_init */
 #define MONITOR_IS_DEFAULT    0x01
diff --git a/monitor.c b/monitor.c
index 6a4642493a..8e1a2e85b8 100644
--- a/monitor.c
+++ b/monitor.c
@@ -226,7 +226,6 @@ static mon_cmd_t info_cmds[];
 static const mon_cmd_t qmp_cmds[];
 
 Monitor *cur_mon;
-Monitor *default_mon;
 
 static void monitor_command_cb(void *opaque, const char *cmdline,
                                void *readline_opaque);
@@ -5298,9 +5297,6 @@ void monitor_init(CharDriverState *chr, int flags)
     qemu_mutex_lock(&monitor_lock);
     QLIST_INSERT_HEAD(&mon_list, mon, entry);
     qemu_mutex_unlock(&monitor_lock);
-
-    if (!default_mon || (flags & MONITOR_IS_DEFAULT))
-        default_mon = mon;
 }
 
 static void bdrv_password_cb(void *opaque, const char *password,
diff --git a/trace-events b/trace-events
index 6060d36773..52b7efa9a4 100644
--- a/trace-events
+++ b/trace-events
@@ -1632,3 +1632,19 @@ cpu_unhalt(int cpu_index) "unhalting cpu %d"
 
 # hw/arm/virt-acpi-build.c
 virt_acpi_setup(void) "No fw cfg or ACPI disabled. Bailing out."
+
+# audio/alsaaudio.c
+alsa_revents(int revents) "revents = %d"
+alsa_pollout(int i, int fd) "i = %d fd = %d"
+alsa_set_handler(int events, int index, int fd, int err) "events=%#x index=%d fd=%d err=%d"
+alsa_wrote_zero(int len) "Failed to write %d frames (wrote zero)"
+alsa_read_zero(long len) "Failed to read %ld frames (read zero)"
+alsa_xrun_out(void) "Recovering from playback xrun"
+alsa_xrun_in(void) "Recovering from capture xrun"
+alsa_resume_out(void) "Resuming suspended output stream"
+alsa_resume_in(void) "Resuming suspended input stream"
+alsa_no_frames(int state) "No frames available and ALSA state is %d"
+
+# audio/ossaudio.c
+oss_version(int version) "OSS version = %#x"
+oss_invalid_available_size(int size, int bufsize) "Invalid available size, size=%d bufsize=%d"