diff --git a/src/audio_core/cubeb_input.cpp b/src/audio_core/cubeb_input.cpp
index f191fd8cd..9e83125e7 100644
--- a/src/audio_core/cubeb_input.cpp
+++ b/src/audio_core/cubeb_input.cpp
@@ -113,7 +113,7 @@ long CubebInput::Impl::DataCallback(cubeb_stream* stream, void* user_data, const
         return 0;
     }
 
-    u8 const* data = reinterpret_cast<u8 const*>(input_buffer);
+    const u8* data = reinterpret_cast<const u8*>(input_buffer);
     std::vector<u8> samples{data, data + num_frames * impl->sample_size_in_bytes};
     impl->sample_queue->Push(samples);
 
diff --git a/src/citra_qt/configuration/configure_audio.cpp b/src/citra_qt/configuration/configure_audio.cpp
index e9d700c9b..6c2fd09fd 100644
--- a/src/citra_qt/configuration/configure_audio.cpp
+++ b/src/citra_qt/configuration/configure_audio.cpp
@@ -42,9 +42,6 @@ ConfigureAudio::ConfigureAudio(QWidget* parent)
     connect(ui->input_type_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this,
             &ConfigureAudio::updateAudioInputDevices);
 
-    ui->input_type_combo_box->setEnabled(!Core::System::GetInstance().IsPoweredOn());
-    ui->input_device_combo_box->setEnabled(!Core::System::GetInstance().IsPoweredOn());
-
     this->setConfiguration();
     connect(ui->output_sink_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this,
             &ConfigureAudio::updateAudioOutputDevices);
@@ -142,12 +139,7 @@ void ConfigureAudio::updateAudioOutputDevices(int sink_index) {
     }
 }
 
-void ConfigureAudio::updateAudioInputDevices(int index) {
-    // TODO: Don't hardcode this to the index for "Real Device" without making it a constant
-    // somewhere
-    ui->input_device_combo_box->setEnabled(index == 1 &&
-                                           !Core::System::GetInstance().IsPoweredOn());
-}
+void ConfigureAudio::updateAudioInputDevices(int index) {}
 
 void ConfigureAudio::retranslateUi() {
     ui->retranslateUi(this);
diff --git a/src/core/frontend/mic.h b/src/core/frontend/mic.h
index 296e434f6..1605e77c0 100644
--- a/src/core/frontend/mic.h
+++ b/src/core/frontend/mic.h
@@ -46,8 +46,10 @@ public:
      */
     virtual Samples Read() = 0;
 
-    /// Adjusts the Parameters. Implementations should update the parameters field in addition to
-    /// changing the mic to sample according to the new parameters. Called by Core
+    /**
+     * Adjusts the Parameters. Implementations should update the parameters field in addition to
+     * changing the mic to sample according to the new parameters. Called by Core
+     */
     virtual void AdjustSampleRate(u32 sample_rate) = 0;
 
     /// Value from 0 - 100 to adjust the mic gain setting. Called by Core
@@ -111,8 +113,4 @@ private:
     std::vector<u8> CACHE_16_BIT;
 };
 
-void RegisterMic(std::shared_ptr<Mic::Interface> mic);
-
-std::shared_ptr<Mic::Interface> GetCurrentMic();
-
 } // namespace Frontend::Mic
diff --git a/src/core/hle/service/mic_u.cpp b/src/core/hle/service/mic_u.cpp
index 709844676..ca2f06554 100644
--- a/src/core/hle/service/mic_u.cpp
+++ b/src/core/hle/service/mic_u.cpp
@@ -2,6 +2,9 @@
 // Licensed under GPLv2 or any later version
 // Refer to the license.txt file included.
 
+#ifdef HAVE_CUBEB
+#include "audio_core/cubeb_input.h"
+#endif
 #include "common/logging/log.h"
 #include "core/core.h"
 #include "core/frontend/mic.h"
@@ -12,6 +15,7 @@
 #include "core/hle/kernel/kernel.h"
 #include "core/hle/kernel/shared_memory.h"
 #include "core/hle/service/mic_u.h"
+#include "core/settings.h"
 
 namespace Service::MIC {
 
@@ -129,6 +133,9 @@ struct MIC_U::Impl {
     }
 
     void UpdateSharedMemBuffer(u64 userdata, s64 cycles_late) {
+        if (change_mic_impl_requested.exchange(false)) {
+            CreateMic();
+        }
         // If the event was scheduled before the application requested the mic to stop sampling
         if (!mic->IsSampling()) {
             return;
@@ -311,13 +318,49 @@ struct MIC_U::Impl {
         rb.Push(RESULT_SUCCESS);
     }
 
+    void CreateMic() {
+        std::unique_ptr<Frontend::Mic::Interface> new_mic;
+        switch (Settings::values.mic_input_type) {
+        case Settings::MicInputType::None:
+            new_mic = std::make_unique<Frontend::Mic::NullMic>();
+            break;
+        case Settings::MicInputType::Real:
+#if HAVE_CUBEB
+            new_mic = std::make_unique<AudioCore::CubebInput>();
+#else
+            new_mic = std::make_unique<Frontend::Mic::NullMic>();
+#endif
+            break;
+        case Settings::MicInputType::Static:
+            new_mic = std::make_unique<Frontend::Mic::StaticMic>();
+            break;
+        default:
+            LOG_CRITICAL(Audio, "Mic type not found. Defaulting to null mic");
+            new_mic = std::make_unique<Frontend::Mic::NullMic>();
+        }
+        // If theres already a mic, copy over any data to the new mic impl
+        if (mic) {
+            new_mic->SetGain(mic->GetGain());
+            new_mic->SetPower(mic->GetPower());
+            auto params = mic->GetParameters();
+            if (mic->IsSampling()) {
+                mic->StopSampling();
+                new_mic->StartSampling(params);
+            }
+        }
+
+        mic = std::move(new_mic);
+        change_mic_impl_requested.store(false);
+    }
+
+    std::atomic<bool> change_mic_impl_requested = false;
     Kernel::SharedPtr<Kernel::Event> buffer_full_event;
     Core::TimingEventType* buffer_write_event = nullptr;
     Kernel::SharedPtr<Kernel::SharedMemory> shared_memory;
     u32 client_version = 0;
     bool allow_shell_closed = false;
     bool clamp = false;
-    std::shared_ptr<Frontend::Mic::Interface> mic;
+    std::unique_ptr<Frontend::Mic::Interface> mic;
     Core::Timing& timing;
     State state{};
 };
@@ -407,7 +450,7 @@ MIC_U::MIC_U(Core::System& system)
         {0x00100040, &MIC_U::SetClientVersion, "SetClientVersion"},
     };
 
-    impl->mic = Frontend::Mic::GetCurrentMic();
+    impl->CreateMic();
     RegisterHandlers(functions);
 }
 
@@ -415,25 +458,20 @@ MIC_U::~MIC_U() {
     impl->mic->StopSampling();
 }
 
+void MIC_U::ReloadMic() {
+    impl->change_mic_impl_requested.store(true);
+}
+
+void ReloadMic(Core::System& system) {
+    auto micu = system.ServiceManager().GetService<Service::MIC::MIC_U>("mic:u");
+    if (!micu)
+        return;
+    micu->ReloadMic();
+}
+
 void InstallInterfaces(Core::System& system) {
     auto& service_manager = system.ServiceManager();
     std::make_shared<MIC_U>(system)->InstallAsService(service_manager);
 }
 
 } // namespace Service::MIC
-
-namespace Frontend::Mic {
-static std::shared_ptr<Mic::Interface> current_mic;
-
-void RegisterMic(std::shared_ptr<Mic::Interface> mic) {
-    current_mic = mic;
-}
-
-std::shared_ptr<Mic::Interface> GetCurrentMic() {
-    if (!current_mic) {
-        current_mic = std::make_shared<Mic::NullMic>();
-    }
-    return current_mic;
-}
-
-} // namespace Frontend::Mic
diff --git a/src/core/hle/service/mic_u.h b/src/core/hle/service/mic_u.h
index bc4933229..2e40ed404 100644
--- a/src/core/hle/service/mic_u.h
+++ b/src/core/hle/service/mic_u.h
@@ -19,6 +19,8 @@ public:
     explicit MIC_U(Core::System& system);
     ~MIC_U();
 
+    void ReloadMic();
+
 private:
     /**
      * MIC::MapSharedMem service function
@@ -190,6 +192,8 @@ private:
     std::unique_ptr<Impl> impl;
 };
 
+void ReloadMic(Core::System& system);
+
 void InstallInterfaces(Core::System& system);
 
 } // namespace Service::MIC
diff --git a/src/core/settings.cpp b/src/core/settings.cpp
index 9574e7bde..c7311e268 100644
--- a/src/core/settings.cpp
+++ b/src/core/settings.cpp
@@ -3,17 +3,14 @@
 // Refer to the license.txt file included.
 
 #include <utility>
-#if HAVE_CUBEB
-#include "audio_core/cubeb_input.h"
-#endif
 #include "audio_core/dsp_interface.h"
 #include "core/core.h"
 #include "core/frontend/emu_window.h"
-#include "core/frontend/mic.h"
 #include "core/gdbstub/gdbstub.h"
 #include "core/hle/service/hid/hid.h"
 #include "core/hle/service/ir/ir_rst.h"
 #include "core/hle/service/ir/ir_user.h"
+#include "core/hle/service/mic_u.h"
 #include "core/settings.h"
 #include "video_core/renderer_base.h"
 #include "video_core/video_core.h"
@@ -61,20 +58,8 @@ void Apply() {
         if (cam) {
             cam->ReloadCameraDevices();
         }
-    }
-    // TODO support mic hotswapping by creating the new impl, and copying any parameters to it.
-    switch (Settings::values.mic_input_type) {
-    case Settings::MicInputType::None:
-        Frontend::Mic::RegisterMic(std::make_shared<Frontend::Mic::NullMic>());
-        break;
-    case Settings::MicInputType::Real:
-#if HAVE_CUBEB
-        Frontend::Mic::RegisterMic(std::make_shared<AudioCore::CubebInput>());
-#endif
-        break;
-    case Settings::MicInputType::Static:
-        Frontend::Mic::RegisterMic(std::make_shared<Frontend::Mic::StaticMic>());
-        break;
+
+        Service::MIC::ReloadMic(system);
     }
 }
 
@@ -105,6 +90,8 @@ void LogSettings() {
     LogSetting("Audio_OutputEngine", Settings::values.sink_id);
     LogSetting("Audio_EnableAudioStretching", Settings::values.enable_audio_stretching);
     LogSetting("Audio_OutputDevice", Settings::values.audio_device_id);
+    LogSetting("Audio_InputDeviceType", static_cast<int>(Settings::values.mic_input_type));
+    LogSetting("Audio_InputDevice", Settings::values.mic_input_device);
     using namespace Service::CAM;
     LogSetting("Camera_OuterRightName", Settings::values.camera_name[OuterRightCamera]);
     LogSetting("Camera_OuterRightConfig", Settings::values.camera_config[OuterRightCamera]);