]> git.sesse.net Git - nageru/blobdiff - alsa_input.cpp
Move InputMapping and friends into its own header file.
[nageru] / alsa_input.cpp
index 78faaf31ffc1ee584cc4f3fccad7f7e5fd25f15c..c53b24189da2f43a7335522aecf4aaaf81226a4a 100644 (file)
@@ -454,6 +454,7 @@ ALSAPool::ProbeResult ALSAPool::probe_device_once(unsigned card_index, unsigned
        string info = snd_pcm_info_get_name(pcm_info);
 
        unsigned internal_dev_index;
+       string display_name;
        {
                lock_guard<mutex> lock(mu);
                internal_dev_index = find_free_device_index(name, info, num_channels, address);
@@ -462,15 +463,34 @@ ALSAPool::ProbeResult ALSAPool::probe_device_once(unsigned card_index, unsigned
                devices[internal_dev_index].info = info;
                devices[internal_dev_index].num_channels = num_channels;
                // Note: Purposefully does not overwrite held.
+
+               display_name = devices[internal_dev_index].display_name();
        }
 
        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).
 
+       DeviceSpec spec{InputSourceType::ALSA_INPUT, internal_dev_index};
+       global_audio_mixer->set_display_name(spec, display_name);
+       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 +539,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 +596,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 +651,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();
 }