X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=mainwindow.cpp;h=17209408d4668d6eb07450b83bbbcfe8c6aea2eb;hb=45aa08dd2f81037860fdd3c5d1115736f7acf1a8;hp=a16d5bd159bfde3b37ac85833907737102a7754c;hpb=1d75037f1e47e1e86adc444417922b402ba8272a;p=nageru diff --git a/mainwindow.cpp b/mainwindow.cpp index a16d5bd..1720940 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -24,6 +25,7 @@ #include "glwidget.h" #include "input_mapping_dialog.h" #include "lrameter.h" +#include "midi_mapping.pb.h" #include "mixer.h" #include "post_to_main_thread.h" #include "ui_audio_miniview.h" @@ -143,7 +145,7 @@ void set_peak_label(QLabel *peak_label, float peak_db) } // namespace MainWindow::MainWindow() - : ui(new Ui::MainWindow) + : ui(new Ui::MainWindow), midi_mapper(this) { global_mainwindow = this; ui->setupUi(this); @@ -153,6 +155,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 +166,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) { @@ -189,7 +197,27 @@ MainWindow::MainWindow() connect(ui->full_prev_page, &QAbstractButton::clicked, bind(&QStackedWidget::setCurrentIndex, ui->audio_views, 0)); connect(ui->full_next_page, &QAbstractButton::clicked, bind(&QStackedWidget::setCurrentIndex, ui->audio_views, 0)); + // And bind the same to PgUp/PgDown. + auto switch_page = [this]{ + 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); + last_audio_level_callback = steady_clock::now() - seconds(1); + + if (!global_flags.midi_mapping_filename.empty()) { + MIDIMappingProto midi_mapping; + if (!load_midi_mapping_from_file(global_flags.midi_mapping_filename, &midi_mapping)) { + fprintf(stderr, "Couldn't load MIDI mapping '%s'; exiting.\n", + global_flags.midi_mapping_filename.c_str()); + exit(1); + } + midi_mapper.set_midi_mapping(midi_mapping); + } + midi_mapper.start_thread(); } void MainWindow::resizeEvent(QResizeEvent* event) @@ -233,8 +261,7 @@ 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); slave_knob(ui->limiter_threshold_knob, ui->limiter_threshold_knob_2); @@ -242,42 +269,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); @@ -312,6 +335,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. @@ -321,6 +371,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()); @@ -338,7 +392,8 @@ void MainWindow::setup_audio_miniview() peak_meter->set_max_level(0.0f); peak_meter->set_ref_level(0.0f); - // TODO: Set the fader position. + ui_audio_miniview->fader->setDbValue(global_audio_mixer->get_fader_volume(bus_index)); + ui->faders->addWidget(channel); connect(ui_audio_miniview->fader, &NonLinearFader::dbValueChanged, @@ -359,6 +414,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()); @@ -372,7 +431,7 @@ void MainWindow::setup_audio_expanded_view() update_eq_label(bus_index, EQ_BAND_TREBLE, global_audio_mixer->get_eq(bus_index, EQ_BAND_TREBLE)); 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)); - // TODO: Set the fader position. + ui_audio_expanded_view->fader->setDbValue(global_audio_mixer->get_fader_volume(bus_index)); ui->buses->addWidget(channel); ui_audio_expanded_view->locut_enabled->setChecked(global_audio_mixer->get_locut_enabled(bus_index)); @@ -459,6 +518,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::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) { @@ -705,7 +801,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; @@ -737,6 +833,99 @@ void MainWindow::relayout() ui->preview_displays->setStretch(previews.size(), lrintf(remaining_preview_width)); } +void MainWindow::set_locut(float value) +{ + set_relative_value(ui->locut_cutoff_knob, value); +} + +void MainWindow::set_limiter_threshold(float value) +{ + set_relative_value(ui->limiter_threshold_knob, value); +} + +void MainWindow::set_makeup_gain(float value) +{ + set_relative_value(ui->makeup_gain_knob, value); +} + +void MainWindow::set_treble(unsigned bus_idx, float value) +{ + set_relative_value_if_exists(bus_idx, &Ui::AudioExpandedView::treble_knob, value); +} + +void MainWindow::set_mid(unsigned bus_idx, float value) +{ + set_relative_value_if_exists(bus_idx, &Ui::AudioExpandedView::mid_knob, value); +} + +void MainWindow::set_bass(unsigned bus_idx, float value) +{ + set_relative_value_if_exists(bus_idx, &Ui::AudioExpandedView::bass_knob, value); +} + +void MainWindow::set_gain(unsigned bus_idx, float value) +{ + set_relative_value_if_exists(bus_idx, &Ui::AudioExpandedView::gainstaging_knob, value); +} + +void MainWindow::set_compressor_threshold(unsigned bus_idx, float value) +{ + set_relative_value_if_exists(bus_idx, &Ui::AudioExpandedView::compressor_threshold_knob, value); +} + +void MainWindow::set_fader(unsigned bus_idx, float value) +{ + set_relative_value_if_exists(bus_idx, &Ui::AudioExpandedView::fader, value); +} + +void MainWindow::toggle_locut(unsigned bus_idx) +{ + click_button_if_exists(bus_idx, &Ui::AudioExpandedView::locut_enabled); +} + +void MainWindow::toggle_auto_gain_staging(unsigned bus_idx) +{ + click_button_if_exists(bus_idx, &Ui::AudioExpandedView::gainstaging_auto_checkbox); +} + +void MainWindow::toggle_compressor(unsigned bus_idx) +{ + click_button_if_exists(bus_idx, &Ui::AudioExpandedView::compressor_enabled); +} + +void MainWindow::clear_peak(unsigned bus_idx) +{ + if (global_audio_mixer->get_mapping_mode() == AudioMixer::MappingMode::MULTICHANNEL) { + global_audio_mixer->reset_peak(bus_idx); + } +} + +template +void MainWindow::set_relative_value(T *control, float value) +{ + post_to_main_thread([control, value]{ + control->setValue(lrintf(control->minimum() + value * (control->maximum() - control->minimum()))); + }); +} + +template +void MainWindow::set_relative_value_if_exists(unsigned bus_idx, T *(Ui_AudioExpandedView::*control), float value) +{ + if (global_audio_mixer->get_mapping_mode() == AudioMixer::MappingMode::MULTICHANNEL && + bus_idx < audio_expanded_views.size()) { + set_relative_value(audio_expanded_views[bus_idx]->*control, value); + } +} + +template +void MainWindow::click_button_if_exists(unsigned bus_idx, T *(Ui_AudioExpandedView::*control)) +{ + if (global_audio_mixer->get_mapping_mode() == AudioMixer::MappingMode::MULTICHANNEL && + bus_idx < audio_expanded_views.size()) { + (audio_expanded_views[bus_idx]->*control)->click(); + } +} + void MainWindow::set_transition_names(vector transition_names) { if (transition_names.size() < 1 || transition_names[0].empty()) { @@ -841,3 +1030,27 @@ void MainWindow::set_white_balance(int channel_number, int x, int y) global_mixer->set_wb(Mixer::OUTPUT_INPUT0 + channel_number, r, g, b); previews[channel_number]->display->updateGL(); } + +void MainWindow::audio_state_changed() +{ + post_to_main_thread([this]{ + InputMapping mapping = global_audio_mixer->get_input_mapping(); + for (unsigned bus_index = 0; bus_index < mapping.buses.size(); ++bus_index) { + const InputMapping::Bus &bus = mapping.buses[bus_index]; + string suffix; + if (bus.device.type == InputSourceType::ALSA_INPUT) { + ALSAPool::Device::State state = global_audio_mixer->get_alsa_card_state(bus.device.index); + if (state == ALSAPool::Device::State::STARTING) { + suffix = " (busy)"; + } else if (state == ALSAPool::Device::State::DEAD) { + suffix = " (dead)"; + } + } + + audio_miniviews[bus_index]->bus_desc_label->setFullText( + QString::fromStdString(bus.name + suffix)); + audio_expanded_views[bus_index]->bus_desc_label->setFullText( + QString::fromStdString(bus.name + suffix)); + } + }); +}