Skip to content

Commit

Permalink
Overview: add scale (gain) modes
Browse files Browse the repository at this point in the history
* normalized
* file gain (legacy, normalized off)
* All gain + pregain
* custom gain
  • Loading branch information
ronso0 committed Mar 10, 2025
1 parent 99583a0 commit 3312be5
Show file tree
Hide file tree
Showing 7 changed files with 235 additions and 54 deletions.
74 changes: 56 additions & 18 deletions src/preferences/dialog/dlgprefwaveform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ const ConfigKey kOverviewTypeCfgKey(QStringLiteral("[Waveform]"),
QStringLiteral("WaveformOverviewType"));
} // namespace

// for OverviewScaleMode from waveform/waveformwidgetfactory.h
using namespace mixxx;

DlgPrefWaveform::DlgPrefWaveform(
QWidget* pParent,
UserSettingsPointer pConfig,
Expand Down Expand Up @@ -173,14 +176,17 @@ DlgPrefWaveform::DlgPrefWaveform(
QOverload<double>::of(&QDoubleSpinBox::valueChanged),
this,
&DlgPrefWaveform::slotSetVisualGainHigh);
connect(normalizeOverviewCheckBox,
&QCheckBox::toggled,

connect(overview_scale_options,
QOverload<QAbstractButton*>::of(&QButtonGroup::buttonClicked),
this,
&DlgPrefWaveform::slotSetNormalizeOverview);
connect(overviewMinuteMarkersCheckBox,
&QCheckBox::toggled,
QOverload<QAbstractButton*>::of(
&DlgPrefWaveform::slotSetOverviewScaling));
connect(overview_scale_custom_spinbox,
QOverload<double>::of(&QDoubleSpinBox::valueChanged),
this,
&DlgPrefWaveform::slotSetOverviewMinuteMarkers);
&DlgPrefWaveform::slotSetOverviewCustomScaling);

connect(factory,
&WaveformWidgetFactory::waveformMeasured,
this,
Expand Down Expand Up @@ -289,7 +295,6 @@ void DlgPrefWaveform::slotUpdate() {
lowVisualGain->setValue(factory->getVisualGain(WaveformWidgetFactory::Low));
midVisualGain->setValue(factory->getVisualGain(WaveformWidgetFactory::Mid));
highVisualGain->setValue(factory->getVisualGain(WaveformWidgetFactory::High));
normalizeOverviewCheckBox->setChecked(factory->isOverviewNormalized());
// Round zoom to int to get a default zoom index.
defaultZoomComboBox->setCurrentIndex(static_cast<int>(factory->getDefaultZoom()) - 1);
playMarkerPositionSlider->setValue(static_cast<int>(factory->getPlayMarkerPosition() * 100));
Expand All @@ -315,6 +320,21 @@ void DlgPrefWaveform::slotUpdate() {
waveformOverviewComboBox->setCurrentIndex(cfgOverviewTypeIndex);
}

auto* pWidgetFactory = WaveformWidgetFactory::instance();
const OverviewScaleMode mode = pWidgetFactory->getOverviewScaleMode();
if (mode == OverviewScaleMode::FileGain) {
overview_scale_fileGain->setChecked(true);
} else if (mode == OverviewScaleMode::Normalize) {
overview_scale_normalize->setChecked(true);
} else if (mode == OverviewScaleMode::AllGainReplayGain) {
overview_scale_allReplayGain->setChecked(true);
} else { // OverviewScaleMode::Custom
overview_scale_custom_button->setChecked(true);
}

double customGain = pWidgetFactory->getOverviewCustomGain();
overview_scale_custom_spinbox->setValue(customGain);

bool drawOverviewMinuteMarkers = m_pConfig->getValue(
ConfigKey("[Waveform]", "draw_overview_minute_markers"), true);
overviewMinuteMarkersCheckBox->setChecked(drawOverviewMinuteMarkers);
Expand All @@ -328,6 +348,7 @@ void DlgPrefWaveform::slotUpdate() {
}

void DlgPrefWaveform::slotApply() {
// All other settings have already been applied instantly for preview purpose
WaveformSettings waveformSettings(m_pConfig);
waveformSettings.setWaveformCachingEnabled(enableWaveformCaching->isChecked());
waveformSettings.setWaveformGenerationWithAnalysisEnabled(
Expand Down Expand Up @@ -374,12 +395,15 @@ void DlgPrefWaveform::slotResetToDefaults() {
waveformOverviewComboBox->setCurrentIndex(
waveformOverviewComboBox->findData(QVariant::fromValue(WOverview::Type::RGB)));

// Don't normalize overview.
normalizeOverviewCheckBox->setChecked(false);

// Show minute markers.
overviewMinuteMarkersCheckBox->setChecked(true);

// Use file gain
overview_scale_fileGain->setChecked(false);

// load custom gain
overview_scale_custom_spinbox->setValue(1.0);

// 60FPS is the default
frameRateSlider->setValue(60);
endOfTrackWarningTimeSlider->setValue(30);
Expand Down Expand Up @@ -572,12 +596,12 @@ void DlgPrefWaveform::updateWaveformGeneralOptionsEnabled() {
}

void DlgPrefWaveform::updateWaveformGainEnabled() {
bool enabled = useWaveformCheckBox->isChecked() ||
!normalizeOverviewCheckBox->isChecked();
allVisualGain->setEnabled(enabled);
lowVisualGain->setEnabled(enabled);
midVisualGain->setEnabled(enabled);
highVisualGain->setEnabled(enabled);
bool waveformsEnabled = useWaveformCheckBox->isChecked();
bool allGainEnabled = waveformsEnabled || overview_scale_allReplayGain->isChecked();
allVisualGain->setEnabled(allGainEnabled);
lowVisualGain->setEnabled(waveformsEnabled);
midVisualGain->setEnabled(waveformsEnabled);
highVisualGain->setEnabled(waveformsEnabled);
}

void DlgPrefWaveform::slotSetWaveformOverviewType() {
Expand Down Expand Up @@ -613,11 +637,25 @@ void DlgPrefWaveform::slotSetVisualGainHigh(double gain) {
WaveformWidgetFactory::instance()->setVisualGain(WaveformWidgetFactory::High,gain);
}

void DlgPrefWaveform::slotSetNormalizeOverview(bool normalize) {
WaveformWidgetFactory::instance()->setOverviewNormalized(normalize);
void DlgPrefWaveform::slotSetOverviewScaling(QAbstractButton* b) {
auto* pWidgetFactory = WaveformWidgetFactory::instance();
if (b == overview_scale_fileGain) {
pWidgetFactory->setOverviewScaleMode(OverviewScaleMode::FileGain);
} else if (b == overview_scale_normalize) {
pWidgetFactory->setOverviewScaleMode(OverviewScaleMode::Normalize);
} else if (b == overview_scale_allReplayGain) {
pWidgetFactory->setOverviewScaleMode(OverviewScaleMode::AllGainReplayGain);
} else { // b == overview_scale_custom_button
pWidgetFactory->setOverviewScaleMode(OverviewScaleMode::Custom);
}
updateWaveformGainEnabled();
}

void DlgPrefWaveform::slotSetOverviewCustomScaling(double gain) {
// TODO validate 0 < v < 5 here or in WaveformWidgetFactory ?
WaveformWidgetFactory::instance()->setOverviewCustomGain(gain);
}

void DlgPrefWaveform::slotSetOverviewMinuteMarkers(bool draw) {
m_pConfig->setValue(ConfigKey("[Waveform]", "draw_overview_minute_markers"), draw);
m_pOverviewMinuteMarkersControl->forceSet(draw);
Expand Down
8 changes: 5 additions & 3 deletions src/preferences/dialog/dlgprefwaveform.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,12 @@ class DlgPrefWaveform : public DlgPreferencePage, public Ui::DlgPrefWaveformDlg
slotSetWaveformOptions(allshader::WaveformRendererSignalBase::Option::HighDetail, checked);
}
#endif
void slotSetWaveformOverviewType();
void slotSetDefaultZoom(int index);
void slotSetZoomSynchronization(bool checked);
void slotSetVisualGainAll(double gain);
void slotSetVisualGainLow(double gain);
void slotSetVisualGainMid(double gain);
void slotSetVisualGainHigh(double gain);
void slotSetNormalizeOverview(bool normalize);
void slotSetOverviewMinuteMarkers(bool minuteMarkers);
void slotWaveformMeasured(float frameRate, int droppedFrames);
void slotClearCachedWaveforms();
void slotSetBeatGridAlpha(int alpha);
Expand All @@ -63,6 +60,11 @@ class DlgPrefWaveform : public DlgPreferencePage, public Ui::DlgPrefWaveformDlg
void slotSetUntilMarkAlign(int index);
void slotSetUntilMarkTextPointSize(int value);
void slotSetUntilMarkTextHeightLimit(int index);
// overview options
void slotSetWaveformOverviewType();
void slotSetOverviewMinuteMarkers(bool minuteMarkers);
void slotSetOverviewScaling(QAbstractButton* b);
void slotSetOverviewCustomScaling(double gain);

private:
void initWaveformControl();
Expand Down
73 changes: 68 additions & 5 deletions src/preferences/dialog/dlgprefwaveformdlg.ui
Original file line number Diff line number Diff line change
Expand Up @@ -620,20 +620,76 @@ Select from different types of displays for the waveform overview, which differ
</item>

<item row="1" column="1" colspan="4">
<widget class="QCheckBox" name="normalizeOverviewCheckBox">
<widget class="QCheckBox" name="overviewMinuteMarkersCheckBox">
<property name="text">
<string>Normalize waveform overview</string>
<string>Show minute markers on waveform overview</string>
</property>
</widget>
</item>

<item row="2" column="1" colspan="4">
<widget class="QCheckBox" name="overviewMinuteMarkersCheckBox">
<widget class="QRadioButton" name="overview_scale_fileGain">
<property name="text">
<string>Show minute markers on waveform overview</string>
<string>Use file gain</string>
</property>
<attribute name="buttonGroup">
<string notr="true">overview_scale_options</string>
</attribute>
</widget>
</item>
<item row="3" column="1" colspan="4">
<widget class="QRadioButton" name="overview_scale_normalize">
<property name="text">
<string>Normalize</string>
</property>
<attribute name="buttonGroup">
<string notr="true">overview_scale_options</string>
</attribute>
</widget>
</item>
<item row="4" column="1" colspan="4">
<widget class="QRadioButton" name="overview_scale_allReplayGain">
<property name="text">
<string>Use Waveform "All" gain incl. ReplayGain</string>
</property>
<attribute name="buttonGroup">
<string notr="true">overview_scale_options</string>
</attribute>
</widget>
</item>
<item row="5" column="1" colspan="4">
<layout class="QHBoxLayout" name="overview_customGain_layout">
<item>
<widget class="QRadioButton" name="overview_scale_custom_button">
<property name="text">
<string>Use custom gain</string>
</property>
<attribute name="buttonGroup">
<string notr="true">overview_scale_options</string>
</attribute>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="overview_scale_custom_spinbox">
<property name="toolTip">
<string>Global visual gain</string>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>0.500000000000000</double>
</property>
<property name="maximum">
<double>5.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
</layout>
</item>

</layout>
</widget>
Expand Down Expand Up @@ -778,12 +834,19 @@ Select from different types of displays for the waveform overview, which differ
<tabstop>untilMarkTextPointSizeSpinBox</tabstop>
<tabstop>untilMarkTextHeightLimitComboBox</tabstop>
<tabstop>waveformOverviewComboBox</tabstop>
<tabstop>normalizeOverviewCheckBox</tabstop>
<tabstop>overview_scale_fileGain</tabstop>
<tabstop>overview_scale_normalize</tabstop>
<tabstop>overview_scale_allReplayGain</tabstop>
<tabstop>overview_scale_custom_button</tabstop>
<tabstop>overview_scale_custom_spinbox</tabstop>
<tabstop>overviewMinuteMarkersCheckBox</tabstop>
<tabstop>enableWaveformCaching</tabstop>
<tabstop>enableWaveformGenerationWithAnalysis</tabstop>
<tabstop>clearCachedWaveforms</tabstop>
</tabstops>
<buttongroups>
<buttongroup name="overview_scale_options"/>
</buttongroups>
<resources/>
<connections/>
</ui>
59 changes: 51 additions & 8 deletions src/waveform/waveformwidgetfactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ ConfigKey visualGainKey(int index) {

} // anonymous namespace

// for OverviewScaleMode
using namespace mixxx;

///////////////////////////////////////////

WaveformWidgetAbstractHandle::WaveformWidgetAbstractHandle()
Expand Down Expand Up @@ -119,7 +122,8 @@ WaveformWidgetFactory::WaveformWidgetFactory()
m_endOfTrackWarningTime(30),
m_defaultZoom(WaveformWidgetRenderer::s_waveformDefaultZoom),
m_zoomSync(true),
m_overviewNormalized(false),
m_overviewScaleMode(OverviewScaleMode::AllGainReplayGain),
m_overviewCustomGain(1.0),
m_untilMarkShowBeats(false),
m_untilMarkShowTime(false),
m_untilMarkAlign(Qt::AlignVCenter),
Expand Down Expand Up @@ -405,11 +409,28 @@ bool WaveformWidgetFactory::setConfig(UserSettingsPointer config) {
}
}

int overviewNormalized = m_config->getValueString(ConfigKey("[Waveform]","OverviewNormalized")).toInt(&ok);
// Try to read scale mode or, if doesn't exists, try migrate legacy normalize option
int scaleMode = m_config->getValueString(kOverviewScaleModeKey).toInt(&ok);
if (ok) {
setOverviewScaleMode(static_cast<OverviewScaleMode>(scaleMode));
} else {
bool overviewNormalized = m_config->getValue<bool>(
ConfigKey(QStringLiteral("[Waveform]"),
QStringLiteral("OverviewNormalized")),
false);
if (overviewNormalized) {
setOverviewScaleMode(OverviewScaleMode::Normalize);
} else {
// Else use same gain as scrolling waveforms, OverviewScaleMode::AllGainReplayGain
m_config->setValue(kOverviewScaleModeKey, m_overviewScaleMode);
}
}

double customGain = m_config->getValueString(kOverviewCustomGainKey).toDouble(&ok);
if (ok) {
setOverviewNormalized(static_cast<bool>(overviewNormalized));
setOverviewCustomGain(customGain);
} else {
m_config->set(ConfigKey("[Waveform]","OverviewNormalized"), ConfigValue(m_overviewNormalized));
m_config->setValue(kOverviewCustomGainKey, m_overviewCustomGain);
}

m_playMarkerPosition =
Expand Down Expand Up @@ -717,12 +738,34 @@ double WaveformWidgetFactory::getVisualGain(FilterIndex index) const {
return m_visualGain[index];
}

void WaveformWidgetFactory::setOverviewNormalized(bool normalize) {
m_overviewNormalized = normalize;
void WaveformWidgetFactory::setOverviewScaleMode(OverviewScaleMode mode) {
if (m_overviewScaleMode == mode) {
return;
}
m_overviewScaleMode = mode;
emit overviewScalingChanged();
}

OverviewScaleMode WaveformWidgetFactory::getOverviewScaleMode() const {
return m_overviewScaleMode;
}

void WaveformWidgetFactory::setOverviewCustomGain(double gain) {
VERIFY_OR_DEBUG_ASSERT(gain > 0) {
return;
}
m_overviewCustomGain = gain;
if (m_config) {
m_config->set(ConfigKey("[Waveform]","OverviewNormalized"), ConfigValue(m_overviewNormalized));
m_config->set(kOverviewCustomGainKey,
QString::number(gain));
}
emit overviewNormalizeChanged();
if (m_overviewScaleMode == OverviewScaleMode::Custom) {
emit overviewScalingChanged();
}
}

double WaveformWidgetFactory::getOverviewCustomGain() const {
return m_overviewCustomGain;
}

void WaveformWidgetFactory::setPlayMarkerPosition(double position) {
Expand Down
Loading

0 comments on commit 3312be5

Please sign in to comment.