]> git.sesse.net Git - nageru/commitdiff
Reenable simple audio.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Wed, 28 Sep 2016 18:08:30 +0000 (20:08 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Wed, 19 Oct 2016 22:55:44 +0000 (00:55 +0200)
Now that most of the multichannel work has been done, we can put the
wraps back on and reenable the simple audio model from 1.3.x, which is
less flexible but also easier for the casual user. Users can choose
between the old model (simple) and the new (multichannel) through a
UI toggle, or with a command-line flag; they map to the same processing
code.

audio_mixer.cpp
audio_mixer.h
flags.cpp
flags.h
glwidget.cpp
mainwindow.cpp
mainwindow.h
mixer.h
ui_mainwindow.ui

index a0628fe1f68a647675b09f998a4041a708cfffca..506e78d50ede72820e08ba1acfecb6d6dbad8411 100644 (file)
@@ -6,6 +6,7 @@
 #include <stdio.h>
 #include <endian.h>
 #include <cmath>
+#include <limits>
 #ifdef __SSE__
 #include <immintrin.h>
 #endif
@@ -179,8 +180,9 @@ AudioMixer::AudioMixer(unsigned num_cards)
        set_final_makeup_gain_auto(global_flags.final_makeup_gain_auto);
        alsa_pool.init();
 
-       InputMapping new_input_mapping;
        if (!global_flags.input_mapping_filename.empty()) {
+               current_mapping_mode = MappingMode::MULTICHANNEL;
+               InputMapping new_input_mapping;
                if (!load_input_mapping_from_file(get_devices(),
                                                  global_flags.input_mapping_filename,
                                                  &new_input_mapping)) {
@@ -188,18 +190,13 @@ AudioMixer::AudioMixer(unsigned num_cards)
                                global_flags.input_mapping_filename.c_str());
                        exit(1);
                }
+               set_input_mapping(new_input_mapping);
        } else {
-               // Generate a very simple, default input mapping.
-               InputMapping::Bus input;
-               input.name = "Main";
-               input.device.type = InputSourceType::CAPTURE_CARD;
-               input.device.index = 0;
-               input.source_channel[0] = 0;
-               input.source_channel[1] = 1;
-
-               new_input_mapping.buses.push_back(input);
+               set_simple_input(/*card_index=*/0);
+               if (global_flags.multichannel_mapping_mode) {
+                       current_mapping_mode = MappingMode::MULTICHANNEL;
+               }
        }
-       set_input_mapping(new_input_mapping);
 
        r128.init(2, OUTPUT_FREQUENCY);
        r128.integr_start();
@@ -888,10 +885,52 @@ void AudioMixer::serialize_device(DeviceSpec device_spec, DeviceSpecProto *devic
        }
 }
 
+void AudioMixer::set_simple_input(unsigned card_index)
+{
+       InputMapping new_input_mapping;
+       InputMapping::Bus input;
+       input.name = "Main";
+       input.device.type = InputSourceType::CAPTURE_CARD;
+       input.device.index = card_index;
+       input.source_channel[0] = 0;
+       input.source_channel[1] = 1;
+
+       new_input_mapping.buses.push_back(input);
+
+       lock_guard<timed_mutex> lock(audio_mutex);
+       current_mapping_mode = MappingMode::SIMPLE;
+       set_input_mapping_lock_held(new_input_mapping);
+       fader_volume_db[0] = 0.0f;
+}
+
+unsigned AudioMixer::get_simple_input() const
+{
+       lock_guard<timed_mutex> lock(audio_mutex);
+       if (input_mapping.buses.size() == 1 &&
+           input_mapping.buses[0].device.type == InputSourceType::CAPTURE_CARD &&
+           input_mapping.buses[0].source_channel[0] == 0 &&
+           input_mapping.buses[0].source_channel[1] == 1) {
+               return input_mapping.buses[0].device.index;
+       } else {
+               return numeric_limits<unsigned>::max();
+       }
+}
+
 void AudioMixer::set_input_mapping(const InputMapping &new_input_mapping)
 {
        lock_guard<timed_mutex> lock(audio_mutex);
+       set_input_mapping_lock_held(new_input_mapping);
+       current_mapping_mode = MappingMode::MULTICHANNEL;
+}
 
+AudioMixer::MappingMode AudioMixer::get_mapping_mode() const
+{
+       lock_guard<timed_mutex> lock(audio_mutex);
+       return current_mapping_mode;
+}
+
+void AudioMixer::set_input_mapping_lock_held(const InputMapping &new_input_mapping)
+{
        map<DeviceSpec, set<unsigned>> interesting_channels;
        for (const InputMapping::Bus &bus : new_input_mapping.buses) {
                if (bus.device.type == InputSourceType::CAPTURE_CARD ||
index 1570d26373eb3592fbf897990954521ba36d1fb4..789cd1dcf0bb5b56b0042089632c90ce94cc4ac5 100644 (file)
@@ -90,7 +90,28 @@ public:
        // Note: The card should be held (currently this isn't enforced, though).
        void serialize_device(DeviceSpec device_spec, DeviceSpecProto *device_spec_proto);
 
+       enum class MappingMode {
+               // A single bus, only from a video card (no ALSA devices),
+               // only channel 1 and 2, locked to +0 dB. Note that this is
+               // only an UI abstraction around exactly the same audio code
+               // as MULTICHANNEL; it's just less flexible.
+               SIMPLE,
+
+               // Full, arbitrary mappings.
+               MULTICHANNEL
+       };
+
+       // Automatically sets mapping mode to MappingMode::SIMPLE.
+       void set_simple_input(unsigned card_index);
+
+       // If mapping mode is not representable as a MappingMode::SIMPLE type
+       // mapping, returns numeric_limits<unsigned>::max().
+       unsigned get_simple_input() const;
+
+       // Implicitly sets mapping mode to MappingMode::MULTICHANNEL.
        void set_input_mapping(const InputMapping &input_mapping);
+
+       MappingMode get_mapping_mode() const;
        InputMapping get_input_mapping() const;
 
        void set_locut_cutoff(float cutoff_hz)
@@ -296,6 +317,7 @@ private:
        void measure_bus_levels(unsigned bus_index, const std::vector<float> &left, const std::vector<float> &right);
        void send_audio_level_callback();
        std::vector<DeviceSpec> get_active_devices() const;
+       void set_input_mapping_lock_held(const InputMapping &input_mapping);
 
        unsigned num_cards;
 
@@ -339,6 +361,7 @@ 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.
 
+       MappingMode current_mapping_mode;  // Under audio_mutex.
        InputMapping input_mapping;  // Under audio_mutex.
        std::atomic<float> fader_volume_db[MAX_BUSES] {{ 0.0f }};
        float last_fader_volume_db[MAX_BUSES] { 0.0f };  // Under audio_mutex.
index 996107bbfa1b2d32538828ac71a98f34f7b656c2..b22d0254c720e04c21cc6595c312fc50c1418005 100644 (file)
--- a/flags.cpp
+++ b/flags.cpp
@@ -13,7 +13,8 @@ Flags global_flags;
 
 // Long options that have no corresponding short option.
 enum LongOption {
-       OPTION_FAKE_CARDS_AUDIO = 1000,
+       OPTION_MULTICHANNEL = 1000,
+       OPTION_FAKE_CARDS_AUDIO,
        OPTION_HTTP_UNCOMPRESSED_VIDEO,
        OPTION_HTTP_X264_VIDEO,
        OPTION_X264_PRESET,
@@ -55,7 +56,8 @@ void usage()
        fprintf(stderr, "  -v, --va-display=SPEC           VA-API device for H.264 encoding\n");
        fprintf(stderr, "                                    ($DISPLAY spec or /dev/dri/render* path)\n");
        fprintf(stderr, "  -m, --map-signal=SIGNAL,CARD    set a default card mapping (can be given multiple times)\n");
-       fprintf(stderr, "  -M, --input-mapping=FILE        start with the given audio input mapping\n");
+       fprintf(stderr, "  -M, --input-mapping=FILE        start with the given audio input mapping (implies --multichannel)\n");
+       fprintf(stderr, "      --multichannel              start in multichannel audio mapping mode\n");
        fprintf(stderr, "      --fake-cards-audio          make fake (disconnected) cards output a simple tone\n");
        fprintf(stderr, "      --http-uncompressed-video   send uncompressed NV12 video to HTTP clients\n");
        fprintf(stderr, "      --http-x264-video           send x264-compressed video to HTTP clients\n");
@@ -103,6 +105,7 @@ void parse_flags(int argc, char * const argv[])
                { "map-signal", required_argument, 0, 'm' },
                { "input-mapping", required_argument, 0, 'M' },
                { "va-display", required_argument, 0, 'v' },
+               { "multichannel", no_argument, 0, OPTION_MULTICHANNEL },
                { "fake-cards-audio", no_argument, 0, OPTION_FAKE_CARDS_AUDIO },
                { "http-uncompressed-video", no_argument, 0, OPTION_HTTP_UNCOMPRESSED_VIDEO },
                { "http-x264-video", no_argument, 0, OPTION_HTTP_X264_VIDEO },
@@ -172,6 +175,9 @@ void parse_flags(int argc, char * const argv[])
                case 'M':
                        global_flags.input_mapping_filename = optarg;
                        break;
+               case OPTION_MULTICHANNEL:
+                       global_flags.multichannel_mapping_mode = true;
+                       break;
                case 'v':
                        global_flags.va_display = optarg;
                        break;
diff --git a/flags.h b/flags.h
index 8e68a66893d766a8f6223be1c351a5b935d8802d..5fed2a88517a5effd5da13eb49a111dda9d2d7e0 100644 (file)
--- a/flags.h
+++ b/flags.h
@@ -36,6 +36,7 @@ struct Flags {
        std::vector<std::string> x264_extra_param;  // In “key[,value]” format.
        bool enable_alsa_output = true;
        std::map<int, int> default_stream_mapping;
+       bool multichannel_mapping_mode = false;  // Implicitly true if input_mapping_filename is nonempty.
        std::string input_mapping_filename;  // Empty for none.
 };
 extern Flags global_flags;
index ec4335359e72557df0d0b9e434781fac35c227d5..9d5e02cd3c72e86207298042c155a092e5599d8f 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <stdio.h>
 #include <functional>
+#include <limits>
 #include <mutex>
 #include <movit/effect_chain.h>
 #include <movit/resource_pool.h>
@@ -224,13 +225,16 @@ void GLWidget::show_context_menu(unsigned signal_num, const QPoint &pos)
        // --- End of card-dependent choices ---
 
        // Add an audio source selector.
-       QAction *audio_source_action = new QAction("Use as audio source", &menu);
-       audio_source_action->setCheckable(true);
-       if (global_mixer->get_audio_source() == signal_num) {
-               audio_source_action->setChecked(true);
-               audio_source_action->setEnabled(false);
+       QAction *audio_source_action = nullptr;
+       if (global_audio_mixer->get_mapping_mode() == AudioMixer::MappingMode::SIMPLE) {
+               audio_source_action = new QAction("Use as audio source", &menu);
+               audio_source_action->setCheckable(true);
+               if (global_audio_mixer->get_simple_input() == signal_num) {
+                       audio_source_action->setChecked(true);
+                       audio_source_action->setEnabled(false);
+               }
+               menu.addAction(audio_source_action);
        }
-       menu.addAction(audio_source_action);
 
        // And a master clock selector.
        QAction *master_clock_action = new QAction("Use as master clock", &menu);
@@ -243,8 +247,8 @@ void GLWidget::show_context_menu(unsigned signal_num, const QPoint &pos)
 
        // Show the menu and look at the result.
        QAction *selected_item = menu.exec(global_pos);
-       if (selected_item == audio_source_action) {
-               global_mixer->set_audio_source(signal_num);
+       if (audio_source_action != nullptr && selected_item == audio_source_action) {
+               global_audio_mixer->set_simple_input(signal_num);
        } else if (selected_item == master_clock_action) {
                global_mixer->set_master_clock(signal_num);
        } else if (selected_item != nullptr) {
index e62594dc04554cb002d3e9c1bb4574b1c5d0658e..9e4ad0d9e5dc4b6fa48036d6ea848bb51603145d 100644 (file)
@@ -11,6 +11,7 @@
 #include <QInputDialog>
 #include <QKeySequence>
 #include <QLabel>
+#include <QMessageBox>
 #include <QMetaType>
 #include <QPushButton>
 #include <QResizeEvent>
@@ -153,6 +154,10 @@ MainWindow::MainWindow()
        disk_free_label->setStyleSheet("QLabel {padding-right: 5px;}");
        ui->menuBar->setCornerWidget(disk_free_label);
 
+       QActionGroup *audio_mapping_group = new QActionGroup(this);
+       ui->simple_audio_mode->setActionGroup(audio_mapping_group);
+       ui->multichannel_audio_mode->setActionGroup(audio_mapping_group);
+
        ui->me_live->set_output(Mixer::OUTPUT_LIVE);
        ui->me_preview->set_output(Mixer::OUTPUT_PREVIEW);
 
@@ -160,6 +165,8 @@ MainWindow::MainWindow()
        connect(ui->cut_action, &QAction::triggered, this, &MainWindow::cut_triggered);
        connect(ui->exit_action, &QAction::triggered, this, &MainWindow::exit_triggered);
        connect(ui->about_action, &QAction::triggered, this, &MainWindow::about_triggered);
+       connect(ui->simple_audio_mode, &QAction::triggered, this, &MainWindow::simple_audio_mode_triggered);
+       connect(ui->multichannel_audio_mode, &QAction::triggered, this, &MainWindow::multichannel_audio_mode_triggered);
        connect(ui->input_mapping_action, &QAction::triggered, this, &MainWindow::input_mapping_triggered);
 
        if (global_flags.x264_video_to_http) {
@@ -191,7 +198,9 @@ MainWindow::MainWindow()
 
        // And bind the same to PgUp/PgDown.
        auto switch_page = [this]{
-               ui->audio_views->setCurrentIndex(1 - ui->audio_views->currentIndex());
+               if (global_audio_mixer->get_mapping_mode() == AudioMixer::MappingMode::MULTICHANNEL) {
+                       ui->audio_views->setCurrentIndex(1 - ui->audio_views->currentIndex());
+               }
        };
        connect(new QShortcut(QKeySequence::MoveToNextPage, this), &QShortcut::activated, switch_page);
        connect(new QShortcut(QKeySequence::MoveToPreviousPage, this), &QShortcut::activated, switch_page);
@@ -240,8 +249,6 @@ void MainWindow::mixer_created(Mixer *mixer)
                connect(ui_display->wb_button, &QPushButton::clicked, bind(&MainWindow::wb_button_clicked, this, i));
        }
 
-       setup_audio_miniview();
-       setup_audio_expanded_view();
        global_audio_mixer->set_state_changed_callback(bind(&MainWindow::audio_state_changed, this));
 
        slave_knob(ui->locut_cutoff_knob, ui->locut_cutoff_knob_2);
@@ -250,42 +257,38 @@ void MainWindow::mixer_created(Mixer *mixer)
        slave_checkbox(ui->makeup_gain_auto_checkbox, ui->makeup_gain_auto_checkbox_2);
        slave_checkbox(ui->limiter_enabled, ui->limiter_enabled_2);
 
+       reset_audio_mapping_ui();
+
        // TODO: Fetch all of the values these for completeness,
        // not just the enable knobs implied by flags.
-#if 0
-       // TODO: Reenable for simple audio.
-       ui->locut_enabled->setChecked(global_audio_mixer->get_locut_enabled(0));
+       ui->limiter_enabled->setChecked(global_audio_mixer->get_limiter_enabled());
+       ui->makeup_gain_auto_checkbox->setChecked(global_audio_mixer->get_final_makeup_gain_auto());
+
+       // Controls used only for simple audio fetch their state from the first bus.
+       constexpr unsigned simple_bus_index = 0;
+       if (global_audio_mixer->get_mapping_mode() == AudioMixer::MappingMode::SIMPLE) {
+               ui->locut_enabled->setChecked(global_audio_mixer->get_locut_enabled(simple_bus_index));
+               ui->gainstaging_knob->setValue(global_audio_mixer->get_gain_staging_db(simple_bus_index));
+               ui->gainstaging_auto_checkbox->setChecked(global_audio_mixer->get_gain_staging_auto(simple_bus_index));
+               ui->compressor_enabled->setChecked(global_audio_mixer->get_compressor_enabled(simple_bus_index));
+               ui->compressor_threshold_db_display->setText(
+                       QString::fromStdString(format_db(mixer->get_audio_mixer()->get_compressor_threshold_dbfs(simple_bus_index), DB_WITH_SIGN)));
+       }
        connect(ui->locut_enabled, &QCheckBox::stateChanged, [this](int state){
-               global_audio_mixer->set_locut_enabled(0, state == Qt::Checked);
+               global_audio_mixer->set_locut_enabled(simple_bus_index, state == Qt::Checked);
        });
-       ui->gainstaging_knob->setValue(global_audio_mixer->get_gain_staging_db());
-       ui->gainstaging_auto_checkbox->setChecked(global_audio_mixer->get_gain_staging_auto());
-       ui->compressor_enabled->setChecked(global_audio_mixer->get_compressor_enabled());
-       connect(ui->gainstaging_knob, &QAbstractSlider::valueChanged, this, &MainWindow::gain_staging_knob_changed);
-       connect(ui->gainstaging_auto_checkbox, &QCheckBox::stateChanged, [this](int state){
-               global_audio_mixer->set_gain_staging_auto(state == Qt::Checked);
+       connect(ui->gainstaging_knob, &QAbstractSlider::valueChanged,
+               bind(&MainWindow::gain_staging_knob_changed, this, simple_bus_index, _1));
+       connect(ui->gainstaging_auto_checkbox, &QCheckBox::stateChanged, [this, simple_bus_index](int state){
+               global_audio_mixer->set_gain_staging_auto(simple_bus_index, state == Qt::Checked);
        });
-       ui->compressor_threshold_db_display->setText(
-               QString::fromStdString(format_db(mixer->get_audio_mixer()->get_compressor_threshold_dbfs(), DB_WITH_SIGN)));
-       ui->compressor_threshold_db_display->setText(buf);
-       connect(ui->compressor_threshold_knob, &QDial::valueChanged, this, &MainWindow::compressor_threshold_knob_changed);
-       connect(ui->compressor_enabled, &QCheckBox::stateChanged, [this](int state){
-               global_audio_mixer->set_compressor_enabled(state == Qt::Checked);
+       connect(ui->compressor_threshold_knob, &QDial::valueChanged,
+               bind(&MainWindow::compressor_threshold_knob_changed, this, simple_bus_index, _1));
+       connect(ui->compressor_enabled, &QCheckBox::stateChanged, [this, simple_bus_index](int state){
+               global_audio_mixer->set_compressor_enabled(simple_bus_index, state == Qt::Checked);
        });
-#else
-       ui->locut_enabled->setVisible(false);
-       ui->gainstaging_label->setVisible(false);
-       ui->gainstaging_knob->setVisible(false);
-       ui->gainstaging_db_display->setVisible(false);
-       ui->gainstaging_auto_checkbox->setVisible(false);
-       ui->compressor_threshold_label->setVisible(false);
-       ui->compressor_threshold_knob->setVisible(false);
-       ui->compressor_threshold_db_display->setVisible(false);
-       ui->compressor_enabled->setVisible(false);
-#endif
-       ui->limiter_enabled->setChecked(global_audio_mixer->get_limiter_enabled());
-       ui->makeup_gain_auto_checkbox->setChecked(global_audio_mixer->get_final_makeup_gain_auto());
 
+       // Global mastering controls.
        QString limiter_threshold_label(
                QString::fromStdString(format_db(mixer->get_audio_mixer()->get_limiter_threshold_dbfs(), DB_WITH_SIGN)));
        ui->limiter_threshold_db_display->setText(limiter_threshold_label);
@@ -320,6 +323,33 @@ void MainWindow::mixer_created(Mixer *mixer)
        sigaction(SIGUSR1, &act, nullptr);
 }
 
+void MainWindow::reset_audio_mapping_ui()
+{
+       bool simple = (global_audio_mixer->get_mapping_mode() == AudioMixer::MappingMode::SIMPLE);
+
+       ui->simple_audio_mode->setChecked(simple);
+       ui->multichannel_audio_mode->setChecked(!simple);
+       ui->input_mapping_action->setEnabled(!simple);
+
+       ui->locut_enabled->setVisible(simple);
+       ui->gainstaging_label->setVisible(simple);
+       ui->gainstaging_knob->setVisible(simple);
+       ui->gainstaging_db_display->setVisible(simple);
+       ui->gainstaging_auto_checkbox->setVisible(simple);
+       ui->compressor_threshold_label->setVisible(simple);
+       ui->compressor_threshold_knob->setVisible(simple);
+       ui->compressor_threshold_db_display->setVisible(simple);
+       ui->compressor_enabled->setVisible(simple);
+
+       setup_audio_miniview();
+       setup_audio_expanded_view();
+
+       if (simple) {
+               ui->audio_views->setCurrentIndex(0);
+       }
+       ui->compact_header->setVisible(!simple);
+}
+
 void MainWindow::setup_audio_miniview()
 {
        // Remove any existing channels.
@@ -329,6 +359,10 @@ void MainWindow::setup_audio_miniview()
        }
        audio_miniviews.clear();
 
+       if (global_audio_mixer->get_mapping_mode() == AudioMixer::MappingMode::SIMPLE) {
+               return;
+       }
+
        // Set up brand new ones from the input mapping.
        InputMapping mapping = global_audio_mixer->get_input_mapping();
        audio_miniviews.resize(mapping.buses.size());
@@ -368,6 +402,10 @@ void MainWindow::setup_audio_expanded_view()
        }
        audio_expanded_views.clear();
 
+       if (global_audio_mixer->get_mapping_mode() == AudioMixer::MappingMode::SIMPLE) {
+               return;
+       }
+
        // Set up brand new ones from the input mapping.
        InputMapping mapping = global_audio_mixer->get_input_mapping();
        audio_expanded_views.resize(mapping.buses.size());
@@ -468,6 +506,43 @@ void MainWindow::about_triggered()
        AboutDialog().exec();
 }
 
+void MainWindow::simple_audio_mode_triggered()
+{
+       if (global_audio_mixer->get_mapping_mode() == AudioMixer::MappingMode::SIMPLE) {
+               return;
+       }
+       unsigned card_index = global_audio_mixer->get_simple_input();
+       if (card_index == numeric_limits<unsigned>::max()) {
+               QMessageBox::StandardButton reply =
+                       QMessageBox::question(this,
+                               "Mapping too complex",
+                               "The current audio mapping is too complicated to be representable in simple mode, "
+                                       "and will be discarded if you proceed. Really go to simple audio mode?",
+                               QMessageBox::Yes | QMessageBox::No);
+               if (reply == QMessageBox::No) {
+                       ui->simple_audio_mode->setChecked(false);
+                       ui->multichannel_audio_mode->setChecked(true);
+                       return;
+               }
+               card_index = 0;
+       }
+       global_audio_mixer->set_simple_input(/*card_index=*/card_index);
+       reset_audio_mapping_ui();
+}
+
+void MainWindow::multichannel_audio_mode_triggered()
+{
+       if (global_audio_mixer->get_mapping_mode() == AudioMixer::MappingMode::MULTICHANNEL) {
+               return;
+       }
+
+       // Take the generated input mapping from the simple input,
+       // and set it as a normal multichannel mapping, which causes
+       // the mode to go to multichannel.
+       global_audio_mixer->set_input_mapping(global_audio_mixer->get_input_mapping());
+       reset_audio_mapping_ui();
+}
+
 void MainWindow::input_mapping_triggered()
 {
        if (InputMappingDialog().exec() == QDialog::Accepted) {
@@ -714,7 +789,7 @@ void MainWindow::relayout()
        remaining_height -= ui->vertical_layout->spacing();
 
        // The label above the audio strip.
-       double compact_label_height = ui->compact_label->geometry().height() +
+       double compact_label_height = ui->compact_label->minimumHeight() +
                ui->compact_audio_layout->spacing();
        remaining_height -= compact_label_height;
 
index 374bd49d6e36961417c73f2733f0f189c921d1e6..77742bf7926ffc86e4b0c437c2279dd09f11e654 100644 (file)
@@ -40,6 +40,8 @@ public slots:
        void x264_bitrate_triggered();
        void exit_triggered();
        void about_triggered();
+       void simple_audio_mode_triggered();
+       void multichannel_audio_mode_triggered();
        void input_mapping_triggered();
        void transition_clicked(int transition_number);
        void channel_clicked(int channel_number);
@@ -58,6 +60,7 @@ public slots:
        void relayout();
 
 private:
+       void reset_audio_mapping_ui();
        void setup_audio_miniview();
        void setup_audio_expanded_view();
        bool eventFilter(QObject *watched, QEvent *event) override;
diff --git a/mixer.h b/mixer.h
index f5e72e42e237a5a1df16152b4a3b28aac34d24fb..39b259b45938b4a4dbbf9ffedbf36dcb9c4b5ed3 100644 (file)
--- a/mixer.h
+++ b/mixer.h
@@ -199,16 +199,6 @@ public:
                return theme->map_signal(channel);
        }
 
-       unsigned get_audio_source() const
-       {
-               return audio_source_channel;
-       }
-
-       void set_audio_source(unsigned channel)
-       {
-               audio_source_channel = channel;
-       }
-
        unsigned get_master_clock() const
        {
                return master_clock_channel;
index 256390aa543a5d4b4efdd87f3f70974bd210a9cc..67bf75cee31f517d60258f381a0ae47adc4e73b8 100644 (file)
            <number>0</number>
           </property>
           <item>
-           <layout class="QHBoxLayout" name="compact_header">
-            <property name="spacing">
-             <number>0</number>
+           <widget class="QWidget" name="compact_header" native="true">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+              <horstretch>8</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
             </property>
-            <item>
-             <widget class="QLabel" name="compact_label">
-              <property name="text">
-               <string>Compact audio view  </string>
-              </property>
-              <property name="alignment">
-               <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-              </property>
-             </widget>
-            </item>
-            <item>
-             <widget class="QToolButton" name="compact_prev_page">
-              <property name="enabled">
-               <bool>true</bool>
-              </property>
-              <property name="maximumSize">
-               <size>
-                <width>15</width>
-                <height>15</height>
-               </size>
-              </property>
-              <property name="text">
-               <string>...</string>
-              </property>
-              <property name="autoRaise">
-               <bool>true</bool>
-              </property>
-              <property name="arrowType">
-               <enum>Qt::LeftArrow</enum>
-              </property>
-             </widget>
-            </item>
-            <item>
-             <widget class="QToolButton" name="compact_next_page">
-              <property name="maximumSize">
-               <size>
-                <width>15</width>
-                <height>15</height>
-               </size>
-              </property>
-              <property name="text">
-               <string>...</string>
-              </property>
-              <property name="autoRaise">
-               <bool>true</bool>
-              </property>
-              <property name="arrowType">
-               <enum>Qt::RightArrow</enum>
-              </property>
-             </widget>
-            </item>
-           </layout>
+            <layout class="QHBoxLayout" name="horizontalLayout_3">
+             <property name="spacing">
+              <number>0</number>
+             </property>
+             <property name="leftMargin">
+              <number>0</number>
+             </property>
+             <property name="topMargin">
+              <number>0</number>
+             </property>
+             <property name="rightMargin">
+              <number>0</number>
+             </property>
+             <property name="bottomMargin">
+              <number>0</number>
+             </property>
+             <item>
+              <widget class="QLabel" name="compact_label">
+               <property name="text">
+                <string>Compact audio view  </string>
+               </property>
+               <property name="alignment">
+                <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+               </property>
+              </widget>
+             </item>
+             <item>
+              <widget class="QToolButton" name="compact_prev_page">
+               <property name="enabled">
+                <bool>true</bool>
+               </property>
+               <property name="maximumSize">
+                <size>
+                 <width>15</width>
+                 <height>15</height>
+                </size>
+               </property>
+               <property name="text">
+                <string>...</string>
+               </property>
+               <property name="autoRaise">
+                <bool>true</bool>
+               </property>
+               <property name="arrowType">
+                <enum>Qt::LeftArrow</enum>
+               </property>
+              </widget>
+             </item>
+             <item>
+              <widget class="QToolButton" name="compact_next_page">
+               <property name="maximumSize">
+                <size>
+                 <width>15</width>
+                 <height>15</height>
+                </size>
+               </property>
+               <property name="text">
+                <string>...</string>
+               </property>
+               <property name="autoRaise">
+                <bool>true</bool>
+               </property>
+               <property name="arrowType">
+                <enum>Qt::RightArrow</enum>
+               </property>
+              </widget>
+             </item>
+            </layout>
+           </widget>
           </item>
           <item>
            <layout class="QHBoxLayout" name="audiostrip" stretch="0,1,0">
     <property name="title">
      <string>&amp;Audio</string>
     </property>
+    <addaction name="simple_audio_mode"/>
+    <addaction name="multichannel_audio_mode"/>
+    <addaction name="separator"/>
     <addaction name="input_mapping_action"/>
    </widget>
    <addaction name="menuWhat"/>
     <string>&amp;Input mapping…</string>
    </property>
   </action>
+  <action name="simple_audio_mode">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="checked">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Simple</string>
+   </property>
+  </action>
+  <action name="multichannel_audio_mode">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Multichannel</string>
+   </property>
+  </action>
  </widget>
  <layoutdefault spacing="6" margin="11"/>
  <customwidgets>