static constexpr float falloff_db_sec = 15.0f; // dB/sec falloff after hold.
float current_peak;
PeakHistory &history = peak_history[bus_index][channel];
+ history.historic_peak = max(history.historic_peak, peak_levels[channel]);
if (history.age_seconds < hold_sec) {
current_peak = history.last_peak;
} else {
bus_levels[bus_index].current_level_dbfs[1] = to_db(peak_history[bus_index][1].current_level);
bus_levels[bus_index].peak_level_dbfs[0] = to_db(peak_history[bus_index][0].current_peak);
bus_levels[bus_index].peak_level_dbfs[1] = to_db(peak_history[bus_index][1].current_peak);
+ bus_levels[bus_index].historic_peak_dbfs = to_db(
+ max(peak_history[bus_index][0].historic_peak,
+ peak_history[bus_index][1].historic_peak));
bus_levels[bus_index].gain_staging_db = gain_staging_db[bus_index];
if (compressor_enabled[bus_index]) {
bus_levels[bus_index].compressor_attenuation_db = -to_db(compressor[bus_index]->get_attenuation());
struct BusLevel {
float current_level_dbfs[2]; // Digital peak of last frame, left and right.
float peak_level_dbfs[2]; // Digital peak with hold, left and right.
+ float historic_peak_dbfs;
float gain_staging_db;
float compressor_attenuation_db; // A positive number; 0.0 for no attenuation.
};
std::atomic<float> compressor_threshold_dbfs[MAX_BUSES];
std::atomic<bool> compressor_enabled[MAX_BUSES];
+ // Note: The values here are not in dB.
struct PeakHistory {
- float current_level = 0.0f; // Peak of the last frame (not in dB).
- float current_peak = 0.0f; // Current peak of the peak meter (not in dB).
+ float current_level = 0.0f; // Peak of the last frame.
+ float historic_peak = 0.0f; // Highest peak since last reset; no falloff.
+ float current_peak = 0.0f; // Current peak of the peak meter.
float last_peak = 0.0f;
float age_seconds = 0.0f; // Time since "last_peak" was set.
};
return text;
}
+void set_peak_label(QLabel *peak_label, float peak_db)
+{
+ peak_label->setText(QString::fromStdString(format_db(peak_db, DB_BARE)));
+
+ // -0.1 dBFS is EBU peak limit. We use it consistently, even for the bus meters
+ // (which don't calculate interpolate peak, and in general don't follow EBU recommendations).
+ if (peak_db > -0.1f) {
+ peak_label->setStyleSheet("QLabel { background-color: red; color: white; }");
+ } else {
+ peak_label->setStyleSheet("");
+ }
+}
+
} // namespace
MainWindow::MainWindow()
level.current_level_dbfs[0], level.current_level_dbfs[1]);
miniview->peak_meter->set_peak(
level.peak_level_dbfs[0], level.peak_level_dbfs[1]);
+ set_peak_label(miniview->peak_display_label, level.historic_peak_dbfs);
Ui::AudioExpandedView *view = audio_expanded_views[bus_index];
view->peak_meter->set_level(
view->gainstaging_db_display->setText(
QString("Gain: ") +
QString::fromStdString(format_db(level.gain_staging_db, DB_WITH_SIGN)));
+ set_peak_label(view->peak_display_label, level.historic_peak_dbfs);
}
}
ui->lra_meter->set_levels(global_level_lufs, range_low_lufs, range_high_lufs);
ui->correlation_meter->set_correlation(correlation);
ui->peak_display->setText(QString::fromStdString(format_db(peak_db, DB_BARE)));
- if (peak_db > -0.1f) { // -0.1 dBFS is EBU peak limit.
- ui->peak_display->setStyleSheet("QLabel { background-color: red; color: white; }");
- } else {
- ui->peak_display->setStyleSheet("");
- }
+ set_peak_label(ui->peak_display, peak_db);
// NOTE: Will be invisible when using multitrack audio.
ui->gainstaging_knob->blockSignals(true);