]> git.sesse.net Git - nageru/commitdiff
Add mute buttons.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Thu, 20 Oct 2016 21:44:12 +0000 (23:44 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Tue, 25 Oct 2016 16:48:35 +0000 (18:48 +0200)
Actually this is mostly because I like being able to press the
mute button on my MIDI controller and have it light up :-)
Internally, it's implemented by forcing the volume to zero
(or sometimes -90 dB), which means we get all the nice
fading properties and such.

In the process, we now declare -90 dB to be truly zero, and don't
bother adding it to the bus.

audio_mixer.cpp
audio_mixer.h
mainwindow.cpp
mainwindow.h
midi_mapper.cpp
midi_mapper.h
midi_mapping.proto
midi_mapping_dialog.cpp
midi_mapping_dialog.h
ui_audio_expanded_view.ui

index 401c89bb20ba154cf3f6395236300a7bed441e85..46ae44c6f74e73a1f432b712e76008aafdb92394 100644 (file)
@@ -319,6 +319,7 @@ AudioMixer::BusSettings AudioMixer::get_default_bus_settings()
 {
        BusSettings settings;
        settings.fader_volume_db = 0.0f;
+       settings.muted = false;
        settings.locut_enabled = global_flags.locut_enabled;
        for (unsigned band_index = 0; band_index < NUM_EQ_BANDS; ++band_index) {
                settings.eq_level_db[band_index] = 0.0f;
@@ -335,6 +336,7 @@ AudioMixer::BusSettings AudioMixer::get_bus_settings(unsigned bus_index) const
        lock_guard<timed_mutex> lock(audio_mutex);
        BusSettings settings;
        settings.fader_volume_db = fader_volume_db[bus_index];
+       settings.muted = mute[bus_index];
        settings.locut_enabled = locut_enabled[bus_index];
        for (unsigned band_index = 0; band_index < NUM_EQ_BANDS; ++band_index) {
                settings.eq_level_db[band_index] = eq_level_db[bus_index][band_index];
@@ -350,6 +352,7 @@ void AudioMixer::set_bus_settings(unsigned bus_index, const AudioMixer::BusSetti
 {
        lock_guard<timed_mutex> lock(audio_mutex);
        fader_volume_db[bus_index] = settings.fader_volume_db;
+       mute[bus_index] = settings.muted;
        locut_enabled[bus_index] = settings.locut_enabled;
        for (unsigned band_index = 0; band_index < NUM_EQ_BANDS; ++band_index) {
                eq_level_db[bus_index][band_index] = settings.eq_level_db[band_index];
@@ -683,13 +686,14 @@ void AudioMixer::add_bus_to_master(unsigned bus_index, const vector<float> &samp
        assert(samples_bus.size() == samples_out->size());
        assert(samples_bus.size() % 2 == 0);
        unsigned num_samples = samples_bus.size() / 2;
-       if (fabs(fader_volume_db[bus_index] - last_fader_volume_db[bus_index]) > 1e-3) {
+       const float new_volume_db = mute[bus_index] ? -90.0f : fader_volume_db[bus_index].load();
+       if (fabs(new_volume_db - last_fader_volume_db[bus_index]) > 1e-3) {
                // The volume has changed; do a fade over the course of this frame.
                // (We might have some numerical issues here, but it seems to sound OK.)
                // For the purpose of fading here, the silence floor is set to -90 dB
                // (the fader only goes to -84).
                float old_volume = from_db(max<float>(last_fader_volume_db[bus_index], -90.0f));
-               float volume = from_db(max<float>(fader_volume_db[bus_index], -90.0f));
+               float volume = from_db(max<float>(new_volume_db, -90.0f));
 
                float volume_inc = pow(volume / old_volume, 1.0 / num_samples);
                volume = old_volume;
@@ -706,8 +710,8 @@ void AudioMixer::add_bus_to_master(unsigned bus_index, const vector<float> &samp
                                volume *= volume_inc;
                        }
                }
-       } else {
-               float volume = from_db(fader_volume_db[bus_index]);
+       } else if (new_volume_db > -90.0f) {
+               float volume = from_db(new_volume_db);
                if (bus_index == 0) {
                        for (unsigned i = 0; i < num_samples; ++i) {
                                (*samples_out)[i * 2 + 0] = samples_bus[i * 2 + 0] * volume;
@@ -721,13 +725,13 @@ void AudioMixer::add_bus_to_master(unsigned bus_index, const vector<float> &samp
                }
        }
 
-       last_fader_volume_db[bus_index] = fader_volume_db[bus_index];
+       last_fader_volume_db[bus_index] = new_volume_db;
 }
 
 void AudioMixer::measure_bus_levels(unsigned bus_index, const vector<float> &left, const vector<float> &right)
 {
        assert(left.size() == right.size());
-       const float volume = from_db(fader_volume_db[bus_index]);
+       const float volume = mute[bus_index] ? 0.0f : from_db(fader_volume_db[bus_index]);
        const float peak_levels[2] = {
                find_peak(left.data(), left.size()) * volume,
                find_peak(right.data(), right.size()) * volume
index 38b98f7ce0673e025fb6c96df392281189a98fac..821171037f6faf70b11e7d8518484380ecbe587f 100644 (file)
@@ -67,6 +67,9 @@ public:
        float get_fader_volume(unsigned bus_index) const { return fader_volume_db[bus_index]; }
        void set_fader_volume(unsigned bus_index, float level_db) { fader_volume_db[bus_index] = level_db; }
 
+       bool get_mute(unsigned bus_index) const { return mute[bus_index]; }
+       void set_mute(unsigned bus_index, bool muted) { mute[bus_index] = muted; }
+
        // Note: This operation holds all ALSA devices (see ALSAPool::get_devices()).
        // You will need to call set_input_mapping() to get the hold state correctly,
        // or every card will be held forever.
@@ -281,6 +284,7 @@ public:
        // or set_* functions for that bus.
        struct BusSettings {
                float fader_volume_db;
+               bool muted;
                bool locut_enabled;
                float eq_level_db[NUM_EQ_BANDS];
                float gain_staging_db;
@@ -367,6 +371,7 @@ private:
        MappingMode current_mapping_mode;  // Under audio_mutex.
        InputMapping input_mapping;  // Under audio_mutex.
        std::atomic<float> fader_volume_db[MAX_BUSES] {{ 0.0f }};
+       std::atomic<bool> mute[MAX_BUSES] {{ false }};
        float last_fader_volume_db[MAX_BUSES] { 0.0f };  // Under audio_mutex.
        std::atomic<float> eq_level_db[MAX_BUSES][NUM_EQ_BANDS] {{{ 0.0f }}};
        float last_eq_level_db[MAX_BUSES][NUM_EQ_BANDS] {{ 0.0f }};
index d92847bf0f9e84caf45b9eb50513755b26f566f8..eb78d0e545dc73c817c50d8bc762bb579ceee82a 100644 (file)
@@ -452,6 +452,9 @@ void MainWindow::setup_audio_expanded_view()
                update_eq_label(bus_index, EQ_BAND_MID, global_audio_mixer->get_eq(bus_index, EQ_BAND_MID));
                update_eq_label(bus_index, EQ_BAND_BASS, global_audio_mixer->get_eq(bus_index, EQ_BAND_BASS));
                ui_audio_expanded_view->fader->setDbValue(global_audio_mixer->get_fader_volume(bus_index));
+               ui_audio_expanded_view->mute_button->setChecked(global_audio_mixer->get_mute(bus_index) ? Qt::Checked : Qt::Unchecked);
+               connect(ui_audio_expanded_view->mute_button, &QPushButton::toggled,
+                       bind(&MainWindow::mute_button_toggled, this, bus_index, _1));
                ui->buses->addWidget(channel);
 
                ui_audio_expanded_view->locut_enabled->setChecked(global_audio_mixer->get_locut_enabled(bus_index));
@@ -733,6 +736,12 @@ void MainWindow::mini_fader_changed(int bus, double volume_db)
        global_audio_mixer->set_fader_volume(bus, volume_db);
 }
 
+void MainWindow::mute_button_toggled(int bus, bool checked)
+{
+       global_audio_mixer->set_mute(bus, checked);
+       midi_mapper.refresh_lights();
+}
+
 void MainWindow::reset_meters_button_clicked()
 {
        global_audio_mixer->reset_meters();
@@ -914,6 +923,11 @@ void MainWindow::set_fader(unsigned bus_idx, float value)
        set_relative_value_if_exists(bus_idx, &Ui::AudioExpandedView::fader, value);
 }
 
+void MainWindow::toggle_mute(unsigned bus_idx)
+{
+       click_button_if_exists(bus_idx, &Ui::AudioExpandedView::mute_button);
+}
+
 void MainWindow::toggle_locut(unsigned bus_idx)
 {
        click_button_if_exists(bus_idx, &Ui::AudioExpandedView::locut_enabled);
@@ -955,6 +969,7 @@ void MainWindow::clear_all_highlights()
                        highlight_gain(bus_idx, false);
                        highlight_compressor_threshold(bus_idx, false);
                        highlight_fader(bus_idx, false);
+                       highlight_mute(bus_idx, false);
                        highlight_toggle_locut(bus_idx, false);
                        highlight_toggle_auto_gain_staging(bus_idx, false);
                        highlight_toggle_compressor(bus_idx, false);
@@ -1030,6 +1045,11 @@ void MainWindow::highlight_fader(unsigned bus_idx, bool highlight)
        highlight_control_if_exists(bus_idx, &Ui::AudioExpandedView::fader, highlight);
 }
 
+void MainWindow::highlight_mute(unsigned bus_idx, bool highlight)
+{
+       highlight_control_if_exists(bus_idx, &Ui::AudioExpandedView::mute_button, highlight, /*is_mute_btton=*/true);
+}
+
 void MainWindow::highlight_toggle_locut(unsigned bus_idx, bool highlight)
 {
        highlight_control_if_exists(bus_idx, &Ui::AudioExpandedView::locut_enabled, highlight);
@@ -1109,11 +1129,32 @@ void MainWindow::highlight_control(T *control, bool highlight)
 }
 
 template<class T>
-void MainWindow::highlight_control_if_exists(unsigned bus_idx, T *(Ui_AudioExpandedView::*control), bool highlight)
+void MainWindow::highlight_mute_control(T *control, bool highlight)
 {
-       post_to_main_thread([this, bus_idx, control, highlight]{
+       if (control == nullptr) {
+               return;
+       }
+       if (global_audio_mixer == nullptr ||
+           global_audio_mixer->get_mapping_mode() != AudioMixer::MappingMode::MULTICHANNEL) {
+               highlight = false;
+       }
+       if (highlight) {
+               control->setStyleSheet("QPushButton { background: rgb(0,255,0,80); } QPushButton:checked { background: rgba(255,80,0,140); }");
+       } else {
+               control->setStyleSheet("QPushButton:checked { background: rgba(255,0,0,80); }");
+       }
+}
+
+template<class T>
+void MainWindow::highlight_control_if_exists(unsigned bus_idx, T *(Ui_AudioExpandedView::*control), bool highlight, bool is_mute_button)
+{
+       post_to_main_thread([this, bus_idx, control, highlight, is_mute_button]{
                if (bus_idx < audio_expanded_views.size()) {
-                       highlight_control(audio_expanded_views[bus_idx]->*control, highlight);
+                       if (is_mute_button) {
+                               highlight_mute_control(audio_expanded_views[bus_idx]->*control, highlight);
+                       } else {
+                               highlight_control(audio_expanded_views[bus_idx]->*control, highlight);
+                       }
                }
        });
 }
index f0729a6a122ad64bac62e334f93f10ba880cc8e8..8dfbf835db9f412ce79d13c5bab3d19fce38b841 100644 (file)
@@ -60,6 +60,7 @@ public slots:
        void limiter_threshold_knob_changed(int value);
        void compressor_threshold_knob_changed(unsigned bus_index, int value);
        void mini_fader_changed(int bus, double db_volume);
+       void mute_button_toggled(int bus, bool checked);
        void reset_meters_button_clicked();
        void relayout();
 
@@ -75,6 +76,7 @@ public slots:
        void set_compressor_threshold(unsigned bus_idx, float value) override;
        void set_fader(unsigned bus_idx, float value) override;
 
+       void toggle_mute(unsigned bus_idx) override;
        void toggle_locut(unsigned bus_idx) override;
        void toggle_auto_gain_staging(unsigned bus_idx) override;
        void toggle_compressor(unsigned bus_idx) override;
@@ -95,6 +97,7 @@ public slots:
        void highlight_compressor_threshold(unsigned bus_idx, bool highlight) override;
        void highlight_fader(unsigned bus_idx, bool highlight) override;
 
+       void highlight_mute(unsigned bus_idx, bool highlight) override;
        void highlight_toggle_locut(unsigned bus_idx, bool highlight) override;
        void highlight_toggle_auto_gain_staging(unsigned bus_idx, bool highlight) override;
        void highlight_toggle_compressor(unsigned bus_idx, bool highlight) override;
@@ -137,7 +140,10 @@ private:
        void highlight_control(T *control, bool highlight);
 
        template<class T>
-       void highlight_control_if_exists(unsigned bus_idx, T *(Ui_AudioExpandedView::*control), bool highlight);
+       void highlight_mute_control(T *control, bool highlight);
+
+       template<class T>
+       void highlight_control_if_exists(unsigned bus_idx, T *(Ui_AudioExpandedView::*control), bool highlight, bool is_mute_button = false);
 
        Ui::MainWindow *ui;
        QLabel *disk_free_label;
index ba996e8f4fab580f5eaf6b388b670b7ed8c7d3b5..8f43d21bc0de569ecf5d5ad28dcae765bca82cc8 100644 (file)
@@ -335,6 +335,8 @@ void MIDIMapper::handle_event(snd_seq_t *seq, snd_seq_event_t *event)
                        bind(&ControllerReceiver::toggle_compressor, receiver, _1));
                match_button(note, MIDIMappingBusProto::kClearPeakFieldNumber, MIDIMappingProto::kClearPeakBankFieldNumber,
                        bind(&ControllerReceiver::clear_peak, receiver, _1));
+               match_button(note, MIDIMappingBusProto::kToggleMuteFieldNumber, MIDIMappingProto::kClearPeakBankFieldNumber,
+                       bind(&ControllerReceiver::toggle_mute, receiver, _1));
                match_button(note, MIDIMappingBusProto::kToggleLimiterFieldNumber, MIDIMappingProto::kToggleLimiterBankFieldNumber,
                        bind(&ControllerReceiver::toggle_limiter, receiver));
                match_button(note, MIDIMappingBusProto::kToggleAutoMakeupGainFieldNumber, MIDIMappingProto::kToggleAutoMakeupGainBankFieldNumber,
@@ -534,6 +536,8 @@ void MIDIMapper::update_highlights()
                        bus_idx, MIDIMappingBusProto::kCompressorThresholdFieldNumber, MIDIMappingProto::kCompressorThresholdBankFieldNumber));
                receiver->highlight_fader(bus_idx, has_active_controller(
                        bus_idx, MIDIMappingBusProto::kFaderFieldNumber, MIDIMappingProto::kFaderBankFieldNumber));
+               receiver->highlight_mute(bus_idx, has_active_controller(
+                       bus_idx, MIDIMappingBusProto::kToggleMuteFieldNumber, MIDIMappingProto::kToggleMuteBankFieldNumber));
                receiver->highlight_toggle_locut(bus_idx, has_active_controller(
                        bus_idx, MIDIMappingBusProto::kToggleLocutFieldNumber, MIDIMappingProto::kToggleLocutBankFieldNumber));
                receiver->highlight_toggle_auto_gain_staging(bus_idx, has_active_controller(
@@ -573,6 +577,9 @@ void MIDIMapper::update_lights_lock_held()
        }
        unsigned num_buses = min<unsigned>(global_audio_mixer->num_buses(), mapping_proto->bus_mapping_size());
        for (unsigned bus_idx = 0; bus_idx < num_buses; ++bus_idx) {
+               if (global_audio_mixer->get_mute(bus_idx)) {
+                       activate_lights(bus_idx, MIDIMappingBusProto::kIsMutedFieldNumber, &active_lights);
+               }
                if (global_audio_mixer->get_locut_enabled(bus_idx)) {
                        activate_lights(bus_idx, MIDIMappingBusProto::kLocutIsOnFieldNumber, &active_lights);
                }
index 62746165370c2eb9ac24f21ea1217aa8e5e3a782..04e5192ecb0d69a432cc159b83553f0827d37e75 100644 (file)
@@ -39,6 +39,7 @@ public:
        virtual void set_compressor_threshold(unsigned bus_idx, float value) = 0;
        virtual void set_fader(unsigned bus_idx, float value) = 0;
 
+       virtual void toggle_mute(unsigned bus_idx) = 0;
        virtual void toggle_locut(unsigned bus_idx) = 0;
        virtual void toggle_auto_gain_staging(unsigned bus_idx) = 0;
        virtual void toggle_compressor(unsigned bus_idx) = 0;
@@ -61,6 +62,7 @@ public:
        virtual void highlight_compressor_threshold(unsigned bus_idx, bool highlight) = 0;
        virtual void highlight_fader(unsigned bus_idx, bool highlight) = 0;
 
+       virtual void highlight_mute(unsigned bus_idx, bool highlight) = 0;
        virtual void highlight_toggle_locut(unsigned bus_idx, bool highlight) = 0;
        virtual void highlight_toggle_auto_gain_staging(unsigned bus_idx, bool highlight) = 0;
        virtual void highlight_toggle_compressor(unsigned bus_idx, bool highlight) = 0;
index d2b170d46396aec87b445fdb56fe3f7049714529..36bfe8d444aad8e2b7e7b5a9bbd4d81548da7359 100644 (file)
@@ -31,50 +31,50 @@ message MIDIMappingBusProto {
        optional MIDIControllerProto compressor_threshold = 6;
        optional MIDIControllerProto fader = 7;
 
-       // TODO: Add mute and cue? (Of course, we should those to the UI before
-       // making them MIDI controllable.)
-       optional MIDIButtonProto toggle_locut = 8;
-       optional MIDIButtonProto toggle_auto_gain_staging = 9;
-       optional MIDIButtonProto toggle_compressor = 10;
-       optional MIDIButtonProto clear_peak = 11;
+       optional MIDIButtonProto toggle_mute = 8;
+       optional MIDIButtonProto toggle_locut = 9;
+       optional MIDIButtonProto toggle_auto_gain_staging = 10;
+       optional MIDIButtonProto toggle_compressor = 11;
+       optional MIDIButtonProto clear_peak = 12;
 
        // These are really global (controller bank change affects all buss),
        // but it's not uncommon that we'd want one button per bus to switch banks.
        // E.g., if the user binds the “mute” button to “next bank”, they'd want every
        // mute button on the mixer to do that, so they need one mapping per bus.
-       optional MIDIButtonProto prev_bank = 12;
-       optional MIDIButtonProto next_bank = 13;
-       optional MIDIButtonProto select_bank_1 = 14;
-       optional MIDIButtonProto select_bank_2 = 15;
-       optional MIDIButtonProto select_bank_3 = 16;
-       optional MIDIButtonProto select_bank_4 = 17;
-       optional MIDIButtonProto select_bank_5 = 18;
-       optional MIDIButtonProto toggle_limiter = 19;
-       optional MIDIButtonProto toggle_auto_makeup_gain = 20;
+       optional MIDIButtonProto prev_bank = 13;
+       optional MIDIButtonProto next_bank = 14;
+       optional MIDIButtonProto select_bank_1 = 15;
+       optional MIDIButtonProto select_bank_2 = 16;
+       optional MIDIButtonProto select_bank_3 = 17;
+       optional MIDIButtonProto select_bank_4 = 18;
+       optional MIDIButtonProto select_bank_5 = 19;
+       optional MIDIButtonProto toggle_limiter = 20;
+       optional MIDIButtonProto toggle_auto_makeup_gain = 21;
 
        // These are also global (they belong to the master bus), and unlike
        // the bank change commands, one would usually have only one of each,
        // but there's no reason to limit them to one each, and the editor UI
        // becomes simpler if they are the treated the same way as the bank
        // commands.
-       optional MIDIControllerProto locut = 21;
-       optional MIDIControllerProto limiter_threshold = 22;
-       optional MIDIControllerProto makeup_gain = 23;
+       optional MIDIControllerProto locut = 22;
+       optional MIDIControllerProto limiter_threshold = 23;
+       optional MIDIControllerProto makeup_gain = 24;
 
        // Per-bus lights.
-       optional MIDILightProto locut_is_on = 24;
-       optional MIDILightProto auto_gain_staging_is_on = 25;
-       optional MIDILightProto compressor_is_on = 26;
-       optional MIDILightProto has_peaked = 27;
+       optional MIDILightProto is_muted = 25;
+       optional MIDILightProto locut_is_on = 26;
+       optional MIDILightProto auto_gain_staging_is_on = 27;
+       optional MIDILightProto compressor_is_on = 28;
+       optional MIDILightProto has_peaked = 29;
 
        // Global lights. Same logic as above for why they're in this proto.
-       optional MIDILightProto bank_1_is_selected = 28;
-       optional MIDILightProto bank_2_is_selected = 29;
-       optional MIDILightProto bank_3_is_selected = 30;
-       optional MIDILightProto bank_4_is_selected = 31;
-       optional MIDILightProto bank_5_is_selected = 32;
-       optional MIDILightProto limiter_is_on = 33;
-       optional MIDILightProto auto_makeup_gain_is_on = 34;
+       optional MIDILightProto bank_1_is_selected = 30;
+       optional MIDILightProto bank_2_is_selected = 31;
+       optional MIDILightProto bank_3_is_selected = 32;
+       optional MIDILightProto bank_4_is_selected = 33;
+       optional MIDILightProto bank_5_is_selected = 34;
+       optional MIDILightProto limiter_is_on = 35;
+       optional MIDILightProto auto_makeup_gain_is_on = 36;
 }
 
 // The top-level protobuf, containing all the bus mappings, as well as
@@ -98,19 +98,20 @@ message MIDIMappingProto {
        optional int32 fader_bank = 7;
 
        // Bus button banks.
-       optional int32 toggle_locut_bank = 8;
-       optional int32 toggle_auto_gain_staging_bank = 9;
-       optional int32 toggle_compressor_bank = 10;
-       optional int32 clear_peak_bank = 11;
+       optional int32 toggle_mute_bank = 8;
+       optional int32 toggle_locut_bank = 9;
+       optional int32 toggle_auto_gain_staging_bank = 10;
+       optional int32 toggle_compressor_bank = 11;
+       optional int32 clear_peak_bank = 12;
 
        // Global controller banks.
-       optional int32 locut_bank = 12;
-       optional int32 limiter_threshold_bank = 13;
-       optional int32 makeup_gain_bank = 14;
+       optional int32 locut_bank = 13;
+       optional int32 limiter_threshold_bank = 14;
+       optional int32 makeup_gain_bank = 15;
 
        // Global buttons.
-       optional int32 toggle_limiter_bank = 15;
-       optional int32 toggle_auto_makeup_gain_bank = 16;
+       optional int32 toggle_limiter_bank = 16;
+       optional int32 toggle_auto_makeup_gain_bank = 17;
 
-       repeated MIDIMappingBusProto bus_mapping = 17;
+       repeated MIDIMappingBusProto bus_mapping = 18;
 }
index 95de0d97c2150916270aeb673549e7b702c63525..9e5d11ba83d162de03d742dba6d2ead661927798 100644 (file)
@@ -26,6 +26,8 @@ vector<MIDIMappingDialog::Control> per_bus_controllers = {
        { "Fader",                    MIDIMappingBusProto::kFaderFieldNumber,  MIDIMappingProto::kFaderBankFieldNumber }
 };
 vector<MIDIMappingDialog::Control> per_bus_buttons = {
+       { "Toggle mute",              MIDIMappingBusProto::kToggleMuteFieldNumber,
+                                     MIDIMappingProto::kToggleMuteBankFieldNumber },
        { "Toggle locut",             MIDIMappingBusProto::kToggleLocutFieldNumber,
                                      MIDIMappingProto::kToggleLocutBankFieldNumber },
        { "Togle auto gain staging",  MIDIMappingBusProto::kToggleAutoGainStagingFieldNumber,
@@ -36,6 +38,7 @@ vector<MIDIMappingDialog::Control> per_bus_buttons = {
                                      MIDIMappingProto::kClearPeakBankFieldNumber }
 };
 vector<MIDIMappingDialog::Control> per_bus_lights = {
+       { "Is muted",                 MIDIMappingBusProto::kIsMutedFieldNumber, 0 },
        { "Locut is on",              MIDIMappingBusProto::kLocutIsOnFieldNumber, 0 },
        { "Auto gain staging is on",  MIDIMappingBusProto::kAutoGainStagingIsOnFieldNumber, 0 },
        { "Compressor is on",         MIDIMappingBusProto::kCompressorIsOnFieldNumber, 0 },
index 465f8fd5f0259a1ae2fe13a556d5d81a59b8545f..a413ef1e19c38a719d68c746d5af40df481c5789 100644 (file)
@@ -51,6 +51,7 @@ public:
        void set_compressor_threshold(unsigned bus_idx, float value) override {}
        void set_fader(unsigned bus_idx, float value) override {}
 
+       void toggle_mute(unsigned bus_idx) override {}
        void toggle_locut(unsigned bus_idx) override {}
        void toggle_auto_gain_staging(unsigned bus_idx) override {}
        void toggle_compressor(unsigned bus_idx) override {}
@@ -71,6 +72,7 @@ public:
        void highlight_compressor_threshold(unsigned bus_idx, bool highlight) override {}
        void highlight_fader(unsigned bus_idx, bool highlight) override {}
 
+       void highlight_mute(unsigned bus_idx, bool highlight) override {}
        void highlight_toggle_locut(unsigned bus_idx, bool highlight) override {}
        void highlight_toggle_auto_gain_staging(unsigned bus_idx, bool highlight) override {}
        void highlight_toggle_compressor(unsigned bus_idx, bool highlight) override {}
index 489e4b20c4e090415c600d76767a33a5ced2bcb3..46142e3552dcabfa4795d22fbaf19e163f4e82d8 100644 (file)
       </layout>
      </item>
      <item>
-      <layout class="QVBoxLayout" name="fader_layout" stretch="1,0">
+      <layout class="QVBoxLayout" name="fader_layout" stretch="0,1,0">
+       <item>
+        <layout class="QHBoxLayout" name="mute_centerer">
+         <property name="spacing">
+          <number>0</number>
+         </property>
+         <property name="bottomMargin">
+          <number>0</number>
+         </property>
+         <item>
+          <widget class="QPushButton" name="mute_button">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Maximum" vsizetype="MinimumExpanding">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>40</width>
+             <height>22</height>
+            </size>
+           </property>
+           <property name="font">
+            <font>
+             <pointsize>8</pointsize>
+            </font>
+           </property>
+           <property name="styleSheet">
+            <string notr="true">QPushButton:checked { background: rgba(255,0,0,80); }</string>
+           </property>
+           <property name="text">
+            <string>Mute</string>
+           </property>
+           <property name="checkable">
+            <bool>true</bool>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
        <item>
         <layout class="QHBoxLayout" name="fader_centerer">
          <item>
    <header>vumeter.h</header>
    <container>1</container>
   </customwidget>
+  <customwidget>
+   <class>ClickableLabel</class>
+   <extends>QLabel</extends>
+   <header>clickable_label.h</header>
+  </customwidget>
   <customwidget>
    <class>NonLinearFader</class>
    <extends>QSlider</extends>
    <extends>QLabel</extends>
    <header>ellipsis_label.h</header>
   </customwidget>
-  <customwidget>
-   <class>ClickableLabel</class>
-   <extends>QLabel</extends>
-   <header>clickable_label.h</header>
-  </customwidget>
  </customwidgets>
  <resources/>
  <connections/>