]> git.sesse.net Git - nageru/commitdiff
Store an input mapping, and show it in the UI.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sat, 30 Jul 2016 23:26:59 +0000 (01:26 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Wed, 19 Oct 2016 22:55:44 +0000 (00:55 +0200)
Edits you do in the UI are not actually editable yet, and the mixer doesn't
care about the mapping either.

audio_mixer.cpp
audio_mixer.h
input_mapping_dialog.cpp [new file with mode: 0644]
input_mapping_dialog.h
mixer.cpp
ui_input_mapping.ui

index 2544ad1deef84635cf5fd28d487dd78ba7293201..15c65de53566d2c776b2b6096e82af2f21cf9c9a 100644 (file)
@@ -59,6 +59,16 @@ AudioMixer::AudioMixer(unsigned num_cards)
        set_compressor_enabled(global_flags.compressor_enabled);
        set_limiter_enabled(global_flags.limiter_enabled);
        set_final_makeup_gain_auto(global_flags.final_makeup_gain_auto);
+
+       // Generate a very simple, default input mapping.
+       InputMapping::Input input;
+       input.name = "Main";
+       input.input_source_type = InputSourceType::CAPTURE_CARD;
+       input.input_source_index = 0;
+       input.source_channel[0] = 0;
+       input.source_channel[1] = 1;
+
+       input_mapping.inputs.push_back(input);
 }
 
 void AudioMixer::reset_card(unsigned card_index)
@@ -259,3 +269,33 @@ vector<float> AudioMixer::get_output(double pts, unsigned num_samples, Resamplin
 
        return samples_out;
 }
+
+vector<string> AudioMixer::get_names() const
+{
+       vector<string> names;
+       for (unsigned card_index = 0; card_index < num_cards; ++card_index) {
+               const CaptureCard *card = &cards[card_index];
+               unique_lock<mutex> lock(card->audio_mutex);
+               names.push_back(card->name);
+       }
+       return names;
+}
+
+void AudioMixer::set_name(unsigned card_index, const string &name)
+{
+       CaptureCard *card = &cards[card_index];
+       unique_lock<mutex> lock(card->audio_mutex);
+       card->name = name;
+}
+
+void AudioMixer::set_input_mapping(const InputMapping &input_mapping)
+{
+       lock_guard<mutex> lock(mapping_mutex);
+       this->input_mapping = input_mapping;
+}
+
+InputMapping AudioMixer::get_input_mapping() const
+{
+       lock_guard<mutex> lock(mapping_mutex);
+       return input_mapping;
+}
index 8e15f543d48ac7921a7da0b6e98a3855436167fc..6f7dbe5d0b45850fed81f743b6674eeb176c6c7b 100644 (file)
@@ -29,6 +29,19 @@ namespace bmusb {
 struct AudioFormat;
 }  // namespace bmusb
 
+enum class InputSourceType { SILENCE, CAPTURE_CARD };
+
+struct InputMapping {
+       struct Input {
+               std::string name;
+               InputSourceType input_source_type;
+               unsigned input_source_index;
+               int source_channel[2] { -1, -1 };  // Left and right. -1 = none.
+       };
+
+       std::vector<Input> inputs;
+};
+
 class AudioMixer {
 public:
        AudioMixer(unsigned num_cards);
@@ -43,6 +56,11 @@ public:
        void set_current_loudness(double level_lufs) { loudness_lufs = level_lufs; }
 
        void set_fader_volume(unsigned card_index, float level_db) { cards[card_index].fader_volume_db = level_db; }
+       std::vector<std::string> get_names() const;
+       void set_name(unsigned card_index, const std::string &name);
+
+       void set_input_mapping(const InputMapping &input_mapping);
+       InputMapping get_input_mapping() const;
 
        void set_locut_cutoff(float cutoff_hz)
        {
@@ -153,10 +171,13 @@ private:
        unsigned num_cards;
 
        struct CaptureCard {
-               std::mutex audio_mutex;
-               std::unique_ptr<ResamplingQueue> resampling_queue;  // Under audio_mutex.
-               int64_t next_local_pts = 0;  // Beginning of next frame, in TIMEBASE units. Under audio_mutex.
                std::atomic<float> fader_volume_db{0.0f};
+
+               // Everything below audio_mutex is protected by it.
+               mutable std::mutex audio_mutex;
+               std::unique_ptr<ResamplingQueue> resampling_queue;
+               int64_t next_local_pts = 0;
+               std::string name;
        };
        CaptureCard cards[MAX_CARDS];
 
@@ -184,6 +205,9 @@ private:
 
        double final_makeup_gain = 1.0;  // Under compressor_mutex. Read/write by the user. Note: Not in dB, we want the numeric precision so that we can change it slowly.
        bool final_makeup_gain_auto = true;  // Under compressor_mutex.
+
+       mutable std::mutex mapping_mutex;
+       InputMapping input_mapping;  // Under mapping_mutex.
 };
 
 #endif  // !defined(_AUDIO_MIXER_H)
diff --git a/input_mapping_dialog.cpp b/input_mapping_dialog.cpp
new file mode 100644 (file)
index 0000000..ea20fdc
--- /dev/null
@@ -0,0 +1,67 @@
+#include "input_mapping_dialog.h"
+
+#include "ui_input_mapping.h"
+
+#include <QComboBox>
+
+using namespace std;
+
+InputMappingDialog::InputMappingDialog()
+       : ui(new Ui::InputMappingDialog)
+{
+       ui->setupUi(this);
+
+       //connect(ui->button_box, &QDialogButtonBox::accepted, [this]{ this->close(); });
+       vector<string> card_names = global_mixer->get_audio_mixer()->get_names();
+       fill_ui_from_mapping(global_mixer->get_audio_mixer()->get_input_mapping(), card_names);
+}
+
+void InputMappingDialog::fill_ui_from_mapping(const InputMapping &mapping, const vector<string> &card_names)
+{
+       ui->table->verticalHeader()->hide();
+
+       ui->table->setRowCount(mapping.inputs.size());
+       for (unsigned row = 0; row < mapping.inputs.size(); ++row) {
+               // TODO: Mark as some sort of header (by means of background color, probably).
+               QString name(QString::fromStdString(mapping.inputs[row].name));
+               ui->table->setItem(row, 0, new QTableWidgetItem(name));
+
+               // Card choices.
+               QComboBox *card_combo = new QComboBox;
+               card_combo->addItem(QString("(none)"));
+               for (const string &name : card_names) {
+                       card_combo->addItem(QString::fromStdString(name));
+               }
+               switch (mapping.inputs[row].input_source_type) {
+               case InputSourceType::SILENCE:
+                       card_combo->setCurrentIndex(0);
+                       break;
+               case InputSourceType::CAPTURE_CARD:
+                       card_combo->setCurrentIndex(mapping.inputs[row].input_source_index + 1);
+                       break;
+               default:
+                       assert(false);
+               }
+               ui->table->setCellWidget(row, 1, card_combo);
+
+               // Left and right channel.
+               fill_channel_ui_from_mapping(row, mapping.inputs[row]);
+       }
+}
+
+void InputMappingDialog::fill_channel_ui_from_mapping(unsigned row, const InputMapping::Input &input)
+{
+       for (unsigned channel = 0; channel < 2; ++channel) {
+               QComboBox *channel_combo = new QComboBox;
+               channel_combo->addItem(QString("(none)"));
+               if (input.input_source_type == InputSourceType::CAPTURE_CARD) {
+                       for (unsigned source = 0; source < 8; ++source) {  // TODO: Ask the card about number of channels, and names.
+                               char buf[256];
+                               snprintf(buf, sizeof(buf), "Channel %u", source + 1);
+                               channel_combo->addItem(QString(buf));
+                       }
+               }
+               channel_combo->setCurrentIndex(input.source_channel[channel] + 1);
+               ui->table->setCellWidget(row, 2 + channel, channel_combo);
+       }
+}
index c7fea24f3675a0278dd45340196579136c469d0b..4eb5e4cd75b62674855f8c1ad298cb8536c9b1b4 100644 (file)
@@ -20,6 +20,9 @@ public:
        InputMappingDialog();
 
 private:
+       void fill_ui_from_mapping(const InputMapping &mapping, const std::vector<std::string> &card_names);
+       void fill_channel_ui_from_mapping(unsigned row, const InputMapping::Input &input);
+
        Ui::InputMappingDialog *ui;
 };
 
index b684b3d4d0e4dc404973ae4ef08c6c703599c2ac..e8bbc028222b6a0f3724f7bf584d9d3410824ffb 100644 (file)
--- a/mixer.cpp
+++ b/mixer.cpp
@@ -281,11 +281,12 @@ void Mixer::configure_card(unsigned card_index, CaptureInterface *capture, bool
        if (card->surface == nullptr) {
                card->surface = create_surface_with_same_format(mixer_surface);
        }
-       audio_mixer.reset_card(card_index);
        while (!card->new_frames.empty()) card->new_frames.pop();
        card->fractional_samples = 0;
        card->last_timecode = -1;
        card->capture->configure_card();
+       audio_mixer.reset_card(card_index);
+       audio_mixer.set_name(card_index, card->capture->get_description());
 }
 
 
index 82a0d3db8ae3926f14694da17861df4571826faf..f2c28ab911a6793e2184acc16f4e2b36d4a73031 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <ui version="4.0">
  <class>InputMappingDialog</class>
- <widget class="QDialog" name="Dialog">
+ <widget class="QDialog" name="InputMappingDialog">
   <property name="geometry">
    <rect>
     <x>0</x>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout_2">
    <item>
-    <widget class="QTableWidget" name="tableWidget">
+    <widget class="QTableWidget" name="table">
+     <column>
+      <property name="text">
+       <string/>
+      </property>
+     </column>
      <column>
       <property name="text">
        <string>Device</string>
@@ -53,7 +58,8 @@
         <string/>
        </property>
        <property name="icon">
-        <iconset theme="list-add"/>
+        <iconset theme="list-add">
+         <normaloff>.</normaloff>.</iconset>
        </property>
       </widget>
      </item>
         <string/>
        </property>
        <property name="icon">
-        <iconset theme="go-up"/>
+        <iconset theme="go-up">
+         <normaloff>.</normaloff>.</iconset>
        </property>
       </widget>
      </item>
         <string/>
        </property>
        <property name="icon">
-        <iconset theme="go-down"/>
+        <iconset theme="go-down">
+         <normaloff>.</normaloff>.</iconset>
        </property>
       </widget>
      </item>