]> git.sesse.net Git - nageru/blobdiff - alsa_input.cpp
Update the UI with state changes and new ALSA cards as they come in.
[nageru] / alsa_input.cpp
index 78faaf31ffc1ee584cc4f3fccad7f7e5fd25f15c..09cbbd2bc66526fb6be6544ac431774ec444968f 100644 (file)
@@ -467,10 +467,26 @@ ALSAPool::ProbeResult ALSAPool::probe_device_once(unsigned card_index, unsigned
        fprintf(stderr, "%s: Probed successfully.\n", address);
 
        reset_device(internal_dev_index);  // Restarts it if it is held (ie., we just replaced a dead card).
+       if (global_audio_mixer) {
+               global_audio_mixer->trigger_state_changed_callback();
+       }
 
        return ALSAPool::ProbeResult::SUCCESS;
 }
 
+void ALSAPool::unplug_device(unsigned card_index, unsigned dev_index)
+{
+       char address[256];
+       snprintf(address, sizeof(address), "hw:%d,%d", card_index, dev_index);
+       for (unsigned i = 0; i < devices.size(); ++i) {
+               if (devices[i].state != Device::State::EMPTY &&
+                   devices[i].state != Device::State::DEAD &&
+                   devices[i].address == address) {
+                       free_card(i);
+               }
+       }
+}
+
 void ALSAPool::init()
 {
        thread(&ALSAPool::inotify_thread_func, this).detach();
@@ -519,7 +535,7 @@ void ALSAPool::inotify_thread_func()
                        if (sscanf(event->name, "pcmC%uD%u%c", &card, &device, &type) == 3 && type == 'c') {
                                if (event->mask & (IN_MOVED_FROM | IN_DELETE)) {
                                        printf("Deleted capture device: Card %u, device %u\n", card, device);
-                                       // TODO: Unplug.
+                                       unplug_device(card, device);
                                }
                                if (event->mask & (IN_MOVED_TO | IN_CREATE)) {
                                        printf("Adding capture device: Card %u, device %u\n", card, device);
@@ -576,6 +592,7 @@ void ALSAPool::set_card_state(unsigned index, ALSAPool::Device::State state)
        bool silence = (state != ALSAPool::Device::State::RUNNING);
        while (!global_audio_mixer->silence_card(spec, silence))
                ;
+       global_audio_mixer->trigger_state_changed_callback();
 }
 
 unsigned ALSAPool::find_free_device_index(const string &name, const string &info, unsigned num_channels, const string &address)
@@ -630,15 +647,19 @@ void ALSAPool::free_card(unsigned index)
        while (!global_audio_mixer->silence_card(spec, true))
                ;
 
-       lock_guard<mutex> lock(mu);
-       if (devices[index].held) {
-               devices[index].state = Device::State::DEAD;
-       } else {
-               devices[index].state = Device::State::EMPTY;
-               inputs[index].reset();
-       }
-       while (!devices.empty() && devices.back().state == Device::State::EMPTY) {
-               devices.pop_back();
-               inputs.pop_back();
+       {
+               lock_guard<mutex> lock(mu);
+               if (devices[index].held) {
+                       devices[index].state = Device::State::DEAD;
+               } else {
+                       devices[index].state = Device::State::EMPTY;
+                       inputs[index].reset();
+               }
+               while (!devices.empty() && devices.back().state == Device::State::EMPTY) {
+                       devices.pop_back();
+                       inputs.pop_back();
+               }
        }
+
+       global_audio_mixer->trigger_state_changed_callback();
 }