});
}
-constexpr unsigned DB_NO_FLAGS = 0x0;
constexpr unsigned DB_WITH_SIGN = 0x1;
constexpr unsigned DB_BARE = 0x2;
}
}
+string get_bus_desc_label(const InputMapping::Bus &bus)
+{
+ 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)";
+ }
+ }
+
+ return bus.name + suffix;
+}
+
} // namespace
MainWindow::MainWindow()
qRegisterMetaType<Mixer::Output>("Mixer::Output");
// Hook up the prev/next buttons on the audio views.
- connect(ui->compact_prev_page, &QAbstractButton::clicked, bind(&QStackedWidget::setCurrentIndex, ui->audio_views, 2));
- connect(ui->compact_next_page, &QAbstractButton::clicked, bind(&QStackedWidget::setCurrentIndex, ui->audio_views, 1));
- 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, 2));
- connect(ui->video_grid_prev_page, &QAbstractButton::clicked, bind(&QStackedWidget::setCurrentIndex, ui->audio_views, 1));
- connect(ui->video_grid_next_page, &QAbstractButton::clicked, bind(&QStackedWidget::setCurrentIndex, ui->audio_views, 0));
-
- // And bind the same to PgUp/PgDown.
auto prev_page = [this]{
if (global_audio_mixer->get_mapping_mode() == AudioMixer::MappingMode::MULTICHANNEL) {
ui->audio_views->setCurrentIndex((ui->audio_views->currentIndex() + 2) % 3);
+ } else {
+ ui->audio_views->setCurrentIndex(2 - ui->audio_views->currentIndex()); // Switch between 0 and 2.
}
};
auto next_page = [this]{
if (global_audio_mixer->get_mapping_mode() == AudioMixer::MappingMode::MULTICHANNEL) {
ui->audio_views->setCurrentIndex((ui->audio_views->currentIndex() + 1) % 3);
+ } else {
+ ui->audio_views->setCurrentIndex(2 - ui->audio_views->currentIndex()); // Switch between 0 and 2.
}
};
+ connect(ui->compact_prev_page, &QAbstractButton::clicked, prev_page);
+ connect(ui->compact_next_page, &QAbstractButton::clicked, next_page);
+ connect(ui->full_prev_page, &QAbstractButton::clicked, prev_page);
+ connect(ui->full_next_page, &QAbstractButton::clicked, next_page);
+ connect(ui->video_grid_prev_page, &QAbstractButton::clicked, prev_page);
+ connect(ui->video_grid_next_page, &QAbstractButton::clicked, next_page);
+
+ // And bind the same to PgUp/PgDown.
connect(new QShortcut(QKeySequence::MoveToNextPage, this), &QShortcut::activated, next_page);
connect(new QShortcut(QKeySequence::MoveToPreviousPage, this), &QShortcut::activated, prev_page);
}
midi_mapper.refresh_highlights();
midi_mapper.refresh_lights();
+ if (global_flags.fullscreen) {
+ QMainWindow::showFullScreen();
+ }
}
void MainWindow::resizeEvent(QResizeEvent* event)
connect(ui_display->display, &GLWidget::color_updated, this, &MainWindow::update_channel_color);
// Hook up the keyboard key.
- QShortcut *shortcut = new QShortcut(QKeySequence(Qt::Key_1 + i), this);
- connect(shortcut, &QShortcut::activated, bind(&MainWindow::channel_clicked, this, i));
+ QShortcut *shortcut = nullptr;
+ if (i < 9) {
+ shortcut = new QShortcut(QKeySequence(Qt::Key_1 + i), this);
+ } else if (i == 9) {
+ shortcut = new QShortcut(QKeySequence(Qt::Key_0), this);
+ }
+ if (shortcut != nullptr) {
+ connect(shortcut, &QShortcut::activated, bind(&MainWindow::channel_clicked, this, i));
+ }
// Hook up the quick-cut key.
if (i < strlen(qwerty)) {
});
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){
+ connect(ui->gainstaging_auto_checkbox, &QCheckBox::stateChanged, [this](int state){
global_audio_mixer->set_gain_staging_auto(simple_bus_index, state == Qt::Checked);
midi_mapper.refresh_lights();
});
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){
+ connect(ui->compressor_enabled, &QCheckBox::stateChanged, [this](int state){
global_audio_mixer->set_compressor_enabled(simple_bus_index, state == Qt::Checked);
midi_mapper.refresh_lights();
});
analyzer.reset(new Analyzer);
+ global_mixer->set_theme_menu_callback(bind(&MainWindow::setup_theme_menu, this));
+ setup_theme_menu();
+
struct sigaction act;
memset(&act, 0, sizeof(act));
act.sa_handler = schedule_cut_signal;
setup_audio_expanded_view();
if (simple) {
- ui->audio_views->setCurrentIndex(0);
+ ui->compact_label->setText("Compact audio view (1/2) ");
+ ui->video_grid_label->setText("Video grid display (2/2) ");
+ if (ui->audio_views->currentIndex() == 1) {
+ // Full audio view is not available in simple mode.
+ ui->audio_views->setCurrentIndex(0);
+ }
+ } else {
+ ui->compact_label->setText("Compact audio view (1/3) ");
+ ui->full_label->setText("Full audio view (2/3) ");
+ ui->video_grid_label->setText("Video grid display (3/3) ");
}
- ui->compact_header->setVisible(!simple);
midi_mapper.refresh_highlights();
midi_mapper.refresh_lights();
Ui::AudioMiniView *ui_audio_miniview = new Ui::AudioMiniView;
ui_audio_miniview->setupUi(channel);
ui_audio_miniview->bus_desc_label->setFullText(
- QString::fromStdString(mapping.buses[bus_index].name));
+ QString::fromStdString(get_bus_desc_label(mapping.buses[bus_index])));
audio_miniviews[bus_index] = ui_audio_miniview;
// Set up the peak meter.
Ui::AudioExpandedView *ui_audio_expanded_view = new Ui::AudioExpandedView;
ui_audio_expanded_view->setupUi(channel);
ui_audio_expanded_view->bus_desc_label->setFullText(
- QString::fromStdString(mapping.buses[bus_index].name));
+ QString::fromStdString(get_bus_desc_label(mapping.buses[bus_index])));
audio_expanded_views[bus_index] = ui_audio_expanded_view;
+ update_stereo_knob_and_label(bus_index, lrintf(100.0f * global_audio_mixer->get_stereo_width(bus_index)));
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));
midi_mapper.refresh_lights();
});
+ connect(ui_audio_expanded_view->stereo_width_knob, &QDial::valueChanged,
+ bind(&MainWindow::stereo_width_knob_changed, this, bus_index, _1));
+
connect(ui_audio_expanded_view->treble_knob, &QDial::valueChanged,
bind(&MainWindow::eq_knob_changed, this, bus_index, EQ_BAND_TREBLE, _1));
connect(ui_audio_expanded_view->mid_knob, &QDial::valueChanged,
});
}
+void MainWindow::stereo_width_knob_changed(unsigned bus_index, int value)
+{
+ float stereo_width = value * 0.01f;
+ global_audio_mixer->set_stereo_width(bus_index, stereo_width);
+
+ update_stereo_label(bus_index, value);
+}
+
void MainWindow::eq_knob_changed(unsigned bus_index, EQBand band, int value)
{
float gain_db = value * 0.1f;
update_eq_label(bus_index, band, gain_db);
}
+void MainWindow::update_stereo_knob_and_label(unsigned bus_index, int stereo_width_percent)
+{
+ Ui::AudioExpandedView *view = audio_expanded_views[bus_index];
+
+ if (global_audio_mixer->is_mono(bus_index)) {
+ view->stereo_width_knob->setEnabled(false);
+ view->stereo_width_label->setEnabled(false);
+ } else {
+ view->stereo_width_knob->setEnabled(true);
+ view->stereo_width_label->setEnabled(true);
+ }
+ view->stereo_width_knob->setValue(stereo_width_percent);
+ update_stereo_label(bus_index, stereo_width_percent);
+}
+
+void MainWindow::update_stereo_label(unsigned bus_index, int stereo_width_percent)
+{
+ Ui::AudioExpandedView *view = audio_expanded_views[bus_index];
+
+ if (global_audio_mixer->is_mono(bus_index)) {
+ view->stereo_width_label->setText("Mono");
+ } else {
+ char buf[256];
+ snprintf(buf, sizeof(buf), "Stereo: %d%%", stereo_width_percent);
+ view->stereo_width_label->setText(buf);
+ }
+}
+
void MainWindow::update_eq_label(unsigned bus_index, EQBand band, float gain_db)
{
Ui::AudioExpandedView *view = audio_expanded_views[bus_index];
}
}
+void MainWindow::setup_theme_menu()
+{
+ std::vector<Theme::MenuEntry> theme_menu_entries = global_mixer->get_theme_menu();
+
+ if (theme_menu != nullptr) {
+ ui->menuBar->removeAction(theme_menu->menuAction());
+ theme_menu = nullptr;
+ }
+
+ if (!theme_menu_entries.empty()) {
+ theme_menu = new QMenu("&Theme");
+ for (const Theme::MenuEntry &entry : theme_menu_entries) {
+ QAction *action = theme_menu->addAction(QString::fromStdString(entry.text));
+ connect(action, &QAction::triggered, [entry] {
+ global_mixer->theme_menu_entry_clicked(entry.lua_ref);
+ });
+ }
+ ui->menuBar->insertMenu(ui->menu_Help->menuAction(), theme_menu);
+ }
+}
+
void MainWindow::limiter_threshold_knob_changed(int value)
{
float threshold_dbfs = value * 0.1f;
set_peak_label(ui->peak_display, peak_db);
// NOTE: Will be invisible when using multitrack audio.
- ui->gainstaging_knob->blockSignals(true);
- ui->gainstaging_knob->setValue(lrintf(bus_levels[0].gain_staging_db * 10.0f));
- ui->gainstaging_knob->blockSignals(false);
- ui->gainstaging_db_display->setText(
- QString::fromStdString(format_db(bus_levels[0].gain_staging_db, DB_WITH_SIGN)));
+ if (!bus_levels.empty()) {
+ ui->gainstaging_knob->blockSignals(true);
+ ui->gainstaging_knob->setValue(lrintf(bus_levels[0].gain_staging_db * 10.0f));
+ ui->gainstaging_knob->blockSignals(false);
+ ui->gainstaging_db_display->setText(
+ QString::fromStdString(format_db(bus_levels[0].gain_staging_db, DB_WITH_SIGN)));
+ }
ui->makeup_gain_knob->blockSignals(true);
ui->makeup_gain_knob->setValue(lrintf(final_makeup_gain_db * 10.0f));
set_relative_value(ui->makeup_gain_knob, value);
}
+void MainWindow::set_stereo_width(unsigned bus_idx, float value)
+{
+ set_relative_value_if_exists(bus_idx, &Ui::AudioExpandedView::stereo_width_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::highlight_stereo_width(unsigned bus_idx, bool highlight)
+{
+ highlight_control_if_exists(bus_idx, &Ui::AudioExpandedView::stereo_width_knob, highlight);
+}
+
void MainWindow::highlight_treble(unsigned bus_idx, bool highlight)
{
highlight_control_if_exists(bus_idx, &Ui::AudioExpandedView::treble_knob, highlight);
QApplication::restoreOverrideCursor();
if (watched == previews[current_wb_pick_display]->display) {
const QMouseEvent *mouse_event = (QMouseEvent *)event;
- set_white_balance(current_wb_pick_display, mouse_event->x(), mouse_event->y());
+ previews[current_wb_pick_display]->display->grab_white_balance(
+ current_wb_pick_display,
+ mouse_event->x(), mouse_event->y());
} else {
// The user clicked on something else, give up.
// (The click goes through, which might not be ideal, but, yes.)
event->accept();
}
-namespace {
-
-double srgb_to_linear(double x)
-{
- if (x < 0.04045) {
- return x / 12.92;
- } else {
- return pow((x + 0.055) / 1.055, 2.4);
- }
-}
-
-} // namespace
-
-void MainWindow::set_white_balance(int channel_number, int x, int y)
-{
- // Set the white balance to neutral for the grab. It's probably going to
- // flicker a bit, but hopefully this display is not live anyway.
- global_mixer->set_wb(Mixer::OUTPUT_INPUT0 + channel_number, 0.5, 0.5, 0.5);
- previews[channel_number]->display->updateGL();
- QRgb reference_color = previews[channel_number]->display->grabFrameBuffer().pixel(x, y);
-
- double r = srgb_to_linear(qRed(reference_color) / 255.0);
- double g = srgb_to_linear(qGreen(reference_color) / 255.0);
- double b = srgb_to_linear(qBlue(reference_color) / 255.0);
- 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)";
- }
- }
-
+ string label = get_bus_desc_label(mapping.buses[bus_index]);
audio_miniviews[bus_index]->bus_desc_label->setFullText(
- QString::fromStdString(bus.name + suffix));
+ QString::fromStdString(label));
audio_expanded_views[bus_index]->bus_desc_label->setFullText(
- QString::fromStdString(bus.name + suffix));
+ QString::fromStdString(label));
}
});
}