X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=mainwindow.cpp;h=841952f8b28eda6b2c83483aedf717e00ef6c834;hb=b561d43a60201395f1354a585aa37670eda45883;hp=68c446af8ed4b8921ede7b6339ba5af06b3193d5;hpb=a6c753ed4139540d734eddc45afbeaa9dd3487ed;p=nageru diff --git a/mainwindow.cpp b/mainwindow.cpp index 68c446a..841952f 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -18,6 +19,7 @@ #include #include "aboutdialog.h" +#include "disk_space_estimator.h" #include "flags.h" #include "glwidget.h" #include "lrameter.h" @@ -30,6 +32,7 @@ class QResizeEvent; using namespace std; +using namespace std::chrono; using namespace std::placeholders; Q_DECLARE_METATYPE(std::string); @@ -49,32 +52,40 @@ void quit_signal(int ignored) global_mainwindow->close(); } -string format_db_with_sign(double db) -{ - if (isfinite(db)) { - char buf[256]; - snprintf(buf, sizeof(buf), "%+.1f dB", db); - return buf; - } else if (db < 0.0) { - return "-∞ dB"; - } else { - // Should never happen, really. - return "+∞ dB"; - } -} +constexpr unsigned DB_NO_FLAGS = 0x0; +constexpr unsigned DB_WITH_SIGN = 0x1; +constexpr unsigned DB_BARE = 0x2; -string format_db(double db) +string format_db(double db, unsigned flags) { - if (isfinite(db)) { - char buf[256]; - snprintf(buf, sizeof(buf), "%.1f dB", db); - return buf; - } else if (db < 0.0) { - return "-∞ dB"; + string text; + if (flags & DB_WITH_SIGN) { + if (isfinite(db)) { + char buf[256]; + snprintf(buf, sizeof(buf), "%+.1f", db); + text = buf; + } else if (db < 0.0) { + text = "-∞"; + } else { + // Should never happen, really. + text = "+∞"; + } } else { - // Should never happen, really. - return "+∞ dB"; + if (isfinite(db)) { + char buf[256]; + snprintf(buf, sizeof(buf), "%.1f", db); + text = buf; + } else if (db < 0.0) { + text = "-∞"; + } else { + // Should never happen, really. + text = "∞"; + } } + if (!(flags & DB_BARE)) { + text += " dB"; + } + return text; } } // namespace @@ -85,6 +96,11 @@ MainWindow::MainWindow() global_mainwindow = this; ui->setupUi(this); + global_disk_space_estimator = new DiskSpaceEstimator(bind(&MainWindow::report_disk_space, this, _1, _2)); + disk_free_label = new QLabel(this); + disk_free_label->setStyleSheet("QLabel {padding-right: 5px;}"); + ui->menuBar->setCornerWidget(disk_free_label); + ui->me_live->set_output(Mixer::OUTPUT_LIVE); ui->me_preview->set_output(Mixer::OUTPUT_PREVIEW); @@ -113,6 +129,8 @@ MainWindow::MainWindow() qRegisterMetaType>("std::vector"); connect(ui->me_live, &GLWidget::transition_names_updated, this, &MainWindow::set_transition_names); qRegisterMetaType("Mixer::Output"); + + last_audio_level_callback = steady_clock::now() - seconds(1); } void MainWindow::resizeEvent(QResizeEvent* event) @@ -166,9 +184,9 @@ void MainWindow::mixer_created(Mixer *mixer) ui->makeup_gain_auto_checkbox->setChecked(global_mixer->get_final_makeup_gain_auto()); ui->limiter_threshold_db_display->setText( - QString::fromStdString(format_db(mixer->get_limiter_threshold_dbfs()))); + QString::fromStdString(format_db(mixer->get_limiter_threshold_dbfs(), DB_WITH_SIGN))); ui->compressor_threshold_db_display->setText( - QString::fromStdString(format_db(mixer->get_compressor_threshold_dbfs()))); + QString::fromStdString(format_db(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()); @@ -275,12 +293,45 @@ void MainWindow::cutoff_knob_changed(int value) ui->locut_cutoff_display->setText(buf); } +void MainWindow::report_disk_space(off_t free_bytes, double estimated_seconds_left) +{ + char time_str[256]; + if (estimated_seconds_left < 60.0) { + strcpy(time_str, "Less than a minute"); + } else if (estimated_seconds_left < 1800.0) { // Less than half an hour: Xm Ys (red). + int s = lrintf(estimated_seconds_left); + int m = s / 60; + s %= 60; + snprintf(time_str, sizeof(time_str), "%dm %ds", m, s); + } else if (estimated_seconds_left < 3600.0) { // Less than an hour: Xm. + int m = lrintf(estimated_seconds_left / 60.0); + snprintf(time_str, sizeof(time_str), "%dm", m); + } else if (estimated_seconds_left < 36000.0) { // Less than ten hours: Xh Ym. + int m = lrintf(estimated_seconds_left / 60.0); + int h = m / 60; + m %= 60; + snprintf(time_str, sizeof(time_str), "%dh %dm", h, m); + } else { // More than ten hours: Xh. + int h = lrintf(estimated_seconds_left / 3600.0); + snprintf(time_str, sizeof(time_str), "%dh", h); + } + char buf[256]; + snprintf(buf, sizeof(buf), "Disk free: %'.0f MB (approx. %s)", free_bytes / 1048576.0, time_str); + + std::string label = buf; + + post_to_main_thread([this, label]{ + disk_free_label->setText(QString::fromStdString(label)); + ui->menuBar->setCornerWidget(disk_free_label); // Need to set this again for the sizing to get right. + }); +} + void MainWindow::limiter_threshold_knob_changed(int value) { float threshold_dbfs = value * 0.1f; global_mixer->set_limiter_threshold_dbfs(threshold_dbfs); ui->limiter_threshold_db_display->setText( - QString::fromStdString(format_db(threshold_dbfs))); + QString::fromStdString(format_db(threshold_dbfs, DB_WITH_SIGN))); } void MainWindow::compressor_threshold_knob_changed(int value) @@ -288,13 +339,13 @@ void MainWindow::compressor_threshold_knob_changed(int value) float threshold_dbfs = value * 0.1f; global_mixer->set_compressor_threshold_dbfs(threshold_dbfs); ui->compressor_threshold_db_display->setText( - QString::fromStdString(format_db(threshold_dbfs))); + QString::fromStdString(format_db(threshold_dbfs, DB_WITH_SIGN))); } void MainWindow::reset_meters_button_clicked() { global_mixer->reset_meters(); - ui->peak_display->setText("-inf"); + ui->peak_display->setText(QString::fromStdString(format_db(-HUGE_VAL, DB_WITH_SIGN | DB_BARE))); ui->peak_display->setStyleSheet(""); } @@ -303,13 +354,11 @@ void MainWindow::audio_level_callback(float level_lufs, float peak_db, float glo float gain_staging_db, float final_makeup_gain_db, float correlation) { - timeval now; - gettimeofday(&now, nullptr); + steady_clock::time_point now = steady_clock::now(); // The meters are somewhat inefficient to update. Only update them // every 100 ms or so (we get updates every 5–20 ms). - double last_update_age = now.tv_sec - last_audio_level_callback.tv_sec + - 1e-6 * (now.tv_usec - last_audio_level_callback.tv_usec); + double last_update_age = duration(now - last_audio_level_callback).count(); if (last_update_age < 0.100) { return; } @@ -320,7 +369,7 @@ void MainWindow::audio_level_callback(float level_lufs, float peak_db, float glo 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))); + 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 { @@ -331,13 +380,13 @@ void MainWindow::audio_level_callback(float level_lufs, float peak_db, float glo ui->gainstaging_knob->setValue(lrintf(gain_staging_db * 10.0f)); ui->gainstaging_knob->blockSignals(false); ui->gainstaging_db_display->setText( - QString::fromStdString(format_db_with_sign(gain_staging_db))); + QString::fromStdString(format_db(gain_staging_db, DB_WITH_SIGN))); ui->makeup_gain_knob->blockSignals(true); ui->makeup_gain_knob->setValue(lrintf(final_makeup_gain_db * 10.0f)); ui->makeup_gain_knob->blockSignals(false); ui->makeup_gain_db_display->setText( - QString::fromStdString(format_db_with_sign(final_makeup_gain_db))); + QString::fromStdString(format_db(final_makeup_gain_db, DB_WITH_SIGN))); }); }