]> git.sesse.net Git - nageru/commitdiff
Move the gain staging and compressors into each bus, and hook up the corresponding...
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Mon, 22 Aug 2016 22:00:18 +0000 (00:00 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Wed, 19 Oct 2016 22:55:44 +0000 (00:55 +0200)
audio_mixer.cpp
audio_mixer.h
mainwindow.cpp
mainwindow.h

index 03c894ce89f3680e6018e0c7adc732950f6ef4ca..3b7d3e5821eb2fd1c4343de8a245a603165fcb20 100644 (file)
@@ -105,18 +105,19 @@ void deinterleave_samples(const vector<float> &in, vector<float> *out_l, vector<
 
 AudioMixer::AudioMixer(unsigned num_cards)
        : num_cards(num_cards),
-         level_compressor(OUTPUT_FREQUENCY),
          limiter(OUTPUT_FREQUENCY),
-         compressor(OUTPUT_FREQUENCY),
          correlation(OUTPUT_FREQUENCY)
 {
        for (unsigned bus_index = 0; bus_index < MAX_BUSES; ++bus_index) {
                locut[bus_index].init(FILTER_HPF, 2);
                locut_enabled[bus_index] = global_flags.locut_enabled;
+               gain_staging_db[bus_index] = global_flags.initial_gain_staging_db;
+               compressor[bus_index].reset(new StereoCompressor(OUTPUT_FREQUENCY));
+               compressor_threshold_dbfs[bus_index] = ref_level_dbfs - 12.0f;  // -12 dB.
+               compressor_enabled[bus_index] = global_flags.compressor_enabled;
+               level_compressor[bus_index].reset(new StereoCompressor(OUTPUT_FREQUENCY));
+               level_compressor_enabled[bus_index] = global_flags.gain_staging_auto;
        }
-       set_gain_staging_db(global_flags.initial_gain_staging_db);
-       set_gain_staging_auto(global_flags.gain_staging_auto);
-       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);
 
@@ -351,7 +352,6 @@ vector<float> AudioMixer::get_output(double pts, unsigned num_samples, Resamplin
                }
        }
 
-       // TODO: Move lo-cut etc. into each bus.
        vector<float> samples_out, left, right;
        samples_out.resize(num_samples * 2);
        samples_bus.resize(num_samples * 2);
@@ -366,6 +366,50 @@ vector<float> AudioMixer::get_output(double pts, unsigned num_samples, Resamplin
                        locut[bus_index].render(samples_bus.data(), samples_bus.size() / 2, locut_cutoff_hz * 2.0 * M_PI / OUTPUT_FREQUENCY, 0.5f);
                }
 
+               {
+                       lock_guard<mutex> lock(compressor_mutex);
+
+                       // Apply a level compressor to get the general level right.
+                       // Basically, if it's over about -40 dBFS, we squeeze it down to that level
+                       // (or more precisely, near it, since we don't use infinite ratio),
+                       // then apply a makeup gain to get it to -14 dBFS. -14 dBFS is, of course,
+                       // entirely arbitrary, but from practical tests with speech, it seems to
+                       // put ut around -23 LUFS, so it's a reasonable starting point for later use.
+                       if (level_compressor_enabled[bus_index]) {
+                               float threshold = 0.01f;   // -40 dBFS.
+                               float ratio = 20.0f;
+                               float attack_time = 0.5f;
+                               float release_time = 20.0f;
+                               float makeup_gain = from_db(ref_level_dbfs - (-40.0f));  // +26 dB.
+                               level_compressor[bus_index]->process(samples_bus.data(), samples_bus.size() / 2, threshold, ratio, attack_time, release_time, makeup_gain);
+                               gain_staging_db[bus_index] = to_db(level_compressor[bus_index]->get_attenuation() * makeup_gain);
+                       } else {
+                               // Just apply the gain we already had.
+                               float g = from_db(gain_staging_db[bus_index]);
+                               for (size_t i = 0; i < samples_bus.size(); ++i) {
+                                       samples_bus[i] *= g;
+                               }
+                       }
+
+#if 0
+                       printf("level=%f (%+5.2f dBFS) attenuation=%f (%+5.2f dB) end_result=%+5.2f dB\n",
+                               level_compressor.get_level(), to_db(level_compressor.get_level()),
+                               level_compressor.get_attenuation(), to_db(level_compressor.get_attenuation()),
+                               to_db(level_compressor.get_level() * level_compressor.get_attenuation() * makeup_gain));
+#endif
+
+                       // The real compressor.
+                       if (compressor_enabled[bus_index]) {
+                               float threshold = from_db(compressor_threshold_dbfs[bus_index]);
+                               float ratio = 20.0f;
+                               float attack_time = 0.005f;
+                               float release_time = 0.040f;
+                               float makeup_gain = 2.0f;  // +6 dB.
+                               compressor[bus_index]->process(samples_bus.data(), samples_bus.size() / 2, threshold, ratio, attack_time, release_time, makeup_gain);
+               //              compressor_att = compressor.get_attenuation();
+                       }
+               }
+
                // TODO: We should measure post-fader.
                deinterleave_samples(samples_bus, &left, &right);
                measure_bus_levels(bus_index, left, right);
@@ -385,50 +429,6 @@ vector<float> AudioMixer::get_output(double pts, unsigned num_samples, Resamplin
        {
                lock_guard<mutex> lock(compressor_mutex);
 
-               // Apply a level compressor to get the general level right.
-               // Basically, if it's over about -40 dBFS, we squeeze it down to that level
-               // (or more precisely, near it, since we don't use infinite ratio),
-               // then apply a makeup gain to get it to -14 dBFS. -14 dBFS is, of course,
-               // entirely arbitrary, but from practical tests with speech, it seems to
-               // put ut around -23 LUFS, so it's a reasonable starting point for later use.
-               {
-                       if (level_compressor_enabled) {
-                               float threshold = 0.01f;   // -40 dBFS.
-                               float ratio = 20.0f;
-                               float attack_time = 0.5f;
-                               float release_time = 20.0f;
-                               float makeup_gain = from_db(ref_level_dbfs - (-40.0f));  // +26 dB.
-                               level_compressor.process(samples_out.data(), samples_out.size() / 2, threshold, ratio, attack_time, release_time, makeup_gain);
-                               gain_staging_db = to_db(level_compressor.get_attenuation() * makeup_gain);
-                       } else {
-                               // Just apply the gain we already had.
-                               float g = from_db(gain_staging_db);
-                               for (size_t i = 0; i < samples_out.size(); ++i) {
-                                       samples_out[i] *= g;
-                               }
-                       }
-               }
-
-       #if 0
-               printf("level=%f (%+5.2f dBFS) attenuation=%f (%+5.2f dB) end_result=%+5.2f dB\n",
-                       level_compressor.get_level(), to_db(level_compressor.get_level()),
-                       level_compressor.get_attenuation(), to_db(level_compressor.get_attenuation()),
-                       to_db(level_compressor.get_level() * level_compressor.get_attenuation() * makeup_gain));
-       #endif
-
-       //      float limiter_att, compressor_att;
-
-               // The real compressor.
-               if (compressor_enabled) {
-                       float threshold = from_db(compressor_threshold_dbfs);
-                       float ratio = 20.0f;
-                       float attack_time = 0.005f;
-                       float release_time = 0.040f;
-                       float makeup_gain = 2.0f;  // +6 dB.
-                       compressor.process(samples_out.data(), samples_out.size() / 2, threshold, ratio, attack_time, release_time, makeup_gain);
-       //              compressor_att = compressor.get_attenuation();
-               }
-
                // Finally a limiter at -4 dB (so, -10 dBFS) to take out the worst peaks only.
                // Note that since ratio is not infinite, we could go slightly higher than this.
                if (limiter_enabled) {
@@ -444,7 +444,8 @@ vector<float> AudioMixer::get_output(double pts, unsigned num_samples, Resamplin
        //      printf("limiter=%+5.1f  compressor=%+5.1f\n", to_db(limiter_att), to_db(compressor_att));
        }
 
-       // At this point, we are most likely close to +0 LU, but all of our
+       // At this point, we are most likely close to +0 LU (at least if the
+       // faders sum to 0 dB and the compressors are on), but all of our
        // measurements have been on raw sample values, not R128 values.
        // So we have a final makeup gain to get us to +0 LU; the gain
        // adjustments required should be relatively small, and also, the
@@ -562,7 +563,7 @@ void AudioMixer::send_audio_level_callback()
 
        audio_level_callback(loudness_s, to_db(peak), bus_loudness,
                loudness_i, loudness_range_low, loudness_range_high,
-               gain_staging_db,
+               vector<float>(gain_staging_db, gain_staging_db + MAX_BUSES),
                to_db(final_makeup_gain),
                correlation.get_correlation());
 }
index 0c401d5e6b858f9f9a8c30e5eed5b5865a8a6d80..d00e8ecb4eeb3dd968940575944b9de5e8eba77e 100644 (file)
@@ -116,9 +116,9 @@ public:
                return limiter_threshold_dbfs;
        }
 
-       float get_compressor_threshold_dbfs() const
+       float get_compressor_threshold_dbfs(unsigned bus_index) const
        {
-               return compressor_threshold_dbfs;
+               return compressor_threshold_dbfs[bus_index];
        }
 
        void set_limiter_threshold_dbfs(float threshold_dbfs)
@@ -126,9 +126,9 @@ public:
                limiter_threshold_dbfs = threshold_dbfs;
        }
 
-       void set_compressor_threshold_dbfs(float threshold_dbfs)
+       void set_compressor_threshold_dbfs(unsigned bus_index, float threshold_dbfs)
        {
-               compressor_threshold_dbfs = threshold_dbfs;
+               compressor_threshold_dbfs[bus_index] = threshold_dbfs;
        }
 
        void set_limiter_enabled(bool enabled)
@@ -141,39 +141,39 @@ public:
                return limiter_enabled;
        }
 
-       void set_compressor_enabled(bool enabled)
+       void set_compressor_enabled(unsigned bus_index, bool enabled)
        {
-               compressor_enabled = enabled;
+               compressor_enabled[bus_index] = enabled;
        }
 
-       bool get_compressor_enabled() const
+       bool get_compressor_enabled(unsigned bus_index) const
        {
-               return compressor_enabled;
+               return compressor_enabled[bus_index];
        }
 
-       void set_gain_staging_db(float gain_db)
+       void set_gain_staging_db(unsigned bus_index, float gain_db)
        {
                std::unique_lock<std::mutex> lock(compressor_mutex);
-               level_compressor_enabled = false;
-               gain_staging_db = gain_db;
+               level_compressor_enabled[bus_index] = false;
+               gain_staging_db[bus_index] = gain_db;
        }
 
-       float get_gain_staging_db() const
+       float get_gain_staging_db(unsigned bus_index) const
        {
                std::unique_lock<std::mutex> lock(compressor_mutex);
-               return gain_staging_db;
+               return gain_staging_db[bus_index];
        }
 
-       void set_gain_staging_auto(bool enabled)
+       void set_gain_staging_auto(unsigned bus_index, bool enabled)
        {
                std::unique_lock<std::mutex> lock(compressor_mutex);
-               level_compressor_enabled = enabled;
+               level_compressor_enabled[bus_index] = enabled;
        }
 
-       bool get_gain_staging_auto() const
+       bool get_gain_staging_auto(unsigned bus_index) const
        {
                std::unique_lock<std::mutex> lock(compressor_mutex);
-               return level_compressor_enabled;
+               return level_compressor_enabled[bus_index];
        }
 
        void set_final_makeup_gain_db(float gain_db)
@@ -204,7 +204,7 @@ public:
        typedef std::function<void(float level_lufs, float peak_db,
                                   std::vector<float> bus_level_lufs,
                                   float global_level_lufs, float range_low_lufs, float range_high_lufs,
-                                  float gain_staging_db, float final_makeup_gain_db,
+                                  std::vector<float> gain_staging_db, float final_makeup_gain_db,
                                   float correlation)> audio_level_callback_t;
        void set_audio_level_callback(audio_level_callback_t callback)
        {
@@ -249,9 +249,9 @@ private:
 
        // First compressor; takes us up to about -12 dBFS.
        mutable std::mutex compressor_mutex;
-       StereoCompressor level_compressor;  // Under compressor_mutex. Used to set/override gain_staging_db if <level_compressor_enabled>.
-       float gain_staging_db = 0.0f;  // Under compressor_mutex.
-       bool level_compressor_enabled = true;  // Under compressor_mutex.
+       std::unique_ptr<StereoCompressor> level_compressor[MAX_BUSES];  // Under compressor_mutex. Used to set/override gain_staging_db if <level_compressor_enabled>.
+       float gain_staging_db[MAX_BUSES];  // Under compressor_mutex.
+       bool level_compressor_enabled[MAX_BUSES];  // Under compressor_mutex.
 
        static constexpr float ref_level_dbfs = -14.0f;  // Chosen so that we end up around 0 LU in practice.
        static constexpr float ref_level_lufs = -23.0f;  // 0 LU, more or less by definition.
@@ -259,9 +259,9 @@ private:
        StereoCompressor limiter;
        std::atomic<float> limiter_threshold_dbfs{ref_level_dbfs + 4.0f};   // 4 dB.
        std::atomic<bool> limiter_enabled{true};
-       StereoCompressor compressor;
-       std::atomic<float> compressor_threshold_dbfs{ref_level_dbfs - 12.0f};  // -12 dB.
-       std::atomic<bool> compressor_enabled{true};
+       std::unique_ptr<StereoCompressor> compressor[MAX_BUSES];
+       std::atomic<float> compressor_threshold_dbfs[MAX_BUSES];
+       std::atomic<bool> compressor_enabled[MAX_BUSES];
 
        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.
index 02371060cae3b3f065d42e7fa6a232392ea3e94e..ac59305302c60ff84650d7ab294564878da8bae1 100644 (file)
@@ -237,12 +237,31 @@ void MainWindow::mixer_created(Mixer *mixer)
        connect(ui->locut_enabled, &QCheckBox::stateChanged, [this](int state){
                global_mixer->get_audio_mixer()->set_locut_enabled(0, state == Qt::Checked);
        });
-#else
-       ui->locut_enabled->setVisible(false);
-#endif
        ui->gainstaging_knob->setValue(global_mixer->get_audio_mixer()->get_gain_staging_db());
        ui->gainstaging_auto_checkbox->setChecked(global_mixer->get_audio_mixer()->get_gain_staging_auto());
        ui->compressor_enabled->setChecked(global_mixer->get_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_mixer->get_audio_mixer()->set_gain_staging_auto(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_mixer->get_audio_mixer()->set_compressor_enabled(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_mixer->get_audio_mixer()->get_limiter_enabled());
        ui->makeup_gain_auto_checkbox->setChecked(global_mixer->get_audio_mixer()->get_final_makeup_gain_auto());
 
@@ -250,29 +269,19 @@ void MainWindow::mixer_created(Mixer *mixer)
                QString::fromStdString(format_db(mixer->get_audio_mixer()->get_limiter_threshold_dbfs(), DB_WITH_SIGN)));
        ui->limiter_threshold_db_display->setText(limiter_threshold_label);
        ui->limiter_threshold_db_display_2->setText(limiter_threshold_label);
-       ui->compressor_threshold_db_display->setText(
-               QString::fromStdString(format_db(mixer->get_audio_mixer()->get_compressor_threshold_dbfs(), DB_WITH_SIGN)));
 
        connect(ui->locut_cutoff_knob, &QDial::valueChanged, this, &MainWindow::cutoff_knob_changed);
        cutoff_knob_changed(ui->locut_cutoff_knob->value());
 
-       connect(ui->gainstaging_knob, &QAbstractSlider::valueChanged, this, &MainWindow::gain_staging_knob_changed);
-       connect(ui->gainstaging_auto_checkbox, &QCheckBox::stateChanged, [this](int state){
-               global_mixer->get_audio_mixer()->set_gain_staging_auto(state == Qt::Checked);
-       });
        connect(ui->makeup_gain_knob, &QAbstractSlider::valueChanged, this, &MainWindow::final_makeup_gain_knob_changed);
        connect(ui->makeup_gain_auto_checkbox, &QCheckBox::stateChanged, [this](int state){
                global_mixer->get_audio_mixer()->set_final_makeup_gain_auto(state == Qt::Checked);
        });
 
        connect(ui->limiter_threshold_knob, &QDial::valueChanged, this, &MainWindow::limiter_threshold_knob_changed);
-       connect(ui->compressor_threshold_knob, &QDial::valueChanged, this, &MainWindow::compressor_threshold_knob_changed);
        connect(ui->limiter_enabled, &QCheckBox::stateChanged, [this](int state){
                global_mixer->get_audio_mixer()->set_limiter_enabled(state == Qt::Checked);
        });
-       connect(ui->compressor_enabled, &QCheckBox::stateChanged, [this](int state){
-               global_mixer->get_audio_mixer()->set_compressor_enabled(state == Qt::Checked);
-       });
        connect(ui->reset_meters_button, &QPushButton::clicked, this, &MainWindow::reset_meters_button_clicked);
        mixer->get_audio_mixer()->set_audio_level_callback(bind(&MainWindow::audio_level_callback, this, _1, _2, _3, _4, _5, _6, _7, _8, _9));
 
@@ -340,10 +349,24 @@ void MainWindow::setup_audio_expanded_view()
                ui->buses->addWidget(channel);
 
                ui_audio_expanded_view->locut_enabled->setChecked(global_mixer->get_audio_mixer()->get_locut_enabled(bus_index));
-               connect(ui->locut_enabled, &QCheckBox::stateChanged, [this, bus_index](int state){
+               connect(ui_audio_expanded_view->locut_enabled, &QCheckBox::stateChanged, [this, bus_index](int state){
                        global_mixer->get_audio_mixer()->set_locut_enabled(bus_index, state == Qt::Checked);
                });
 
+               ui_audio_expanded_view->gainstaging_knob->setValue(global_mixer->get_audio_mixer()->get_gain_staging_db(bus_index));
+               ui_audio_expanded_view->gainstaging_auto_checkbox->setChecked(global_mixer->get_audio_mixer()->get_gain_staging_auto(bus_index));
+               ui_audio_expanded_view->compressor_enabled->setChecked(global_mixer->get_audio_mixer()->get_compressor_enabled(bus_index));
+
+               connect(ui_audio_expanded_view->gainstaging_knob, &QAbstractSlider::valueChanged, bind(&MainWindow::gain_staging_knob_changed, this, bus_index, _1));
+               connect(ui_audio_expanded_view->gainstaging_auto_checkbox, &QCheckBox::stateChanged, [this, bus_index](int state){
+                       global_mixer->get_audio_mixer()->set_gain_staging_auto(bus_index, state == Qt::Checked);
+               });
+
+               connect(ui_audio_expanded_view->compressor_threshold_knob, &QDial::valueChanged, bind(&MainWindow::compressor_threshold_knob_changed, this, bus_index, _1));
+               connect(ui_audio_expanded_view->compressor_enabled, &QCheckBox::stateChanged, [this, bus_index](int state){
+                       global_mixer->get_audio_mixer()->set_compressor_enabled(bus_index, state == Qt::Checked);
+               });
+
                slave_fader(audio_miniviews[bus_index]->fader, ui_audio_expanded_view->fader);
        }
 }
@@ -390,12 +413,17 @@ void MainWindow::input_mapping_triggered()
        }
 }
 
-void MainWindow::gain_staging_knob_changed(int value)
+void MainWindow::gain_staging_knob_changed(unsigned bus_index, int value)
 {
-       ui->gainstaging_auto_checkbox->setCheckState(Qt::Unchecked);
+       if (bus_index == 0) {
+               ui->gainstaging_auto_checkbox->setCheckState(Qt::Unchecked);
+       }
+       if (bus_index < audio_expanded_views.size()) {
+               audio_expanded_views[bus_index]->gainstaging_auto_checkbox->setCheckState(Qt::Unchecked);
+       }
 
        float gain_db = value * 0.1f;
-       global_mixer->get_audio_mixer()->set_gain_staging_db(gain_db);
+       global_mixer->get_audio_mixer()->set_gain_staging_db(bus_index, gain_db);
 
        // The label will be updated by the audio level callback.
 }
@@ -465,12 +493,18 @@ void MainWindow::limiter_threshold_knob_changed(int value)
                QString::fromStdString(format_db(threshold_dbfs, DB_WITH_SIGN)));
 }
 
-void MainWindow::compressor_threshold_knob_changed(int value)
+void MainWindow::compressor_threshold_knob_changed(unsigned bus_index, int value)
 {
        float threshold_dbfs = value * 0.1f;
-       global_mixer->get_audio_mixer()->set_compressor_threshold_dbfs(threshold_dbfs);
-       ui->compressor_threshold_db_display->setText(
-               QString::fromStdString(format_db(threshold_dbfs, DB_WITH_SIGN)));
+       global_mixer->get_audio_mixer()->set_compressor_threshold_dbfs(bus_index, threshold_dbfs);
+
+       QString label(QString::fromStdString(format_db(threshold_dbfs, DB_WITH_SIGN)));
+       if (bus_index == 0) {
+               ui->compressor_threshold_db_display->setText(label);
+       }
+       if (bus_index < audio_expanded_views.size()) {
+               audio_expanded_views[bus_index]->compressor_threshold_db_display->setText(label);
+       }
 }
 
 void MainWindow::mini_fader_changed(int bus, double volume_db)
@@ -492,7 +526,7 @@ void MainWindow::reset_meters_button_clicked()
 void MainWindow::audio_level_callback(float level_lufs, float peak_db, vector<float> bus_level_lufs,
                                       float global_level_lufs,
                                       float range_low_lufs, float range_high_lufs,
-                                      float gain_staging_db, float final_makeup_gain_db,
+                                      vector<float> gain_staging_db, float final_makeup_gain_db,
                                       float correlation)
 {
        steady_clock::time_point now = steady_clock::now();
@@ -511,6 +545,15 @@ void MainWindow::audio_level_callback(float level_lufs, float peak_db, vector<fl
                        if (bus_index < audio_miniviews.size()) {
                                audio_miniviews[bus_index]->vu_meter_meter->set_level(
                                        bus_level_lufs[bus_index]);
+
+                               Ui::AudioExpandedView *view = audio_expanded_views[bus_index];
+                               view->vu_meter_meter->set_level(bus_level_lufs[bus_index]);
+                               view->gainstaging_knob->blockSignals(true);
+                               view->gainstaging_knob->setValue(lrintf(gain_staging_db[bus_index] * 10.0f));
+                               view->gainstaging_knob->blockSignals(false);
+                               view->gainstaging_db_display->setText(
+                                       QString("Gain: ") +
+                                       QString::fromStdString(format_db(gain_staging_db[bus_index], DB_WITH_SIGN)));
                        }
                }
                ui->lra_meter->set_levels(global_level_lufs, range_low_lufs, range_high_lufs);
@@ -523,11 +566,12 @@ void MainWindow::audio_level_callback(float level_lufs, float peak_db, vector<fl
                        ui->peak_display->setStyleSheet("");
                }
 
+               // NOTE: Will be invisible when using multitrack audio.
                ui->gainstaging_knob->blockSignals(true);
-               ui->gainstaging_knob->setValue(lrintf(gain_staging_db * 10.0f));
+               ui->gainstaging_knob->setValue(lrintf(gain_staging_db[0] * 10.0f));
                ui->gainstaging_knob->blockSignals(false);
                ui->gainstaging_db_display->setText(
-                       QString::fromStdString(format_db(gain_staging_db, DB_WITH_SIGN)));
+                       QString::fromStdString(format_db(gain_staging_db[0], DB_WITH_SIGN)));
 
                ui->makeup_gain_knob->blockSignals(true);
                ui->makeup_gain_knob->setValue(lrintf(final_makeup_gain_db * 10.0f));
index ff33b7ffa04964c3b6e6ba00e19c34b5a194fd49..41c9fe713241cb1e9111adc9e732dac2b6524f31 100644 (file)
@@ -47,11 +47,11 @@ public slots:
        void set_transition_names(std::vector<std::string> transition_names);
        void update_channel_name(Mixer::Output output, const std::string &name);
        void update_channel_color(Mixer::Output output, const std::string &color);
-       void gain_staging_knob_changed(int value);
+       void gain_staging_knob_changed(unsigned bus_index, int value);
        void final_makeup_gain_knob_changed(int value);
        void cutoff_knob_changed(int value);
        void limiter_threshold_knob_changed(int value);
-       void compressor_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 reset_meters_button_clicked();
        void relayout();
@@ -66,7 +66,7 @@ private:
        void report_disk_space(off_t free_bytes, double estimated_seconds_left);
 
        // Called from the mixer.
-       void audio_level_callback(float level_lufs, float peak_db, std::vector<float> bus_level_lufs, float global_level_lufs, float range_low_lufs, float range_high_lufs, float gain_staging_db, float final_makeup_gain_db, float correlation);
+       void audio_level_callback(float level_lufs, float peak_db, std::vector<float> bus_level_lufs, float global_level_lufs, float range_low_lufs, float range_high_lufs, std::vector<float> gain_staging_db, float final_makeup_gain_db, float correlation);
        std::chrono::steady_clock::time_point last_audio_level_callback;
 
        Ui::MainWindow *ui;