]> git.sesse.net Git - nageru/blobdiff - nageru/input_mapping_dialog.cpp
Support delaying audio sources selectively.
[nageru] / nageru / input_mapping_dialog.cpp
index b4565152a4af01b290941025633e7224b8c4d4dd..529b2e5aa93b41bc59d08bca9302289801ff089e 100644 (file)
@@ -12,6 +12,7 @@
 #include <QList>
 #include <QMessageBox>
 #include <QPushButton>
+#include <QSpinBox>
 #include <QTableWidget>
 #include <QVariant>
 #include <functional>
@@ -41,6 +42,7 @@ InputMappingDialog::InputMappingDialog()
        ui->setupUi(this);
        ui->table->setSelectionBehavior(QAbstractItemView::SelectRows);
        ui->table->setSelectionMode(QAbstractItemView::SingleSelection);  // Makes implementing moving easier for now.
+       ui->table->setColumnWidth(4, 200);
 
        fill_ui_from_mapping(mapping);
        connect(ui->table, &QTableWidget::cellChanged, this, &InputMappingDialog::cell_changed);
@@ -61,7 +63,7 @@ InputMappingDialog::InputMappingDialog()
                post_to_main_thread([this]{
                        devices = global_audio_mixer->get_devices();
                        for (unsigned row = 0; row < mapping.buses.size(); ++row) {
-                               fill_row_from_bus(row, mapping.buses[row]);
+                               fill_row_from_bus(row, mapping.buses[row], mapping);
                        }
                });
        });
@@ -82,11 +84,11 @@ void InputMappingDialog::fill_ui_from_mapping(const InputMapping &mapping)
 
        ui->table->setRowCount(mapping.buses.size());
        for (unsigned row = 0; row < mapping.buses.size(); ++row) {
-               fill_row_from_bus(row, mapping.buses[row]);
+               fill_row_from_bus(row, mapping.buses[row], mapping);
        }
 }
 
-void InputMappingDialog::fill_row_from_bus(unsigned row, const InputMapping::Bus &bus)
+void InputMappingDialog::fill_row_from_bus(unsigned row, const InputMapping::Bus &bus, const InputMapping &mapping)
 {
        QString name(QString::fromStdString(bus.name));
        ui->table->setItem(row, 0, new QTableWidgetItem(name));
@@ -136,6 +138,7 @@ void InputMappingDialog::fill_row_from_bus(unsigned row, const InputMapping::Bus
                bind(&InputMappingDialog::card_selected, this, card_combo, row, _1));
        ui->table->setCellWidget(row, 1, card_combo);
 
+       fill_delay_from_bus(row, bus, mapping);
        setup_channel_choices_from_bus(row, bus);
 }
 
@@ -169,6 +172,34 @@ void InputMappingDialog::setup_channel_choices_from_bus(unsigned row, const Inpu
        }
 }
 
+void InputMappingDialog::fill_delay_from_bus(unsigned row, const InputMapping::Bus &bus, const InputMapping &mapping)
+{
+       QDoubleSpinBox *delay_spinner = static_cast<QDoubleSpinBox *>(ui->table->cellWidget(row, 4));
+       if (delay_spinner == nullptr) {
+               delay_spinner = new QDoubleSpinBox;
+               delay_spinner->setDecimals(1);
+               delay_spinner->setMinimum(-50.0);
+               delay_spinner->setMaximum(500.0);
+               connect(delay_spinner, static_cast<void(QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
+                       bind(&InputMappingDialog::delay_changed, this, row, _1));
+       }
+       delay_spinner->blockSignals(true);
+       if (bus.device.type == InputSourceType::SILENCE) {
+               delay_spinner->setEnabled(false);
+               delay_spinner->setValue(0.0);
+       } else {
+               delay_spinner->setEnabled(true);
+               const auto delay_it = mapping.extra_delay_ms.find(bus.device);
+               if (delay_it != mapping.extra_delay_ms.end()) {
+                       delay_spinner->setValue(delay_it->second);
+               } else {
+                       delay_spinner->setValue(0.0);
+               }
+       }
+       delay_spinner->blockSignals(false);
+       ui->table->setCellWidget(row, 4, delay_spinner);
+}
+
 void InputMappingDialog::ok_clicked()
 {
        global_audio_mixer->set_state_changed_callback(saved_callback);
@@ -200,6 +231,7 @@ void InputMappingDialog::card_selected(QComboBox *card_combo, unsigned row, int
 {
        uint64_t key = card_combo->itemData(index).toULongLong();
        mapping.buses[row].device = key_to_DeviceSpec(key);
+       fill_delay_from_bus(row, mapping.buses[row], mapping);
        setup_channel_choices_from_bus(row, mapping.buses[row]);
 }
 
@@ -208,6 +240,17 @@ void InputMappingDialog::channel_selected(unsigned row, unsigned channel, int in
        mapping.buses[row].source_channel[channel] = index - 1;
 }
 
+void InputMappingDialog::delay_changed(unsigned row, double value)
+{
+       mapping.extra_delay_ms[mapping.buses[row].device] = value;
+
+       for (unsigned other_row = 0; other_row < mapping.buses.size(); ++other_row) {
+               if (row != other_row && mapping.buses[row].device == mapping.buses[other_row].device) {
+                       fill_delay_from_bus(other_row, mapping.buses[other_row], mapping);
+               }
+       }
+}
+
 void InputMappingDialog::add_clicked()
 {
        QTableWidgetSelectionRange all(0, 0, ui->table->rowCount() - 1, ui->table->columnCount() - 1);
@@ -221,7 +264,7 @@ void InputMappingDialog::add_clicked()
        ui->table->setRowCount(mapping.buses.size());
 
        unsigned row = mapping.buses.size() - 1;
-       fill_row_from_bus(row, new_bus);
+       fill_row_from_bus(row, new_bus, mapping);
        ui->table->editItem(ui->table->item(row, 0));  // Start editing the name.
        update_button_state();
 }
@@ -257,8 +300,8 @@ void InputMappingDialog::updown_clicked(int direction)
 
        swap(mapping.buses[a_row], mapping.buses[b_row]);
        swap(bus_settings[a_row], bus_settings[b_row]);
-       fill_row_from_bus(a_row, mapping.buses[a_row]);
-       fill_row_from_bus(b_row, mapping.buses[b_row]);
+       fill_row_from_bus(a_row, mapping.buses[a_row], mapping);
+       fill_row_from_bus(b_row, mapping.buses[b_row], mapping);
 
        QTableWidgetSelectionRange a_sel(a_row, 0, a_row, ui->table->columnCount() - 1);
        QTableWidgetSelectionRange b_sel(b_row, 0, b_row, ui->table->columnCount() - 1);