diff --git a/daemon/src/audio/alsa/alsalayer.cpp b/daemon/src/audio/alsa/alsalayer.cpp
index 6a0fd0c86cd6ac7b538f5d7ef4a027a7e2f5b8d5..56b1ae2a4cc285451f86690a485addbe0370ffc6 100644
--- a/daemon/src/audio/alsa/alsalayer.cpp
+++ b/daemon/src/audio/alsa/alsalayer.cpp
@@ -101,11 +101,20 @@ AlsaLayer::~AlsaLayer (void)
     closePlaybackStream();
 }
 
+// Retry approach taken from pa_linux_alsa.c, part of PortAudio
 bool AlsaLayer::openDevice(snd_pcm_t **pcm, const std::string &dev, snd_pcm_stream_t stream)
 {
-	int err = snd_pcm_open(pcm, dev.c_str(),stream, 0);
+    static const int MAX_RETRIES = 100;
+    int err = snd_pcm_open(pcm, dev.c_str(), stream, 0);
+    // Retry if busy, since dmix plugin may not have released the device yet
+    for (int tries = 0; tries < MAX_RETRIES and err == -EBUSY; ++tries) {
+        usleep(10000);
+        err = snd_pcm_open(pcm, dev.c_str(), stream, 0);
+    }
+
     if (err < 0) {
-        _error("Alsa: couldn't open device %s : %s",  dev.c_str(), snd_strerror(err));
+        _error("Alsa: couldn't open device %s : %s",  dev.c_str(),
+                snd_strerror(err));
         return false;
     }
 
@@ -141,9 +150,8 @@ AlsaLayer::startStream (void)
 
     if (not is_capture_open_) {
     	is_capture_open_ = openDevice(&captureHandle_, pcmc, SND_PCM_STREAM_CAPTURE);
-    	if (not is_capture_open_) {
+        if (not is_capture_open_)
             Manager::instance().getDbusManager()->getConfigurationManager()->errorAlert(ALSA_CAPTURE_DEVICE);
-    	}
     }
 
     if (not is_playback_open_) {
diff --git a/daemon/src/audio/alsa/alsalayer.h b/daemon/src/audio/alsa/alsalayer.h
index 9c14a1e6c2abc8e39a86f0543ac076975c3de385..a406667a0075926c1fdb9a05a0bb68cba05e5a70 100644
--- a/daemon/src/audio/alsa/alsalayer.h
+++ b/daemon/src/audio/alsa/alsalayer.h
@@ -146,6 +146,11 @@ class AlsaLayer : public AudioLayer
     private:
 
 
+        /**
+         * Calls snd_pcm_open and retries if device is busy, since dmix plugin
+         * will often hold on to a device temporarily after it has been opened
+         * and closed.
+         */
         bool openDevice(snd_pcm_t **pcm, const std::string &dev, snd_pcm_stream_t stream);
 
         /**
diff --git a/daemon/src/managerimpl.cpp b/daemon/src/managerimpl.cpp
index 6e7c93b38128451f61e9e7227baa73b5ca1dccff..11713224eda502f61d321476c0270ae5c271d2da 100644
--- a/daemon/src/managerimpl.cpp
+++ b/daemon/src/managerimpl.cpp
@@ -1994,6 +1994,7 @@ void ManagerImpl::setAudioPlugin (const std::string& audioPlugin)
     // Recreate audio driver with new settings
     delete _audiodriver;
     _audiodriver = new AlsaLayer;
+    assert(preferences.getAudioApi() == ALSA_API_STR);
     if (wasStarted)
         _audiodriver->startStream();
 
@@ -2033,6 +2034,7 @@ void ManagerImpl::setAudioDevice (const int index, int streamType)
     // Recreate audio driver with new settings
     delete _audiodriver;
     _audiodriver = new AlsaLayer;
+    assert(preferences.getAudioApi() == ALSA_API_STR);
 
     if (wasStarted)
         _audiodriver->startStream();