From 227fc47a97d51f4d1b68b0943ac25ade2f456834 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Mon, 11 Mar 2024 22:38:45 +0100 Subject: [PATCH 01/31] Fix NaNs in basic filters and Equalizer (#7141) Fix several NaNs in the context of the basic filters and the Equalizer. The coefficients of the `BiQuad` were not initialized which seems to have led to NaNs down the line. Fix a division by zero in `EqEffect::peakBand` and `EqSpectrumView::paintEvent` if the energy is zero. The condition `m_peakSum <= 0` was removed from `EqSpectrumView::paintEvent` because the value is initialized to 0 down the line and later only potentially positive values are added. --- include/BasicFilters.h | 7 ++++++- plugins/Eq/EqEffect.cpp | 5 ++++- plugins/Eq/EqSpectrumView.cpp | 9 +++++---- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/include/BasicFilters.h b/include/BasicFilters.h index 4cde320a638..215c32dfb49 100644 --- a/include/BasicFilters.h +++ b/include/BasicFilters.h @@ -144,7 +144,12 @@ template class BiQuad { public: - BiQuad() + BiQuad() : + m_a1(0.), + m_a2(0.), + m_b0(0.), + m_b1(0.), + m_b2(0.) { clearHistory(); } diff --git a/plugins/Eq/EqEffect.cpp b/plugins/Eq/EqEffect.cpp index 8a795414429..31be4d0f5b6 100644 --- a/plugins/Eq/EqEffect.cpp +++ b/plugins/Eq/EqEffect.cpp @@ -289,6 +289,9 @@ bool EqEffect::processAudioBuffer( sampleFrame *buf, const fpp_t frames ) float EqEffect::peakBand( float minF, float maxF, EqAnalyser *fft, int sr ) { + auto const fftEnergy = fft->getEnergy(); + if (fftEnergy == 0.) { return 0.; } + float peak = -60; float *b = fft->m_bands; float h = 0; @@ -296,7 +299,7 @@ float EqEffect::peakBand( float minF, float maxF, EqAnalyser *fft, int sr ) { if( bandToFreq( x ,sr) >= minF && bandToFreq( x,sr ) <= maxF ) { - h = 20 * ( log10( *b / fft->getEnergy() ) ); + h = 20. * log10(*b / fftEnergy); peak = h > peak ? h : peak; } } diff --git a/plugins/Eq/EqSpectrumView.cpp b/plugins/Eq/EqSpectrumView.cpp index e75248755e2..35eb90dc088 100644 --- a/plugins/Eq/EqSpectrumView.cpp +++ b/plugins/Eq/EqSpectrumView.cpp @@ -208,10 +208,10 @@ EqSpectrumView::EqSpectrumView(EqAnalyser *b, QWidget *_parent) : void EqSpectrumView::paintEvent(QPaintEvent *event) { - const float energy = m_analyser->getEnergy(); - if( energy <= 0 && m_peakSum <= 0 ) + const float energy = m_analyser->getEnergy(); + if (energy <= 0.) { - //dont draw anything + // If there is no energy in the signal we don't need to draw anything return; } @@ -238,7 +238,8 @@ void EqSpectrumView::paintEvent(QPaintEvent *event) const float fallOff = 1.07; for( int x = 0; x < MAX_BANDS; ++x, ++bands ) { - peak = ( fh * 2.0 / 3.0 * ( 20 * ( log10( *bands / energy ) ) - LOWER_Y ) / ( - LOWER_Y ) ); + peak = *bands != 0. ? (fh * 2.0 / 3.0 * (20. * log10(*bands / energy) - LOWER_Y) / (-LOWER_Y)) : 0.; + if( peak < 0 ) { peak = 0; From 238974253d0fc8137939a8983fc57e7bac0b6752 Mon Sep 17 00:00:00 2001 From: Dalton Messmer Date: Tue, 12 Mar 2024 14:56:49 -0400 Subject: [PATCH 02/31] Update game-music-emu submodule --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 82f3e464c0f..1c43fd1b339 100644 --- a/.gitmodules +++ b/.gitmodules @@ -6,7 +6,7 @@ url = https://github.com/lmms/zynaddsubfx.git [submodule "plugins/FreeBoy/game-music-emu"] path = plugins/FreeBoy/game-music-emu - url = https://bitbucket.org/mpyne/game-music-emu.git + url = https://github.com/libgme/game-music-emu.git [submodule "plugins/OpulenZ/adplug"] path = plugins/OpulenZ/adplug url = https://github.com/adplug/adplug.git From 37073af49475a5574db28f2dc3fd31d7939c2556 Mon Sep 17 00:00:00 2001 From: Dalton Messmer Date: Tue, 12 Mar 2024 15:45:34 -0400 Subject: [PATCH 03/31] Update to latest commit --- plugins/FreeBoy/game-music-emu | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/FreeBoy/game-music-emu b/plugins/FreeBoy/game-music-emu index 21a064ea66a..6b676192d98 160000 --- a/plugins/FreeBoy/game-music-emu +++ b/plugins/FreeBoy/game-music-emu @@ -1 +1 @@ -Subproject commit 21a064ea66a5cdf71910e207c4756095c266814f +Subproject commit 6b676192d98302e698ac78fe3c00833eae6a74e5 From 04ecf733951d2aba5bc8dad08c50f189979c8737 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Wed, 13 Mar 2024 20:00:58 +0100 Subject: [PATCH 04/31] Fix missing icons for some instruments (#7132) Revert some of the changes made in commit 88e0e94dcdb. The underlying idea was that the `InstrumentTrackView` should be responsible for assigning the icon that's shown by its `TrackLabelButton`. However, this does not work because in some cases the `InstrumentTrack` that's passed into `InstrumentTrackView::determinePixmap` does not have an `Instrument` assigned. This in turn seems to be caused due to initalizations that are running in parallel in different threads. Here are the steps to reproduce the threading problem (line numbers refer to commit 360254f): 1. Set a break point in line 1054 of `InstrumentTrack`, i.e. the line in `InstrumentTrack::loadInstrument` where `m_instrument` is being assigned to. 2. Set a break point in `InstrumentTrackView::determinePixmap`, e.g. inside of the first if statement. 3. Drop an instance of "Sf2 Player" onto the Song Editor. 4. The first break point in `InstrumentTrack` is hit in a thread called "lmms::Instrumen" (shown like that in my debugger). Try to step over it. 5. The second break point in `InstrumentTrackView` now gets hit before the code is stepped over. This time we are in the thread called "lmms". I guess this is the GUI main thread. 6. Continue execution. If you now switch to the application then the icon is shown. I guess the debugger is halted long enough in the main thread so that the InstrumentTrack gets an instrument assigned in another thread. If you delete/disable the break point in `InstrumentTrack::determinePixmap` and follow the coarse steps above then the icon is not shown because the track has no instrument. The current fix still delegates to the `InstrumentTrackView` to determine the pixmap in hopes that one day there will be a better solution where the parent component can be fully responsible for its child component. Fixes #7116. --- include/InstrumentTrackView.h | 2 ++ include/TrackLabelButton.h | 1 + src/gui/tracks/InstrumentTrackView.cpp | 5 +++++ src/gui/tracks/TrackLabelButton.cpp | 11 +++++++++++ 4 files changed, 19 insertions(+) diff --git a/include/InstrumentTrackView.h b/include/InstrumentTrackView.h index c7d524b36cf..cfde89bde82 100644 --- a/include/InstrumentTrackView.h +++ b/include/InstrumentTrackView.h @@ -71,6 +71,8 @@ class InstrumentTrackView : public TrackView // Create a menu for assigning/creating channels for this track QMenu * createMixerMenu( QString title, QString newMixerLabel ) override; + QPixmap determinePixmap(); + protected: void modelChanged() override; diff --git a/include/TrackLabelButton.h b/include/TrackLabelButton.h index e19fc6be9bc..1d3620d12f9 100644 --- a/include/TrackLabelButton.h +++ b/include/TrackLabelButton.h @@ -55,6 +55,7 @@ public slots: void mousePressEvent( QMouseEvent * _me ) override; void mouseDoubleClickEvent( QMouseEvent * _me ) override; void mouseReleaseEvent( QMouseEvent * _me ) override; + void paintEvent(QPaintEvent* pe) override; void resizeEvent( QResizeEvent * _re ) override; private: diff --git a/src/gui/tracks/InstrumentTrackView.cpp b/src/gui/tracks/InstrumentTrackView.cpp index 788991ed0f8..c812999fd62 100644 --- a/src/gui/tracks/InstrumentTrackView.cpp +++ b/src/gui/tracks/InstrumentTrackView.cpp @@ -397,6 +397,11 @@ QMenu * InstrumentTrackView::createMixerMenu(QString title, QString newMixerLabe return mixerMenu; } +QPixmap InstrumentTrackView::determinePixmap() +{ + return determinePixmap(dynamic_cast(getTrack())); +} + QPixmap InstrumentTrackView::determinePixmap(InstrumentTrack* instrumentTrack) { diff --git a/src/gui/tracks/TrackLabelButton.cpp b/src/gui/tracks/TrackLabelButton.cpp index 087edba3d74..c164b780e75 100644 --- a/src/gui/tracks/TrackLabelButton.cpp +++ b/src/gui/tracks/TrackLabelButton.cpp @@ -30,6 +30,7 @@ #include "ConfigManager.h" #include "embed.h" +#include "InstrumentTrackView.h" #include "RenameDialog.h" #include "TrackRenameLineEdit.h" #include "TrackView.h" @@ -178,6 +179,16 @@ void TrackLabelButton::mouseReleaseEvent( QMouseEvent *_me ) } +void TrackLabelButton::paintEvent(QPaintEvent* pe) +{ + InstrumentTrackView* instrumentTrackView = dynamic_cast(m_trackView); + if (instrumentTrackView) + { + setIcon(instrumentTrackView->determinePixmap()); + } + + QToolButton::paintEvent(pe); +} void TrackLabelButton::resizeEvent(QResizeEvent *_re) From b9ebc24e13893ed83e87eac3647b52408e7cedca Mon Sep 17 00:00:00 2001 From: saker Date: Fri, 15 Mar 2024 21:40:15 -0400 Subject: [PATCH 05/31] Check if `m_peakSum` is less than or equal to 0 again (#7146) --- plugins/Eq/EqSpectrumView.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/plugins/Eq/EqSpectrumView.cpp b/plugins/Eq/EqSpectrumView.cpp index 35eb90dc088..540450883db 100644 --- a/plugins/Eq/EqSpectrumView.cpp +++ b/plugins/Eq/EqSpectrumView.cpp @@ -209,11 +209,7 @@ EqSpectrumView::EqSpectrumView(EqAnalyser *b, QWidget *_parent) : void EqSpectrumView::paintEvent(QPaintEvent *event) { const float energy = m_analyser->getEnergy(); - if (energy <= 0.) - { - // If there is no energy in the signal we don't need to draw anything - return; - } + if (energy <= 0. && m_peakSum <= 0) { return; } const int fh = height(); const int LOWER_Y = -36; // dB From 4120a04d0be6c7c00dd9610da7a2ec9d023c55ce Mon Sep 17 00:00:00 2001 From: Rossmaxx <74815851+Rossmaxx@users.noreply.github.com> Date: Sat, 16 Mar 2024 11:04:01 +0530 Subject: [PATCH 06/31] Replace QRegExp with QRegularExpression (#7133) * replace QRegExp with QRegularExpression (find n replace) * follow up to fix errors * removed rpmalloc * Fix compilation for qt5, to be fixed when qt6 fully supported. Co-authored-by: Kevin Zander * Added QtGlobal header for version finding fix * Use the other syntax to try fix compilation. * Check for 5.12 instead. * Fix the header * Attempt at fixing it further. * Use version checks properly in header file * Use QT_VERSION_CHECK macro in sources * Apply suggestions from messmerd's review Co-authored-by: Dalton Messmer --------- Co-authored-by: Kevin Zander Co-authored-by: Dalton Messmer --- include/AutomatableModel.h | 3 ++- include/EffectSelectDialog.h | 17 +++++++++++++---- include/LadspaBase.h | 4 +++- plugins/CarlaBase/Carla.h | 5 +++-- .../LadspaEffect/LadspaSubPluginFeatures.cpp | 3 +-- plugins/ZynAddSubFx/ZynAddSubFx.cpp | 2 +- src/core/AutomatableModel.cpp | 4 ++-- src/core/DataFile.cpp | 6 +++--- src/core/RenderManager.cpp | 3 ++- src/gui/MicrotunerConfig.cpp | 14 +++++++------- src/gui/instrument/InstrumentTrackWindow.cpp | 2 +- src/gui/modals/EffectSelectDialog.cpp | 6 ++++++ src/gui/modals/VersionedSaveDialog.cpp | 4 ++-- 13 files changed, 46 insertions(+), 27 deletions(-) diff --git a/include/AutomatableModel.h b/include/AutomatableModel.h index 87adfdc6e7b..15285e17ab3 100644 --- a/include/AutomatableModel.h +++ b/include/AutomatableModel.h @@ -25,9 +25,10 @@ #ifndef LMMS_AUTOMATABLE_MODEL_H #define LMMS_AUTOMATABLE_MODEL_H +#include #include #include -#include +#include #include "JournallingObject.h" #include "Model.h" diff --git a/include/EffectSelectDialog.h b/include/EffectSelectDialog.h index db8e60f0d1f..53e8dbe7e44 100644 --- a/include/EffectSelectDialog.h +++ b/include/EffectSelectDialog.h @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include #include @@ -65,10 +65,19 @@ class DualColumnFilterProxyModel : public QSortFilterProxyModel QString name = sourceModel()->data(nameIndex, Qt::DisplayRole).toString(); QString type = sourceModel()->data(typeIndex, Qt::DisplayRole).toString(); - QRegExp nameRegExp(filterRegExp()); - nameRegExp.setCaseSensitivity(Qt::CaseInsensitive); + // TODO: cleanup once we drop Qt5 support +#if (QT_VERSION >= QT_VERSION_CHECK(5,12,0)) + QRegularExpression nameRegularExpression(filterRegularExpression()); + nameRegularExpression.setPatternOptions(QRegularExpression::CaseInsensitiveOption); + + bool nameFilterPassed = nameRegularExpression.match(name).capturedStart() != -1; +#else + QRegExp nameRegularExpression(filterRegExp()); + nameRegularExpression.setCaseSensitivity(Qt::CaseInsensitive); + + bool nameFilterPassed = nameRegularExpression.indexIn(name) != -1; +#endif - bool nameFilterPassed = nameRegExp.indexIn(name) != -1; bool typeFilterPassed = type.contains(m_effectTypeFilter, Qt::CaseInsensitive); return nameFilterPassed && typeFilterPassed; diff --git a/include/LadspaBase.h b/include/LadspaBase.h index 6569c5a309e..0a2b067d4f2 100644 --- a/include/LadspaBase.h +++ b/include/LadspaBase.h @@ -26,6 +26,8 @@ #ifndef LMMS_LADSPA_BASE_H #define LMMS_LADSPA_BASE_H +#include + #include "LadspaManager.h" #include "Plugin.h" @@ -75,7 +77,7 @@ inline Plugin::Descriptor::SubPluginFeatures::Key ladspaKeyToSubPluginKey( { Plugin::Descriptor::SubPluginFeatures::Key::AttributeMap m; QString file = _key.first; - m["file"] = file.remove( QRegExp( "\\.so$" ) ).remove( QRegExp( "\\.dll$" ) ); + m["file"] = file.remove(QRegularExpression("\\.so$")).remove(QRegularExpression("\\.dll$")); m["plugin"] = _key.second; return Plugin::Descriptor::SubPluginFeatures::Key( _desc, _name, m ); } diff --git a/plugins/CarlaBase/Carla.h b/plugins/CarlaBase/Carla.h index e04444f91b2..3d0e424a277 100644 --- a/plugins/CarlaBase/Carla.h +++ b/plugins/CarlaBase/Carla.h @@ -33,6 +33,7 @@ #include #include #include +#include // carla/source/includes #include "carlabase_export.h" @@ -89,8 +90,8 @@ class CarlaParamFloatModel : public FloatModel // From AutomatableModel.h, it's private there. inline static bool mustQuoteName(const QString &name) { - QRegExp reg("^[A-Za-z0-9._-]+$"); - return !reg.exactMatch(name); + QRegularExpression reg("^[A-Za-z0-9._-]+$"); + return !reg.match(name).hasMatch(); } inline void loadSettings(const QDomElement& element, const QString& name = QString("value")) override diff --git a/plugins/LadspaEffect/LadspaSubPluginFeatures.cpp b/plugins/LadspaEffect/LadspaSubPluginFeatures.cpp index 46a211f9f75..fc46671528a 100644 --- a/plugins/LadspaEffect/LadspaSubPluginFeatures.cpp +++ b/plugins/LadspaEffect/LadspaSubPluginFeatures.cpp @@ -171,8 +171,7 @@ ladspa_key_t LadspaSubPluginFeatures::subPluginKeyToLadspaKey( const Key * _key ) { QString file = _key->attributes["file"]; - return( ladspa_key_t( file.remove( QRegExp( "\\.so$" ) ). - remove( QRegExp( "\\.dll$" ) ) + + return(ladspa_key_t(file.remove(QRegularExpression("\\.so$")).remove(QRegularExpression("\\.dll$")) + #ifdef LMMS_BUILD_WIN32 ".dll" #else diff --git a/plugins/ZynAddSubFx/ZynAddSubFx.cpp b/plugins/ZynAddSubFx/ZynAddSubFx.cpp index be38bcb7978..01fa6400b79 100644 --- a/plugins/ZynAddSubFx/ZynAddSubFx.cpp +++ b/plugins/ZynAddSubFx/ZynAddSubFx.cpp @@ -311,7 +311,7 @@ void ZynAddSubFxInstrument::loadFile( const QString & _file ) m_pluginMutex.unlock(); } - instrumentTrack()->setName( QFileInfo( _file ).baseName().replace( QRegExp( "^[0-9]{4}-" ), QString() ) ); + instrumentTrack()->setName(QFileInfo(_file).baseName().replace(QRegularExpression("^[0-9]{4}-"), QString())); m_modifiedControllers.clear(); diff --git a/src/core/AutomatableModel.cpp b/src/core/AutomatableModel.cpp index e46a864f897..c701f28e36d 100644 --- a/src/core/AutomatableModel.cpp +++ b/src/core/AutomatableModel.cpp @@ -97,8 +97,8 @@ bool AutomatableModel::isAutomated() const bool AutomatableModel::mustQuoteName(const QString& name) { - QRegExp reg("^[A-Za-z0-9._-]+$"); - return !reg.exactMatch(name); + QRegularExpression reg("^[A-Za-z0-9._-]+$"); + return !reg.match(name).hasMatch(); } void AutomatableModel::saveSettings( QDomDocument& doc, QDomElement& element, const QString& name ) diff --git a/src/core/DataFile.cpp b/src/core/DataFile.cpp index a520e6bc5c9..3c6309db85f 100644 --- a/src/core/DataFile.cpp +++ b/src/core/DataFile.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include "base64.h" @@ -973,8 +974,7 @@ void DataFile::upgrade_0_4_0_20080622() { QDomElement el = list.item( i ).toElement(); QString s = el.attribute( "name" ); - s.replace( QRegExp( "^Beat/Baseline " ), - "Beat/Bassline " ); + s.replace(QRegularExpression("^Beat/Baseline "), "Beat/Bassline"); el.setAttribute( "name", s ); } } @@ -1109,7 +1109,7 @@ void DataFile::upgrade_1_1_91() { QDomElement el = list.item( i ).toElement(); QString s = el.attribute( "src" ); - s.replace( QRegExp("/samples/bassloopes/"), "/samples/bassloops/" ); + s.replace(QRegularExpression("/samples/bassloopes/"), "/samples/bassloops/"); el.setAttribute( "src", s ); } diff --git a/src/core/RenderManager.cpp b/src/core/RenderManager.cpp index 9f619203903..d375b95ee5a 100644 --- a/src/core/RenderManager.cpp +++ b/src/core/RenderManager.cpp @@ -23,6 +23,7 @@ */ #include +#include #include "RenderManager.h" @@ -182,7 +183,7 @@ QString RenderManager::pathForTrack(const Track *track, int num) { QString extension = ProjectRenderer::getFileExtensionFromFormat( m_format ); QString name = track->name(); - name = name.remove(QRegExp(FILENAME_FILTER)); + name = name.remove(QRegularExpression(FILENAME_FILTER)); name = QString( "%1_%2%3" ).arg( num ).arg( name ).arg( extension ); return QDir(m_outputPath).filePath(name); } diff --git a/src/gui/MicrotunerConfig.cpp b/src/gui/MicrotunerConfig.cpp index 4156b9e79df..6bb8415bd45 100644 --- a/src/gui/MicrotunerConfig.cpp +++ b/src/gui/MicrotunerConfig.cpp @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include "ComboBox.h" @@ -342,7 +342,7 @@ bool MicrotunerConfig::validateScaleForm() { if (line.isEmpty()) {continue;} if (line[0] == '!') {continue;} // comment - QString firstSection = line.section(QRegExp("\\s+|/"), 0, 0, QString::SectionSkipEmpty); + QString firstSection = line.section(QRegularExpression("\\s+|/"), 0, 0, QString::SectionSkipEmpty); if (firstSection.contains('.')) // cent mode { bool ok = true; @@ -357,7 +357,7 @@ bool MicrotunerConfig::validateScaleForm() if (!ok) {fail(tr("Numerator of an interval defined as a ratio cannot be converted to a number")); return false;} if (line.contains('/')) { - den = line.split('/').at(1).section(QRegExp("\\s+"), 0, 0, QString::SectionSkipEmpty).toInt(&ok); + den = line.split('/').at(1).section(QRegularExpression("\\s+"), 0, 0, QString::SectionSkipEmpty).toInt(&ok); } if (!ok) {fail(tr("Denominator of an interval defined as a ratio cannot be converted to a number")); return false;} if (num * den < 0) {fail(tr("Interval defined as a ratio cannot be negative")); return false;} @@ -390,7 +390,7 @@ bool MicrotunerConfig::validateKeymapForm() { if (line.isEmpty()) {continue;} if (line[0] == '!') {continue;} // comment - QString firstSection = line.section(QRegExp("\\s+"), 0, 0, QString::SectionSkipEmpty); + QString firstSection = line.section(QRegularExpression("\\s+"), 0, 0, QString::SectionSkipEmpty); if (firstSection == "x") {continue;} // not mapped // otherwise must contain a number bool ok = true; @@ -424,7 +424,7 @@ bool MicrotunerConfig::applyScale() { if (line.isEmpty()) {continue;} if (line[0] == '!') {continue;} // comment - QString firstSection = line.section(QRegExp("\\s+|/"), 0, 0, QString::SectionSkipEmpty); + QString firstSection = line.section(QRegularExpression("\\s+|/"), 0, 0, QString::SectionSkipEmpty); if (firstSection.contains('.')) // cent mode { newIntervals.emplace_back(firstSection.toFloat()); @@ -435,7 +435,7 @@ bool MicrotunerConfig::applyScale() num = firstSection.toInt(); if (line.contains('/')) { - den = line.split('/').at(1).section(QRegExp("\\s+"), 0, 0, QString::SectionSkipEmpty).toInt(); + den = line.split('/').at(1).section(QRegularExpression("\\s+"), 0, 0, QString::SectionSkipEmpty).toInt(); } newIntervals.emplace_back(num, den); } @@ -470,7 +470,7 @@ bool MicrotunerConfig::applyKeymap() { if (line.isEmpty()) {continue;} if (line[0] == '!') {continue;} // comment - QString firstSection = line.section(QRegExp("\\s+"), 0, 0, QString::SectionSkipEmpty); + QString firstSection = line.section(QRegularExpression("\\s+"), 0, 0, QString::SectionSkipEmpty); if (firstSection == "x") { newMap.push_back(-1); // not mapped diff --git a/src/gui/instrument/InstrumentTrackWindow.cpp b/src/gui/instrument/InstrumentTrackWindow.cpp index fa9be2a5055..a726dd5b989 100644 --- a/src/gui/instrument/InstrumentTrackWindow.cpp +++ b/src/gui/instrument/InstrumentTrackWindow.cpp @@ -420,7 +420,7 @@ void InstrumentTrackWindow::saveSettingsBtnClicked() sfd.setDirectory(presetRoot + m_track->instrumentName()); sfd.setFileMode( FileDialog::AnyFile ); QString fname = m_track->name(); - sfd.selectFile(fname.remove(QRegExp(FILENAME_FILTER))); + sfd.selectFile(fname.remove(QRegularExpression(FILENAME_FILTER))); sfd.setDefaultSuffix( "xpf"); if( sfd.exec() == QDialog::Accepted && diff --git a/src/gui/modals/EffectSelectDialog.cpp b/src/gui/modals/EffectSelectDialog.cpp index 4e6427e8144..65976059fca 100644 --- a/src/gui/modals/EffectSelectDialog.cpp +++ b/src/gui/modals/EffectSelectDialog.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -126,7 +127,12 @@ EffectSelectDialog::EffectSelectDialog(QWidget* parent) : m_filterEdit = new QLineEdit(this); connect(m_filterEdit, &QLineEdit::textChanged, this, [this](const QString &text) { +// TODO: Cleanup when we don't support Qt5 anymore +#if (QT_VERSION >= QT_VERSION_CHECK(5,12,0)) + m_model.setFilterRegularExpression(QRegularExpression(text, QRegularExpression::CaseInsensitiveOption)); +#else m_model.setFilterRegExp(QRegExp(text, Qt::CaseInsensitive)); +#endif }); connect(m_filterEdit, &QLineEdit::textChanged, this, &EffectSelectDialog::updateSelection); m_filterEdit->setFocus(); diff --git a/src/gui/modals/VersionedSaveDialog.cpp b/src/gui/modals/VersionedSaveDialog.cpp index 0c61df9f2ba..c8e1c682120 100644 --- a/src/gui/modals/VersionedSaveDialog.cpp +++ b/src/gui/modals/VersionedSaveDialog.cpp @@ -89,9 +89,9 @@ VersionedSaveDialog::VersionedSaveDialog( QWidget *parent, bool VersionedSaveDialog::changeFileNameVersion(QString &fileName, bool increment ) { - static QRegExp regexp( "[- ]\\d+(\\.\\w+)?$" ); + static QRegularExpression regex( "[- ]\\d+(\\.\\w+)?$" ); - int idx = regexp.indexIn( fileName ); + int idx = regex.match(fileName).capturedStart(); // For file names without extension (no ".mmpz") int insertIndex = fileName.lastIndexOf( '.' ); if ( insertIndex < idx+1 ) From af7431be994bdbb6e0a1edbc1ec6261bc47dddd3 Mon Sep 17 00:00:00 2001 From: TechnoPorg <69441745+TechnoPorg@users.noreply.github.com> Date: Sat, 16 Mar 2024 15:53:22 -0600 Subject: [PATCH 07/31] Add GitHub issue forms for bug reports and feature requests (#7102) --- .github/ISSUE_TEMPLATE/bug_report.md | 36 --------- .github/ISSUE_TEMPLATE/bug_report.yml | 90 ++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 18 ----- .github/ISSUE_TEMPLATE/feature_request.yml | 31 ++++++++ 4 files changed, 121 insertions(+), 54 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml delete mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index fcc87560172..00000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve -title: '' -labels: bug -assignees: '' - ---- - -# Please search the issue tracker for existing bug reports before submitting your own. Delete this line to confirm no similar report has been posted yet. - -### Bug Summary - -#### Steps to reproduce - -#### Expected behavior - -#### Actual behavior - -#### Screenshot - -#### Affected LMMS versions - - - -#### Logs -
- Click to expand -
-
-
-
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000000..4cd1464d67b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,90 @@ +# yamllint disable-file rule:line-length +name: Bug Report +description: File a bug report to help us improve +labels: + - bug +body: + - type: input + id: system-information + attributes: + label: System Information + description: | + - The operating system you use to run LMMS. + - When relevant, also include your hardware information. + placeholder: ex. Fedora Linux 39, KDE Plasma 5.27.10 - 13th Gen Intel® Core™ i9-13950HX, 32GB RAM + validations: + required: true + - type: input + id: affected-version + attributes: + label: LMMS Version(s) + description: | + - The version of LMMS affected by the bug. + - Can be an official version number, nightly release identifier, or commit hash. + - The version number can be found under the Help > About menu. + placeholder: ex. 1.2.2, 1.3.0-alpha.1.518+gdd53bec31, 2d185df + validations: + required: true + - type: input + id: working-version + attributes: + label: Most Recent Working Version + description: | + - If there is a previous version of LMMS that did not exhibit the bug, include it here. + placeholder: ex. 1.2.2, 1.3.0-alpha.1.518+gdd53bec31, 2d185df + validations: + required: false + - type: textarea + id: bug-summary + attributes: + label: Bug Summary + description: Briefly describe the bug. + validations: + required: true + - type: textarea + id: expected-behaviour + attributes: + label: Expected Behaviour + description: Describe what should have happened. + validations: + required: true + - type: textarea + id: steps-to-reproduce + attributes: + label: Steps To Reproduce + description: | + - Describe the minimum set of steps required to reproduce this bug. + - If you included a minimum reproducible project below, you can describe here how it should be used. + validations: + required: true + - type: textarea + id: logs + attributes: + label: Logs + description: | + - Copy and paste any relevant log output here. + value: | +
+ Click to expand +
+          
+        
+
+ validations: + required: false + - type: textarea + id: supporting-files + attributes: + label: Screenshots / Minimum Reproducible Project + description: | + - Upload any screenshots showing the bug in action. + - If possible, also include a .mmp/.mmpz project containing the simplest possible setup needed to reproduce the bug. + + ***Note:** To upload a project file to GitHub, it will need to be placed in a .zip archive.* + - type: checkboxes + id: search-for-existing + attributes: + label: Please search the issue tracker for existing bug reports before submitting your own. + options: + - label: I have searched all existing issues and confirmed that this is not a duplicate. + required: true diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index f9a0ae1928c..00000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: '' -labels: enhancement -assignees: '' - ---- - -# Please search the issue tracker for existing feature requests before submitting your own. Delete this line to confirm no similar request has been posted yet. - -### Enhancement Summary - -#### Justification - -#### Mockup - - diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 00000000000..1f11b4eb37c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,31 @@ +# yamllint disable-file rule:line-length +name: Feature Request +description: Suggest an idea for the project +labels: + - "enhancement" +body: + - type: textarea + id: enhancement-summary + attributes: + label: Enhancement Summary + description: | + - Briefly describe the enhancement. + - Explain why you believe the proposed enhancement to be a good idea, and (if applicable) how it helps overcome a limitation of LMMS you are currently facing. + validations: + required: true + - type: textarea + id: mockup + attributes: + label: Implementation Details / Mockup + description: | + - Explain how you believe this enhancement should be implemented. + - If your proposal encompasses changes to the user interface, include diagrams displaying your intent. + validations: + required: true + - type: checkboxes + id: search-for-existing + attributes: + label: Please search the issue tracker for existing feature requests before submitting your own. + options: + - label: I have searched all existing issues and confirmed that this is not a duplicate. + required: true From 3f5ac806e9c74048da6e2b0276ddc3581fdc575a Mon Sep 17 00:00:00 2001 From: Alexander Medvedev <71594357+Snowiiii@users.noreply.github.com> Date: Sun, 17 Mar 2024 00:53:40 +0100 Subject: [PATCH 08/31] Update jack2 (#7147) --- src/3rdparty/jack2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/3rdparty/jack2 b/src/3rdparty/jack2 index db76dd6bb87..ac334fabfb5 160000 --- a/src/3rdparty/jack2 +++ b/src/3rdparty/jack2 @@ -1 +1 @@ -Subproject commit db76dd6bb879a0a24d73ec41cc2e6a21bca8ee08 +Subproject commit ac334fabfb56989e9115ee6e2a77c1f6162d14fb From 3e19d1335f478504c22ed68af9c96fccd6a6774b Mon Sep 17 00:00:00 2001 From: Alexander Medvedev <71594357+Snowiiii@users.noreply.github.com> Date: Wed, 20 Mar 2024 18:43:41 +0100 Subject: [PATCH 09/31] Update carla (#7149) --- plugins/CarlaBase/carla | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/CarlaBase/carla b/plugins/CarlaBase/carla index 4ac8ff2ef41..66afe24a087 160000 --- a/plugins/CarlaBase/carla +++ b/plugins/CarlaBase/carla @@ -1 +1 @@ -Subproject commit 4ac8ff2ef412d4ab190d2e285e318b1f339af4ae +Subproject commit 66afe24a08790732cc17d81d4b846a1e0cfa0118 From 9ff63a5f5a49f445ee53afcb055adff447638b59 Mon Sep 17 00:00:00 2001 From: saker Date: Sun, 24 Mar 2024 18:05:15 -0400 Subject: [PATCH 10/31] Set mixer channel LCD when its index changes (#7160) --- src/gui/MixerChannelView.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/MixerChannelView.cpp b/src/gui/MixerChannelView.cpp index 928255806ce..e7d4fc5b37e 100644 --- a/src/gui/MixerChannelView.cpp +++ b/src/gui/MixerChannelView.cpp @@ -277,6 +277,7 @@ namespace lmms::gui m_muteButton->setModel(&mixerChannel->m_muteModel); m_soloButton->setModel(&mixerChannel->m_soloModel); m_effectRackView->setModel(&mixerChannel->m_fxChain); + m_channelNumberLcd->setValue(index); m_channelIndex = index; } From c2fdb8cfd20957bc4f6a9078b647574e24f72257 Mon Sep 17 00:00:00 2001 From: Kevin Zander Date: Mon, 25 Mar 2024 18:22:37 -0500 Subject: [PATCH 11/31] Move confirmation to remove mixer channels outside `MixerView::deleteChannel` #7154) Moves the confirmation to remove mixer channels outside of `MixerView::deleteChannel` and into `MixerChannelView::removeChannel`. This is so that the confirmation only applies when the user uses the context menu to remove a channel, which is important since no confirmation should apply when, for example, the mixer view is cleared with calls to `MixerView::clear`. --- include/MixerChannelView.h | 1 + include/MixerView.h | 1 - src/gui/MixerChannelView.cpp | 39 ++++++++++++++++++++++++++++ src/gui/MixerView.cpp | 49 ------------------------------------ 4 files changed, 40 insertions(+), 50 deletions(-) diff --git a/include/MixerChannelView.h b/include/MixerChannelView.h index 1710623d780..cbaf0ccc6b4 100644 --- a/include/MixerChannelView.h +++ b/include/MixerChannelView.h @@ -104,6 +104,7 @@ namespace lmms::gui void moveChannelRight(); private: + bool confirmRemoval(int index); QString elideName(const QString& name); MixerChannel* mixerChannel() const; auto isMasterChannel() const -> bool { return m_channelIndex == 0; } diff --git a/include/MixerView.h b/include/MixerView.h index 81287bc547f..89315f93ab7 100644 --- a/include/MixerView.h +++ b/include/MixerView.h @@ -78,7 +78,6 @@ class LMMS_EXPORT MixerView : public QWidget, public ModelView, // notify the view that a mixer channel was deleted void deleteChannel(int index); - bool confirmRemoval(int index); // delete all unused channels void deleteUnusedChannels(); diff --git a/src/gui/MixerChannelView.cpp b/src/gui/MixerChannelView.cpp index e7d4fc5b37e..bd518093b4c 100644 --- a/src/gui/MixerChannelView.cpp +++ b/src/gui/MixerChannelView.cpp @@ -29,6 +29,7 @@ #include "MixerChannelView.h" #include "MixerView.h" #include "Song.h" +#include "ConfigManager.h" #include "gui_templates.h" #include "lmms_math.h" @@ -38,6 +39,8 @@ #include #include #include +#include +#include #include @@ -412,8 +415,44 @@ namespace lmms::gui update(); } + bool MixerChannelView::confirmRemoval(int index) + { + // if config variable is set to false, there is no need for user confirmation + bool needConfirm = ConfigManager::inst()->value("ui", "mixerchanneldeletionwarning", "1").toInt(); + if (!needConfirm) { return true; } + + // is the channel is not in use, there is no need for user confirmation + if (!getGUI()->mixerView()->getMixer()->isChannelInUse(index)) { return true; } + + QString messageRemoveTrack = tr("This Mixer Channel is being used.\n" + "Are you sure you want to remove this channel?\n\n" + "Warning: This operation can not be undone."); + + QString messageTitleRemoveTrack = tr("Confirm removal"); + QString askAgainText = tr("Don't ask again"); + auto askAgainCheckBox = new QCheckBox(askAgainText, nullptr); + connect(askAgainCheckBox, &QCheckBox::stateChanged, [](int state) { + // Invert button state, if it's checked we *shouldn't* ask again + ConfigManager::inst()->setValue("ui", "mixerchanneldeletionwarning", state ? "0" : "1"); + }); + + QMessageBox mb(this); + mb.setText(messageRemoveTrack); + mb.setWindowTitle(messageTitleRemoveTrack); + mb.setIcon(QMessageBox::Warning); + mb.addButton(QMessageBox::Cancel); + mb.addButton(QMessageBox::Ok); + mb.setCheckBox(askAgainCheckBox); + mb.setDefaultButton(QMessageBox::Cancel); + + int answer = mb.exec(); + + return answer == QMessageBox::Ok; + } + void MixerChannelView::removeChannel() { + if (!confirmRemoval(m_channelIndex)) { return; } auto mix = getGUI()->mixerView(); mix->deleteChannel(m_channelIndex); } diff --git a/src/gui/MixerView.cpp b/src/gui/MixerView.cpp index 8b2ecdc5672..e97b5414fd7 100644 --- a/src/gui/MixerView.cpp +++ b/src/gui/MixerView.cpp @@ -23,9 +23,7 @@ */ -#include #include -#include #include #include #include @@ -377,12 +375,6 @@ void MixerView::deleteChannel(int index) // can't delete master if (index == 0) return; - // if there is no user confirmation, do nothing - if (!confirmRemoval(index)) - { - return; - } - // Disconnect from the solo/mute models of the channel we are about to delete disconnectFromSoloAndMute(index); @@ -421,47 +413,6 @@ void MixerView::deleteChannel(int index) updateMaxChannelSelector(); } -bool MixerView::confirmRemoval(int index) -{ - // if config variable is set to false, there is no need for user confirmation - bool needConfirm = ConfigManager::inst()->value("ui", "mixerchanneldeletionwarning", "1").toInt(); - if (!needConfirm) { return true; } - - Mixer* mix = getMixer(); - - if (!mix->isChannelInUse(index)) - { - // is the channel is not in use, there is no need for user confirmation - return true; - } - - QString messageRemoveTrack = tr("This Mixer Channel is being used.\n" - "Are you sure you want to remove this channel?\n\n" - "Warning: This operation can not be undone."); - - QString messageTitleRemoveTrack = tr("Confirm removal"); - QString askAgainText = tr("Don't ask again"); - auto askAgainCheckBox = new QCheckBox(askAgainText, nullptr); - connect(askAgainCheckBox, &QCheckBox::stateChanged, [](int state) { - // Invert button state, if it's checked we *shouldn't* ask again - ConfigManager::inst()->setValue("ui", "mixerchanneldeletionwarning", state ? "0" : "1"); - }); - - QMessageBox mb(this); - mb.setText(messageRemoveTrack); - mb.setWindowTitle(messageTitleRemoveTrack); - mb.setIcon(QMessageBox::Warning); - mb.addButton(QMessageBox::Cancel); - mb.addButton(QMessageBox::Ok); - mb.setCheckBox(askAgainCheckBox); - mb.setDefaultButton(QMessageBox::Cancel); - - int answer = mb.exec(); - - return answer == QMessageBox::Ok; -} - - void MixerView::deleteUnusedChannels() { Mixer* mix = getMixer(); From 0e1eb712d834c12f20fe6e959a1561209c5d0efe Mon Sep 17 00:00:00 2001 From: Lassi <57831590+87x@users.noreply.github.com> Date: Tue, 26 Mar 2024 16:16:47 +0200 Subject: [PATCH 12/31] Bump project year (#7167) --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e45db03e475..d10a62d1040 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,7 +46,7 @@ INCLUDE(GenerateExportHeader) STRING(TOUPPER "${CMAKE_PROJECT_NAME}" PROJECT_NAME_UCASE) -SET(PROJECT_YEAR 2023) +SET(PROJECT_YEAR 2024) SET(PROJECT_AUTHOR "LMMS Developers") SET(PROJECT_URL "https://lmms.io") From 66081ba1b1924b45aff1a6ab07336d463360224d Mon Sep 17 00:00:00 2001 From: Alexander Medvedev <71594357+Snowiiii@users.noreply.github.com> Date: Tue, 26 Mar 2024 15:49:13 +0100 Subject: [PATCH 13/31] CMake: Replace EXEC_PROGRAM with execute_process (#7166) * CMake: Replace EXEC_PROGRAM with execute_process exec_program is Deprecated since version 3.0: Use the execute_process() command instead. --- cmake/modules/DetectMachine.cmake | 2 +- cmake/modules/FindWine.cmake | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/modules/DetectMachine.cmake b/cmake/modules/DetectMachine.cmake index 388efeb820c..65bc6d2b7e8 100644 --- a/cmake/modules/DetectMachine.cmake +++ b/cmake/modules/DetectMachine.cmake @@ -92,7 +92,7 @@ IF(WIN32) endif() ELSE() # Detect target architecture based on compiler target triple e.g. "x86_64-pc-linux" - EXEC_PROGRAM( ${CMAKE_C_COMPILER} ARGS "-dumpmachine ${CMAKE_C_FLAGS}" OUTPUT_VARIABLE Machine ) + execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpmachine ${CMAKE_C_FLAGS} OUTPUT_VARIABLE Machine) MESSAGE("Machine: ${Machine}") STRING(REGEX MATCH "i.86" IS_X86 "${Machine}") STRING(REGEX MATCH "86_64|amd64" IS_X86_64 "${Machine}") diff --git a/cmake/modules/FindWine.cmake b/cmake/modules/FindWine.cmake index 024dac1ea50..aabb5ef78b5 100644 --- a/cmake/modules/FindWine.cmake +++ b/cmake/modules/FindWine.cmake @@ -32,8 +32,8 @@ FIND_PROGRAM(WINE_CXX FIND_PROGRAM(WINE_BUILD NAMES winebuild) # Detect wine paths and handle linking problems IF(WINE_CXX) - EXEC_PROGRAM(${WINE_CXX} ARGS "-m32 -v /dev/zero" OUTPUT_VARIABLE WINEBUILD_OUTPUT_32) - EXEC_PROGRAM(${WINE_CXX} ARGS "-m64 -v /dev/zero" OUTPUT_VARIABLE WINEBUILD_OUTPUT_64) + execute_process(COMMAND ${WINE_CXX} -m32 -v /dev/zero OUTPUT_VARIABLE WINEBUILD_OUTPUT_32) + execute_process(COMMAND ${WINE_CXX} -m64 -v /dev/zero OUTPUT_VARIABLE WINEBUILD_OUTPUT_64) _findwine_find_flags("${WINEBUILD_OUTPUT_32}" "^-isystem/usr/include$" BUGGED_WINEGCC) _findwine_find_flags("${WINEBUILD_OUTPUT_32}" "^-isystem" WINEGCC_INCLUDE_DIR) _findwine_find_flags("${WINEBUILD_OUTPUT_32}" "libwinecrt0\\.a.*" WINECRT_32) From 45fd3267879b93d4972c6c28cf7e5e7007b4324e Mon Sep 17 00:00:00 2001 From: Lost Robot <34612565+LostRobotMusic@users.noreply.github.com> Date: Tue, 26 Mar 2024 09:10:26 -0700 Subject: [PATCH 14/31] Make Compressor background themeable (#7157) --- data/themes/classic/style.css | 1 + data/themes/default/style.css | 1 + .../Compressor/CompressorControlDialog.cpp | 20 +++--------------- plugins/Compressor/CompressorControlDialog.h | 2 ++ plugins/Compressor/artwork.png | Bin 1405 -> 0 bytes 5 files changed, 7 insertions(+), 17 deletions(-) delete mode 100755 plugins/Compressor/artwork.png diff --git a/data/themes/classic/style.css b/data/themes/classic/style.css index f61d4ba580c..2398c541e13 100644 --- a/data/themes/classic/style.css +++ b/data/themes/classic/style.css @@ -996,6 +996,7 @@ lmms--gui--CompressorControlDialog { qproperty-textColor: rgba(209, 216, 228, 50); qproperty-graphColor: rgba(209, 216, 228, 50); qproperty-resetColor: rgba(200, 100, 15, 200); + qproperty-backgroundColor: rgba(7, 8, 9, 255); } lmms--gui--CompressorControlDialog lmms--gui--Knob { diff --git a/data/themes/default/style.css b/data/themes/default/style.css index e1f0cf395b7..a0d20234742 100644 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -1038,6 +1038,7 @@ lmms--gui--CompressorControlDialog { qproperty-textColor: rgba(209, 216, 228, 50); qproperty-graphColor: rgba(209, 216, 228, 50); qproperty-resetColor: rgba(200, 100, 15, 200); + qproperty-backgroundColor: rgba(7, 8, 9, 255); } lmms--gui--CompressorControlDialog lmms--gui--Knob { diff --git a/plugins/Compressor/CompressorControlDialog.cpp b/plugins/Compressor/CompressorControlDialog.cpp index ab81c84ec2d..d7350ba5966 100755 --- a/plugins/Compressor/CompressorControlDialog.cpp +++ b/plugins/Compressor/CompressorControlDialog.cpp @@ -45,26 +45,12 @@ namespace lmms::gui CompressorControlDialog::CompressorControlDialog(CompressorControls* controls) : EffectControlDialog(controls), - m_controls(controls), - m_inVolAreaColor(209, 216, 228, 17), - m_inVolColor(209, 216, 228, 100), - m_outVolAreaColor(209, 216, 228, 30), - m_outVolColor(209, 216, 228, 240), - m_gainReductionColor(180, 100, 100, 210), - m_kneeColor(39, 171, 95, 255), - m_kneeColor2(9, 171, 160, 255), - m_threshColor(39, 171, 95, 100), - m_textColor(209, 216, 228, 50), - m_graphColor(209, 216, 228, 50), - m_resetColor(200, 100, 15, 200) + m_controls(controls) { setAutoFillBackground(false); setAttribute(Qt::WA_OpaquePaintEvent, true); setAttribute(Qt::WA_NoSystemBackground, true); - QPalette pal; - pal.setBrush(backgroundRole(), PLUGIN_NAME::getIconPixmap("artwork")); - setPalette(pal); setMinimumSize(MIN_COMP_SCREEN_X, MIN_COMP_SCREEN_Y); resize(COMP_SCREEN_X, COMP_SCREEN_Y); @@ -615,7 +601,7 @@ void CompressorControlDialog::paintEvent(QPaintEvent *event) m_p.begin(this); m_p.setCompositionMode(QPainter::CompositionMode_Source); - m_p.fillRect(0, 0, m_windowSizeX, m_windowSizeY, QColor("transparent")); + m_p.fillRect(0, 0, m_windowSizeX, m_windowSizeY, m_backgroundColor); m_p.setCompositionMode(QPainter::CompositionMode_SourceOver); m_p.drawPixmap(0, 0, m_graphPixmap); @@ -683,7 +669,7 @@ void CompressorControlDialog::drawGraph() // Redraw graph m_p.setPen(QPen(m_graphColor, 1)); - for (int i = 1; i < m_dbRange / COMP_GRID_SPACING + 1; ++i) + for (int i = 0; i < m_dbRange / COMP_GRID_SPACING + 1; ++i) { m_p.drawLine(0, dbfsToYPoint(-COMP_GRID_SPACING * i), m_windowSizeX, dbfsToYPoint(-COMP_GRID_SPACING * i)); m_p.drawLine(dbfsToXPoint(-COMP_GRID_SPACING * i), 0, dbfsToXPoint(-COMP_GRID_SPACING * i), m_kneeWindowSizeY); diff --git a/plugins/Compressor/CompressorControlDialog.h b/plugins/Compressor/CompressorControlDialog.h index a61482ad89b..cedba4b04cc 100755 --- a/plugins/Compressor/CompressorControlDialog.h +++ b/plugins/Compressor/CompressorControlDialog.h @@ -86,6 +86,7 @@ class CompressorControlDialog : public EffectControlDialog Q_PROPERTY(QColor textColor MEMBER m_textColor) Q_PROPERTY(QColor graphColor MEMBER m_graphColor) Q_PROPERTY(QColor resetColor MEMBER m_resetColor) + Q_PROPERTY(QColor backgroundColor MEMBER m_backgroundColor) protected: void resizeEvent(QResizeEvent *event) override; @@ -150,6 +151,7 @@ private slots: QColor m_textColor = QColor(209, 216, 228, 50); QColor m_graphColor = QColor(209, 216, 228, 50); QColor m_resetColor = QColor(200, 100, 15, 200); + QColor m_backgroundColor = QColor(7, 8, 9, 255); float m_peakAvg; float m_gainAvg; diff --git a/plugins/Compressor/artwork.png b/plugins/Compressor/artwork.png deleted file mode 100755 index 8f94e3d494b7e7577ec5c34ac46d894c54a0945e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1405 zcmeAS@N?(olHy`uVBq!ia0y~yV7kD-z$n4N1{5h}Id}s|u_bxCyDx` z7I;J!Gca%qgD@k*tT_@uLG}_)Usv`gECNgtBK3D?DFTHQGD9Ltobz*YQ}arITn2`K z{PNVI)D(rJN(FbnP<@}wywZv}fz96-7+CIkx;TbZ+P>{iZgJEM3=Udr-bDLPr zrnwyQmw%rw%fOKE#0zK!n-l{Bj|l^VL&e}4icrB&`CR}2 From a41da8155402092277449ca256721a05b5aa62d4 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Tue, 26 Mar 2024 20:19:52 +0100 Subject: [PATCH 15/31] Enable different colors for oscilloscope channels (#7155) Enable to set different colors for the oscilloscope channels: * Left channel color * Right channel color * Color of all other channels The clipping color is now used per channel, i.e. if the left channel clips but the right does not then only the signal of the left channel is painted in the clipping color. Enable setting the colors in the style sheets and adjust the style sheets of the default and classic theme accordingly. --- data/themes/classic/style.css | 4 ++- data/themes/default/style.css | 4 ++- include/Oscilloscope.h | 20 +++++++++--- src/gui/widgets/Oscilloscope.cpp | 56 +++++++++++++++++++++----------- 4 files changed, 58 insertions(+), 26 deletions(-) diff --git a/data/themes/classic/style.css b/data/themes/classic/style.css index 2398c541e13..08a04f01df7 100644 --- a/data/themes/classic/style.css +++ b/data/themes/classic/style.css @@ -203,7 +203,9 @@ lmms--gui--GroupBox { lmms--gui--Oscilloscope { background: none; border: none; - qproperty-normalColor: rgb(71, 253, 133); + qproperty-leftChannelColor: rgb(71, 253, 133); + qproperty-rightChannelColor: rgb(238, 253, 71); + qproperty-otherChannelsColor: rgb(71, 235, 253); qproperty-clippingColor: rgb(255, 64, 64); } diff --git a/data/themes/default/style.css b/data/themes/default/style.css index a0d20234742..89c14f20a2a 100644 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -234,7 +234,9 @@ lmms--gui--GroupBox { lmms--gui--Oscilloscope { background: none; border: none; - qproperty-normalColor: rgb(71, 253, 133); + qproperty-leftChannelColor: rgb(71, 253, 133); + qproperty-rightChannelColor: rgb(238, 253, 71); + qproperty-otherChannelsColor: rgb(71, 235, 253); qproperty-clippingColor: rgb(255, 64, 64); } diff --git a/include/Oscilloscope.h b/include/Oscilloscope.h index 209370ce034..13c946aa512 100644 --- a/include/Oscilloscope.h +++ b/include/Oscilloscope.h @@ -38,7 +38,9 @@ class Oscilloscope : public QWidget { Q_OBJECT public: - Q_PROPERTY( QColor normalColor READ normalColor WRITE setNormalColor ) + Q_PROPERTY( QColor leftChannelColor READ leftChannelColor WRITE setLeftChannelColor ) + Q_PROPERTY( QColor rightChannelColor READ rightChannelColor WRITE setRightChannelColor ) + Q_PROPERTY( QColor otherChannelsColor READ otherChannelsColor WRITE setOtherChannelsColor ) Q_PROPERTY( QColor clippingColor READ clippingColor WRITE setClippingColor ) Oscilloscope( QWidget * _parent ); @@ -46,8 +48,14 @@ class Oscilloscope : public QWidget void setActive( bool _active ); - QColor const & normalColor() const; - void setNormalColor(QColor const & normalColor); + QColor const & leftChannelColor() const; + void setLeftChannelColor(QColor const & leftChannelColor); + + QColor const & rightChannelColor() const; + void setRightChannelColor(QColor const & rightChannelColor); + + QColor const & otherChannelsColor() const; + void setOtherChannelsColor(QColor const & otherChannelsColor); QColor const & clippingColor() const; void setClippingColor(QColor const & clippingColor); @@ -62,7 +70,7 @@ protected slots: void updateAudioBuffer( const lmms::surroundSampleFrame * buffer ); private: - QColor const & determineLineColor(float level) const; + bool clips(float level) const; private: QPixmap m_background; @@ -71,7 +79,9 @@ protected slots: sampleFrame * m_buffer; bool m_active; - QColor m_normalColor; + QColor m_leftChannelColor; + QColor m_rightChannelColor; + QColor m_otherChannelsColor; QColor m_clippingColor; } ; diff --git a/src/gui/widgets/Oscilloscope.cpp b/src/gui/widgets/Oscilloscope.cpp index a689f53f367..f426e1b1987 100644 --- a/src/gui/widgets/Oscilloscope.cpp +++ b/src/gui/widgets/Oscilloscope.cpp @@ -45,7 +45,9 @@ Oscilloscope::Oscilloscope( QWidget * _p ) : m_background( embed::getIconPixmap( "output_graph" ) ), m_points( new QPointF[Engine::audioEngine()->framesPerPeriod()] ), m_active( false ), - m_normalColor(71, 253, 133), + m_leftChannelColor(71, 253, 133), + m_rightChannelColor(71, 253, 133), + m_otherChannelsColor(71, 253, 133), m_clippingColor(255, 64, 64) { setFixedSize( m_background.width(), m_background.height() ); @@ -112,14 +114,34 @@ void Oscilloscope::setActive( bool _active ) } -QColor const & Oscilloscope::normalColor() const +QColor const & Oscilloscope::leftChannelColor() const { - return m_normalColor; + return m_leftChannelColor; } -void Oscilloscope::setNormalColor(QColor const & normalColor) +void Oscilloscope::setLeftChannelColor(QColor const & leftChannelColor) { - m_normalColor = normalColor; + m_leftChannelColor = leftChannelColor; +} + +QColor const & Oscilloscope::rightChannelColor() const +{ + return m_rightChannelColor; +} + +void Oscilloscope::setRightChannelColor(QColor const & rightChannelColor) +{ + m_rightChannelColor = rightChannelColor; +} + +QColor const & Oscilloscope::otherChannelsColor() const +{ + return m_otherChannelsColor; +} + +void Oscilloscope::setOtherChannelsColor(QColor const & otherChannelsColor) +{ + m_otherChannelsColor = otherChannelsColor; } QColor const & Oscilloscope::clippingColor() const @@ -147,11 +169,9 @@ void Oscilloscope::paintEvent( QPaintEvent * ) const fpp_t frames = audioEngine->framesPerPeriod(); AudioEngine::StereoSample peakValues = audioEngine->getPeakValues(m_buffer, frames); - const float max_level = qMax( peakValues.left, peakValues.right ); - // Set the color of the line according to the maximum level - float const maxLevelWithAppliedMasterGain = max_level * masterOutput; - p.setPen(QPen(determineLineColor(maxLevelWithAppliedMasterGain), 0.7)); + auto const leftChannelClips = clips(peakValues.left * masterOutput); + auto const rightChannelClips = clips(peakValues.right * masterOutput); p.setRenderHint( QPainter::Antialiasing ); @@ -162,8 +182,14 @@ void Oscilloscope::paintEvent( QPaintEvent * ) int x_base = 2; const qreal y_base = height() / 2 - 0.5; + qreal const width = 0.7; for( ch_cnt_t ch = 0; ch < DEFAULT_CHANNELS; ++ch ) { + QColor color = ch == 0 ? (leftChannelClips ? clippingColor() : leftChannelColor()) : // Check left channel + ch == 1 ? (rightChannelClips ? clippingColor() : rightChannelColor()) : // Check right channel + otherChannelsColor(); // Any other channel + p.setPen(QPen(color, width)); + for( int frame = 0; frame < frames; ++frame ) { sample_t const clippedSample = AudioEngine::clip(m_buffer[frame][ch]); @@ -193,17 +219,9 @@ void Oscilloscope::mousePressEvent( QMouseEvent * _me ) } } - -QColor const & Oscilloscope::determineLineColor(float level) const +bool Oscilloscope::clips(float level) const { - if( level <= 1.0f ) - { - return normalColor(); - } - else - { - return clippingColor(); - } + return level > 1.0f; } From 286d15724aa701641e94005ab456d28f6f0b084a Mon Sep 17 00:00:00 2001 From: Rossmaxx <74815851+Rossmaxx@users.noreply.github.com> Date: Wed, 27 Mar 2024 18:29:27 +0530 Subject: [PATCH 16/31] Refactor `gui_templates.h` (#7159) * remove the gui_templates header where functions not used * refactor and replace template with function argument * refactor: merge pointSizeF function with pointSize * removed template per michael's review * use std::max for more readability * remove the QDesktopWidget header * cleanup arguments and remove parentheses from return --- include/gui_templates.h | 42 +++++++------------ .../AudioFileProcessorView.cpp | 4 +- .../AudioFileProcessorWaveView.cpp | 2 +- plugins/CarlaBase/Carla.cpp | 4 +- .../DualFilter/DualFilterControlDialog.cpp | 4 +- plugins/LadspaBrowser/LadspaBrowser.cpp | 2 +- plugins/Monstro/Monstro.cpp | 10 ++--- plugins/Patman/Patman.cpp | 4 +- plugins/Stk/Mallets/Mallets.cpp | 2 +- plugins/Vestige/Vestige.cpp | 8 ++-- plugins/VstEffect/VstEffectControlDialog.cpp | 2 +- plugins/ZynAddSubFx/ZynAddSubFx.cpp | 2 +- src/core/audio/AudioJack.cpp | 1 - src/core/audio/AudioOss.cpp | 1 - src/core/audio/AudioPortAudio.cpp | 1 - src/core/audio/AudioPulseAudio.cpp | 1 - src/core/audio/AudioSdl.cpp | 1 - src/core/audio/AudioSndio.cpp | 1 - src/core/audio/AudioSoundIo.cpp | 1 - src/gui/AudioAlsaSetupWidget.cpp | 1 - src/gui/EffectView.cpp | 4 +- src/gui/Lv2ViewBase.cpp | 3 +- src/gui/MidiSetupWidget.cpp | 1 - src/gui/MixerChannelView.cpp | 2 +- src/gui/SampleTrackWindow.cpp | 1 - src/gui/editors/AutomationEditor.cpp | 4 +- src/gui/editors/PianoRoll.cpp | 4 +- src/gui/instrument/EnvelopeAndLfoView.cpp | 6 +-- .../instrument/InstrumentFunctionViews.cpp | 8 ++-- src/gui/instrument/InstrumentMidiIOView.cpp | 2 +- .../instrument/InstrumentSoundShapingView.cpp | 4 +- src/gui/instrument/InstrumentTrackWindow.cpp | 2 +- src/gui/instrument/InstrumentTuningView.cpp | 2 +- src/gui/instrument/PianoView.cpp | 2 +- src/gui/menus/MidiPortMenu.cpp | 1 - src/gui/modals/SetupDialog.cpp | 1 - src/gui/tracks/TrackOperationsWidget.cpp | 1 - src/gui/widgets/ComboBox.cpp | 2 +- src/gui/widgets/GroupBox.cpp | 2 +- src/gui/widgets/Knob.cpp | 6 +-- src/gui/widgets/LcdFloatSpinBox.cpp | 2 +- src/gui/widgets/LcdWidget.cpp | 4 +- src/gui/widgets/LedCheckBox.cpp | 7 +--- src/gui/widgets/MeterDialog.cpp | 4 +- src/gui/widgets/Oscilloscope.cpp | 2 +- src/gui/widgets/TabBar.cpp | 2 +- src/gui/widgets/TabWidget.cpp | 8 ++-- 47 files changed, 76 insertions(+), 105 deletions(-) diff --git a/include/gui_templates.h b/include/gui_templates.h index c0afbdfc0bb..4833c6cdf1a 100644 --- a/include/gui_templates.h +++ b/include/gui_templates.h @@ -27,45 +27,33 @@ #include "lmmsconfig.h" +#include #include #include -#include +#include -namespace lmms +// TODO: remove once qt5 support is dropped +#if (QT_VERSION < QT_VERSION_CHECK(6,0,0)) + #include +#endif + +namespace lmms::gui { // return DPI-independent font-size - font with returned font-size has always // the same size in pixels -template -inline QFont pointSize( QFont _f ) +inline QFont pointSize(QFont fontPointer, float fontSize) { - static const float DPI = 96; -#ifdef LMMS_BUILD_WIN32 - _f.setPointSizeF( ((float) SIZE+0.5f) * DPI / - QApplication::desktop()->logicalDpiY() ); -#else - _f.setPointSizeF( (float) SIZE * DPI / - QApplication::desktop()->logicalDpiY() ); -#endif - return( _f ); -} + // to calculate DPI of a screen to make it HiDPI ready + qreal devicePixelRatio = QGuiApplication::primaryScreen()->devicePixelRatio(); + qreal scaleFactor = std::max(devicePixelRatio, 1.0); // Ensure scaleFactor is at least 1.0 - -inline QFont pointSizeF( QFont _f, float SIZE ) -{ - static const float DPI = 96; -#ifdef LMMS_BUILD_WIN32 - _f.setPointSizeF( (SIZE+0.5f) * DPI / - QApplication::desktop()->logicalDpiY() ); -#else - _f.setPointSizeF( SIZE * DPI / - QApplication::desktop()->logicalDpiY() ); -#endif - return( _f ); + fontPointer.setPointSizeF(fontSize * scaleFactor); + return fontPointer; } -} // namespace lmms +} // namespace lmms::gui #endif // LMMS_GUI_TEMPLATES_H diff --git a/plugins/AudioFileProcessor/AudioFileProcessorView.cpp b/plugins/AudioFileProcessor/AudioFileProcessorView.cpp index d16b1d019a1..94f0da4fb67 100644 --- a/plugins/AudioFileProcessor/AudioFileProcessorView.cpp +++ b/plugins/AudioFileProcessor/AudioFileProcessorView.cpp @@ -134,7 +134,7 @@ AudioFileProcessorView::AudioFileProcessorView(Instrument* instrument, // interpolation selector m_interpBox = new ComboBox(this); m_interpBox->setGeometry(142, 62, 82, ComboBox::DEFAULT_HEIGHT); - m_interpBox->setFont(pointSize<8>(m_interpBox->font())); + m_interpBox->setFont(pointSize(m_interpBox->font(), 8)); // wavegraph m_waveView = 0; @@ -228,7 +228,7 @@ void AudioFileProcessorView::paintEvent(QPaintEvent*) int idx = a->sample().sampleFile().length(); - p.setFont(pointSize<8>(font())); + p.setFont(pointSize(font(), 8)); QFontMetrics fm(p.font()); diff --git a/plugins/AudioFileProcessor/AudioFileProcessorWaveView.cpp b/plugins/AudioFileProcessor/AudioFileProcessorWaveView.cpp index 507c4e7c0ee..818fb14cb6c 100644 --- a/plugins/AudioFileProcessor/AudioFileProcessorWaveView.cpp +++ b/plugins/AudioFileProcessor/AudioFileProcessorWaveView.cpp @@ -273,7 +273,7 @@ void AudioFileProcessorWaveView::paintEvent(QPaintEvent * pe) p.fillRect(s_padding, s_padding, m_graph.width(), 14, g); p.setPen(QColor(255, 255, 255)); - p.setFont(pointSize<8>(font())); + p.setFont(pointSize(font(), 8)); QString length_text; const int length = m_sample->sampleDuration().count(); diff --git a/plugins/CarlaBase/Carla.cpp b/plugins/CarlaBase/Carla.cpp index 819736e928b..e58cb14af79 100644 --- a/plugins/CarlaBase/Carla.cpp +++ b/plugins/CarlaBase/Carla.cpp @@ -632,7 +632,7 @@ CarlaInstrumentView::CarlaInstrumentView(CarlaInstrument* const instrument, QWid m_toggleUIButton->setCheckable( true ); m_toggleUIButton->setChecked( false ); m_toggleUIButton->setIcon( embed::getIconPixmap( "zoom" ) ); - m_toggleUIButton->setFont( pointSize<8>( m_toggleUIButton->font() ) ); + m_toggleUIButton->setFont(pointSize(m_toggleUIButton->font(), 8)); connect( m_toggleUIButton, SIGNAL( clicked(bool) ), this, SLOT( toggleUI( bool ) ) ); m_toggleUIButton->setToolTip( @@ -642,7 +642,7 @@ CarlaInstrumentView::CarlaInstrumentView(CarlaInstrument* const instrument, QWid m_toggleParamsWindowButton = new QPushButton(tr("Params"), this); m_toggleParamsWindowButton->setIcon(embed::getIconPixmap("controller")); m_toggleParamsWindowButton->setCheckable(true); - m_toggleParamsWindowButton->setFont(pointSize<8>(m_toggleParamsWindowButton->font())); + m_toggleParamsWindowButton->setFont(pointSize(m_toggleParamsWindowButton->font(), 8)); #if CARLA_VERSION_HEX < CARLA_MIN_PARAM_VERSION m_toggleParamsWindowButton->setEnabled(false); m_toggleParamsWindowButton->setToolTip(tr("Available from Carla version 2.1 and up.")); diff --git a/plugins/DualFilter/DualFilterControlDialog.cpp b/plugins/DualFilter/DualFilterControlDialog.cpp index d316e337213..5a912ac8551 100644 --- a/plugins/DualFilter/DualFilterControlDialog.cpp +++ b/plugins/DualFilter/DualFilterControlDialog.cpp @@ -76,12 +76,12 @@ DualFilterControlDialog::DualFilterControlDialog( DualFilterControls* controls ) auto m_filter1ComboBox = new ComboBox(this); m_filter1ComboBox->setGeometry( 19, 70, 137, ComboBox::DEFAULT_HEIGHT ); - m_filter1ComboBox->setFont( pointSize<8>( m_filter1ComboBox->font() ) ); + m_filter1ComboBox->setFont(pointSize(m_filter1ComboBox->font(), 8)); m_filter1ComboBox->setModel( &controls->m_filter1Model ); auto m_filter2ComboBox = new ComboBox(this); m_filter2ComboBox->setGeometry( 217, 70, 137, ComboBox::DEFAULT_HEIGHT ); - m_filter2ComboBox->setFont( pointSize<8>( m_filter2ComboBox->font() ) ); + m_filter2ComboBox->setFont(pointSize(m_filter2ComboBox->font(), 8)); m_filter2ComboBox->setModel( &controls->m_filter2Model ); } diff --git a/plugins/LadspaBrowser/LadspaBrowser.cpp b/plugins/LadspaBrowser/LadspaBrowser.cpp index 31be6405649..54d019aad32 100644 --- a/plugins/LadspaBrowser/LadspaBrowser.cpp +++ b/plugins/LadspaBrowser/LadspaBrowser.cpp @@ -172,7 +172,7 @@ QWidget * LadspaBrowserView::createTab( QWidget * _parent, const QString & _txt, auto title = new QLabel(type + _txt, tab); QFont f = title->font(); f.setBold( true ); - title->setFont( pointSize<12>( f ) ); + title->setFont(pointSize(f, 12)); layout->addSpacing( 5 ); layout->addWidget( title ); diff --git a/plugins/Monstro/Monstro.cpp b/plugins/Monstro/Monstro.cpp index 9563f756d3c..76ab6e47790 100644 --- a/plugins/Monstro/Monstro.cpp +++ b/plugins/Monstro/Monstro.cpp @@ -1694,7 +1694,7 @@ QWidget * MonstroView::setupOperatorsView( QWidget * _parent ) m_osc2WaveBox = new ComboBox( view ); m_osc2WaveBox -> setGeometry( 204, O2ROW + 7, 42, ComboBox::DEFAULT_HEIGHT ); - m_osc2WaveBox->setFont( pointSize<8>( m_osc2WaveBox->font() ) ); + m_osc2WaveBox->setFont(pointSize(m_osc2WaveBox->font(), 8)); maketinyled( m_osc2SyncHButton, 212, O2ROW - 3, tr( "Hard sync oscillator 2" ) ) maketinyled( m_osc2SyncRButton, 191, O2ROW - 3, tr( "Reverse sync oscillator 2" ) ) @@ -1709,18 +1709,18 @@ QWidget * MonstroView::setupOperatorsView( QWidget * _parent ) m_osc3Wave1Box = new ComboBox( view ); m_osc3Wave1Box -> setGeometry( 160, O3ROW + 7, 42, ComboBox::DEFAULT_HEIGHT ); - m_osc3Wave1Box->setFont( pointSize<8>( m_osc3Wave1Box->font() ) ); + m_osc3Wave1Box->setFont(pointSize(m_osc3Wave1Box->font(), 8)); m_osc3Wave2Box = new ComboBox( view ); m_osc3Wave2Box -> setGeometry( 204, O3ROW + 7, 42, ComboBox::DEFAULT_HEIGHT ); - m_osc3Wave2Box->setFont( pointSize<8>( m_osc3Wave2Box->font() ) ); + m_osc3Wave2Box->setFont(pointSize(m_osc3Wave2Box->font(), 8)); maketinyled( m_osc3SyncHButton, 212, O3ROW - 3, tr( "Hard sync oscillator 3" ) ) maketinyled( m_osc3SyncRButton, 191, O3ROW - 3, tr( "Reverse sync oscillator 3" ) ) m_lfo1WaveBox = new ComboBox( view ); m_lfo1WaveBox -> setGeometry( 2, LFOROW + 7, 42, ComboBox::DEFAULT_HEIGHT ); - m_lfo1WaveBox->setFont( pointSize<8>( m_lfo1WaveBox->font() ) ); + m_lfo1WaveBox->setFont(pointSize(m_lfo1WaveBox->font(), 8)); maketsknob( m_lfo1AttKnob, LFOCOL1, LFOROW, tr( "Attack" ), " ms", "lfoKnob" ) maketsknob( m_lfo1RateKnob, LFOCOL2, LFOROW, tr( "Rate" ), " ms", "lfoKnob" ) @@ -1728,7 +1728,7 @@ QWidget * MonstroView::setupOperatorsView( QWidget * _parent ) m_lfo2WaveBox = new ComboBox( view ); m_lfo2WaveBox -> setGeometry( 127, LFOROW + 7, 42, ComboBox::DEFAULT_HEIGHT ); - m_lfo2WaveBox->setFont( pointSize<8>( m_lfo2WaveBox->font() ) ); + m_lfo2WaveBox->setFont(pointSize(m_lfo2WaveBox->font(), 8)); maketsknob(m_lfo2AttKnob, LFOCOL4, LFOROW, tr("Attack"), " ms", "lfoKnob") maketsknob(m_lfo2RateKnob, LFOCOL5, LFOROW, tr("Rate"), " ms", "lfoKnob") diff --git a/plugins/Patman/Patman.cpp b/plugins/Patman/Patman.cpp index e525498a5ee..25664ae0dd6 100644 --- a/plugins/Patman/Patman.cpp +++ b/plugins/Patman/Patman.cpp @@ -548,7 +548,7 @@ void PatmanView::updateFilename() m_displayFilename = ""; int idx = m_pi->m_patchFile.length(); - QFontMetrics fm( pointSize<8>( font() ) ); + QFontMetrics fm(pointSize(font(), 8)); // simple algorithm for creating a text from the filename that // matches in the white rectangle @@ -618,7 +618,7 @@ void PatmanView::paintEvent( QPaintEvent * ) { QPainter p( this ); - p.setFont( pointSize<8>( font() ) ); + p.setFont(pointSize(font() ,8)); p.drawText( 8, 116, 235, 16, Qt::AlignLeft | Qt::TextSingleLine | Qt::AlignVCenter, m_displayFilename ); diff --git a/plugins/Stk/Mallets/Mallets.cpp b/plugins/Stk/Mallets/Mallets.cpp index c67814b5f32..1d7cbd86bad 100644 --- a/plugins/Stk/Mallets/Mallets.cpp +++ b/plugins/Stk/Mallets/Mallets.cpp @@ -450,7 +450,7 @@ MalletsInstrumentView::MalletsInstrumentView( MalletsInstrument * _instrument, m_presetsCombo = new ComboBox( this, tr( "Instrument" ) ); m_presetsCombo->setGeometry( 140, 50, 99, ComboBox::DEFAULT_HEIGHT ); - m_presetsCombo->setFont( pointSize<8>( m_presetsCombo->font() ) ); + m_presetsCombo->setFont(pointSize(m_presetsCombo->font(), 8)); connect( &_instrument->m_presetsModel, SIGNAL( dataChanged() ), this, SLOT( changePreset() ) ); diff --git a/plugins/Vestige/Vestige.cpp b/plugins/Vestige/Vestige.cpp index 583075c0cd3..a3ec267e5cc 100644 --- a/plugins/Vestige/Vestige.cpp +++ b/plugins/Vestige/Vestige.cpp @@ -587,7 +587,7 @@ VestigeInstrumentView::VestigeInstrumentView( Instrument * _instrument, m_toggleGUIButton = new QPushButton( tr( "Show/hide GUI" ), this ); m_toggleGUIButton->setGeometry( 20, 130, 200, 24 ); m_toggleGUIButton->setIcon( embed::getIconPixmap( "zoom" ) ); - m_toggleGUIButton->setFont( pointSize<8>( m_toggleGUIButton->font() ) ); + m_toggleGUIButton->setFont(pointSize(m_toggleGUIButton->font(), 8)); connect( m_toggleGUIButton, SIGNAL( clicked() ), this, SLOT( toggleGUI() ) ); @@ -596,7 +596,7 @@ VestigeInstrumentView::VestigeInstrumentView( Instrument * _instrument, this); note_off_all_btn->setGeometry( 20, 160, 200, 24 ); note_off_all_btn->setIcon( embed::getIconPixmap( "stop" ) ); - note_off_all_btn->setFont( pointSize<8>( note_off_all_btn->font() ) ); + note_off_all_btn->setFont(pointSize(note_off_all_btn->font(), 8)); connect( note_off_all_btn, SIGNAL( clicked() ), this, SLOT( noteOffAll() ) ); @@ -881,7 +881,7 @@ void VestigeInstrumentView::paintEvent( QPaintEvent * ) tr( "No VST plugin loaded" ); QFont f = p.font(); f.setBold( true ); - p.setFont( pointSize<10>( f ) ); + p.setFont(pointSize(f, 10)); p.setPen( QColor( 255, 255, 255 ) ); p.drawText( 10, 100, plugin_name ); @@ -893,7 +893,7 @@ void VestigeInstrumentView::paintEvent( QPaintEvent * ) { p.setPen( QColor( 0, 0, 0 ) ); f.setBold( false ); - p.setFont( pointSize<8>( f ) ); + p.setFont(pointSize(f, 8)); p.drawText( 10, 114, tr( "by " ) + m_vi->m_plugin->vendorString() ); p.setPen( QColor( 255, 255, 255 ) ); diff --git a/plugins/VstEffect/VstEffectControlDialog.cpp b/plugins/VstEffect/VstEffectControlDialog.cpp index 5bee94155d9..671eef56191 100644 --- a/plugins/VstEffect/VstEffectControlDialog.cpp +++ b/plugins/VstEffect/VstEffectControlDialog.cpp @@ -246,7 +246,7 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) : tb->addWidget(space1); tbLabel = new QLabel( tr( "Effect by: " ), this ); - tbLabel->setFont( pointSize<7>( f ) ); + tbLabel->setFont(pointSize(f, 7)); tbLabel->setTextFormat(Qt::RichText); tbLabel->setAlignment( Qt::AlignTop | Qt::AlignLeft ); tb->addWidget( tbLabel ); diff --git a/plugins/ZynAddSubFx/ZynAddSubFx.cpp b/plugins/ZynAddSubFx/ZynAddSubFx.cpp index 01fa6400b79..4988e1b8bde 100644 --- a/plugins/ZynAddSubFx/ZynAddSubFx.cpp +++ b/plugins/ZynAddSubFx/ZynAddSubFx.cpp @@ -541,7 +541,7 @@ ZynAddSubFxView::ZynAddSubFxView( Instrument * _instrument, QWidget * _parent ) m_toggleUIButton->setCheckable( true ); m_toggleUIButton->setChecked( false ); m_toggleUIButton->setIcon( embed::getIconPixmap( "zoom" ) ); - m_toggleUIButton->setFont( pointSize<8>( m_toggleUIButton->font() ) ); + m_toggleUIButton->setFont(pointSize(m_toggleUIButton->font(), 8)); connect( m_toggleUIButton, SIGNAL( toggled( bool ) ), this, SLOT( toggleUI() ) ); diff --git a/src/core/audio/AudioJack.cpp b/src/core/audio/AudioJack.cpp index 61d7814ed78..64819cbebba 100644 --- a/src/core/audio/AudioJack.cpp +++ b/src/core/audio/AudioJack.cpp @@ -37,7 +37,6 @@ #include "LcdSpinBox.h" #include "MainWindow.h" #include "MidiJack.h" -#include "gui_templates.h" namespace lmms { diff --git a/src/core/audio/AudioOss.cpp b/src/core/audio/AudioOss.cpp index bd6d46c955f..1653e93fae9 100644 --- a/src/core/audio/AudioOss.cpp +++ b/src/core/audio/AudioOss.cpp @@ -34,7 +34,6 @@ #include "LcdSpinBox.h" #include "AudioEngine.h" #include "Engine.h" -#include "gui_templates.h" #ifdef LMMS_HAVE_UNISTD_H #include diff --git a/src/core/audio/AudioPortAudio.cpp b/src/core/audio/AudioPortAudio.cpp index f303545d2ff..2fbdb04b532 100644 --- a/src/core/audio/AudioPortAudio.cpp +++ b/src/core/audio/AudioPortAudio.cpp @@ -53,7 +53,6 @@ void AudioPortAudioSetupUtil::updateChannels() #include "Engine.h" #include "ConfigManager.h" -#include "gui_templates.h" #include "ComboBox.h" #include "AudioEngine.h" diff --git a/src/core/audio/AudioPulseAudio.cpp b/src/core/audio/AudioPulseAudio.cpp index a0c5ccaf9e1..63b81a9e98e 100644 --- a/src/core/audio/AudioPulseAudio.cpp +++ b/src/core/audio/AudioPulseAudio.cpp @@ -32,7 +32,6 @@ #include "ConfigManager.h" #include "LcdSpinBox.h" #include "AudioEngine.h" -#include "gui_templates.h" #include "Engine.h" namespace lmms diff --git a/src/core/audio/AudioSdl.cpp b/src/core/audio/AudioSdl.cpp index 679912c50f5..da81886acbd 100644 --- a/src/core/audio/AudioSdl.cpp +++ b/src/core/audio/AudioSdl.cpp @@ -32,7 +32,6 @@ #include "AudioEngine.h" #include "ConfigManager.h" -#include "gui_templates.h" namespace lmms { diff --git a/src/core/audio/AudioSndio.cpp b/src/core/audio/AudioSndio.cpp index d934dfb9c8d..7d8e7fa8c09 100644 --- a/src/core/audio/AudioSndio.cpp +++ b/src/core/audio/AudioSndio.cpp @@ -35,7 +35,6 @@ #include "LcdSpinBox.h" #include "AudioEngine.h" #include "Engine.h" -#include "gui_templates.h" #include "ConfigManager.h" diff --git a/src/core/audio/AudioSoundIo.cpp b/src/core/audio/AudioSoundIo.cpp index 6e8a03e384f..a3d72e36b50 100644 --- a/src/core/audio/AudioSoundIo.cpp +++ b/src/core/audio/AudioSoundIo.cpp @@ -32,7 +32,6 @@ #include "Engine.h" #include "debug.h" #include "ConfigManager.h" -#include "gui_templates.h" #include "ComboBox.h" #include "AudioEngine.h" diff --git a/src/gui/AudioAlsaSetupWidget.cpp b/src/gui/AudioAlsaSetupWidget.cpp index 7db822b4be8..bc0ecde8e9f 100644 --- a/src/gui/AudioAlsaSetupWidget.cpp +++ b/src/gui/AudioAlsaSetupWidget.cpp @@ -31,7 +31,6 @@ #include "ConfigManager.h" #include "LcdSpinBox.h" -#include "gui_templates.h" namespace lmms::gui { diff --git a/src/gui/EffectView.cpp b/src/gui/EffectView.cpp index 7f7f9ee9df5..cbe2e4e95ed 100644 --- a/src/gui/EffectView.cpp +++ b/src/gui/EffectView.cpp @@ -90,7 +90,7 @@ EffectView::EffectView( Effect * _model, QWidget * _parent ) : { auto ctls_btn = new QPushButton(tr("Controls"), this); QFont f = ctls_btn->font(); - ctls_btn->setFont( pointSize<8>( f ) ); + ctls_btn->setFont(pointSize(f, 8)); ctls_btn->setGeometry( 150, 14, 50, 20 ); connect( ctls_btn, SIGNAL(clicked()), this, SLOT(editControls())); @@ -257,7 +257,7 @@ void EffectView::paintEvent( QPaintEvent * ) QPainter p( this ); p.drawPixmap( 0, 0, m_bg ); - QFont f = pointSizeF( font(), 7.5f ); + QFont f = pointSize(font(), 7.5f); f.setBold( true ); p.setFont( f ); diff --git a/src/gui/Lv2ViewBase.cpp b/src/gui/Lv2ViewBase.cpp index 77268bb9b75..6de47f450b9 100644 --- a/src/gui/Lv2ViewBase.cpp +++ b/src/gui/Lv2ViewBase.cpp @@ -157,8 +157,7 @@ Lv2ViewBase::Lv2ViewBase(QWidget* meAsWidget, Lv2ControlBase *ctrlBase) : m_toggleUIButton->setCheckable(true); m_toggleUIButton->setChecked(false); m_toggleUIButton->setIcon(embed::getIconPixmap("zoom")); - m_toggleUIButton->setFont( - pointSize<8>(m_toggleUIButton->font())); + m_toggleUIButton->setFont(pointSize(m_toggleUIButton->font(), 8)); btnBox->addWidget(m_toggleUIButton, 0); } btnBox->addStretch(1); diff --git a/src/gui/MidiSetupWidget.cpp b/src/gui/MidiSetupWidget.cpp index 2385def02dd..0e6678727ce 100644 --- a/src/gui/MidiSetupWidget.cpp +++ b/src/gui/MidiSetupWidget.cpp @@ -28,7 +28,6 @@ #include #include "ConfigManager.h" -#include "gui_templates.h" namespace lmms::gui diff --git a/src/gui/MixerChannelView.cpp b/src/gui/MixerChannelView.cpp index bd518093b4c..9b43991d3b6 100644 --- a/src/gui/MixerChannelView.cpp +++ b/src/gui/MixerChannelView.cpp @@ -76,7 +76,7 @@ namespace lmms::gui m_renameLineEdit = new QLineEdit{mixerName, nullptr}; m_renameLineEdit->setFixedWidth(65); - m_renameLineEdit->setFont(pointSizeF(font(), 7.5f)); + m_renameLineEdit->setFont(pointSize(font(), 7.5f)); m_renameLineEdit->setReadOnly(true); m_renameLineEdit->installEventFilter(this); diff --git a/src/gui/SampleTrackWindow.cpp b/src/gui/SampleTrackWindow.cpp index c0dd8e04e6a..630119253aa 100644 --- a/src/gui/SampleTrackWindow.cpp +++ b/src/gui/SampleTrackWindow.cpp @@ -33,7 +33,6 @@ #include "EffectRackView.h" #include "embed.h" -#include "gui_templates.h" #include "GuiApplication.h" #include "Knob.h" #include "MainWindow.h" diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index 8fd892597df..ae026fff3e2 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -1065,7 +1065,7 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) p.fillRect( 0, 0, width(), height(), bgColor ); // set font-size to 8 - p.setFont( pointSize<8>( p.font() ) ); + p.setFont(pointSize(p.font(), 8)); int grid_height = height() - TOP_MARGIN - SCROLLBAR_SIZE; @@ -1423,7 +1423,7 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) { QFont f = p.font(); f.setBold( true ); - p.setFont( pointSize<14>( f ) ); + p.setFont(pointSize(f, 14)); p.setPen( QApplication::palette().color( QPalette::Active, QPalette::BrightText ) ); p.drawText( VALUES_WIDTH + 20, TOP_MARGIN + 40, diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index ff88323253a..47e658f1148 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -3338,7 +3338,7 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) // display note editing info //QFont f = p.font(); f.setBold( false ); - p.setFont( pointSize<10>( f ) ); + p.setFont(pointSize(f, 10)); p.setPen(m_noteModeColor); p.drawText( QRect( 0, keyAreaBottom(), m_whiteKeyWidth, noteEditBottom() - keyAreaBottom()), @@ -3601,7 +3601,7 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) { QFont f = p.font(); f.setBold( true ); - p.setFont( pointSize<14>( f ) ); + p.setFont(pointSize(f, 14)); p.setPen( QApplication::palette().color( QPalette::Active, QPalette::BrightText ) ); p.drawText(m_whiteKeyWidth + 20, PR_TOP_MARGIN + 40, diff --git a/src/gui/instrument/EnvelopeAndLfoView.cpp b/src/gui/instrument/EnvelopeAndLfoView.cpp index c3bf53b39a4..4043ea2295b 100644 --- a/src/gui/instrument/EnvelopeAndLfoView.cpp +++ b/src/gui/instrument/EnvelopeAndLfoView.cpp @@ -207,7 +207,7 @@ EnvelopeAndLfoView::EnvelopeAndLfoView( QWidget * _parent ) : m_lfoWaveBtnGrp->addButton( random_lfo_btn ); m_x100Cb = new LedCheckBox( tr( "FREQ x 100" ), this ); - m_x100Cb->setFont( pointSizeF( m_x100Cb->font(), 6.5 ) ); + m_x100Cb->setFont(pointSize(m_x100Cb->font(), 6.5)); m_x100Cb->move( LFO_PREDELAY_KNOB_X, LFO_GRAPH_Y + 36 ); m_x100Cb->setToolTip(tr("Multiply LFO frequency by 100")); @@ -215,7 +215,7 @@ EnvelopeAndLfoView::EnvelopeAndLfoView( QWidget * _parent ) : m_controlEnvAmountCb = new LedCheckBox( tr( "MODULATE ENV AMOUNT" ), this ); m_controlEnvAmountCb->move( LFO_PREDELAY_KNOB_X, LFO_GRAPH_Y + 54 ); - m_controlEnvAmountCb->setFont( pointSizeF( m_controlEnvAmountCb->font(), 6.5 ) ); + m_controlEnvAmountCb->setFont(pointSize(m_controlEnvAmountCb->font(), 6.5)); m_controlEnvAmountCb->setToolTip( tr( "Control envelope amount by this LFO" ) ); @@ -340,7 +340,7 @@ void EnvelopeAndLfoView::paintEvent( QPaintEvent * ) // draw LFO-graph p.drawPixmap(LFO_GRAPH_X, LFO_GRAPH_Y, m_lfoGraph); - p.setFont( pointSize<8>( p.font() ) ); + p.setFont(pointSize(p.font(), 8)); const float gray_amount = 1.0f - fabsf( m_amountKnob->value() ); diff --git a/src/gui/instrument/InstrumentFunctionViews.cpp b/src/gui/instrument/InstrumentFunctionViews.cpp index c9aa04272da..ea16486004c 100644 --- a/src/gui/instrument/InstrumentFunctionViews.cpp +++ b/src/gui/instrument/InstrumentFunctionViews.cpp @@ -57,7 +57,7 @@ InstrumentFunctionNoteStackingView::InstrumentFunctionNoteStackingView( Instrume mainLayout->setVerticalSpacing( 1 ); auto chordLabel = new QLabel(tr("Chord:")); - chordLabel->setFont( pointSize<8>( chordLabel->font() ) ); + chordLabel->setFont(pointSize(chordLabel->font(), 8)); m_chordRangeKnob->setLabel( tr( "RANGE" ) ); m_chordRangeKnob->setHintText( tr( "Chord range:" ), " " + tr( "octave(s)" ) ); @@ -146,13 +146,13 @@ InstrumentFunctionArpeggioView::InstrumentFunctionArpeggioView( InstrumentFuncti m_arpGateKnob->setHintText( tr( "Arpeggio gate:" ), tr( "%" ) ); auto arpChordLabel = new QLabel(tr("Chord:")); - arpChordLabel->setFont( pointSize<8>( arpChordLabel->font() ) ); + arpChordLabel->setFont(pointSize(arpChordLabel->font(), 8)); auto arpDirectionLabel = new QLabel(tr("Direction:")); - arpDirectionLabel->setFont( pointSize<8>( arpDirectionLabel->font() ) ); + arpDirectionLabel->setFont(pointSize(arpDirectionLabel->font(), 8)); auto arpModeLabel = new QLabel(tr("Mode:")); - arpModeLabel->setFont( pointSize<8>( arpModeLabel->font() ) ); + arpModeLabel->setFont(pointSize(arpModeLabel->font(), 8)); mainLayout->addWidget( arpChordLabel, 0, 0 ); mainLayout->addWidget( m_arpComboBox, 1, 0 ); diff --git a/src/gui/instrument/InstrumentMidiIOView.cpp b/src/gui/instrument/InstrumentMidiIOView.cpp index e321d061e98..1e95751ead0 100644 --- a/src/gui/instrument/InstrumentMidiIOView.cpp +++ b/src/gui/instrument/InstrumentMidiIOView.cpp @@ -155,7 +155,7 @@ InstrumentMidiIOView::InstrumentMidiIOView( QWidget* parent ) : auto baseVelocityHelp = new QLabel(tr("Specify the velocity normalization base for MIDI-based instruments at 100% note velocity.")); baseVelocityHelp->setWordWrap( true ); - baseVelocityHelp->setFont( pointSize<8>( baseVelocityHelp->font() ) ); + baseVelocityHelp->setFont(pointSize(baseVelocityHelp->font(), 8)); baseVelocityLayout->addWidget( baseVelocityHelp ); diff --git a/src/gui/instrument/InstrumentSoundShapingView.cpp b/src/gui/instrument/InstrumentSoundShapingView.cpp index 1bfc166b342..59df3097cb2 100644 --- a/src/gui/instrument/InstrumentSoundShapingView.cpp +++ b/src/gui/instrument/InstrumentSoundShapingView.cpp @@ -77,7 +77,7 @@ InstrumentSoundShapingView::InstrumentSoundShapingView( QWidget * _parent ) : m_filterComboBox = new ComboBox( m_filterGroupBox ); m_filterComboBox->setGeometry( 14, 22, 120, ComboBox::DEFAULT_HEIGHT ); - m_filterComboBox->setFont( pointSize<8>( m_filterComboBox->font() ) ); + m_filterComboBox->setFont(pointSize(m_filterComboBox->font(), 8)); m_filterCutKnob = new Knob( KnobType::Bright26, m_filterGroupBox ); @@ -94,7 +94,7 @@ InstrumentSoundShapingView::InstrumentSoundShapingView( QWidget * _parent ) : m_singleStreamInfoLabel = new QLabel( tr( "Envelopes, LFOs and filters are not supported by the current instrument." ), this ); m_singleStreamInfoLabel->setWordWrap( true ); - m_singleStreamInfoLabel->setFont( pointSize<8>( m_singleStreamInfoLabel->font() ) ); + m_singleStreamInfoLabel->setFont(pointSize(m_singleStreamInfoLabel->font(), 8)); m_singleStreamInfoLabel->setGeometry( TARGETS_TABWIDGET_X, TARGETS_TABWIDGET_Y, diff --git a/src/gui/instrument/InstrumentTrackWindow.cpp b/src/gui/instrument/InstrumentTrackWindow.cpp index a726dd5b989..b6a51624b26 100644 --- a/src/gui/instrument/InstrumentTrackWindow.cpp +++ b/src/gui/instrument/InstrumentTrackWindow.cpp @@ -107,7 +107,7 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) : // setup line edit for changing instrument track name m_nameLineEdit = new QLineEdit; - m_nameLineEdit->setFont( pointSize<9>( m_nameLineEdit->font() ) ); + m_nameLineEdit->setFont(pointSize(m_nameLineEdit->font(), 9)); connect( m_nameLineEdit, SIGNAL( textChanged( const QString& ) ), this, SLOT( textChanged( const QString& ) ) ); diff --git a/src/gui/instrument/InstrumentTuningView.cpp b/src/gui/instrument/InstrumentTuningView.cpp index 355d7d18c73..41c18213b5f 100644 --- a/src/gui/instrument/InstrumentTuningView.cpp +++ b/src/gui/instrument/InstrumentTuningView.cpp @@ -60,7 +60,7 @@ InstrumentTuningView::InstrumentTuningView(InstrumentTrack *it, QWidget *parent) auto tlabel = new QLabel(tr("Enables the use of global transposition")); tlabel->setWordWrap(true); - tlabel->setFont(pointSize<8>(tlabel->font())); + tlabel->setFont(pointSize(tlabel->font(), 8)); masterPitchLayout->addWidget(tlabel); // Microtuner settings diff --git a/src/gui/instrument/PianoView.cpp b/src/gui/instrument/PianoView.cpp index c8882898bc2..87ee6af9bed 100644 --- a/src/gui/instrument/PianoView.cpp +++ b/src/gui/instrument/PianoView.cpp @@ -807,7 +807,7 @@ void PianoView::paintEvent( QPaintEvent * ) QPainter p( this ); // set smaller font for printing number of every octave - p.setFont( pointSize( p.font() ) ); + p.setFont(pointSize(p.font(), LABEL_TEXT_SIZE)); // draw bar above the keyboard (there will be the labels diff --git a/src/gui/menus/MidiPortMenu.cpp b/src/gui/menus/MidiPortMenu.cpp index b99c3a0b72f..6c573fdf5c3 100644 --- a/src/gui/menus/MidiPortMenu.cpp +++ b/src/gui/menus/MidiPortMenu.cpp @@ -24,7 +24,6 @@ */ #include "MidiPortMenu.h" -#include "gui_templates.h" namespace lmms::gui { diff --git a/src/gui/modals/SetupDialog.cpp b/src/gui/modals/SetupDialog.cpp index fffa94c82ba..63560e33dff 100644 --- a/src/gui/modals/SetupDialog.cpp +++ b/src/gui/modals/SetupDialog.cpp @@ -37,7 +37,6 @@ #include "embed.h" #include "Engine.h" #include "FileDialog.h" -#include "gui_templates.h" #include "MainWindow.h" #include "MidiSetupWidget.h" #include "ProjectJournal.h" diff --git a/src/gui/tracks/TrackOperationsWidget.cpp b/src/gui/tracks/TrackOperationsWidget.cpp index e846370e69c..de119c64f64 100644 --- a/src/gui/tracks/TrackOperationsWidget.cpp +++ b/src/gui/tracks/TrackOperationsWidget.cpp @@ -38,7 +38,6 @@ #include "DataFile.h" #include "embed.h" #include "Engine.h" -#include "gui_templates.h" #include "InstrumentTrackView.h" #include "PixmapButton.h" #include "Song.h" diff --git a/src/gui/widgets/ComboBox.cpp b/src/gui/widgets/ComboBox.cpp index ccc0c675b0d..b11990b273b 100644 --- a/src/gui/widgets/ComboBox.cpp +++ b/src/gui/widgets/ComboBox.cpp @@ -49,7 +49,7 @@ ComboBox::ComboBox( QWidget * _parent, const QString & _name ) : { setFixedHeight( ComboBox::DEFAULT_HEIGHT ); - setFont( pointSize<9>( font() ) ); + setFont(pointSize(font(), 9)); connect( &m_menu, SIGNAL(triggered(QAction*)), this, SLOT(setItem(QAction*))); diff --git a/src/gui/widgets/GroupBox.cpp b/src/gui/widgets/GroupBox.cpp index e3e71a8124e..229ab13cd45 100644 --- a/src/gui/widgets/GroupBox.cpp +++ b/src/gui/widgets/GroupBox.cpp @@ -111,7 +111,7 @@ void GroupBox::paintEvent( QPaintEvent * pe ) // draw text p.setPen( palette().color( QPalette::Active, QPalette::Text ) ); - p.setFont( pointSize<8>( font() ) ); + p.setFont(pointSize(font(), 8)); int const captionX = ledButtonShown() ? 22 : 6; p.drawText(captionX, m_titleBarHeight, m_caption); diff --git a/src/gui/widgets/Knob.cpp b/src/gui/widgets/Knob.cpp index 00a9363c87f..a6411d6cf07 100644 --- a/src/gui/widgets/Knob.cpp +++ b/src/gui/widgets/Knob.cpp @@ -139,7 +139,7 @@ void Knob::setLabel( const QString & txt ) if( m_knobPixmap ) { setFixedSize(qMax( m_knobPixmap->width(), - horizontalAdvance(QFontMetrics(pointSizeF(font(), 6.5)), m_label)), + horizontalAdvance(QFontMetrics(pointSize(font(), 6.5)), m_label)), m_knobPixmap->height() + 10); } @@ -459,7 +459,7 @@ void Knob::paintEvent( QPaintEvent * _me ) { if (!m_isHtmlLabel) { - p.setFont(pointSizeF(p.font(), 6.5)); + p.setFont(pointSize(p.font(), 6.5f)); p.setPen(textColor()); p.drawText(width() / 2 - horizontalAdvance(p.fontMetrics(), m_label) / 2, @@ -467,7 +467,7 @@ void Knob::paintEvent( QPaintEvent * _me ) } else { - m_tdRenderer->setDefaultFont(pointSizeF(p.font(), 6.5)); + m_tdRenderer->setDefaultFont(pointSize(p.font(), 6.5f)); p.translate((width() - m_tdRenderer->idealWidth()) / 2, (height() - m_tdRenderer->pageSize().height()) / 2); m_tdRenderer->drawContents(&p); } diff --git a/src/gui/widgets/LcdFloatSpinBox.cpp b/src/gui/widgets/LcdFloatSpinBox.cpp index c7e20467a5b..667a034815b 100644 --- a/src/gui/widgets/LcdFloatSpinBox.cpp +++ b/src/gui/widgets/LcdFloatSpinBox.cpp @@ -245,7 +245,7 @@ void LcdFloatSpinBox::paintEvent(QPaintEvent*) // Label if (!m_label.isEmpty()) { - p.setFont(pointSizeF(p.font(), 6.5)); + p.setFont(pointSize(p.font(), 6.5f)); p.setPen(m_wholeDisplay.textShadowColor()); p.drawText(width() / 2 - p.fontMetrics().boundingRect(m_label).width() / 2 + 1, height(), m_label); p.setPen(m_wholeDisplay.textColor()); diff --git a/src/gui/widgets/LcdWidget.cpp b/src/gui/widgets/LcdWidget.cpp index a409fee8bf6..fa7dea1da07 100644 --- a/src/gui/widgets/LcdWidget.cpp +++ b/src/gui/widgets/LcdWidget.cpp @@ -203,7 +203,7 @@ void LcdWidget::paintEvent( QPaintEvent* ) // Label if( !m_label.isEmpty() ) { - p.setFont( pointSizeF( p.font(), 6.5 ) ); + p.setFont(pointSize(p.font(), 6.5f)); p.setPen( textShadowColor() ); p.drawText(width() / 2 - horizontalAdvance(p.fontMetrics(), m_label) / 2 + 1, @@ -255,7 +255,7 @@ void LcdWidget::updateSize() setFixedSize( qMax( m_cellWidth * m_numDigits + marginX1 + marginX2, - horizontalAdvance(QFontMetrics(pointSizeF(font(), 6.5)), m_label) + horizontalAdvance(QFontMetrics(pointSize(font(), 6.5f)), m_label) ), m_cellHeight + (2 * marginY) + 9 ); diff --git a/src/gui/widgets/LedCheckBox.cpp b/src/gui/widgets/LedCheckBox.cpp index 1dbf650ed6e..3cb85deff08 100644 --- a/src/gui/widgets/LedCheckBox.cpp +++ b/src/gui/widgets/LedCheckBox.cpp @@ -92,10 +92,7 @@ void LedCheckBox::initUi( LedColor _color ) m_ledOnPixmap = embed::getIconPixmap(names[static_cast(_color)].toUtf8().constData()); m_ledOffPixmap = embed::getIconPixmap("led_off"); - if (m_legacyMode) - { - setFont( pointSize<7>( font() ) ); - } + if (m_legacyMode){ setFont(pointSize(font(), 7)); } setText( m_text ); } @@ -116,7 +113,7 @@ void LedCheckBox::onTextUpdated() void LedCheckBox::paintLegacy(QPaintEvent * pe) { QPainter p( this ); - p.setFont( pointSize<7>( font() ) ); + p.setFont(pointSize(font(), 7)); p.drawPixmap(0, 0, model()->value() ? m_ledOnPixmap : m_ledOffPixmap); diff --git a/src/gui/widgets/MeterDialog.cpp b/src/gui/widgets/MeterDialog.cpp index ced08382ef1..eb8e5435376 100644 --- a/src/gui/widgets/MeterDialog.cpp +++ b/src/gui/widgets/MeterDialog.cpp @@ -60,7 +60,7 @@ MeterDialog::MeterDialog( QWidget * _parent, bool _simple ) : { auto num_label = new QLabel(tr("Meter Numerator"), num); QFont f = num_label->font(); - num_label->setFont( pointSize<7>( f ) ); + num_label->setFont(pointSize(f, 7)); num_layout->addSpacing( 5 ); num_layout->addWidget( num_label ); } @@ -84,7 +84,7 @@ MeterDialog::MeterDialog( QWidget * _parent, bool _simple ) : { auto den_label = new QLabel(tr("Meter Denominator"), den); QFont f = den_label->font(); - den_label->setFont( pointSize<7>( f ) ); + den_label->setFont(pointSize(f, 7)); den_layout->addSpacing( 5 ); den_layout->addWidget( den_label ); } diff --git a/src/gui/widgets/Oscilloscope.cpp b/src/gui/widgets/Oscilloscope.cpp index f426e1b1987..bd944937a7d 100644 --- a/src/gui/widgets/Oscilloscope.cpp +++ b/src/gui/widgets/Oscilloscope.cpp @@ -203,7 +203,7 @@ void Oscilloscope::paintEvent( QPaintEvent * ) else { p.setPen( QColor( 192, 192, 192 ) ); - p.setFont( pointSize<7>( p.font() ) ); + p.setFont(pointSize(p.font(), 7)); p.drawText( 6, height()-5, tr( "Click to enable" ) ); } } diff --git a/src/gui/widgets/TabBar.cpp b/src/gui/widgets/TabBar.cpp index e2949455138..ce706d5f80b 100644 --- a/src/gui/widgets/TabBar.cpp +++ b/src/gui/widgets/TabBar.cpp @@ -90,7 +90,7 @@ TabButton * TabBar::addTab( QWidget * _w, const QString & _text, int _id, _w->setFixedSize( _w->parentWidget()->size() ); } - b->setFont( pointSize<8>( b->font() ) ); + b->setFont(pointSize(b->font(), 8)); return( b ); } diff --git a/src/gui/widgets/TabWidget.cpp b/src/gui/widgets/TabWidget.cpp index 27671933eea..2c93dba3e22 100644 --- a/src/gui/widgets/TabWidget.cpp +++ b/src/gui/widgets/TabWidget.cpp @@ -58,7 +58,7 @@ TabWidget::TabWidget(const QString& caption, QWidget* parent, bool usePixmap, m_tabheight = caption.isEmpty() ? m_tabbarHeight - 3 : m_tabbarHeight - 4; - setFont(pointSize<8>(font())); + setFont(pointSize(font(), 8)); setAutoFillBackground(true); QColor bg_color = QApplication::palette().color(QPalette::Active, QPalette::Window).darker(132); @@ -70,7 +70,7 @@ TabWidget::TabWidget(const QString& caption, QWidget* parent, bool usePixmap, void TabWidget::addTab(QWidget* w, const QString& name, const char* pixmap, int idx) { - setFont(pointSize<8>(font())); + setFont(pointSize(font(), 8)); // Append tab when position is not given if (idx < 0/* || m_widgets.contains(idx) == true*/) @@ -216,7 +216,7 @@ void TabWidget::resizeEvent(QResizeEvent*) void TabWidget::paintEvent(QPaintEvent* pe) { QPainter p(this); - p.setFont(pointSize<7>(font())); + p.setFont(pointSize(font(), 7)); // Draw background QBrush bg_color = p.background(); @@ -232,7 +232,7 @@ void TabWidget::paintEvent(QPaintEvent* pe) // Draw title, if any if (!m_caption.isEmpty()) { - p.setFont(pointSize<8>(p.font())); + p.setFont(pointSize(p.font(), 8)); p.setPen(tabTitleText()); p.drawText(5, 11, m_caption); } From 682be4e82af8aecc235480ee8d39d412a0130b67 Mon Sep 17 00:00:00 2001 From: Lost Robot <34612565+LostRobotMusic@users.noreply.github.com> Date: Wed, 27 Mar 2024 06:00:49 -0700 Subject: [PATCH 17/31] Fix DynamicsProcessor bugs (#7168) --- plugins/DynamicsProcessor/DynamicsProcessor.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/DynamicsProcessor/DynamicsProcessor.cpp b/plugins/DynamicsProcessor/DynamicsProcessor.cpp index 6bdf41eee4e..f58dcedac19 100644 --- a/plugins/DynamicsProcessor/DynamicsProcessor.cpp +++ b/plugins/DynamicsProcessor/DynamicsProcessor.cpp @@ -56,7 +56,7 @@ Plugin::Descriptor PLUGIN_EXPORT dynamicsprocessor_plugin_descriptor = } const float DYN_NOISE_FLOOR = 0.00001f; // -100dBFS noise floor -const double DNF_LOG = 5.0; +const double DNF_LOG = -1.0; DynProcEffect::DynProcEffect( Model * _parent, const Descriptor::SubPluginFeatures::Key * _key ) : @@ -82,12 +82,12 @@ DynProcEffect::~DynProcEffect() inline void DynProcEffect::calcAttack() { - m_attCoeff = std::pow(10.f, ( DNF_LOG / ( m_dpControls.m_attackModel.value() * 0.001 ) ) / Engine::audioEngine()->processingSampleRate() ); + m_attCoeff = std::exp((DNF_LOG / (m_dpControls.m_attackModel.value() * 0.001)) / Engine::audioEngine()->processingSampleRate()); } inline void DynProcEffect::calcRelease() { - m_relCoeff = std::pow(10.f, ( -DNF_LOG / ( m_dpControls.m_releaseModel.value() * 0.001 ) ) / Engine::audioEngine()->processingSampleRate() ); + m_relCoeff = std::exp((DNF_LOG / (m_dpControls.m_releaseModel.value() * 0.001)) / Engine::audioEngine()->processingSampleRate()); } @@ -155,15 +155,15 @@ bool DynProcEffect::processAudioBuffer( sampleFrame * _buf, const double t = m_rms[i]->update( s[i] ); if( t > m_currentPeak[i] ) { - m_currentPeak[i] = qMin( m_currentPeak[i] * m_attCoeff, t ); + m_currentPeak[i] = m_currentPeak[i] * m_attCoeff + (1 - m_attCoeff) * t; } else if( t < m_currentPeak[i] ) { - m_currentPeak[i] = qMax( m_currentPeak[i] * m_relCoeff, t ); + m_currentPeak[i] = m_currentPeak[i] * m_relCoeff + (1 - m_relCoeff) * t; } - m_currentPeak[i] = qBound( DYN_NOISE_FLOOR, m_currentPeak[i], 10.0f ); + m_currentPeak[i] = std::max(DYN_NOISE_FLOOR, m_currentPeak[i]); } // account for stereo mode From 6f5f2c2ddd40f3b06f6f2cd428f401d2e25ce13f Mon Sep 17 00:00:00 2001 From: Oskar Wallgren Date: Thu, 28 Mar 2024 18:13:32 +0100 Subject: [PATCH 18/31] Fix glitch in SlicerT (#7174) --- plugins/SlicerT/SlicerT.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/SlicerT/SlicerT.cpp b/plugins/SlicerT/SlicerT.cpp index c9e75df601e..1c33970465b 100644 --- a/plugins/SlicerT/SlicerT.cpp +++ b/plugins/SlicerT/SlicerT.cpp @@ -144,8 +144,6 @@ void SlicerT::playNote(NotePlayHandle* handle, sampleFrame* workingBuffer) workingBuffer[i + offset][1] *= fadeValue; } - instrumentTrack()->processAudioBuffer(workingBuffer, frames + offset, handle); - emit isPlaying(noteDone, sliceStart, sliceEnd); } else { emit isPlaying(-1, 0, 0); } From b2f2fc4ad1330516a691f1b8d38a2b4e7f020999 Mon Sep 17 00:00:00 2001 From: saker Date: Thu, 28 Mar 2024 17:21:31 -0400 Subject: [PATCH 19/31] Revisit the initialization for local variables (#7143) * clang-tidy: Apply cppcoreguidelines-init-variables everywhere (treating NaNs as zeros) * Initialize msec and tick outside switch * Update plugins/Vestige/Vestige.cpp Co-authored-by: Kevin Zander * Update plugins/Vestige/Vestige.cpp Co-authored-by: Kevin Zander * Update plugins/Vestige/Vestige.cpp Co-authored-by: Kevin Zander * Update plugins/VstEffect/VstEffectControls.cpp Co-authored-by: Kevin Zander * Update src/core/DrumSynth.cpp Co-authored-by: Kevin Zander * Update plugins/VstEffect/VstEffectControls.cpp Co-authored-by: Kevin Zander * Update plugins/VstEffect/VstEffectControls.cpp Co-authored-by: Kevin Zander * Update src/core/DrumSynth.cpp Co-authored-by: Kevin Zander * Update src/core/DrumSynth.cpp Co-authored-by: Kevin Zander * Update src/core/DrumSynth.cpp Co-authored-by: Kevin Zander * Update src/core/DrumSynth.cpp Co-authored-by: Kevin Zander * Update src/core/DrumSynth.cpp Co-authored-by: Kevin Zander * Update src/core/DrumSynth.cpp Co-authored-by: Kevin Zander * Use initialization with = * Use tabs * Use static_cast * Update DrumSynth.cpp Co-authored-by: Kevin Zander * Update DrumSynth.cpp Co-authored-by: Kevin Zander * Update DrumSynth.cpp Co-authored-by: Kevin Zander * Update src/core/DrumSynth.cpp Co-authored-by: Kevin Zander * Do not use tabs for alignment in src/core/DrumSynth.cpp Co-authored-by: Dalton Messmer * Move x variable inside loop * Use ternary operator for b variable * Revert "Use tabs" This reverts commit 07afd8a83f58b539c3673310b2aad4b63c9198a0. * Remove unnecessary variables in XpressiveView * Simplify initialization in Plugin * Combine declaration and initialization in EqCurve * Combine declaration and initialization in Song * Combine declaration and initialization in AudioAlsa * Combine declaration and initialization in EqCurve (again) * Missed some * Undo changes made to non-LMMS files * Undo indentation changes in SidInstrument.cpp * Combine declaration with assignment in IoHelper * Combine declaration with assignment using auto in Carla * Combine declaration with assignment * Combine declaration with assignment in BasicFilters * Simplify assignments in AudioFileProcessorWaveView::zoom * Simplify out sample variable in BitInvader * Remove sampleLength variable in DelayEffect * Move gain variable in DynamicsProcessor * Combine peak variable declaration with assignment in EqSpectrumView * Move left/right lfo variables in for loop in FlangerEffect * Use ternary operator for group variable in LadspaControlDialog * Combine declaration with assignment in Lb302 * Combine declaration with assignment in MidiExport * Combine declaration with assignment in MidiFile * Combine declaration with assignment in MidiImport * Use ternary operator for vel_adjusted variable in OpulenZ * Move tmpL and dcblkL variables in for loop in ReverbSC * Combine declaration with initialization in SlicerT * Combine declaration with assignment in SaSpectrumView * Combine declaration with assignment in SaWaterfallView * Combine declaration with assignment in StereoEnhancerEffect * Combine declaration with assignment in VibratingString * Combine declaration with assignment in VstEffectControls * Combine declaration with assignment in Xpressive * Combine declaration with assignment in AutomatableModel * Combine declaration with assignment in AutomationClip * Move sample variable in for loop in BandLimitedWave * Combine declaration with assignment in DataFile * Combine declaration with assignment in DrumSynth * Combine declaration with assignment in Effect * Remove redundant assignment to nphsLeft in InstrumentPlayHandle * Combine declaration with assignment in LadspaManager * Combine declaration with assignment in LinkedModelGroups * Combine declaration with assignment in MemoryHelper * Combine declaration with assignment in AudioAlsa * Combine declaration with assignment in AudioFileOgg * Combine declaration with assignment in AudioPortAudio * Combine declaration with assignment in AudioSoundIo * Combine declaration with assignment in Lv2Evbuf * Combine declaration with assignment in Lv2Proc * Combine declaration with assignment in main * Combine declaration with assignment in MidiAlsaRaw * Combine declaration with assignment in MidiAlsaSeq * Combine declaration with assignment in MidiController * Combine declaration with assignment in MidiJack * Combine declaration with assignment in MidiSndio * Combine declaration with assignment in ControlLayout * Combine declaration with assignment in MainWindow * Combine declaration with assignment in ProjectNotes * Use ternary operator for nextValue variable in AutomationClipView * Combine declaration with assignment in AutomationEditor * Move length variable in for-loop in PianoRoll * Combine declaration with assignment in ControllerConnectionDialog * Combine declaration with assignment in Graph * Combine declaration with assignment in LcdFloatSpinBox * Combine declaration with assignment in TimeDisplayWidget * Remove currentNote variable in InstrumentTrack * Combine declaration with assignment in DrumSynth (again) * Use ternary operator for factor variable in BitInvader * Use ternary operator for highestBandwich variable in EqCurve Bandwich? * Move sum variable into for loop in Graph * Fix format in MidiSndio * Fixup a few more * Cleanup error variables * Use ternary operators and combine declaration with initialization * Combine declaration with initialization * Update plugins/LadspaEffect/LadspaControlDialog.cpp Co-authored-by: Kevin Zander * Update plugins/OpulenZ/OpulenZ.cpp Co-authored-by: Kevin Zander * Update plugins/SpectrumAnalyzer/SaProcessor.cpp Co-authored-by: Kevin Zander * Update src/core/midi/MidiAlsaRaw.cpp Co-authored-by: Kevin Zander * Update src/gui/MainWindow.cpp Co-authored-by: Kevin Zander * Update src/gui/clips/AutomationClipView.cpp Co-authored-by: Kevin Zander * Update src/gui/editors/AutomationEditor.cpp Co-authored-by: Kevin Zander * Update src/gui/widgets/Fader.cpp Co-authored-by: Kevin Zander * Move static_cast conversion into separate variable * Use real index when interpolating * Remove empty line * Make helpBtn a private member * Move controller type into separate variable * Fix format of DrumSynth::waveform function * Use tabs and static_cast * Remove redundant if branch * Refactor using static_cast/reinterpret_cast * Add std namespace prefix * Store repeated conditional into boolean variable * Cast to int before assigning to m_currentLength * Rename note_frames to noteFrames * Update src/core/Controller.cpp Co-authored-by: Kevin Zander * Update src/core/DrumSynth.cpp Co-authored-by: Kevin Zander * Update src/gui/widgets/Graph.cpp Co-authored-by: Kevin Zander * Revert changes that initialized variables redudantly For situations where the initialization is more complex or passed into a function by a pointer, we dont need to do initialization ourselves since it is already done for us, just in a different way. * Remove redundant err variable * Remove explicit check of err variable * Clean up changes and address review * Do not initialize to 0/nullptr when not needed * Wrap condition in parentheses for readability --------- Co-authored-by: Kevin Zander Co-authored-by: Dalton Messmer --- include/BasicFilters.h | 41 ++++---- include/IoHelper.h | 5 +- include/LocaleHelper.h | 3 +- .../AudioFileProcessorWaveView.cpp | 35 +++---- plugins/BitInvader/BitInvader.cpp | 45 ++------- plugins/CarlaBase/Carla.cpp | 5 +- plugins/Delay/DelayEffect.cpp | 5 +- .../DynamicsProcessor/DynamicsProcessor.cpp | 19 +--- plugins/Eq/EqCurve.cpp | 83 +++++++--------- plugins/Eq/EqFilter.h | 71 ++++++-------- plugins/Eq/EqSpectrumView.cpp | 3 +- plugins/Flanger/FlangerEffect.cpp | 5 +- plugins/FreeBoy/game-music-emu | 2 +- plugins/LadspaEffect/LadspaControlDialog.cpp | 14 +-- plugins/Lb302/Lb302.cpp | 21 ++-- plugins/MidiExport/MidiExport.cpp | 11 +-- plugins/MidiExport/MidiFile.hpp | 41 +++++--- plugins/MidiImport/MidiImport.h | 4 +- plugins/OpulenZ/OpulenZ.cpp | 95 ++++++++---------- plugins/Patman/Patman.cpp | 9 +- plugins/Sid/SidInstrument.cpp | 19 ++-- plugins/SlicerT/SlicerT.cpp | 9 +- plugins/SpectrumAnalyzer/SaProcessor.cpp | 41 +++----- plugins/SpectrumAnalyzer/SaSpectrumView.cpp | 24 ++--- plugins/SpectrumAnalyzer/SaWaterfallView.cpp | 3 +- plugins/StereoEnhancer/StereoEnhancer.cpp | 11 +-- plugins/Vectorscope/VectorView.cpp | 14 +-- plugins/Vestige/Vestige.cpp | 3 +- plugins/Vibed/VibratingString.cpp | 6 +- plugins/Vibed/VibratingString.h | 25 ++--- plugins/VstEffect/VstEffectControls.cpp | 3 +- plugins/Xpressive/ExprSynth.cpp | 10 +- plugins/Xpressive/Xpressive.cpp | 12 +-- plugins/Xpressive/Xpressive.h | 1 + src/core/AutomatableModel.cpp | 5 +- src/core/AutomationClip.cpp | 8 +- src/core/BandLimitedWave.cpp | 13 ++- src/core/Controller.cpp | 24 ++--- src/core/DataFile.cpp | 7 +- src/core/DrumSynth.cpp | 94 +++++++++--------- src/core/Effect.cpp | 4 +- src/core/InstrumentPlayHandle.cpp | 5 +- src/core/LadspaManager.cpp | 6 +- src/core/LinkedModelGroups.cpp | 7 +- src/core/MemoryHelper.cpp | 7 +- src/core/Plugin.cpp | 4 +- src/core/Song.cpp | 13 ++- src/core/audio/AudioAlsa.cpp | 83 +++++----------- src/core/audio/AudioDevice.cpp | 6 +- src/core/audio/AudioFileOgg.cpp | 10 +- src/core/audio/AudioPortAudio.cpp | 12 +-- src/core/audio/AudioSoundIo.cpp | 36 +++---- src/core/lv2/Lv2Evbuf.cpp | 9 +- src/core/lv2/Lv2Proc.cpp | 8 +- src/core/main.cpp | 12 +-- src/core/midi/MidiAlsaRaw.cpp | 35 +++---- src/core/midi/MidiAlsaSeq.cpp | 5 +- src/core/midi/MidiController.cpp | 6 +- src/core/midi/MidiJack.cpp | 5 +- src/core/midi/MidiSndio.cpp | 13 +-- src/gui/ControlLayout.cpp | 3 +- src/gui/MainWindow.cpp | 3 +- src/gui/ProjectNotes.cpp | 4 +- src/gui/clips/AutomationClipView.cpp | 15 +-- src/gui/editors/AutomationEditor.cpp | 98 +++++-------------- src/gui/editors/PianoRoll.cpp | 11 +-- src/gui/editors/SongEditor.cpp | 14 +-- src/gui/modals/ControllerConnectionDialog.cpp | 5 +- src/gui/widgets/Fader.cpp | 14 ++- src/gui/widgets/Graph.cpp | 3 +- src/gui/widgets/TimeDisplayWidget.cpp | 15 +-- src/tracks/InstrumentTrack.cpp | 12 +-- 72 files changed, 507 insertions(+), 825 deletions(-) diff --git a/include/BasicFilters.h b/include/BasicFilters.h index 215c32dfb49..25dcf834c66 100644 --- a/include/BasicFilters.h +++ b/include/BasicFilters.h @@ -340,7 +340,7 @@ class BasicFilters inline sample_t update( sample_t _in0, ch_cnt_t _chnl ) { - sample_t out; + sample_t out = 0.0f; switch( m_type ) { case FilterType::Moog: @@ -375,7 +375,6 @@ class BasicFilters // input signal is linear-interpolated after oversampling, output signal is averaged from oversampled outputs case FilterType::Tripole: { - out = 0.0f; float ip = 0.0f; for( int i = 0; i < 4; ++i ) { @@ -431,7 +430,6 @@ class BasicFilters case FilterType::Highpass_SV: { float hp; - for( int i = 0; i < 2; ++i ) // 2x oversample { m_delay2[_chnl] = m_delay2[_chnl] + m_svf1 * m_delay1[_chnl]; @@ -444,8 +442,7 @@ class BasicFilters case FilterType::Notch_SV: { - float hp1, hp2; - + float hp1; for( int i = 0; i < 2; ++i ) // 2x oversample { m_delay2[_chnl] = m_delay2[_chnl] + m_svf1 * m_delay1[_chnl]; /* delay2/4 = lowpass output */ @@ -453,7 +450,7 @@ class BasicFilters m_delay1[_chnl] = m_svf1 * hp1 + m_delay1[_chnl]; /* delay1/3 = bandpass output */ m_delay4[_chnl] = m_delay4[_chnl] + m_svf2 * m_delay3[_chnl]; - hp2 = m_delay2[_chnl] - m_delay4[_chnl] - m_svq * m_delay3[_chnl]; + float hp2 = m_delay2[_chnl] - m_delay4[_chnl] - m_svq * m_delay3[_chnl]; m_delay3[_chnl] = m_svf2 * hp2 + m_delay3[_chnl]; } @@ -469,19 +466,19 @@ class BasicFilters case FilterType::Lowpass_RC12: { - sample_t lp, bp, hp, in; + sample_t lp = 0.0f; for( int n = 4; n != 0; --n ) { - in = _in0 + m_rcbp0[_chnl] * m_rcq; + sample_t in = _in0 + m_rcbp0[_chnl] * m_rcq; in = std::clamp(in, -1.0f, 1.0f); lp = in * m_rcb + m_rclp0[_chnl] * m_rca; lp = std::clamp(lp, -1.0f, 1.0f); - hp = m_rcc * ( m_rchp0[_chnl] + in - m_rclast0[_chnl] ); + sample_t hp = m_rcc * (m_rchp0[_chnl] + in - m_rclast0[_chnl]); hp = std::clamp(hp, -1.0f, 1.0f); - bp = hp * m_rcb + m_rcbp0[_chnl] * m_rca; + sample_t bp = hp * m_rcb + m_rcbp0[_chnl] * m_rca; bp = std::clamp(bp, -1.0f, 1.0f); m_rclast0[_chnl] = in; @@ -494,10 +491,10 @@ class BasicFilters case FilterType::Highpass_RC12: case FilterType::Bandpass_RC12: { - sample_t hp, bp, in; + sample_t hp, bp; for( int n = 4; n != 0; --n ) { - in = _in0 + m_rcbp0[_chnl] * m_rcq; + sample_t in = _in0 + m_rcbp0[_chnl] * m_rcq; in = std::clamp(in, -1.0f, 1.0f); hp = m_rcc * ( m_rchp0[_chnl] + in - m_rclast0[_chnl] ); @@ -515,20 +512,20 @@ class BasicFilters case FilterType::Lowpass_RC24: { - sample_t lp, bp, hp, in; + sample_t lp; for( int n = 4; n != 0; --n ) { // first stage is as for the 12dB case... - in = _in0 + m_rcbp0[_chnl] * m_rcq; + sample_t in = _in0 + m_rcbp0[_chnl] * m_rcq; in = std::clamp(in, -1.0f, 1.0f); lp = in * m_rcb + m_rclp0[_chnl] * m_rca; lp = std::clamp(lp, -1.0f, 1.0f); - hp = m_rcc * ( m_rchp0[_chnl] + in - m_rclast0[_chnl] ); + sample_t hp = m_rcc * ( m_rchp0[_chnl] + in - m_rclast0[_chnl] ); hp = std::clamp(hp, -1.0f, 1.0f); - bp = hp * m_rcb + m_rcbp0[_chnl] * m_rca; + sample_t bp = hp * m_rcb + m_rcbp0[_chnl] * m_rca; bp = std::clamp(bp, -1.0f, 1.0f); m_rclast0[_chnl] = in; @@ -559,11 +556,11 @@ class BasicFilters case FilterType::Highpass_RC24: case FilterType::Bandpass_RC24: { - sample_t hp, bp, in; + sample_t hp, bp; for( int n = 4; n != 0; --n ) { // first stage is as for the 12dB case... - in = _in0 + m_rcbp0[_chnl] * m_rcq; + sample_t in = _in0 + m_rcbp0[_chnl] * m_rcq; in = std::clamp(in, -1.0f, 1.0f); hp = m_rcc * ( m_rchp0[_chnl] + in - m_rclast0[_chnl] ); @@ -600,20 +597,18 @@ class BasicFilters case FilterType::FastFormant: { if (std::abs(_in0) < 1.0e-10f && std::abs(m_vflast[0][_chnl]) < 1.0e-10f) { return 0.0f; } // performance hack - skip processing when the numbers get too small - sample_t hp, bp, in; - out = 0; const int os = m_type == FilterType::FastFormant ? 1 : 4; // no oversampling for fast formant for( int o = 0; o < os; ++o ) { // first formant - in = _in0 + m_vfbp[0][_chnl] * m_vfq; + sample_t in = _in0 + m_vfbp[0][_chnl] * m_vfq; in = std::clamp(in, -1.0f, 1.0f); - hp = m_vfc[0] * ( m_vfhp[0][_chnl] + in - m_vflast[0][_chnl] ); + sample_t hp = m_vfc[0] * ( m_vfhp[0][_chnl] + in - m_vflast[0][_chnl] ); hp = std::clamp(hp, -1.0f, 1.0f); - bp = hp * m_vfb[0] + m_vfbp[0][_chnl] * m_vfa[0]; + sample_t bp = hp * m_vfb[0] + m_vfbp[0][_chnl] * m_vfa[0]; bp = std::clamp(bp, -1.0f, 1.0f); m_vflast[0][_chnl] = in; diff --git a/include/IoHelper.h b/include/IoHelper.h index 40c576b8354..3c453fa58ac 100644 --- a/include/IoHelper.h +++ b/include/IoHelper.h @@ -75,13 +75,12 @@ inline FILE* F_OPEN_UTF8(std::string const& fname, const char* mode){ inline int fileToDescriptor(FILE* f, bool closeFile = true) { - int fh; if (f == nullptr) {return -1;} #ifdef LMMS_BUILD_WIN32 - fh = _dup(_fileno(f)); + int fh = _dup(_fileno(f)); #else - fh = dup(fileno(f)); + int fh = dup(fileno(f)); #endif if (closeFile) {fclose(f);} diff --git a/include/LocaleHelper.h b/include/LocaleHelper.h index 9c829fcaa61..c1e1b473566 100644 --- a/include/LocaleHelper.h +++ b/include/LocaleHelper.h @@ -39,10 +39,9 @@ namespace lmms::LocaleHelper inline double toDouble(QString str, bool* ok = nullptr) { bool isOkay; - double value; QLocale c(QLocale::C); c.setNumberOptions(QLocale::RejectGroupSeparator); - value = c.toDouble(str, &isOkay); + double value = c.toDouble(str, &isOkay); if (!isOkay) { QLocale german(QLocale::German); diff --git a/plugins/AudioFileProcessor/AudioFileProcessorWaveView.cpp b/plugins/AudioFileProcessor/AudioFileProcessorWaveView.cpp index 818fb14cb6c..89e328972f2 100644 --- a/plugins/AudioFileProcessor/AudioFileProcessorWaveView.cpp +++ b/plugins/AudioFileProcessor/AudioFileProcessorWaveView.cpp @@ -354,32 +354,21 @@ void AudioFileProcessorWaveView::zoom(const bool out) const double comp_ratio = double(qMin(d_from, d_to)) / qMax(1, qMax(d_from, d_to)); - f_cnt_t new_from; - f_cnt_t new_to; + const auto boundedFrom = std::clamp(m_from + step_from, 0, start); + const auto boundedTo = std::clamp(m_to + step_to, end, frames); - if ((out && d_from < d_to) || (! out && d_to < d_from)) - { - new_from = qBound(0, m_from + step_from, start); - new_to = qBound( - end, - m_to + f_cnt_t(step_to * (new_from == m_from ? 1 : comp_ratio)), - frames - ); - } - else - { - new_to = qBound(end, m_to + step_to, frames); - new_from = qBound( - 0, - m_from + f_cnt_t(step_from * (new_to == m_to ? 1 : comp_ratio)), - start - ); - } + const auto toStep = static_cast(step_from * (boundedTo == m_to ? 1 : comp_ratio)); + const auto newFrom + = (out && d_from < d_to) || (!out && d_to < d_from) ? boundedFrom : std::clamp(m_from + toStep, 0, start); + + const auto fromStep = static_cast(step_to * (boundedFrom == m_from ? 1 : comp_ratio)); + const auto newTo + = (out && d_from < d_to) || (!out && d_to < d_from) ? std::clamp(m_to + fromStep, end, frames) : boundedTo; - if (static_cast(new_to - new_from) / m_sample->sampleRate() > 0.05) + if (static_cast(newTo - newFrom) / m_sample->sampleRate() > 0.05) { - setFrom(new_from); - setTo(new_to); + setFrom(newFrom); + setTo(newTo); } } diff --git a/plugins/BitInvader/BitInvader.cpp b/plugins/BitInvader/BitInvader.cpp index 4685478ff5b..4743e262d8d 100644 --- a/plugins/BitInvader/BitInvader.cpp +++ b/plugins/BitInvader/BitInvader.cpp @@ -110,34 +110,18 @@ sample_t BSynth::nextStringSample( float sample_length ) sample_realindex -= sample_length; } - sample_t sample; - - if (interpolation) { + const auto currentRealIndex = sample_realindex; + const auto currentIndex = static_cast(sample_realindex); + sample_realindex += sample_step; - // find position in shape - int a = static_cast(sample_realindex); - int b; - if (a < (sample_length-1)) { - b = static_cast(sample_realindex+1); - } else { - b = 0; - } - - // Nachkommaanteil - const float frac = fraction( sample_realindex ); - - sample = linearInterpolate( sample_shape[a], sample_shape[b], frac ); - - } else { - // No interpolation - sample_index = static_cast(sample_realindex); - sample = sample_shape[sample_index]; + if (!interpolation) + { + sample_index = currentIndex; + return sample_shape[sample_index]; } - - // progress in shape - sample_realindex += sample_step; - return sample; + const auto nextIndex = currentIndex < sample_length - 1 ? currentIndex + 1 : 0; + return linearInterpolate(sample_shape[currentIndex], sample_shape[nextIndex], fraction(currentRealIndex)); } /*********************************************************************** @@ -276,16 +260,7 @@ void BitInvader::playNote( NotePlayHandle * _n, { if (!_n->m_pluginData) { - float factor; - if( !m_normalize.value() ) - { - factor = defaultNormalizationFactor; - } - else - { - factor = m_normalizeFactor; - } - + float factor = !m_normalize.value() ? defaultNormalizationFactor : m_normalizeFactor; _n->m_pluginData = new BSynth( const_cast( m_graph.samples() ), _n, diff --git a/plugins/CarlaBase/Carla.cpp b/plugins/CarlaBase/Carla.cpp index e58cb14af79..cb52fe25e8c 100644 --- a/plugins/CarlaBase/Carla.cpp +++ b/plugins/CarlaBase/Carla.cpp @@ -1116,16 +1116,15 @@ void CarlaParamsView::clearKnobs() } // Remove spacers - QLayoutItem* item; for (int16_t i=m_inputScrollAreaLayout->count() - 1; i > 0; i--) { - item = m_inputScrollAreaLayout->takeAt(i); + auto item = m_inputScrollAreaLayout->takeAt(i); if (item->widget()) {continue;} delete item; } for (int16_t i=m_outputScrollAreaLayout->count() - 1; i > 0; i--) { - item = m_outputScrollAreaLayout->takeAt(i); + auto item = m_outputScrollAreaLayout->takeAt(i); if (item->widget()) {continue;} delete item; } diff --git a/plugins/Delay/DelayEffect.cpp b/plugins/Delay/DelayEffect.cpp index 05204f355ee..0050cd6fa19 100644 --- a/plugins/Delay/DelayEffect.cpp +++ b/plugins/Delay/DelayEffect.cpp @@ -115,7 +115,7 @@ bool DelayEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames ) { m_outGain = dbfsToAmp( m_delayControls.m_outGainModel.value() ); } - int sampleLength; + for( fpp_t f = 0; f < frames; ++f ) { dryS[0] = buf[f][0]; @@ -123,8 +123,7 @@ bool DelayEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames ) m_delay->setFeedback( *feedbackPtr ); m_lfo->setFrequency( *lfoTimePtr ); - sampleLength = *lengthPtr * Engine::audioEngine()->processingSampleRate(); - m_currentLength = sampleLength; + m_currentLength = static_cast(*lengthPtr * Engine::audioEngine()->processingSampleRate()); m_delay->setLength( m_currentLength + ( *amplitudePtr * ( float )m_lfo->tick() ) ); m_delay->tick( buf[f] ); diff --git a/plugins/DynamicsProcessor/DynamicsProcessor.cpp b/plugins/DynamicsProcessor/DynamicsProcessor.cpp index f58dcedac19..583128bfb9b 100644 --- a/plugins/DynamicsProcessor/DynamicsProcessor.cpp +++ b/plugins/DynamicsProcessor/DynamicsProcessor.cpp @@ -106,7 +106,6 @@ bool DynProcEffect::processAudioBuffer( sampleFrame * _buf, int i = 0; auto sm_peak = std::array{0.0f, 0.0f}; - float gain; double out_sum = 0.0; const float d = dryLevel(); @@ -196,20 +195,10 @@ bool DynProcEffect::processAudioBuffer( sampleFrame * _buf, if( sm_peak[i] > DYN_NOISE_FLOOR ) { - if ( lookup < 1 ) - { - gain = frac * samples[0]; - } - else - if ( lookup < 200 ) - { - gain = linearInterpolate( samples[ lookup - 1 ], - samples[ lookup ], frac ); - } - else - { - gain = samples[199]; - }; + float gain; + if (lookup < 1) { gain = frac * samples[0]; } + else if (lookup < 200) { gain = linearInterpolate(samples[lookup - 1], samples[lookup], frac); } + else { gain = samples[199]; } s[i] *= gain; s[i] /= sm_peak[i]; diff --git a/plugins/Eq/EqCurve.cpp b/plugins/Eq/EqCurve.cpp index bb721a7e462..0493963b140 100644 --- a/plugins/Eq/EqCurve.cpp +++ b/plugins/Eq/EqCurve.cpp @@ -208,15 +208,14 @@ float EqHandle::getPeakCurve( float x ) double Q = getResonance(); double A = pow( 10, yPixelToGain( EqHandle::y(), m_heigth, m_pixelsPerUnitHeight ) / 40 ); double alpha = s * sinh( log( 2 ) / 2 * Q * w0 / sinf( w0 ) ); - double a0, a1, a2, b0, b1, b2; // coeffs to calculate //calc coefficents - b0 = 1 + alpha * A; - b1 = -2 * c; - b2 = 1 - alpha * A; - a0 = 1 + alpha / A; - a1 = -2 * c; - a2 = 1 - alpha / A; + double b0 = 1 + alpha * A; + double b1 = -2 * c; + double b2 = 1 - alpha * A; + double a0 = 1 + alpha / A; + double a1 = -2 * c; + double a2 = 1 - alpha / A; //normalise b0 /= a0; @@ -245,15 +244,15 @@ float EqHandle::getHighShelfCurve( float x ) double s = sinf( w0 ); double A = pow( 10, yPixelToGain( EqHandle::y(), m_heigth, m_pixelsPerUnitHeight ) * 0.025 ); double beta = sqrt( A ) / m_resonance; - double a0, a1, a2, b0, b1, b2; // coeffs to calculate //calc coefficents - b0 = A * ( ( A + 1 ) + ( A - 1 ) * c + beta * s); - b1 = -2 * A * ( ( A - 1 ) + ( A + 1 ) * c ); - b2 = A * ( ( A + 1 ) + ( A - 1 ) * c - beta * s); - a0 = ( A + 1 ) - ( A - 1 ) * c + beta * s; - a1 = 2 * ( ( A - 1 ) - ( A + 1 ) * c ); - a2 = ( A + 1 ) - ( A - 1 ) * c - beta * s; + double b0 = A * ((A + 1) + (A - 1) * c + beta * s); + double b1 = -2 * A * ((A - 1) + (A + 1) * c); + double b2 = A * ((A + 1) + (A - 1) * c - beta * s); + double a0 = (A + 1) - (A - 1) * c + beta * s; + double a1 = 2 * ((A - 1) - (A + 1) * c); + double a2 = (A + 1) - (A - 1) * c - beta * s; + //normalise b0 /= a0; b1 /= a0; @@ -281,15 +280,14 @@ float EqHandle::getLowShelfCurve( float x ) double s = sinf( w0 ); double A = pow( 10, yPixelToGain( EqHandle::y(), m_heigth, m_pixelsPerUnitHeight ) / 40 ); double beta = sqrt( A ) / m_resonance; - double a0, a1, a2, b0, b1, b2; // coeffs to calculate //calc coefficents - b0 = A * ( ( A + 1 ) - ( A - 1 ) * c + beta * s ); - b1 = 2 * A * ( ( A - 1 ) - ( A + 1 ) * c ) ; - b2 = A * ( ( A + 1 ) - ( A - 1 ) * c - beta * s); - a0 = ( A + 1 ) + ( A - 1 ) * c + beta * s; - a1 = -2 * ( ( A - 1 ) + ( A + 1 ) * c ); - a2 = ( A + 1 ) + ( A - 1) * c - beta * s; + double b0 = A * ((A + 1) - (A - 1) * c + beta * s); + double b1 = 2 * A * ((A - 1) - (A + 1) * c); + double b2 = A * ((A + 1) - (A - 1) * c - beta * s); + double a0 = (A + 1) + (A - 1) * c + beta * s; + double a1 = -2 * ((A - 1) + (A + 1) * c); + double a2 = (A + 1) + (A - 1) * c - beta * s; //normalise b0 /= a0; @@ -318,14 +316,14 @@ float EqHandle::getLowCutCurve( float x ) double s = sinf( w0 ); double resonance = getResonance(); double alpha = s / (2 * resonance); - double a0, a1, a2, b0, b1, b2; // coeffs to calculate - - b0 = ( 1 + c ) * 0.5; - b1 = ( -( 1 + c ) ); - b2 = ( 1 + c ) * 0.5; - a0 = 1 + alpha; - a1 = ( -2 * c ); - a2 = 1 - alpha; + + double b0 = (1 + c) * 0.5; + double b1 = (-(1 + c)); + double b2 = (1 + c) * 0.5; + double a0 = 1 + alpha; + double a1 = (-2 * c); + double a2 = 1 - alpha; + //normalise b0 /= a0; b1 /= a0; @@ -361,14 +359,14 @@ float EqHandle::getHighCutCurve( float x ) double s = sinf( w0 ); double resonance = getResonance(); double alpha = s / (2 * resonance); - double a0, a1, a2, b0, b1, b2; // coeffs to calculate - - b0 = ( 1 - c ) * 0.5; - b1 = 1 - c; - b2 = ( 1 - c ) * 0.5; - a0 = 1 + alpha; - a1 = -2 * c; - a2 = 1 - alpha; + + double b0 = (1 - c) * 0.5; + double b1 = 1 - c; + double b2 = (1 - c) * 0.5; + double a0 = 1 + alpha; + double a1 = -2 * c; + double a2 = 1 - alpha; + //normalise b0 /= a0; b1 /= a0; @@ -569,16 +567,7 @@ void EqHandle::mouseReleaseEvent( QGraphicsSceneMouseEvent *event ) void EqHandle::wheelEvent( QGraphicsSceneWheelEvent *wevent ) { - float highestBandwich; - if( m_type != EqHandleType::Para ) - { - highestBandwich = 10; - } - else - { - highestBandwich = 4; - } - + float highestBandwich = m_type != EqHandleType::Para ? 10 : 4; int numDegrees = wevent->delta() / 120; float numSteps = 0; if( wevent->modifiers() == Qt::ControlModifier ) diff --git a/plugins/Eq/EqFilter.h b/plugins/Eq/EqFilter.h index c64f6d5c345..df2b50493b4 100644 --- a/plugins/Eq/EqFilter.h +++ b/plugins/Eq/EqFilter.h @@ -190,15 +190,13 @@ public : float s = sinf( w0 ); float alpha = s / ( 2 * m_res ); - float a0, a1, a2, b0, b1, b2; // coeffs to calculate - //calc coefficents - b0 = ( 1 + c ) * 0.5; - b1 = ( -( 1 + c ) ); - b2 = ( 1 + c ) * 0.5; - a0 = 1 + alpha; - a1 = ( -2 * c ); - a2 = 1 - alpha; + float b0 = (1 + c) * 0.5; + float b1 = (-(1 + c)); + float b2 = (1 + c) * 0.5; + float a0 = 1 + alpha; + float a1 = (-2 * c); + float a2 = 1 - alpha; //normalise b0 /= a0; @@ -235,15 +233,13 @@ public : float s = sinf( w0 ); float alpha = s / ( 2 * m_res ); - float a0, a1, a2, b0, b1, b2; // coeffs to calculate - //calc coefficents - b0 = ( 1 - c ) * 0.5; - b1 = 1 - c; - b2 = ( 1 - c ) * 0.5; - a0 = 1 + alpha; - a1 = -2 * c; - a2 = 1 - alpha; + float b0 = (1 - c) * 0.5; + float b1 = 1 - c; + float b2 = (1 - c) * 0.5; + float a0 = 1 + alpha; + float a1 = -2 * c; + float a2 = 1 - alpha; //normalise b0 /= a0; @@ -279,15 +275,13 @@ class EqPeakFilter : public EqFilter float A = pow( 10, m_gain * 0.025); float alpha = s * sinh( log( 2 ) / 2 * m_bw * w0 / sinf(w0) ); - float a0, a1, a2, b0, b1, b2; // coeffs to calculate - //calc coefficents - b0 = 1 + alpha*A; - b1 = -2*c; - b2 = 1 - alpha*A; - a0 = 1 + alpha/A; - a1 = -2*c; - a2 = 1 - alpha/A; + float b0 = 1 + alpha * A; + float b1 = -2 * c; + float b2 = 1 - alpha * A; + float a0 = 1 + alpha / A; + float a1 = -2 * c; + float a2 = 1 - alpha / A; //normalise b0 /= a0; @@ -345,15 +339,13 @@ public : // float alpha = s / ( 2 * m_res ); float beta = sqrt( A ) / m_res; - float a0, a1, a2, b0, b1, b2; // coeffs to calculate - //calc coefficents - b0 = A * ( ( A+1 ) - ( A-1 ) * c + beta * s ); - b1 = 2 * A * ( ( A - 1 ) - ( A + 1 ) * c) ; - b2 = A * ( ( A + 1 ) - ( A - 1 ) * c - beta * s); - a0 = ( A + 1 ) + ( A - 1 ) * c + beta * s; - a1 = -2 * ( ( A - 1 ) + ( A + 1 ) * c ); - a2 = ( A + 1 ) + ( A - 1) * c - beta * s; + float b0 = A * ((A + 1) - (A - 1) * c + beta * s); + float b1 = 2 * A * ((A - 1) - (A + 1) * c); + float b2 = A * ((A + 1) - (A - 1) * c - beta * s); + float a0 = (A + 1) + (A - 1) * c + beta * s; + float a1 = -2 * ((A - 1) + (A + 1) * c); + float a2 = (A + 1) + (A - 1) * c - beta * s; //normalise b0 /= a0; @@ -383,15 +375,14 @@ public : float A = pow( 10, m_gain * 0.025 ); float beta = sqrt( A ) / m_res; - float a0, a1, a2, b0, b1, b2; // coeffs to calculate - //calc coefficents - b0 = A *( ( A +1 ) + ( A - 1 ) * c + beta * s); - b1 = -2 * A * ( ( A - 1 ) + ( A + 1 ) * c ); - b2 = A * ( ( A + 1 ) + ( A - 1 ) * c - beta * s); - a0 = ( A + 1 ) - ( A - 1 ) * c + beta * s; - a1 = 2 * ( ( A - 1 ) - ( A + 1 ) * c ); - a2 = ( A + 1) - ( A - 1 ) * c - beta * s; + float b0 = A * ((A + 1) + (A - 1) * c + beta * s); + float b1 = -2 * A * ((A - 1) + (A + 1) * c); + float b2 = A * ((A + 1) + (A - 1) * c - beta * s); + float a0 = (A + 1) - (A - 1) * c + beta * s; + float a1 = 2 * ((A - 1) - (A + 1) * c); + float a2 = (A + 1) - (A - 1) * c - beta * s; + //normalise b0 /= a0; b1 /= a0; diff --git a/plugins/Eq/EqSpectrumView.cpp b/plugins/Eq/EqSpectrumView.cpp index 540450883db..a90682b3674 100644 --- a/plugins/Eq/EqSpectrumView.cpp +++ b/plugins/Eq/EqSpectrumView.cpp @@ -228,13 +228,12 @@ void EqSpectrumView::paintEvent(QPaintEvent *event) //Now we calculate the path m_path = QPainterPath(); float *bands = m_analyser->m_bands; - float peak; m_path.moveTo( 0, height() ); m_peakSum = 0; const float fallOff = 1.07; for( int x = 0; x < MAX_BANDS; ++x, ++bands ) { - peak = *bands != 0. ? (fh * 2.0 / 3.0 * (20. * log10(*bands / energy) - LOWER_Y) / (-LOWER_Y)) : 0.; + float peak = *bands != 0. ? (fh * 2.0 / 3.0 * (20. * log10(*bands / energy) - LOWER_Y) / (-LOWER_Y)) : 0.; if( peak < 0 ) { diff --git a/plugins/Flanger/FlangerEffect.cpp b/plugins/Flanger/FlangerEffect.cpp index 60b5df67b1f..ddba0cb77ec 100644 --- a/plugins/Flanger/FlangerEffect.cpp +++ b/plugins/Flanger/FlangerEffect.cpp @@ -108,10 +108,11 @@ bool FlangerEffect::processAudioBuffer( sampleFrame *buf, const fpp_t frames ) m_lDelay->setFeedback( m_flangerControls.m_feedbackModel.value() ); m_rDelay->setFeedback( m_flangerControls.m_feedbackModel.value() ); auto dryS = std::array{}; - float leftLfo; - float rightLfo; for( fpp_t f = 0; f < frames; ++f ) { + float leftLfo; + float rightLfo; + buf[f][0] += m_noise->tick() * noise; buf[f][1] += m_noise->tick() * noise; dryS[0] = buf[f][0]; diff --git a/plugins/FreeBoy/game-music-emu b/plugins/FreeBoy/game-music-emu index 6b676192d98..21a064ea66a 160000 --- a/plugins/FreeBoy/game-music-emu +++ b/plugins/FreeBoy/game-music-emu @@ -1 +1 @@ -Subproject commit 6b676192d98302e698ac78fe3c00833eae6a74e5 +Subproject commit 21a064ea66a5cdf71910e207c4756095c266814f diff --git a/plugins/LadspaEffect/LadspaControlDialog.cpp b/plugins/LadspaEffect/LadspaControlDialog.cpp index 2a5437fb128..5189b0cde80 100644 --- a/plugins/LadspaEffect/LadspaControlDialog.cpp +++ b/plugins/LadspaEffect/LadspaControlDialog.cpp @@ -88,17 +88,9 @@ void LadspaControlDialog::updateEffectView( LadspaControls * _ctl ) int col = 0; BufferDataType last_port = BufferDataType::None; - QGroupBox * grouper; - if( _ctl->m_processors > 1 ) - { - grouper = new QGroupBox( tr( "Channel " ) + - QString::number( proc + 1 ), - this ); - } - else - { - grouper = new QGroupBox( this ); - } + auto grouper = _ctl->m_processors > 1 + ? new QGroupBox(tr("Channel ") + QString::number(proc + 1), this) + : new QGroupBox(this); auto gl = new QGridLayout(grouper); grouper->setLayout( gl ); diff --git a/plugins/Lb302/Lb302.cpp b/plugins/Lb302/Lb302.cpp index 44583cbc513..e0b31360fb4 100644 --- a/plugins/Lb302/Lb302.cpp +++ b/plugins/Lb302/Lb302.cpp @@ -166,12 +166,10 @@ void Lb302FilterIIR2::recalc() void Lb302FilterIIR2::envRecalc() { - float k, w; - Lb302Filter::envRecalc(); - w = vcf_e0 + vcf_c0; // e0 is adjusted for Hz and doesn't need ENVINC - k = exp(-w/vcf_rescoeff); // Does this mean c0 is inheritantly? + float w = vcf_e0 + vcf_c0; // e0 is adjusted for Hz and doesn't need ENVINC + float k = exp(-w/vcf_rescoeff); // Does this mean c0 is inheritantly? vcf_a = 2.0*cos(2.0*w) * k; vcf_b = -k*k; @@ -219,18 +217,15 @@ void Lb302Filter3Pole::recalc() // TODO: Try using k instead of vcf_reso void Lb302Filter3Pole::envRecalc() { - float w,k; - float kfco; - Lb302Filter::envRecalc(); // e0 is adjusted for Hz and doesn't need ENVINC - w = vcf_e0 + vcf_c0; - k = (fs->cutoff > 0.975)?0.975:fs->cutoff; + float w = vcf_e0 + vcf_c0; + float k = (fs->cutoff > 0.975)?0.975:fs->cutoff; // sampleRateCutoff should not be changed to anything dynamic that is outside the // scope of LB302 (like e.g. the audio engine's sample rate) as this changes the filter's cutoff // behavior without any modification to its controls. - kfco = 50.f + (k)*((2300.f-1600.f*(fs->envmod))+(w) * + float kfco = 50.f + (k)*((2300.f-1600.f*(fs->envmod))+(w) * (700.f+1500.f*(k)+(1500.f+(k)*(sampleRateCutoff/2.f-6000.f)) * (fs->envmod)) ); //+iacc*(.3+.7*kfco*kenvmod)*kaccent*kaccurve*2000 @@ -461,8 +456,6 @@ inline float GET_INC(float freq) { int Lb302Synth::process(sampleFrame *outbuf, const int size) { const float sampleRatio = 44100.f / Engine::audioEngine()->processingSampleRate(); - float w; - float samp; // Hold on to the current VCF, and use it throughout this period Lb302Filter *filter = vcf.loadAcquire(); @@ -566,7 +559,7 @@ int Lb302Synth::process(sampleFrame *outbuf, const int size) vco_k = -0.5 ; } else if (vco_k>0.5) { - w = 2.0*(vco_k-0.5)-1.0; + float w = 2.0 * (vco_k - 0.5) - 1.0; vco_k = 0.5 - sqrtf(1.0-(w*w)); } vco_k *= 2.0; // MOOG wave gets filtered away @@ -610,7 +603,7 @@ int Lb302Synth::process(sampleFrame *outbuf, const int size) #ifdef LB_FILTERED //samp = vcf->process(vco_k)*2.0*vca_a; //samp = vcf->process(vco_k)*2.0; - samp = filter->process(vco_k) * vca_a; + float samp = filter->process(vco_k) * vca_a; //printf("%f %d\n", vco_c, sample_cnt); diff --git a/plugins/MidiExport/MidiExport.cpp b/plugins/MidiExport/MidiExport.cpp index 2600a40f2f9..b3b08a0e113 100644 --- a/plugins/MidiExport/MidiExport.cpp +++ b/plugins/MidiExport/MidiExport.cpp @@ -76,21 +76,18 @@ bool MidiExport::tryExport(const TrackContainer::TrackList &tracks, f.open(QIODevice::WriteOnly); QDataStream midiout(&f); - InstrumentTrack* instTrack; - PatternTrack* patternTrack; QDomElement element; int nTracks = 0; auto buffer = std::array{}; - uint32_t size; for (const Track* track : tracks) if (track->type() == Track::Type::Instrument) nTracks++; for (const Track* track : patternStoreTracks) if (track->type() == Track::Type::Instrument) nTracks++; // midi header MidiFile::MIDIHeader header(nTracks); - size = header.writeToBuffer(buffer.data()); + uint32_t size = header.writeToBuffer(buffer.data()); midiout.writeRawData((char *)buffer.data(), size); std::vector>> plists; @@ -108,7 +105,7 @@ bool MidiExport::tryExport(const TrackContainer::TrackList &tracks, //mtrack.addProgramChange(0, 0); mtrack.addTempo(tempo, 0); - instTrack = dynamic_cast(track); + auto instTrack = dynamic_cast(track); element = instTrack->saveState(dataFile, dataFile.content()); int base_pitch = 0; @@ -146,7 +143,7 @@ bool MidiExport::tryExport(const TrackContainer::TrackList &tracks, if (track->type() == Track::Type::Pattern) { - patternTrack = dynamic_cast(track); + auto patternTrack = dynamic_cast(track); element = patternTrack->saveState(dataFile, dataFile.content()); std::vector> plist; @@ -184,7 +181,7 @@ bool MidiExport::tryExport(const TrackContainer::TrackList &tracks, //mtrack.addProgramChange(0, 0); mtrack.addTempo(tempo, 0); - instTrack = dynamic_cast(track); + auto instTrack = dynamic_cast(track); element = instTrack->saveState(dataFile, dataFile.content()); int base_pitch = 0; diff --git a/plugins/MidiExport/MidiFile.hpp b/plugins/MidiExport/MidiFile.hpp index 79c8dcce2cd..26f203cd67c 100644 --- a/plugins/MidiExport/MidiFile.hpp +++ b/plugins/MidiExport/MidiFile.hpp @@ -25,6 +25,7 @@ #include #include #include +#include using std::string; using std::vector; @@ -47,8 +48,8 @@ int writeVarLength(uint32_t val, uint8_t *buffer) byte in question is the last in the stream */ int size = 0; - uint8_t result, little_endian[4]; - result = val & 0x7F; + uint8_t little_endian[4]; + uint8_t result = val & 0x7F; little_endian[size++] = result; val = val >> 7; while (val > 0) @@ -129,31 +130,37 @@ struct Event inline int writeToBuffer(uint8_t *buffer) const { - uint8_t code, fourbytes[4]; - int size=0; - switch (type) + int size = 0; + switch (type) { case NOTE_ON: - code = 0x9 << 4 | channel; + { + uint8_t code = 0x9 << 4 | channel; size += writeVarLength(time, buffer+size); buffer[size++] = code; buffer[size++] = pitch; buffer[size++] = volume; break; + } case NOTE_OFF: - code = 0x8 << 4 | channel; + { + uint8_t code = 0x8 << 4 | channel; size += writeVarLength(time, buffer+size); buffer[size++] = code; buffer[size++] = pitch; buffer[size++] = volume; break; + } case TEMPO: - code = 0xFF; + { + uint8_t code = 0xFF; size += writeVarLength(time, buffer+size); buffer[size++] = code; buffer[size++] = 0x51; buffer[size++] = 0x03; - writeBigEndian4(int(60000000.0 / tempo), fourbytes); + + std::array fourbytes; + writeBigEndian4(int(60000000.0 / tempo), fourbytes.data()); //printf("tempo of %x translates to ", tempo); /* @@ -164,23 +171,27 @@ struct Event buffer[size++] = fourbytes[2]; buffer[size++] = fourbytes[3]; break; + } case PROG_CHANGE: - code = 0xC << 4 | channel; + { + uint8_t code = 0xC << 4 | channel; size += writeVarLength(time, buffer+size); buffer[size++] = code; buffer[size++] = programNumber; break; + } case TRACK_NAME: + { size += writeVarLength(time, buffer+size); buffer[size++] = 0xFF; buffer[size++] = 0x03; size += writeVarLength(trackName.size(), buffer+size); trackName.copy((char *)(&buffer[size]), trackName.size()); size += trackName.size(); -// buffer[size++] = '\0'; -// buffer[size++] = '\0'; - break; + // buffer[size++] = '\0'; + // buffer[size++] = '\0'; + } } return size; } // writeEventsToBuffer @@ -275,7 +286,7 @@ class MIDITrack vector _events = events; std::sort(_events.begin(), _events.end()); vector::const_iterator it; - uint32_t time_last = 0, tmp; + uint32_t time_last = 0; for (it = _events.begin(); it!=_events.end(); ++it) { Event e = *it; @@ -283,7 +294,7 @@ class MIDITrack printf("error: e.time=%d time_last=%d\n", e.time, time_last); assert(false); } - tmp = e.time; + uint32_t tmp = e.time; e.time -= time_last; time_last = tmp; start += e.writeToBuffer(buffer+start); diff --git a/plugins/MidiImport/MidiImport.h b/plugins/MidiImport/MidiImport.h index 817d06be855..0870511b571 100644 --- a/plugins/MidiImport/MidiImport.h +++ b/plugins/MidiImport/MidiImport.h @@ -61,10 +61,10 @@ class MidiImport : public ImportFilter inline int readInt( int _bytes ) { - int c, value = 0; + int value = 0; do { - c = readByte(); + int c = readByte(); if( c == -1 ) { return( -1 ); diff --git a/plugins/OpulenZ/OpulenZ.cpp b/plugins/OpulenZ/OpulenZ.cpp index d90d5f343a4..f0571ba5ce9 100644 --- a/plugins/OpulenZ/OpulenZ.cpp +++ b/plugins/OpulenZ/OpulenZ.cpp @@ -244,14 +244,12 @@ void OpulenzInstrument::reloadEmulator() { // This shall only be called from code protected by the holy Mutex! void OpulenzInstrument::setVoiceVelocity(int voice, int vel) { - int vel_adjusted; + int vel_adjusted = !fm_mdl.value() + ? 63 - (op1_lvl_mdl.value() * vel / 127.0) + : 63 - op1_lvl_mdl.value(); + // Velocity calculation, some kind of approximation // Only calculate for operator 1 if in adding mode, don't want to change timbre - if( fm_mdl.value() == false ) { - vel_adjusted = 63 - ( op1_lvl_mdl.value() * vel/127.0) ; - } else { - vel_adjusted = 63 - op1_lvl_mdl.value(); - } theEmulator->write(0x40+adlib_opadd[voice], ( (int)op1_scale_mdl.value() & 0x03 << 6) + ( vel_adjusted & 0x3f ) ); @@ -297,66 +295,60 @@ int OpulenzInstrument::pushVoice(int v) { bool OpulenzInstrument::handleMidiEvent( const MidiEvent& event, const TimePos& time, f_cnt_t offset ) { emulatorMutex.lock(); - int key, vel, voice, tmp_pb; - switch(event.type()) { - case MidiNoteOn: - key = event.key(); - vel = event.velocity(); - - voice = popVoice(); - if( voice != OPL2_NO_VOICE ) { + int key = event.key(); + int vel = event.velocity(); + switch (event.type()) + { + case MidiNoteOn: + if (int voice = popVoice(); voice != OPL2_NO_VOICE) + { // Turn voice on, NB! the frequencies are straight by voice number, // not by the adlib_opadd table! - theEmulator->write(0xA0+voice, fnums[key] & 0xff); - theEmulator->write(0xB0+voice, 32 + ((fnums[key] & 0x1f00) >> 8) ); + theEmulator->write(0xA0 + voice, fnums[key] & 0xff); + theEmulator->write(0xB0 + voice, 32 + ((fnums[key] & 0x1f00) >> 8)); setVoiceVelocity(voice, vel); voiceNote[voice] = key; velocities[key] = vel; } - break; - case MidiNoteOff: - key = event.key(); - for(voice=0; voicewrite(0xA0+voice, fnums[key] & 0xff); - theEmulator->write(0xB0+voice, (fnums[key] & 0x1f00) >> 8 ); - voiceNote[voice] |= OPL2_VOICE_FREE; + break; + case MidiNoteOff: + for (int voice = 0; voice < OPL2_VOICES; ++voice) + { + if (voiceNote[voice] == key) + { + theEmulator->write(0xA0 + voice, fnums[key] & 0xff); + theEmulator->write(0xB0 + voice, (fnums[key] & 0x1f00) >> 8); + voiceNote[voice] |= OPL2_VOICE_FREE; pushVoice(voice); - } - } - velocities[key] = 0; - break; - case MidiKeyPressure: - key = event.key(); - vel = event.velocity(); - if( velocities[key] != 0) { - velocities[key] = vel; - } - for(voice=0; voicewrite(0xA0+v, fnums[vn] & 0xff); - theEmulator->write(0xB0+v, (playing ? 32 : 0) + ((fnums[vn] & 0x1f00) >> 8) ); - } - break; + theEmulator->write(0xA0 + v, fnums[vn] & 0xff); + theEmulator->write(0xB0 + v, (playing ? 32 : 0) + ((fnums[vn] & 0x1f00) >> 8)); + } + break; case MidiControlChange: switch (event.controllerNumber()) { case MidiControllerRegisteredParameterNumberLSB: @@ -382,7 +374,7 @@ bool OpulenzInstrument::handleMidiEvent( const MidiEvent& event, const TimePos& printf("Midi event type %d\n",event.type()); #endif break; - } + } emulatorMutex.unlock(); return true; } @@ -504,9 +496,8 @@ void OpulenzInstrument::loadPatch(const unsigned char inst[14]) { } void OpulenzInstrument::tuneEqual(int center, float Hz) { - float tmp; for(int n=0; n<128; ++n) { - tmp = Hz*pow( 2.0, ( n - center ) * ( 1.0 / 12.0 ) + pitchbend * ( 1.0 / 1200.0 ) ); + float tmp = Hz * pow(2.0, (n - center) * (1.0 / 12.0) + pitchbend * (1.0 / 1200.0)); fnums[n] = Hz2fnum( tmp ); } } diff --git a/plugins/Patman/Patman.cpp b/plugins/Patman/Patman.cpp index 25664ae0dd6..a503637772a 100644 --- a/plugins/Patman/Patman.cpp +++ b/plugins/Patman/Patman.cpp @@ -298,17 +298,16 @@ PatmanInstrument::LoadError PatmanInstrument::loadPatch( SKIP_BYTES( 2 + 2 + 36 ); f_cnt_t frames; - sample_t * wave_samples; + std::unique_ptr wave_samples; if( modes & MODES_16BIT ) { frames = data_length >> 1; - wave_samples = new sample_t[frames]; + wave_samples = std::make_unique(frames); for( f_cnt_t frame = 0; frame < frames; ++frame ) { short sample; if ( fread( &sample, 2, 1, fd ) != 1 ) { - delete[] wave_samples; fclose( fd ); return( LoadError::IO ); } @@ -326,13 +325,12 @@ PatmanInstrument::LoadError PatmanInstrument::loadPatch( else { frames = data_length; - wave_samples = new sample_t[frames]; + wave_samples = std::make_unique(frames); for( f_cnt_t frame = 0; frame < frames; ++frame ) { char sample; if ( fread( &sample, 1, 1, fd ) != 1 ) { - delete[] wave_samples; fclose( fd ); return( LoadError::IO ); } @@ -366,7 +364,6 @@ PatmanInstrument::LoadError PatmanInstrument::loadPatch( m_patchSamples.push_back(psample); - delete[] wave_samples; delete[] data; } fclose( fd ); diff --git a/plugins/Sid/SidInstrument.cpp b/plugins/Sid/SidInstrument.cpp index 7f9edf13f18..d85939eb844 100644 --- a/plugins/Sid/SidInstrument.cpp +++ b/plugins/Sid/SidInstrument.cpp @@ -241,24 +241,21 @@ f_cnt_t SidInstrument::desiredReleaseFrames() const static int sid_fillbuffer(unsigned char* sidreg, reSID::SID *sid, int tdelta, short *ptr, int samples) { - int tdelta2; - int result; int total = 0; - int c; // customly added int residdelay = 0; int badline = rand() % NUMSIDREGS; - for (c = 0; c < NUMSIDREGS; c++) + for (int c = 0; c < NUMSIDREGS; c++) { unsigned char o = sidorder[c]; // Extra delay for loading the waveform (and mt_chngate,x) if ((o == 4) || (o == 11) || (o == 18)) { - tdelta2 = SIDWAVEDELAY; - result = sid->clock(tdelta2, ptr, samples); + int tdelta2 = SIDWAVEDELAY; + int result = sid->clock(tdelta2, ptr, samples); total += result; ptr += result; samples -= result; @@ -268,8 +265,8 @@ static int sid_fillbuffer(unsigned char* sidreg, reSID::SID *sid, int tdelta, sh // Possible random badline delay once per writing if ((badline == c) && (residdelay)) { - tdelta2 = residdelay; - result = sid->clock(tdelta2, ptr, samples); + int tdelta2 = residdelay; + int result = sid->clock(tdelta2, ptr, samples); total += result; ptr += result; samples -= result; @@ -278,14 +275,14 @@ static int sid_fillbuffer(unsigned char* sidreg, reSID::SID *sid, int tdelta, sh sid->write(o, sidreg[o]); - tdelta2 = SIDWRITEDELAY; - result = sid->clock(tdelta2, ptr, samples); + int tdelta2 = SIDWRITEDELAY; + int result = sid->clock(tdelta2, ptr, samples); total += result; ptr += result; samples -= result; tdelta -= SIDWRITEDELAY; } - result = sid->clock(tdelta, ptr, samples); + int result = sid->clock(tdelta, ptr, samples); total += result; return total; diff --git a/plugins/SlicerT/SlicerT.cpp b/plugins/SlicerT/SlicerT.cpp index 1c33970465b..732ebfb44f7 100644 --- a/plugins/SlicerT/SlicerT.cpp +++ b/plugins/SlicerT/SlicerT.cpp @@ -198,7 +198,6 @@ void SlicerT::findSlices() int lastPoint = -minDist - 1; // to always store 0 first float spectralFlux = 0; float prevFlux = 1E-10; // small value, no divison by zero - float real, imag, magnitude, diff; for (int i = 0; i < singleChannel.size() - windowSize; i += windowSize) { @@ -209,12 +208,12 @@ void SlicerT::findSlices() // calculate spectral flux in regard to last window for (int j = 0; j < windowSize / 2; j++) // only use niquistic frequencies { - real = fftOut[j][0]; - imag = fftOut[j][1]; - magnitude = std::sqrt(real * real + imag * imag); + float real = fftOut[j][0]; + float imag = fftOut[j][1]; + float magnitude = std::sqrt(real * real + imag * imag); // using L2-norm (euclidean distance) - diff = std::sqrt(std::pow(magnitude - prevMags[j], 2)); + float diff = std::sqrt(std::pow(magnitude - prevMags[j], 2)); spectralFlux += diff; prevMags[j] = magnitude; diff --git a/plugins/SpectrumAnalyzer/SaProcessor.cpp b/plugins/SpectrumAnalyzer/SaProcessor.cpp index 38e8e9e92fb..c55acbdf628 100644 --- a/plugins/SpectrumAnalyzer/SaProcessor.cpp +++ b/plugins/SpectrumAnalyzer/SaProcessor.cpp @@ -209,7 +209,6 @@ void SaProcessor::analyze(LocklessRingBuffer &ring_buffer) memset(pixel, 0, waterfallWidth() * sizeof (QRgb)); // add newest result on top - int target; // pixel being constructed float accL = 0; // accumulators for merging multiple bins float accR = 0; for (unsigned int i = 0; i < binCount(); i++) @@ -233,7 +232,8 @@ void SaProcessor::analyze(LocklessRingBuffer &ring_buffer) if (band_end - band_start > 1.0) { // band spans multiple pixels: draw all pixels it covers - for (target = std::max((int)band_start, 0); target < band_end && target < waterfallWidth(); target++) + for (int target = std::max(static_cast(band_start), 0); + target < band_end && target < waterfallWidth(); target++) { pixel[target] = makePixel(m_normSpectrumL[i], m_normSpectrumR[i]); } @@ -245,7 +245,7 @@ void SaProcessor::analyze(LocklessRingBuffer &ring_buffer) else { // sub-pixel drawing; add contribution of current band - target = (int)band_start; + int target = static_cast(band_start); if ((int)band_start == (int)band_end) { // band ends within current target pixel, accumulate @@ -270,7 +270,8 @@ void SaProcessor::analyze(LocklessRingBuffer &ring_buffer) else { // Linear: always draws one or more pixels per band - for (target = std::max((int)band_start, 0); target < band_end && target < waterfallWidth(); target++) + for (int target = std::max(static_cast(band_start), 0); + target < band_end && target < waterfallWidth(); target++) { pixel[target] = makePixel(m_normSpectrumL[i], m_normSpectrumR[i]); } @@ -361,30 +362,20 @@ void SaProcessor::setWaterfallActive(bool active) // Reallocate data buffers according to newly set block size. void SaProcessor::reallocateBuffers() { - unsigned int new_size_index = m_controls->m_blockSizeModel.value(); - unsigned int new_in_size, new_fft_size; - unsigned int new_bins; + m_zeroPadFactor = m_controls->m_zeroPaddingModel.value(); // get new block sizes and bin count based on selected index - if (new_size_index < FFT_BLOCK_SIZES.size()) - { - new_in_size = FFT_BLOCK_SIZES[new_size_index]; - } - else - { - new_in_size = FFT_BLOCK_SIZES.back(); - } - m_zeroPadFactor = m_controls->m_zeroPaddingModel.value(); - if (new_size_index + m_zeroPadFactor < FFT_BLOCK_SIZES.size()) - { - new_fft_size = FFT_BLOCK_SIZES[new_size_index + m_zeroPadFactor]; - } - else - { - new_fft_size = FFT_BLOCK_SIZES.back(); - } + const unsigned int new_size_index = m_controls->m_blockSizeModel.value(); + + const unsigned int new_in_size = new_size_index < FFT_BLOCK_SIZES.size() + ? FFT_BLOCK_SIZES[new_size_index] + : FFT_BLOCK_SIZES.back(); + + const unsigned int new_fft_size = (new_size_index + m_zeroPadFactor < FFT_BLOCK_SIZES.size()) + ? FFT_BLOCK_SIZES[new_size_index + m_zeroPadFactor] + : FFT_BLOCK_SIZES.back(); - new_bins = new_fft_size / 2 +1; + const unsigned int new_bins = new_fft_size / 2 + 1; // Use m_reallocating to tell analyze() to avoid asking for the lock. This // is needed because under heavy load the FFT thread requests data lock so diff --git a/plugins/SpectrumAnalyzer/SaSpectrumView.cpp b/plugins/SpectrumAnalyzer/SaSpectrumView.cpp index 0d9c2af87a2..7f73ed7cc1e 100644 --- a/plugins/SpectrumAnalyzer/SaSpectrumView.cpp +++ b/plugins/SpectrumAnalyzer/SaSpectrumView.cpp @@ -647,14 +647,13 @@ float SaSpectrumView::ampToYPixel(float amplitude, unsigned int height) std::vector> SaSpectrumView::makeLogFreqTics(int low, int high) { std::vector> result; - int i, j; auto a = std::array{10, 20, 50}; // sparse series multipliers auto b = std::array{14, 30, 70}; // additional (denser) series // generate main steps (powers of 10); use the series to specify smaller steps - for (i = 1; i <= high; i *= 10) + for (int i = 1; i <= high; i *= 10) { - for (j = 0; j < 3; j++) + for (int j = 0; j < 3; j++) { // insert a label from sparse series if it falls within bounds if (i * a[j] >= low && i * a[j] <= high) @@ -691,7 +690,7 @@ std::vector> SaSpectrumView::makeLogFreqTics(int low std::vector> SaSpectrumView::makeLinearFreqTics(int low, int high) { std::vector> result; - int i, increment; + int increment; // select a suitable increment based on zoom level if (high - low < 500) {increment = 50;} @@ -700,7 +699,7 @@ std::vector> SaSpectrumView::makeLinearFreqTics(int else {increment = 2000;} // generate steps based on increment, starting at 0 - for (i = 0; i <= high; i += increment) + for (int i = 0; i <= high; i += increment) { if (i >= low) { @@ -724,7 +723,6 @@ std::vector> SaSpectrumView::makeLinearFreqTics(int std::vector> SaSpectrumView::makeLogAmpTics(int low, int high) { std::vector> result; - float i; double increment; // Base zoom level on selected range and how close is the current height @@ -744,7 +742,7 @@ std::vector> SaSpectrumView::makeLogAmpTics(int lo // Generate n dB increments, start checking at -90 dB. Limits are tweaked // just a little bit to make sure float comparisons do not miss edges. - for (i = 0.000000001; 10 * log10(i) <= (high + 0.001); i *= increment) + for (float i = 0.000000001; 10 * log10(i) <= (high + 0.001); i *= increment) { if (10 * log10(i) >= (low - 0.001)) { @@ -764,8 +762,6 @@ std::vector> SaSpectrumView::makeLogAmpTics(int lo std::vector> SaSpectrumView::makeLinearAmpTics(int low, int high) { std::vector> result; - double i, nearest; - // make about 5 labels when window is small, 10 if it is big float split = (float)height() / sizeHint().height() >= 1.5 ? 10.0 : 5.0; @@ -777,28 +773,28 @@ std::vector> SaSpectrumView::makeLinearAmpTics(int // multiples, just generate a few evenly spaced increments across the range, // paying attention only to the decimal places to keep labels short. // Limits are shifted a bit so that float comparisons do not miss edges. - for (i = 0; i <= (lin_high + 0.0001); i += (lin_high - lin_low) / split) + for (double i = 0; i <= (lin_high + 0.0001); i += (lin_high - lin_low) / split) { if (i >= (lin_low - 0.0001)) { if (i >= 9.99 && i < 99.9) { - nearest = std::round(i); + double nearest = std::round(i); result.emplace_back(nearest, std::to_string(nearest).substr(0, 2)); } else if (i >= 0.099) { // also covers numbers above 100 - nearest = std::round(i * 10) / 10; + double nearest = std::round(i * 10) / 10; result.emplace_back(nearest, std::to_string(nearest).substr(0, 3)); } else if (i >= 0.0099) { - nearest = std::round(i * 1000) / 1000; + double nearest = std::round(i * 1000) / 1000; result.emplace_back(nearest, std::to_string(nearest).substr(0, 4)); } else if (i >= 0.00099) { - nearest = std::round(i * 10000) / 10000; + double nearest = std::round(i * 10000) / 10000; result.emplace_back(nearest, std::to_string(nearest).substr(1, 4)); } else if (i > -0.01 && i < 0.01) diff --git a/plugins/SpectrumAnalyzer/SaWaterfallView.cpp b/plugins/SpectrumAnalyzer/SaWaterfallView.cpp index 598bad72551..024c3aea4d0 100644 --- a/plugins/SpectrumAnalyzer/SaWaterfallView.cpp +++ b/plugins/SpectrumAnalyzer/SaWaterfallView.cpp @@ -213,7 +213,6 @@ float SaWaterfallView::yPixelToTime(float position, int height) std::vector> SaWaterfallView::makeTimeTics() { std::vector> result; - float i; // get time value of the last line float limit = yPixelToTime(m_displayBottom, m_displayHeight); @@ -223,7 +222,7 @@ std::vector> SaWaterfallView::makeTimeTics() if (increment < 0.1) {increment = 0.1;} // NOTE: labels positions are rounded to match the (rounded) label value - for (i = 0; i <= limit; i += increment) + for (float i = 0; i <= limit; i += increment) { if (i > 99) { diff --git a/plugins/StereoEnhancer/StereoEnhancer.cpp b/plugins/StereoEnhancer/StereoEnhancer.cpp index a7937a2ec1d..7840030562c 100644 --- a/plugins/StereoEnhancer/StereoEnhancer.cpp +++ b/plugins/StereoEnhancer/StereoEnhancer.cpp @@ -90,10 +90,6 @@ bool StereoEnhancerEffect::processAudioBuffer( sampleFrame * _buf, // audio with this effect double out_sum = 0.0; - float width; - int frameIndex = 0; - - if( !isEnabled() || !isRunning() ) { return( false ); @@ -110,10 +106,10 @@ bool StereoEnhancerEffect::processAudioBuffer( sampleFrame * _buf, m_delayBuffer[m_currFrame][1] = _buf[f][1]; // Get the width knob value from the Stereo Enhancer effect - width = m_seFX.wideCoeff(); + float width = m_seFX.wideCoeff(); // Calculate the correct sample frame for processing - frameIndex = m_currFrame - width; + int frameIndex = m_currFrame - width; if( frameIndex < 0 ) { @@ -149,8 +145,7 @@ bool StereoEnhancerEffect::processAudioBuffer( sampleFrame * _buf, void StereoEnhancerEffect::clearMyBuffer() { - int i; - for (i = 0; i < DEFAULT_BUFFER_SIZE; i++) + for (int i = 0; i < DEFAULT_BUFFER_SIZE; i++) { m_delayBuffer[i][0] = 0.0f; m_delayBuffer[i][1] = 0.0f; diff --git a/plugins/Vectorscope/VectorView.cpp b/plugins/Vectorscope/VectorView.cpp index f856f6429e0..c4776a688e8 100644 --- a/plugins/Vectorscope/VectorView.cpp +++ b/plugins/Vectorscope/VectorView.cpp @@ -138,8 +138,6 @@ void VectorView::paintEvent(QPaintEvent *event) std::size_t frameCount = inBuffer.size(); // Draw new points on top - float left, right; - int x, y; const bool logScale = m_controls->m_logarithmicModel.value(); const unsigned short activeSize = hq ? m_displaySize : m_displaySize / 2; @@ -164,6 +162,8 @@ void VectorView::paintEvent(QPaintEvent *event) // The longer the line is, the dimmer, simulating real electron trace on luminescent screen. for (std::size_t frame = 0; frame < frameCount; frame++) { + float left = 0.0f; + float right = 0.0f; float inLeft = inBuffer[frame][0] * m_zoom; float inRight = inBuffer[frame][1] * m_zoom; // Scale left and right channel from (-1.0, 1.0) to display range @@ -185,8 +185,8 @@ void VectorView::paintEvent(QPaintEvent *event) } // Rotate display coordinates 45 degrees, flip Y axis and make sure the result stays within bounds - x = saturate(right - left + activeSize / 2.f); - y = saturate(activeSize - (right + left + activeSize / 2.f)); + int x = saturate(right - left + activeSize / 2.f); + int y = saturate(activeSize - (right + left + activeSize / 2.f)); // Estimate number of points needed to fill space between the old and new pixel. Cap at 100. unsigned char points = std::min((int)sqrt((m_oldX - x) * (m_oldX - x) + (m_oldY - y) * (m_oldY - y)), 100); @@ -222,6 +222,8 @@ void VectorView::paintEvent(QPaintEvent *event) // one full-color pixel per sample. for (std::size_t frame = 0; frame < frameCount; frame++) { + float left = 0.0f; + float right = 0.0f; float inLeft = inBuffer[frame][0] * m_zoom; float inRight = inBuffer[frame][1] * m_zoom; if (logScale) { @@ -235,8 +237,8 @@ void VectorView::paintEvent(QPaintEvent *event) left = inLeft * (activeSize - 1) / 4; right = inRight * (activeSize - 1) / 4; } - x = saturate(right - left + activeSize / 2.f); - y = saturate(activeSize - (right + left + activeSize / 2.f)); + int x = saturate(right - left + activeSize / 2.f); + int y = saturate(activeSize - (right + left + activeSize / 2.f)); ((QRgb*)m_displayBuffer.data())[x + y * activeSize] = m_controls->m_colorFG.rgb(); } } diff --git a/plugins/Vestige/Vestige.cpp b/plugins/Vestige/Vestige.cpp index a3ec267e5cc..552b1f3ff37 100644 --- a/plugins/Vestige/Vestige.cpp +++ b/plugins/Vestige/Vestige.cpp @@ -1053,7 +1053,6 @@ void ManageVestigeInstrumentView::syncPlugin( void ) auto paramStr = std::array{}; QStringList s_dumpValues; const QMap & dump = m_vi->m_plugin->parameterDump(); - float f_value; for( int i = 0; i < m_vi->paramCount; i++ ) { @@ -1063,7 +1062,7 @@ void ManageVestigeInstrumentView::syncPlugin( void ) { sprintf(paramStr.data(), "param%d", i); s_dumpValues = dump[paramStr.data()].split(":"); - f_value = LocaleHelper::toFloat(s_dumpValues.at(2)); + float f_value = LocaleHelper::toFloat(s_dumpValues.at(2)); m_vi->knobFModel[ i ]->setAutomatedValue( f_value ); m_vi->knobFModel[ i ]->setInitValue( f_value ); } diff --git a/plugins/Vibed/VibratingString.cpp b/plugins/Vibed/VibratingString.cpp index 44ade3c3a5c..216a5fbf333 100644 --- a/plugins/Vibed/VibratingString.cpp +++ b/plugins/Vibed/VibratingString.cpp @@ -75,12 +75,10 @@ std::unique_ptr VibratingString::initDelayLine(int l if (len > 0) { dl->data = std::make_unique(len); - float r; - float offset = 0.0f; for (int i = 0; i < dl->length; ++i) { - r = static_cast(std::rand()) / RAND_MAX; - offset = (m_randomize / 2.0f - m_randomize) * r; + float r = static_cast(std::rand()) / RAND_MAX; + float offset = (m_randomize / 2.0f - m_randomize) * r; dl->data[i] = offset; } } diff --git a/plugins/Vibed/VibratingString.h b/plugins/Vibed/VibratingString.h index efdaec28256..0ad5a6e6e47 100644 --- a/plugins/Vibed/VibratingString.h +++ b/plugins/Vibed/VibratingString.h @@ -49,8 +49,6 @@ class VibratingString sample_t nextSample() { - sample_t ym0; - sample_t ypM; for (int i = 0; i < m_oversample; ++i) { // Output at pickup position @@ -58,9 +56,9 @@ class VibratingString m_outsamp[i] += toBridgeAccess(m_toBridge.get(), m_pickupLoc); // Sample traveling into "bridge" - ym0 = toBridgeAccess(m_toBridge.get(), 1); + sample_t ym0 = toBridgeAccess(m_toBridge.get(), 1); // Sample to "nut" - ypM = fromBridgeAccess(m_fromBridge.get(), m_fromBridge->length - 2); + sample_t ypM = fromBridgeAccess(m_fromBridge.get(), m_fromBridge->length - 2); // String state update @@ -105,21 +103,18 @@ class VibratingString */ void setDelayLine(DelayLine* dl, int pick, const float* values, int len, float scale, bool state) { - float r; - float offset; - if (!state) { for (int i = 0; i < pick; ++i) { - r = static_cast(std::rand()) / RAND_MAX; - offset = (m_randomize / 2.0f - m_randomize) * r; + float r = static_cast(std::rand()) / RAND_MAX; + float offset = (m_randomize / 2.0f - m_randomize) * r; dl->data[i] = scale * values[dl->length - i - 1] + offset; } for (int i = pick; i < dl->length; ++i) { - r = static_cast(std::rand()) / RAND_MAX; - offset = (m_randomize / 2.0f - m_randomize) * r; + float r = static_cast(std::rand()) / RAND_MAX; + float offset = (m_randomize / 2.0f - m_randomize) * r; dl->data[i] = scale * values[i - pick] + offset; } } @@ -129,8 +124,8 @@ class VibratingString { for (int i = pick; i < dl->length; ++i) { - r = static_cast(std::rand()) / RAND_MAX; - offset = (m_randomize / 2.0f - m_randomize) * r; + float r = static_cast(std::rand()) / RAND_MAX; + float offset = (m_randomize / 2.0f - m_randomize) * r; dl->data[i] = scale * values[i - pick] + offset; } } @@ -138,8 +133,8 @@ class VibratingString { for (int i = 0; i < len; ++i) { - r = static_cast(std::rand()) / RAND_MAX; - offset = (m_randomize / 2.0f - m_randomize) * r; + float r = static_cast(std::rand()) / RAND_MAX; + float offset = (m_randomize / 2.0f - m_randomize) * r; dl->data[i+pick] = scale * values[i] + offset; } } diff --git a/plugins/VstEffect/VstEffectControls.cpp b/plugins/VstEffect/VstEffectControls.cpp index af90e46464e..c9eb4923451 100644 --- a/plugins/VstEffect/VstEffectControls.cpp +++ b/plugins/VstEffect/VstEffectControls.cpp @@ -452,7 +452,6 @@ void ManageVSTEffectView::syncPlugin() auto paramStr = std::array{}; QStringList s_dumpValues; const QMap & dump = m_effect->m_plugin->parameterDump(); - float f_value; for( int i = 0; i < m_vi2->paramCount; i++ ) { @@ -463,7 +462,7 @@ void ManageVSTEffectView::syncPlugin() { sprintf(paramStr.data(), "param%d", i); s_dumpValues = dump[paramStr.data()].split(":"); - f_value = LocaleHelper::toFloat(s_dumpValues.at(2)); + float f_value = LocaleHelper::toFloat(s_dumpValues.at(2)); m_vi2->knobFModel[ i ]->setAutomatedValue( f_value ); m_vi2->knobFModel[ i ]->setInitValue( f_value ); } diff --git a/plugins/Xpressive/ExprSynth.cpp b/plugins/Xpressive/ExprSynth.cpp index 991e0d3e6b2..736b47598ac 100644 --- a/plugins/Xpressive/ExprSynth.cpp +++ b/plugins/Xpressive/ExprSynth.cpp @@ -322,14 +322,8 @@ struct RandomVectorSeedFunction : public exprtk::ifunction inline float operator()(const float& index,const float& seed) override { - int irseed; - if (seed < 0 || std::isnan(seed) || std::isinf(seed)) - { - irseed=0; - } - else - irseed=(int)seed; - return randv(index,irseed); + const int irseed = seed < 0 || std::isnan(seed) || std::isinf(seed) ? 0 : static_cast(seed); + return randv(index, irseed); } static const int data_size=sizeof(random_data)/sizeof(int); diff --git a/plugins/Xpressive/Xpressive.cpp b/plugins/Xpressive/Xpressive.cpp index babc372317a..f738dc96521 100644 --- a/plugins/Xpressive/Xpressive.cpp +++ b/plugins/Xpressive/Xpressive.cpp @@ -256,13 +256,12 @@ void Xpressive::smooth(float smoothness,const graphModel * in,graphModel * out) auto const guassian = new float[guass_size]; float sum = 0.0f; float temp = 0.0f; - int i; - for (i = 0; i < guass_size; i++ ) + for (int i = 0; i < guass_size; i++) { temp = (i - guass_center) / delta; sum += guassian[i] = a * powf(F_E, -0.5f * temp * temp); } - for (i = 0; i < guass_size; i++ ) + for (int i = 0; i < guass_size; i++) { guassian[i] = guassian[i] / sum; } @@ -336,13 +335,6 @@ XpressiveView::XpressiveView(Instrument * _instrument, QWidget * _parent) : pal.setBrush(backgroundRole(), PLUGIN_NAME::getIconPixmap("wavegraph")); m_graph->setPalette(pal); - PixmapButton * m_w1Btn; - PixmapButton * m_w2Btn; - PixmapButton * m_w3Btn; - PixmapButton * m_o1Btn; - PixmapButton * m_o2Btn; - PixmapButton * m_helpBtn; - m_w1Btn = new PixmapButton(this, nullptr); m_w1Btn->move(3, ROW_BTN); m_w1Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("w1_active")); diff --git a/plugins/Xpressive/Xpressive.h b/plugins/Xpressive/Xpressive.h index b91957ac480..974b82b179f 100644 --- a/plugins/Xpressive/Xpressive.h +++ b/plugins/Xpressive/Xpressive.h @@ -190,6 +190,7 @@ protected slots: PixmapButton *m_w3Btn; PixmapButton *m_o1Btn; PixmapButton *m_o2Btn; + PixmapButton *m_helpBtn; PixmapButton *m_sinWaveBtn; PixmapButton *m_triangleWaveBtn; PixmapButton *m_sqrWaveBtn; diff --git a/src/core/AutomatableModel.cpp b/src/core/AutomatableModel.cpp index c701f28e36d..abda0b43ed3 100644 --- a/src/core/AutomatableModel.cpp +++ b/src/core/AutomatableModel.cpp @@ -613,10 +613,9 @@ ValueBuffer * AutomatableModel::valueBuffer() float val = m_value; // make sure our m_value doesn't change midway - ValueBuffer * vb; if (m_controllerConnection && m_useControllerValue && m_controllerConnection->getController()->isSampleExact()) { - vb = m_controllerConnection->valueBuffer(); + auto vb = m_controllerConnection->valueBuffer(); if( vb ) { float * values = vb->values(); @@ -656,7 +655,7 @@ ValueBuffer * AutomatableModel::valueBuffer() if (lm && lm->controllerConnection() && lm->useControllerValue() && lm->controllerConnection()->getController()->isSampleExact()) { - vb = lm->valueBuffer(); + auto vb = lm->valueBuffer(); float * values = vb->values(); float * nvalues = m_valueBuffer.values(); for (int i = 0; i < vb->length(); i++) diff --git a/src/core/AutomationClip.cpp b/src/core/AutomationClip.cpp index 6035502704d..0e427182238 100644 --- a/src/core/AutomationClip.cpp +++ b/src/core/AutomationClip.cpp @@ -1222,11 +1222,9 @@ void AutomationClip::generateTangents(timeMap::iterator it, int numToGenerate) // TODO: This behavior means that a very small difference between the inValue and outValue can // result in a big change in the curve. In the future, allowing the user to manually adjust // the tangents would be better. - float inTangent; - float outTangent; if (OFFSET(it) == 0) { - inTangent = (INVAL(it + 1) - OUTVAL(it - 1)) / (POS(it + 1) - POS(it - 1)); + float inTangent = (INVAL(it + 1) - OUTVAL(it - 1)) / (POS(it + 1) - POS(it - 1)); it.value().setInTangent(inTangent); // inTangent == outTangent in this case it.value().setOutTangent(inTangent); @@ -1234,9 +1232,9 @@ void AutomationClip::generateTangents(timeMap::iterator it, int numToGenerate) else { // Calculate the left side of the curve - inTangent = (INVAL(it) - OUTVAL(it - 1)) / (POS(it) - POS(it - 1)); + float inTangent = (INVAL(it) - OUTVAL(it - 1)) / (POS(it) - POS(it - 1)); // Calculate the right side of the curve - outTangent = (INVAL(it + 1) - OUTVAL(it)) / (POS(it + 1) - POS(it)); + float outTangent = (INVAL(it + 1) - OUTVAL(it)) / (POS(it + 1) - POS(it)); it.value().setInTangent(inTangent); it.value().setOutTangent(outTangent); } diff --git a/src/core/BandLimitedWave.cpp b/src/core/BandLimitedWave.cpp index cb09dc5b8f5..060ff510a43 100644 --- a/src/core/BandLimitedWave.cpp +++ b/src/core/BandLimitedWave.cpp @@ -49,11 +49,11 @@ QDataStream& operator<< ( QDataStream &out, WaveMipMap &waveMipMap ) QDataStream& operator>> ( QDataStream &in, WaveMipMap &waveMipMap ) { - sample_t sample; for( int tbl = 0; tbl <= MAXTBL; tbl++ ) { for( int i = 0; i < TLENS[tbl]; i++ ) { + sample_t sample; in >> sample; waveMipMap.setSampleAt( tbl, i, sample ); } @@ -67,9 +67,8 @@ void BandLimitedWave::generateWaves() // don't generate if they already exist if( s_wavesGenerated ) return; - int i; -// set wavetable directory + // set wavetable directory s_wavetableDir = "data:wavetables/"; // set wavetable files @@ -89,7 +88,7 @@ void BandLimitedWave::generateWaves() } else { - for( i = 0; i <= MAXTBL; i++ ) + for (int i = 0; i <= MAXTBL; i++) { const int len = TLENS[i]; //const double om = 1.0 / len; @@ -131,7 +130,7 @@ void BandLimitedWave::generateWaves() } else { - for( i = 0; i <= MAXTBL; i++ ) + for (int i = 0; i <= MAXTBL; i++) { const int len = TLENS[i]; //const double om = 1.0 / len; @@ -172,7 +171,7 @@ void BandLimitedWave::generateWaves() } else { - for( i = 0; i <= MAXTBL; i++ ) + for (int i = 0; i <= MAXTBL; i++) { const int len = TLENS[i]; //const double om = 1.0 / len; @@ -215,7 +214,7 @@ void BandLimitedWave::generateWaves() } else { - for( i = 0; i <= MAXTBL; i++ ) + for (int i = 0; i <= MAXTBL; i++) { const int len = TLENS[i]; diff --git a/src/core/Controller.cpp b/src/core/Controller.cpp index 3e1b596b8ca..81fc13c865f 100644 --- a/src/core/Controller.cpp +++ b/src/core/Controller.cpp @@ -220,24 +220,12 @@ Controller * Controller::create( ControllerType _ct, Model * _parent ) Controller * Controller::create( const QDomElement & _this, Model * _parent ) { - Controller * c; - if( static_cast(_this.attribute( "type" ).toInt()) == ControllerType::Peak ) - { - c = PeakController::getControllerBySetting( _this ); - } - else - { - c = create( - static_cast( _this.attribute( "type" ).toInt() ), - _parent ); - } - - if( c != nullptr ) - { - c->restoreState( _this ); - } - - return( c ); + const auto controllerType = static_cast(_this.attribute("type").toInt()); + auto controller = controllerType == ControllerType::Peak + ? PeakController::getControllerBySetting(_this) + : create(controllerType, _parent); + if (controller) { controller->restoreState(_this); } + return controller; } diff --git a/src/core/DataFile.cpp b/src/core/DataFile.cpp index 3c6309db85f..eedb7f01d8a 100644 --- a/src/core/DataFile.cpp +++ b/src/core/DataFile.cpp @@ -1194,12 +1194,11 @@ void DataFile::upgrade_1_2_0_rc3() "pattern" ); for( int j = 0; !patterns.item( j ).isNull(); ++j ) { - int patternLength, steps; QDomElement el = patterns.item( j ).toElement(); if( el.attribute( "len" ) != "" ) { - patternLength = el.attribute( "len" ).toInt(); - steps = patternLength / 12; + int patternLength = el.attribute( "len" ).toInt(); + int steps = patternLength / 12; el.setAttribute( "steps", steps ); } } @@ -1456,7 +1455,7 @@ void DataFile::upgrade_1_3_0() if(num == 4) { // don't modify port 4, but some other ones: - int zoom_port; + int zoom_port = 0; if (plugin == "Equalizer5Band") zoom_port = 36; else if (plugin == "Equalizer8Band") diff --git a/src/core/DrumSynth.cpp b/src/core/DrumSynth.cpp index decc6bfa26d..031b19c1cdf 100644 --- a/src/core/DrumSynth.cpp +++ b/src/core/DrumSynth.cpp @@ -69,16 +69,16 @@ float mem_t=1.0f, mem_o=1.0f, mem_n=1.0f, mem_b=1.0f, mem_tune=1.0f, mem_time=1. int DrumSynth::LongestEnv() { - long e, eon, p; - float l=0.f; - - for(e=1; e<7; e++) //3 - { - eon = e - 1; if(eon>2) eon=eon-1; - p = 0; - while (envpts[e][0][p + 1] >= 0.f) p++; - envData[e][MAX] = envpts[e][0][p] * timestretch; - if(chkOn[eon]==1) if(envData[e][MAX]>l) l=envData[e][MAX]; + float l = 0.f; + + for (long e = 1; e < 7; e++) // 3 + { + long eon = e - 1; + if (eon > 2) { eon = eon - 1; } + long p = 0; + while (envpts[e][0][p + 1] >= 0.f) { p++; } + envData[e][MAX] = envpts[e][0][p] * timestretch; + if (chkOn[eon] == 1 && envData[e][MAX] > l) { l = envData[e][MAX]; } } //l *= timestretch; @@ -102,16 +102,15 @@ float DrumSynth::LoudestEnv() void DrumSynth::UpdateEnv(int e, long t) { - float endEnv, dT; - //0.2's added - envData[e][NEXTT] = envpts[e][0][(long)(envData[e][PNT] + 1.f)] * timestretch; //get next point - if(envData[e][NEXTT] < 0) envData[e][NEXTT] = 442000 * timestretch; //if end point, hold - envData[e][ENV] = envpts[e][1][(long)(envData[e][PNT] + 0.f)] * 0.01f; //this level - endEnv = envpts[e][1][(long)(envData[e][PNT] + 1.f)] * 0.01f; //next level - dT = envData[e][NEXTT] - (float)t; - if(dT < 1.0) dT = 1.0; - envData[e][dENV] = (endEnv - envData[e][ENV]) / dT; - envData[e][PNT] = envData[e][PNT] + 1.0f; + // 0.2's added + envData[e][NEXTT] = envpts[e][0][static_cast(envData[e][PNT] + 1.f)] * timestretch; // get next point + if (envData[e][NEXTT] < 0) { envData[e][NEXTT] = 442000 * timestretch; } // if end point, hold + envData[e][ENV] = envpts[e][1][static_cast(envData[e][PNT] + 0.f)] * 0.01f; // this level + float endEnv = envpts[e][1][static_cast(envData[e][PNT] + 1.f)] * 0.01f; // next level + float dT = envData[e][NEXTT] - static_cast(t); + if (dT < 1.0) { dT = 1.0; } + envData[e][dENV] = (endEnv - envData[e][ENV]) / dT; + envData[e][PNT] = envData[e][PNT] + 1.0f; } @@ -149,34 +148,41 @@ void DrumSynth::GetEnv(int env, const char *sec, const char *key, QString ini) float DrumSynth::waveform(float ph, int form) { - float w; - - switch (form) - { - case 0: w = (float)sin(fmod(ph,TwoPi)); break; //sine - case 1: w = (float)fabs(2.0f*(float)sin(fmod(0.5f*ph,TwoPi)))-1.f; break; //sine^2 - case 2: while(ph1.f) w=2.f-w; - break; - case 3: w = ph - TwoPi * (float)(int)(ph / TwoPi); //saw - w = (0.3183098f * w) - 1.f; break; - default: w = (sin(fmod(ph,TwoPi))>0.0)? 1.f: -1.f; break; //square - } - - return w; + float w; + + switch (form) + { + case 0: + w = static_cast(sin(fmod(ph, TwoPi))); + break; // sine + case 1: + w = static_cast(fabs(2.0f * static_cast(sin(fmod(0.5f * ph, TwoPi))) - 1.f)); + break; // sine^2 + case 2: + while (ph < TwoPi) { ph += TwoPi; } + w = 0.6366197f * static_cast(fmod(ph, TwoPi) - 1.f); // tri + if (w > 1.f) { w = 2.f - w; } + break; + case 3: + w = ph - TwoPi * static_cast(static_cast(ph / TwoPi)); // saw + w = (0.3183098f * w) - 1.f; + break; + default: + w = (sin(fmod(ph, TwoPi)) > 0.0) ? 1.f : -1.f; + break; // square + } + + return w; } int DrumSynth::GetPrivateProfileString(const char *sec, const char *key, const char *def, char *buffer, int size, QString file) { - stringstream is; - bool inSection = false; - char *line; - char *k, *b; - int len = 0; + stringstream is; + bool inSection = false; + int len = 0; - line = (char*)malloc(200); + char* line = static_cast(malloc(200)); // Use QFile to handle unicode file name on Windows // Previously we used ifstream directly @@ -201,8 +207,8 @@ int DrumSynth::GetPrivateProfileString(const char *sec, const char *key, const c if (line[0] == '[') break; - k = strtok(line, " \t="); - b = strtok(nullptr, "\n\r\0"); + char* k = strtok(line, " \t="); + char* b = strtok(nullptr, "\n\r\0"); if (k != 0 && strcasecmp(k, key)==0) { if (b==0) { diff --git a/src/core/Effect.cpp b/src/core/Effect.cpp index 51b701d9b54..7ede64e6b07 100644 --- a/src/core/Effect.cpp +++ b/src/core/Effect.cpp @@ -210,8 +210,8 @@ void Effect::resample( int _i, const sampleFrame * _src_buf, m_srcData[_i].data_out = _dst_buf[0].data (); m_srcData[_i].src_ratio = (double) _dst_sr / _src_sr; m_srcData[_i].end_of_input = 0; - int error; - if( ( error = src_process( m_srcState[_i], &m_srcData[_i] ) ) ) + + if (int error = src_process(m_srcState[_i], &m_srcData[_i])) { qFatal( "Effect::resample(): error while resampling: %s\n", src_strerror( error ) ); diff --git a/src/core/InstrumentPlayHandle.cpp b/src/core/InstrumentPlayHandle.cpp index 097719ad83d..06b8837a8e2 100644 --- a/src/core/InstrumentPlayHandle.cpp +++ b/src/core/InstrumentPlayHandle.cpp @@ -46,11 +46,10 @@ void InstrumentPlayHandle::play(sampleFrame * working_buffer) // ensure that all our nph's have been processed first auto nphv = NotePlayHandle::nphsOfInstrumentTrack(instrumentTrack, true); - - bool nphsLeft; + + bool nphsLeft = false; do { - nphsLeft = false; for (const NotePlayHandle * constNotePlayHandle : nphv) { if (constNotePlayHandle->state() != ThreadableJob::ProcessingState::Done && diff --git a/src/core/LadspaManager.cpp b/src/core/LadspaManager.cpp index 064c928efd2..cc63af63054 100644 --- a/src/core/LadspaManager.cpp +++ b/src/core/LadspaManager.cpp @@ -139,11 +139,7 @@ void LadspaManager::addPlugins( LADSPA_Descriptor_Function _descriptor_func, const QString & _file ) { - const LADSPA_Descriptor * descriptor; - - for( long pluginIndex = 0; - ( descriptor = _descriptor_func( pluginIndex ) ) != nullptr; - ++pluginIndex ) + for (long pluginIndex = 0; const auto descriptor = _descriptor_func(pluginIndex); ++pluginIndex) { ladspa_key_t key( _file, QString( descriptor->Label ) ); if( m_ladspaManagerMap.contains( key ) ) diff --git a/src/core/LinkedModelGroups.cpp b/src/core/LinkedModelGroups.cpp index 83bebc2a07e..c52bce43310 100644 --- a/src/core/LinkedModelGroups.cpp +++ b/src/core/LinkedModelGroups.cpp @@ -143,9 +143,7 @@ bool LinkedModelGroup::containsModel(const QString &name) const void LinkedModelGroups::linkAllModels() { LinkedModelGroup* first = getGroup(0); - LinkedModelGroup* cur; - - for (std::size_t i = 1; (cur = getGroup(i)); ++i) + for (size_t i = 1; auto cur = getGroup(i); ++i) { first->linkControls(cur); } @@ -172,8 +170,7 @@ void LinkedModelGroups::saveSettings(QDomDocument& doc, QDomElement& that) void LinkedModelGroups::loadSettings(const QDomElement& that) { QDomElement models = that.firstChildElement("models"); - LinkedModelGroup* grp0; - if (!models.isNull() && (grp0 = getGroup(0))) + if (auto grp0 = getGroup(0); !models.isNull() && grp0) { // only load the first group, the others are linked to the first grp0->loadValues(models); diff --git a/src/core/MemoryHelper.cpp b/src/core/MemoryHelper.cpp index de80ef7701d..8f990d57e92 100644 --- a/src/core/MemoryHelper.cpp +++ b/src/core/MemoryHelper.cpp @@ -36,15 +36,14 @@ namespace lmms */ void* MemoryHelper::alignedMalloc( size_t byteNum ) { - char *ptr, *ptr2, *aligned_ptr; int align_mask = LMMS_ALIGN_SIZE - 1; - ptr = static_cast( malloc( byteNum + LMMS_ALIGN_SIZE + sizeof( int ) ) ); + char* ptr = static_cast(malloc(byteNum + LMMS_ALIGN_SIZE + sizeof(int))); if( ptr == nullptr ) return nullptr; - ptr2 = ptr + sizeof( int ); - aligned_ptr = ptr2 + ( LMMS_ALIGN_SIZE - ( ( size_t ) ptr2 & align_mask ) ); + char* ptr2 = ptr + sizeof(int); + char* aligned_ptr = ptr2 + (LMMS_ALIGN_SIZE - ((size_t)ptr2 & align_mask)); ptr2 = aligned_ptr - sizeof( int ); *( ( int* ) ptr2 ) = ( int )( aligned_ptr - ptr ); diff --git a/src/core/Plugin.cpp b/src/core/Plugin.cpp index 97391450187..f165ddf7509 100644 --- a/src/core/Plugin.cpp +++ b/src/core/Plugin.cpp @@ -226,8 +226,8 @@ Plugin * Plugin::instantiate(const QString& pluginName, Model * parent, } else { - InstantiationHook instantiationHook; - if ((instantiationHook = ( InstantiationHook ) pi.library->resolve( "lmms_plugin_main" ))) + auto instantiationHook = reinterpret_cast(pi.library->resolve("lmms_plugin_main")); + if (instantiationHook) { inst = instantiationHook(parent, data); if(!inst) { diff --git a/src/core/Song.cpp b/src/core/Song.cpp index ddc55707ca2..81a26328709 100644 --- a/src/core/Song.cpp +++ b/src/core/Song.cpp @@ -945,13 +945,12 @@ void Song::createNewProject() m_oldFileName = ""; setProjectFileName(""); - Track * t; - t = Track::create( Track::Type::Instrument, this ); - dynamic_cast( t )->loadInstrument( - "tripleoscillator" ); - t = Track::create(Track::Type::Instrument, Engine::patternStore()); - dynamic_cast( t )->loadInstrument( - "kicker" ); + auto tripleOscTrack = Track::create(Track::Type::Instrument, this); + dynamic_cast(tripleOscTrack)->loadInstrument("tripleoscillator"); + + auto kickerTrack = Track::create(Track::Type::Instrument, Engine::patternStore()); + dynamic_cast(kickerTrack)->loadInstrument("kicker"); + Track::create( Track::Type::Sample, this ); Track::create( Track::Type::Pattern, this ); Track::create( Track::Type::Automation, this ); diff --git a/src/core/audio/AudioAlsa.cpp b/src/core/audio/AudioAlsa.cpp index 201a967a381..d80bc891261 100644 --- a/src/core/audio/AudioAlsa.cpp +++ b/src/core/audio/AudioAlsa.cpp @@ -53,12 +53,7 @@ AudioAlsa::AudioAlsa( bool & _success_ful, AudioEngine* _audioEngine ) : "Could not avoid possible interception by PulseAudio\n" ); } - int err; - - if( ( err = snd_pcm_open( &m_handle, - probeDevice().toLatin1().constData(), - SND_PCM_STREAM_PLAYBACK, - 0 ) ) < 0 ) + if (int err = snd_pcm_open(&m_handle, probeDevice().toLatin1().constData(), SND_PCM_STREAM_PLAYBACK, 0); err < 0) { printf( "Playback open error: %s\n", snd_strerror( err ) ); return; @@ -67,14 +62,13 @@ AudioAlsa::AudioAlsa( bool & _success_ful, AudioEngine* _audioEngine ) : snd_pcm_hw_params_malloc( &m_hwParams ); snd_pcm_sw_params_malloc( &m_swParams ); - if( ( err = setHWParams( channels(), - SND_PCM_ACCESS_RW_INTERLEAVED ) ) < 0 ) + if (int err = setHWParams(channels(), SND_PCM_ACCESS_RW_INTERLEAVED); err < 0) { printf( "Setting of hwparams failed: %s\n", snd_strerror( err ) ); return; } - if( ( err = setSWParams() ) < 0 ) + if (int err = setSWParams(); err < 0) { printf( "Setting of swparams failed: %s\n", snd_strerror( err ) ); @@ -83,9 +77,8 @@ AudioAlsa::AudioAlsa( bool & _success_ful, AudioEngine* _audioEngine ) : // set FD_CLOEXEC flag for all file descriptors so forked processes // do not inherit them - struct pollfd * ufds; int count = snd_pcm_poll_descriptors_count( m_handle ); - ufds = new pollfd[count]; + auto ufds = new pollfd[count]; snd_pcm_poll_descriptors( m_handle, ufds, count ); for (int i = 0; i < std::max(3, count); ++i) { @@ -160,7 +153,7 @@ AudioAlsa::DeviceInfoCollection AudioAlsa::getAvailableDevices() { DeviceInfoCollection deviceInfos; - char **hints; + char** hints = nullptr; /* Enumerate sound devices */ int err = snd_device_name_hint(-1, "pcm", (void***)&hints); @@ -261,25 +254,21 @@ void AudioAlsa::applyQualitySettings() snd_pcm_close( m_handle ); } - int err; - if( ( err = snd_pcm_open( &m_handle, - probeDevice().toLatin1().constData(), - SND_PCM_STREAM_PLAYBACK, - 0 ) ) < 0 ) + if (int err = snd_pcm_open(&m_handle, probeDevice().toLatin1().constData(), SND_PCM_STREAM_PLAYBACK, 0); + err < 0) { printf( "Playback open error: %s\n", snd_strerror( err ) ); return; } - if( ( err = setHWParams( channels(), - SND_PCM_ACCESS_RW_INTERLEAVED ) ) < 0 ) + if (int err = setHWParams(channels(), SND_PCM_ACCESS_RW_INTERLEAVED); err < 0) { printf( "Setting of hwparams failed: %s\n", snd_strerror( err ) ); return; } - if( ( err = setSWParams() ) < 0 ) + if (int err = setSWParams(); err < 0) { printf( "Setting of swparams failed: %s\n", snd_strerror( err ) ); @@ -370,10 +359,8 @@ void AudioAlsa::run() int AudioAlsa::setHWParams( const ch_cnt_t _channels, snd_pcm_access_t _access ) { - int err, dir; - // choose all parameters - if( ( err = snd_pcm_hw_params_any( m_handle, m_hwParams ) ) < 0 ) + if (int err = snd_pcm_hw_params_any(m_handle, m_hwParams); err < 0) { printf( "Broken configuration for playback: no configurations " "available: %s\n", snd_strerror( err ) ); @@ -381,8 +368,7 @@ int AudioAlsa::setHWParams( const ch_cnt_t _channels, snd_pcm_access_t _access ) } // set the interleaved read/write format - if( ( err = snd_pcm_hw_params_set_access( m_handle, m_hwParams, - _access ) ) < 0 ) + if (int err = snd_pcm_hw_params_set_access(m_handle, m_hwParams, _access); err < 0) { printf( "Access type not available for playback: %s\n", snd_strerror( err ) ); @@ -390,11 +376,9 @@ int AudioAlsa::setHWParams( const ch_cnt_t _channels, snd_pcm_access_t _access ) } // set the sample format - if( ( snd_pcm_hw_params_set_format( m_handle, m_hwParams, - SND_PCM_FORMAT_S16_LE ) ) < 0 ) + if (int err = snd_pcm_hw_params_set_format(m_handle, m_hwParams, SND_PCM_FORMAT_S16_LE); err < 0) { - if( ( snd_pcm_hw_params_set_format( m_handle, m_hwParams, - SND_PCM_FORMAT_S16_BE ) ) < 0 ) + if (int err = snd_pcm_hw_params_set_format(m_handle, m_hwParams, SND_PCM_FORMAT_S16_BE); err < 0) { printf( "Neither little- nor big-endian available for " "playback: %s\n", snd_strerror( err ) ); @@ -408,8 +392,7 @@ int AudioAlsa::setHWParams( const ch_cnt_t _channels, snd_pcm_access_t _access ) } // set the count of channels - if( ( err = snd_pcm_hw_params_set_channels( m_handle, m_hwParams, - _channels ) ) < 0 ) + if (int err = snd_pcm_hw_params_set_channels(m_handle, m_hwParams, _channels); err < 0) { printf( "Channel count (%i) not available for playbacks: %s\n" "(Does your soundcard not support surround?)\n", @@ -418,11 +401,9 @@ int AudioAlsa::setHWParams( const ch_cnt_t _channels, snd_pcm_access_t _access ) } // set the sample rate - if( ( err = snd_pcm_hw_params_set_rate( m_handle, m_hwParams, - sampleRate(), 0 ) ) < 0 ) + if (int err = snd_pcm_hw_params_set_rate(m_handle, m_hwParams, sampleRate(), 0); err < 0) { - if( ( err = snd_pcm_hw_params_set_rate( m_handle, m_hwParams, - audioEngine()->baseSampleRate(), 0 ) ) < 0 ) + if (int err = snd_pcm_hw_params_set_rate(m_handle, m_hwParams, audioEngine()->baseSampleRate(), 0); err < 0) { printf( "Could not set sample rate: %s\n", snd_strerror( err ) ); @@ -432,36 +413,29 @@ int AudioAlsa::setHWParams( const ch_cnt_t _channels, snd_pcm_access_t _access ) m_periodSize = audioEngine()->framesPerPeriod(); m_bufferSize = m_periodSize * 8; - dir = 0; - err = snd_pcm_hw_params_set_period_size_near( m_handle, m_hwParams, - &m_periodSize, &dir ); - if( err < 0 ) + int dir; + if (int err = snd_pcm_hw_params_set_period_size_near(m_handle, m_hwParams, &m_periodSize, &dir); err < 0) { printf( "Unable to set period size %lu for playback: %s\n", m_periodSize, snd_strerror( err ) ); return err; } dir = 0; - err = snd_pcm_hw_params_get_period_size( m_hwParams, &m_periodSize, - &dir ); - if( err < 0 ) + if (int err = snd_pcm_hw_params_get_period_size(m_hwParams, &m_periodSize, &dir); err < 0) { printf( "Unable to get period size for playback: %s\n", snd_strerror( err ) ); } dir = 0; - err = snd_pcm_hw_params_set_buffer_size_near( m_handle, m_hwParams, - &m_bufferSize ); - if( err < 0 ) + if (int err = snd_pcm_hw_params_set_buffer_size_near(m_handle, m_hwParams, &m_bufferSize); err < 0) { printf( "Unable to set buffer size %lu for playback: %s\n", m_bufferSize, snd_strerror( err ) ); return ( err ); } - err = snd_pcm_hw_params_get_buffer_size( m_hwParams, &m_bufferSize ); - if( 2 * m_periodSize > m_bufferSize ) + if (int err = snd_pcm_hw_params_get_buffer_size(m_hwParams, &m_bufferSize); 2 * m_periodSize > m_bufferSize) { printf( "buffer to small, could not use\n" ); return ( err ); @@ -469,8 +443,7 @@ int AudioAlsa::setHWParams( const ch_cnt_t _channels, snd_pcm_access_t _access ) // write the parameters to device - err = snd_pcm_hw_params( m_handle, m_hwParams ); - if( err < 0 ) + if (int err = snd_pcm_hw_params(m_handle, m_hwParams); err < 0) { printf( "Unable to set hw params for playback: %s\n", snd_strerror( err ) ); @@ -485,10 +458,8 @@ int AudioAlsa::setHWParams( const ch_cnt_t _channels, snd_pcm_access_t _access ) int AudioAlsa::setSWParams() { - int err; - // get the current swparams - if( ( err = snd_pcm_sw_params_current( m_handle, m_swParams ) ) < 0 ) + if (int err = snd_pcm_sw_params_current(m_handle, m_swParams); err < 0) { printf( "Unable to determine current swparams for playback: %s" "\n", snd_strerror( err ) ); @@ -496,8 +467,7 @@ int AudioAlsa::setSWParams() } // start the transfer when a period is full - if( ( err = snd_pcm_sw_params_set_start_threshold( m_handle, - m_swParams, m_periodSize ) ) < 0 ) + if (int err = snd_pcm_sw_params_set_start_threshold(m_handle, m_swParams, m_periodSize); err < 0) { printf( "Unable to set start threshold mode for playback: %s\n", snd_strerror( err ) ); @@ -506,8 +476,7 @@ int AudioAlsa::setSWParams() // allow the transfer when at least m_periodSize samples can be // processed - if( ( err = snd_pcm_sw_params_set_avail_min( m_handle, m_swParams, - m_periodSize ) ) < 0 ) + if (int err = snd_pcm_sw_params_set_avail_min(m_handle, m_swParams, m_periodSize); err < 0) { printf( "Unable to set avail min for playback: %s\n", snd_strerror( err ) ); @@ -527,7 +496,7 @@ int AudioAlsa::setSWParams() #endif // write the parameters to the playback device - if( ( err = snd_pcm_sw_params( m_handle, m_swParams ) ) < 0 ) + if (int err = snd_pcm_sw_params(m_handle, m_swParams); err < 0) { printf( "Unable to set sw params for playback: %s\n", snd_strerror( err ) ); diff --git a/src/core/audio/AudioDevice.cpp b/src/core/audio/AudioDevice.cpp index 58ba3932e5b..74371662236 100644 --- a/src/core/audio/AudioDevice.cpp +++ b/src/core/audio/AudioDevice.cpp @@ -195,8 +195,7 @@ fpp_t AudioDevice::resample( const surroundSampleFrame * _src, m_srcData.data_out = _dst[0].data (); m_srcData.src_ratio = (double) _dst_sr / _src_sr; m_srcData.end_of_input = 0; - int error; - if( ( error = src_process( m_srcState, &m_srcData ) ) ) + if (int error = src_process(m_srcState, &m_srcData)) { printf( "AudioDevice::resample(): error while resampling: %s\n", src_strerror( error ) ); @@ -213,12 +212,11 @@ int AudioDevice::convertToS16( const surroundSampleFrame * _ab, { if( _convert_endian ) { - int_sample_t temp; for( fpp_t frame = 0; frame < _frames; ++frame ) { for( ch_cnt_t chnl = 0; chnl < channels(); ++chnl ) { - temp = static_cast(AudioEngine::clip(_ab[frame][chnl]) * OUTPUT_SAMPLE_MULTIPLIER); + auto temp = static_cast(AudioEngine::clip(_ab[frame][chnl]) * OUTPUT_SAMPLE_MULTIPLIER); ( _output_buffer + frame * channels() )[chnl] = ( temp & 0x00ff ) << 8 | diff --git a/src/core/audio/AudioFileOgg.cpp b/src/core/audio/AudioFileOgg.cpp index 9d5f0c809bb..3818273d6f1 100644 --- a/src/core/audio/AudioFileOgg.cpp +++ b/src/core/audio/AudioFileOgg.cpp @@ -156,7 +156,6 @@ bool AudioFileOgg::startEncoding() ogg_packet header_main; ogg_packet header_comments; ogg_packet header_codebooks; - int result; // Build the packets vorbis_analysis_headerout( &m_vd, m_comments, &header_main, @@ -167,14 +166,9 @@ bool AudioFileOgg::startEncoding() ogg_stream_packetin( &m_os, &header_comments ); ogg_stream_packetin( &m_os, &header_codebooks ); - while( ( result = ogg_stream_flush( &m_os, &m_og ) ) ) + while (ogg_stream_flush(&m_os, &m_og)) { - if( !result ) - { - break; - } - int ret = writePage(); - if( ret != m_og.header_len + m_og.body_len ) + if (int ret = writePage(); ret != m_og.header_len + m_og.body_len) { // clean up finishEncoding(); diff --git a/src/core/audio/AudioPortAudio.cpp b/src/core/audio/AudioPortAudio.cpp index 2fbdb04b532..1cb8c8eed0c 100644 --- a/src/core/audio/AudioPortAudio.cpp +++ b/src/core/audio/AudioPortAudio.cpp @@ -92,10 +92,9 @@ AudioPortAudio::AudioPortAudio( bool & _success_ful, AudioEngine * _audioEngine PaDeviceIndex inDevIdx = -1; PaDeviceIndex outDevIdx = -1; - const PaDeviceInfo * di; for( int i = 0; i < Pa_GetDeviceCount(); ++i ) { - di = Pa_GetDeviceInfo( i ); + const auto di = Pa_GetDeviceInfo(i); if( di->name == device && Pa_GetHostApiInfo( di->hostApi )->name == backend ) { @@ -343,10 +342,9 @@ void AudioPortAudioSetupUtil::updateBackends() return; } - const PaHostApiInfo * hi; for( int i = 0; i < Pa_GetHostApiCount(); ++i ) { - hi = Pa_GetHostApiInfo( i ); + const auto hi = Pa_GetHostApiInfo(i); m_backendModel.addItem( hi->name ); } @@ -367,10 +365,9 @@ void AudioPortAudioSetupUtil::updateDevices() // get active backend const QString& backend = m_backendModel.currentText(); int hostApi = 0; - const PaHostApiInfo * hi; for( int i = 0; i < Pa_GetHostApiCount(); ++i ) { - hi = Pa_GetHostApiInfo( i ); + const auto hi = Pa_GetHostApiInfo(i); if( backend == hi->name ) { hostApi = i; @@ -380,10 +377,9 @@ void AudioPortAudioSetupUtil::updateDevices() // get devices for selected backend m_deviceModel.clear(); - const PaDeviceInfo * di; for( int i = 0; i < Pa_GetDeviceCount(); ++i ) { - di = Pa_GetDeviceInfo( i ); + const auto di = Pa_GetDeviceInfo(i); if( di->hostApi == hostApi ) { m_deviceModel.addItem( di->name ); diff --git a/src/core/audio/AudioSoundIo.cpp b/src/core/audio/AudioSoundIo.cpp index a3d72e36b50..c16327a901d 100644 --- a/src/core/audio/AudioSoundIo.cpp +++ b/src/core/audio/AudioSoundIo.cpp @@ -69,7 +69,6 @@ AudioSoundIo::AudioSoundIo( bool & outSuccessful, AudioEngine * _audioEngine ) : const QString& configDeviceId = ConfigManager::inst()->value( "audiosoundio", "out_device_id" ); const QString& configDeviceRaw = ConfigManager::inst()->value( "audiosoundio", "out_device_raw" ); - int err; int outDeviceCount = 0; int backendCount = soundio_backend_count(m_soundio); for (int i = 0; i < backendCount; i += 1) @@ -77,11 +76,7 @@ AudioSoundIo::AudioSoundIo( bool & outSuccessful, AudioEngine * _audioEngine ) : SoundIoBackend backend = soundio_get_backend(m_soundio, i); if (configBackend == soundio_backend_name(backend)) { - if ((err = soundio_connect_backend(m_soundio, backend))) - { - // error occurred, leave outDeviceCount 0 - } - else + if (!soundio_connect_backend(m_soundio, backend)) { soundio_flush_events(m_soundio); if (m_disconnectErr) @@ -98,7 +93,7 @@ AudioSoundIo::AudioSoundIo( bool & outSuccessful, AudioEngine * _audioEngine ) : if (outDeviceCount <= 0) { // try connecting to the default backend - if ((err = soundio_connect(m_soundio))) + if (int err = soundio_connect(m_soundio)) { fprintf(stderr, "Unable to initialize soundio: %s\n", soundio_strerror(err)); return; @@ -179,7 +174,7 @@ AudioSoundIo::AudioSoundIo( bool & outSuccessful, AudioEngine * _audioEngine ) : m_outstream->layout = *soundio_channel_layout_get_default(channels()); m_outstream->format = SoundIoFormatFloat32NE; - if ((err = soundio_outstream_open(m_outstream))) + if (int err = soundio_outstream_open(m_outstream)) { fprintf(stderr, "Unable to initialize soundio: %s\n", soundio_strerror(err)); return; @@ -214,8 +209,6 @@ AudioSoundIo::~AudioSoundIo() void AudioSoundIo::startProcessing() { - int err; - m_outBufFrameIndex = 0; m_outBufFramesTotal = 0; m_outBufSize = audioEngine()->framesPerPeriod(); @@ -224,7 +217,7 @@ void AudioSoundIo::startProcessing() if (! m_outstreamStarted) { - if ((err = soundio_outstream_start(m_outstream))) + if (int err = soundio_outstream_start(m_outstream)) { fprintf(stderr, "AudioSoundIo::startProcessing() :: soundio unable to start stream: %s\n", @@ -236,7 +229,7 @@ void AudioSoundIo::startProcessing() m_stopped = false; - if ((err = soundio_outstream_pause(m_outstream, false))) + if (int err = soundio_outstream_pause(m_outstream, false)) { m_stopped = true; fprintf(stderr, @@ -247,12 +240,10 @@ void AudioSoundIo::startProcessing() void AudioSoundIo::stopProcessing() { - int err; - m_stopped = true; if (m_outstream) { - if ((err = soundio_outstream_pause(m_outstream, true))) + if (int err = soundio_outstream_pause(m_outstream, true)) { fprintf(stderr, "AudioSoundIo::stopProcessing() :: pausing result error: %s\n", @@ -281,16 +272,14 @@ void AudioSoundIo::writeCallback(int frameCountMin, int frameCountMax) { if (m_stopped) {return;} const struct SoundIoChannelLayout *layout = &m_outstream->layout; - SoundIoChannelArea *areas; + SoundIoChannelArea* areas; int bytesPerSample = m_outstream->bytes_per_sample; - int err; - int framesLeft = frameCountMax; while (framesLeft > 0) { int frameCount = framesLeft; - if ((err = soundio_outstream_begin_write(m_outstream, &areas, &frameCount))) + if (int err = soundio_outstream_begin_write(m_outstream, &areas, &frameCount)) { errorCallback(err); return; @@ -332,7 +321,7 @@ void AudioSoundIo::writeCallback(int frameCountMin, int frameCountMax) m_outBufFrameIndex += 1; } - if ((err = soundio_outstream_end_write(m_outstream))) + if (int err = soundio_outstream_end_write(m_outstream)) { errorCallback(err); return; @@ -372,11 +361,10 @@ void AudioSoundIo::setupWidget::reconnectSoundIo() soundio_disconnect(m_soundio); - int err; int backend_index = m_backendModel.findText(configBackend); if (backend_index < 0) { - if ((err = soundio_connect(m_soundio))) + if (int err = soundio_connect(m_soundio)) { fprintf(stderr, "soundio: unable to connect backend: %s\n", soundio_strerror(err)); return; @@ -387,11 +375,11 @@ void AudioSoundIo::setupWidget::reconnectSoundIo() else { SoundIoBackend backend = soundio_get_backend(m_soundio, backend_index); - if ((err = soundio_connect_backend(m_soundio, backend))) + if (int err = soundio_connect_backend(m_soundio, backend)) { fprintf(stderr, "soundio: unable to connect %s backend: %s\n", soundio_backend_name(backend), soundio_strerror(err)); - if ((err = soundio_connect(m_soundio))) + if (int err = soundio_connect(m_soundio)) { fprintf(stderr, "soundio: unable to connect backend: %s\n", soundio_strerror(err)); return; diff --git a/src/core/lv2/Lv2Evbuf.cpp b/src/core/lv2/Lv2Evbuf.cpp index acfb9b8aa62..07a3d58e687 100644 --- a/src/core/lv2/Lv2Evbuf.cpp +++ b/src/core/lv2/Lv2Evbuf.cpp @@ -129,12 +129,11 @@ lv2_evbuf_next(LV2_Evbuf_Iterator iter) LV2_Evbuf* evbuf = iter.evbuf; uint32_t offset = iter.offset; - uint32_t size; - size = ((LV2_Atom_Event*) - ((char*)LV2_ATOM_CONTENTS(LV2_Atom_Sequence, &evbuf->buf.atom) - + offset))->body.size; - offset += lv2_evbuf_pad_size(sizeof(LV2_Atom_Event) + size); + const auto contents = static_cast(LV2_ATOM_CONTENTS(LV2_Atom_Sequence, &evbuf->buf.atom)) + offset; + const uint32_t size = reinterpret_cast(contents)->body.size; + + offset += lv2_evbuf_pad_size(sizeof(LV2_Atom_Event) + size); LV2_Evbuf_Iterator next = { evbuf, offset }; return next; } diff --git a/src/core/lv2/Lv2Proc.cpp b/src/core/lv2/Lv2Proc.cpp index 77177a1c0c0..4715aeb7fc9 100644 --- a/src/core/lv2/Lv2Proc.cpp +++ b/src/core/lv2/Lv2Proc.cpp @@ -425,12 +425,8 @@ void Lv2Proc::handleMidiInputEvent(const MidiEvent &event, const TimePos &time, AutomatableModel *Lv2Proc::modelAtPort(const QString &uri) { - // unused currently - AutomatableModel *mod; - auto itr = m_connectedModels.find(uri.toUtf8().data()); - if (itr != m_connectedModels.end()) { mod = itr->second; } - else { mod = nullptr; } - return mod; + const auto itr = m_connectedModels.find(uri.toUtf8().data()); + return itr != m_connectedModels.end() ? itr->second : nullptr; } diff --git a/src/core/main.cpp b/src/core/main.cpp index 25a6ab9c53e..cadffdafa6e 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -906,19 +906,13 @@ int main( int argc, char * * argv ) mb.setWindowIcon( embed::getIconPixmap( "icon_small" ) ); mb.setWindowFlags( Qt::WindowCloseButtonHint ); - QPushButton * recover; - QPushButton * discard; - QPushButton * exit; - // setting all buttons to the same roles allows us // to have a custom layout - discard = mb.addButton( MainWindow::tr( "Discard" ), - QMessageBox::AcceptRole ); - recover = mb.addButton( MainWindow::tr( "Recover" ), - QMessageBox::AcceptRole ); + auto discard = mb.addButton(MainWindow::tr("Discard"), QMessageBox::AcceptRole); + auto recover = mb.addButton(MainWindow::tr("Recover"), QMessageBox::AcceptRole); // have a hidden exit button - exit = mb.addButton( "", QMessageBox::RejectRole); + auto exit = mb.addButton("", QMessageBox::RejectRole); exit->setVisible(false); // set icons diff --git a/src/core/midi/MidiAlsaRaw.cpp b/src/core/midi/MidiAlsaRaw.cpp index 23364fc01ef..f091b789fde 100644 --- a/src/core/midi/MidiAlsaRaw.cpp +++ b/src/core/midi/MidiAlsaRaw.cpp @@ -39,10 +39,7 @@ MidiAlsaRaw::MidiAlsaRaw() : m_outputp( &m_output ), m_quit( false ) { - int err; - if( ( err = snd_rawmidi_open( m_inputp, m_outputp, - probeDevice().toLatin1().constData(), - 0 ) ) < 0 ) + if (int err = snd_rawmidi_open(m_inputp, m_outputp, probeDevice().toLatin1().constData(), 0); err < 0) { printf( "cannot open MIDI-device: %s\n", snd_strerror( err ) ); return; @@ -111,29 +108,27 @@ void MidiAlsaRaw::run() { msleep( 5 ); // must do that, otherwise this thread takes // too much CPU-time, even with LowPriority... - int err = poll( m_pfds, m_npfds, 10000 ); - if( err < 0 && errno == EINTR ) + if (int err = poll(m_pfds, m_npfds, 10000); err < 0 && errno == EINTR) { printf( "MidiAlsaRaw::run(): Got EINTR while " "polling. Will stop polling MIDI-events from " "MIDI-port.\n" ); break; } - if( err < 0 ) + else if (err < 0) { printf( "poll failed: %s\nWill stop polling " "MIDI-events from MIDI-port.\n", strerror( errno ) ); break; } - if( err == 0 ) + else if (err == 0) { //printf( "there seems to be no active MIDI-device %d\n", ++cnt ); continue; } - unsigned short revents; - if( ( err = snd_rawmidi_poll_descriptors_revents( - m_input, m_pfds, m_npfds, &revents ) ) < 0 ) + unsigned short revents = 0; + if (int err = snd_rawmidi_poll_descriptors_revents(m_input, m_pfds, m_npfds, &revents); err < 0) { printf( "cannot get poll events: %s\nWill stop polling " "MIDI-events from MIDI-port.\n", @@ -149,25 +144,19 @@ void MidiAlsaRaw::run() { continue; } - err = snd_rawmidi_read(m_input, buf.data(), buf.size()); - if( err == -EAGAIN ) - { - continue; - } - if( err < 0 ) + + if (int err = snd_rawmidi_read(m_input, buf.data(), buf.size()); err == -EAGAIN) { continue; } + else if (err < 0) { printf( "cannot read from port \"%s\": %s\nWill stop " "polling MIDI-events from MIDI-port.\n", /*port_name*/"default", snd_strerror( err ) ); break; } - if( err == 0 ) - { - continue; - } - for( int i = 0; i < err; ++i ) + else if (err == 0) { continue; } + else { - parseData( buf[i] ); + for (int i = 0; i < err; ++i) { parseData(buf[i]); } } } diff --git a/src/core/midi/MidiAlsaSeq.cpp b/src/core/midi/MidiAlsaSeq.cpp index 0b3bab8195a..e0b8b486efc 100644 --- a/src/core/midi/MidiAlsaSeq.cpp +++ b/src/core/midi/MidiAlsaSeq.cpp @@ -78,10 +78,7 @@ MidiAlsaSeq::MidiAlsaSeq() : m_quit( false ), m_portListUpdateTimer( this ) { - int err; - if( ( err = snd_seq_open( &m_seqHandle, - probeDevice().toLatin1().constData(), - SND_SEQ_OPEN_DUPLEX, 0 ) ) < 0 ) + if (int err = snd_seq_open(&m_seqHandle, probeDevice().toLatin1().constData(), SND_SEQ_OPEN_DUPLEX, 0); err < 0) { fprintf( stderr, "cannot open sequencer: %s\n", snd_strerror( err ) ); diff --git a/src/core/midi/MidiController.cpp b/src/core/midi/MidiController.cpp index 0ae76d352c8..112d9d974b4 100644 --- a/src/core/midi/MidiController.cpp +++ b/src/core/midi/MidiController.cpp @@ -74,11 +74,11 @@ void MidiController::updateName() void MidiController::processInEvent(const MidiEvent& event, const TimePos& time, f_cnt_t offset) { - unsigned char controllerNum; switch(event.type()) { case MidiControlChange: - controllerNum = event.controllerNumber(); + { + unsigned char controllerNum = event.controllerNumber(); if (m_midiPort.inputController() == controllerNum && (m_midiPort.inputChannel() == event.channel() + 1 || m_midiPort.inputChannel() == 0)) @@ -89,7 +89,7 @@ void MidiController::processInEvent(const MidiEvent& event, const TimePos& time, emit valueChanged(); } break; - + } default: // Don't care - maybe add special cases for pitch and mod later break; diff --git a/src/core/midi/MidiJack.cpp b/src/core/midi/MidiJack.cpp index 145a72eccfe..29e7e27ec70 100644 --- a/src/core/midi/MidiJack.cpp +++ b/src/core/midi/MidiJack.cpp @@ -179,7 +179,6 @@ QString MidiJack::probeDevice() // we read data from jack void MidiJack::JackMidiRead(jack_nframes_t nframes) { - unsigned int i,b; void* port_buf = jack_port_get_buffer(m_input_port, nframes); jack_midi_event_t in_event; jack_nframes_t event_index = 0; @@ -188,13 +187,13 @@ void MidiJack::JackMidiRead(jack_nframes_t nframes) int rval = jack_midi_event_get(&in_event, port_buf, 0); if (rval == 0 /* 0 = success */) { - for(i=0; i 0; n--, p++) + for (char* p = buf; n > 0; n--, p++) { parseData( *p ); } diff --git a/src/gui/ControlLayout.cpp b/src/gui/ControlLayout.cpp index 5e9a211014b..75133c8e3d8 100644 --- a/src/gui/ControlLayout.cpp +++ b/src/gui/ControlLayout.cpp @@ -101,8 +101,7 @@ ControlLayout::ControlLayout(QWidget *parent, int margin, int hSpacing, int vSpa ControlLayout::~ControlLayout() { - QLayoutItem *item; - while ((item = takeAt(0))) { delete item; } + while (auto item = takeAt(0)) { delete item; } } void ControlLayout::onTextChanged(const QString&) diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 0413e3bd656..072edc0ec22 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -1108,8 +1108,7 @@ void MainWindow::updateViewMenu() // Here we should put all look&feel -stuff from configmanager // that is safe to change on the fly. There is probably some // more elegant way to do this. - QAction *qa; - qa = new QAction(tr( "Volume as dBFS" ), this); + auto qa = new QAction(tr("Volume as dBFS"), this); qa->setData("displaydbfs"); qa->setCheckable( true ); qa->setChecked( ConfigManager::inst()->value( "app", "displaydbfs" ).toInt() ); diff --git a/src/gui/ProjectNotes.cpp b/src/gui/ProjectNotes.cpp index f131a017c85..a71f146c66e 100644 --- a/src/gui/ProjectNotes.cpp +++ b/src/gui/ProjectNotes.cpp @@ -108,10 +108,8 @@ void ProjectNotes::setText( const QString & _text ) void ProjectNotes::setupActions() { QToolBar * tb = addToolBar( tr( "Edit Actions" ) ); - QAction * a; - a = new QAction( embed::getIconPixmap( "edit_undo" ), tr( "&Undo" ), - this ); + auto a = new QAction(embed::getIconPixmap("edit_undo"), tr("&Undo"), this); a->setShortcut( tr( "%1+Z" ).arg(UI_CTRL_KEY) ); connect( a, SIGNAL(triggered()), m_edit, SLOT(undo())); tb->addAction( a ); diff --git a/src/gui/clips/AutomationClipView.cpp b/src/gui/clips/AutomationClipView.cpp index 7ddb7015182..9b71bb74c74 100644 --- a/src/gui/clips/AutomationClipView.cpp +++ b/src/gui/clips/AutomationClipView.cpp @@ -314,24 +314,17 @@ void AutomationClipView::paintEvent( QPaintEvent * ) // the outValue of the current node). When we have nodes with linear or cubic progression // the value of the end of the shape between the two nodes will be the inValue of // the next node. - float nextValue; - if( m_clip->progressionType() == AutomationClip::ProgressionType::Discrete ) - { - nextValue = OUTVAL(it); - } - else - { - nextValue = INVAL(it + 1); - } + float nextValue = m_clip->progressionType() == AutomationClip::ProgressionType::Discrete + ? OUTVAL(it) + : INVAL(it + 1); QPainterPath path; QPointF origin = QPointF(POS(it) * ppTick, 0.0f); path.moveTo( origin ); path.moveTo(QPointF(POS(it) * ppTick,values[0])); - float x; for (int i = POS(it) + 1; i < POS(it + 1); i++) { - x = i * ppTick; + float x = i * ppTick; if( x > ( width() - BORDER_WIDTH ) ) break; float value = values[i - POS(it)]; path.lineTo( QPointF( x, value ) ); diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index ae026fff3e2..d23682d6e33 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -320,8 +320,6 @@ void AutomationEditor::drawLine( int x0In, float y0, int x1In, float y1 ) auto deltay = qAbs(y1 - y0); int x = x0; float y = y0; - int xstep; - int ystep; if( deltax < AutomationClip::quantization() ) { @@ -332,34 +330,14 @@ void AutomationEditor::drawLine( int x0In, float y0, int x1In, float y1 ) float yscale = deltay / ( deltax ); - if( x0 < x1 ) - { - xstep = AutomationClip::quantization(); - } - else - { - xstep = -( AutomationClip::quantization() ); - } - - float lineAdjust; - if( y0 < y1 ) - { - ystep = 1; - lineAdjust = yscale; - } - else - { - ystep = -1; - lineAdjust = -( yscale ); - } + int xstep = (x0 < x1 ? 1 : -1) * AutomationClip::quantization(); + int ystep = y0 < y1 ? 1 : -1; + float lineAdjust = ystep * yscale; - int i = 0; - while( i < deltax ) + for (int i = 0; i < deltax; ++i) { y = y0 + ( ystep * yscale * i ) + lineAdjust; - x += xstep; - i += 1; m_clip->removeNode(TimePos(x)); m_clip->putValue( TimePos( x ), y ); } @@ -979,7 +957,6 @@ inline void AutomationEditor::drawCross( QPainter & p ) inline void AutomationEditor::drawAutomationPoint(QPainter & p, timeMap::iterator it) { int x = xCoordOfTick(POS(it)); - int y; // Below (m_ppb * AutomationClip::quantization() / 576) is used because: // 1 bar equals to 192/quantization() notes. Hence, to calculate the number of pixels // per note we would have (m_ppb * 1 bar / (192/quantization()) notes per bar), or @@ -988,7 +965,7 @@ inline void AutomationEditor::drawAutomationPoint(QPainter & p, timeMap::iterato const int outerRadius = qBound(3, (m_ppb * AutomationClip::quantization()) / 576, 5); // Draw a circle for the outValue - y = yCoordOfLevel(OUTVAL(it)); + int y = yCoordOfLevel(OUTVAL(it)); p.setPen(QPen(m_nodeOutValueColor.lighter(200))); p.setBrush(QBrush(m_nodeOutValueColor)); p.drawEllipse(x - outerRadius, y - outerRadius, outerRadius * 2, outerRadius * 2); @@ -1006,7 +983,6 @@ inline void AutomationEditor::drawAutomationPoint(QPainter & p, timeMap::iterato inline void AutomationEditor::drawAutomationTangents(QPainter& p, timeMap::iterator it) { int x = xCoordOfTick(POS(it)); - int y, tx, ty; // The tangent value correlates the variation in the node value related to the increase // in ticks. So to have a proportionate drawing of the tangent line, we need to find the @@ -1020,9 +996,9 @@ inline void AutomationEditor::drawAutomationTangents(QPainter& p, timeMap::itera p.setPen(QPen(m_nodeTangentLineColor)); p.setBrush(QBrush(m_nodeTangentLineColor)); - y = yCoordOfLevel(INVAL(it)); - tx = x - 20; - ty = y + 20 * INTAN(it) * proportion; + int y = yCoordOfLevel(INVAL(it)); + int tx = x - 20; + int ty = y + 20 * INTAN(it) * proportion; p.drawLine(x, y, tx, ty); p.setBrush(QBrush(m_nodeTangentLineColor.darker(200))); p.drawEllipse(tx - 3, ty - 3, 6, 6); @@ -1101,7 +1077,6 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) } else { - int y; int level = (int) m_bottomLevel; int printable = qMax( 1, 5 * DEFAULT_Y_DELTA / m_y_delta ); @@ -1116,7 +1091,7 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) { const QString & label = m_clip->firstObject() ->displayValue( level ); - y = yCoordOfLevel( level ); + int y = yCoordOfLevel(level); p.setPen( QApplication::palette().color( QPalette::Active, QPalette::Shadow ) ); p.drawText( 1, y - font_height + 1, @@ -1139,7 +1114,7 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) if( m_clip ) { - int tick, x, q; + int q; int x_line_end = (int)( m_y_auto || m_topLevel < m_maxLevel ? TOP_MARGIN : grid_bottom - ( m_topLevel - m_bottomLevel ) * m_y_delta ); @@ -1163,10 +1138,8 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) // 3 independent loops, because quantization might not divide evenly into // exotic denominators (e.g. 7/11 time), which are allowed ATM. // First quantization grid... - for( tick = m_currentPosition - m_currentPosition % q, - x = xCoordOfTick( tick ); - x<=width(); - tick += q, x = xCoordOfTick( tick ) ) + for (int tick = m_currentPosition - m_currentPosition % q, x = xCoordOfTick(tick); x <= width(); + tick += q, x = xCoordOfTick(tick)) { p.setPen(m_lineColor); p.drawLine( x, grid_bottom, x, x_line_end ); @@ -1187,10 +1160,9 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) } else { - float y; for( int level = (int)m_bottomLevel; level <= m_topLevel; level++) { - y = yCoordOfLevel( (float)level ); + float y = yCoordOfLevel(static_cast(level)); p.setPen(level % 10 == 0 ? m_beatLineColor : m_lineColor); @@ -1226,10 +1198,8 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) int ticksPerBeat = DefaultTicksPerBar / Engine::getSong()->getTimeSigModel().getDenominator(); - for( tick = m_currentPosition - m_currentPosition % ticksPerBeat, - x = xCoordOfTick( tick ); - x<=width(); - tick += ticksPerBeat, x = xCoordOfTick( tick ) ) + for (int tick = m_currentPosition - m_currentPosition % ticksPerBeat, x = xCoordOfTick(tick); x <= width(); + tick += ticksPerBeat, x = xCoordOfTick(tick)) { p.setPen(m_beatLineColor); p.drawLine( x, grid_bottom, x, x_line_end ); @@ -1316,10 +1286,8 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) } // and finally bars - for( tick = m_currentPosition - m_currentPosition % TimePos::ticksPerBar(), - x = xCoordOfTick( tick ); - x<=width(); - tick += TimePos::ticksPerBar(), x = xCoordOfTick( tick ) ) + for (int tick = m_currentPosition - m_currentPosition % TimePos::ticksPerBar(), x = xCoordOfTick(tick); + x <= width(); tick += TimePos::ticksPerBar(), x = xCoordOfTick(tick)) { p.setPen(m_barLineColor); p.drawLine( x, grid_bottom, x, x_line_end ); @@ -1365,15 +1333,9 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) // the outValue of the current node). When we have nodes with linear or cubic progression // the value of the end of the shape between the two nodes will be the inValue of // the next node. - float nextValue; - if( m_clip->progressionType() == AutomationClip::ProgressionType::Discrete ) - { - nextValue = OUTVAL(it); - } - else - { - nextValue = INVAL(it + 1); - } + float nextValue = m_clip->progressionType() == AutomationClip::ProgressionType::Discrete + ? OUTVAL(it) + : INVAL(it + 1); p.setRenderHints( QPainter::Antialiasing, true ); QPainterPath path; @@ -1523,25 +1485,11 @@ void AutomationEditor::drawLevelTick(QPainter & p, int tick, float value) || ( value > m_topLevel && m_topLevel >= 0 ) || ( value < m_bottomLevel && m_bottomLevel <= 0 ) ) { - int y_start = yCoordOfLevel( value ); - int rect_height; - - if( m_y_auto ) - { - int y_end = (int)( grid_bottom - + ( grid_bottom - TOP_MARGIN ) - * m_minLevel - / ( m_maxLevel - m_minLevel ) ); - - rect_height = y_end - y_start; - } - else - { - rect_height = (int)( value * m_y_delta ); - } + const int y_start = yCoordOfLevel(value); + const int y_end = grid_bottom + (grid_bottom - TOP_MARGIN) * m_minLevel / (m_maxLevel - m_minLevel); + const int rect_height = m_y_auto ? y_end - y_start : value * m_y_delta; QBrush currentColor = m_graphColor; - p.fillRect( x, y_start, rect_width, rect_height, currentColor ); } #ifdef LMMS_DEBUG diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 47e658f1148..9d22a21bd20 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -3030,10 +3030,9 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) if (hasValidMidiClip()) { - int pianoAreaHeight, partialKeyVisible, topKey, topNote; - pianoAreaHeight = keyAreaBottom() - keyAreaTop(); - m_pianoKeysVisible = pianoAreaHeight / m_keyLineHeight; - partialKeyVisible = pianoAreaHeight % m_keyLineHeight; + int pianoAreaHeight = keyAreaBottom() - keyAreaTop(); + int m_pianoKeysVisible = pianoAreaHeight / m_keyLineHeight; + int partialKeyVisible = pianoAreaHeight % m_keyLineHeight; // check if we're below the minimum key area size if (m_pianoKeysVisible * m_keyLineHeight < KEY_AREA_MIN_HEIGHT) { @@ -3058,8 +3057,8 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) PR_TOP_MARGIN - PR_BOTTOM_MARGIN; partialKeyVisible = 0; } - topKey = qBound(0, m_startKey + m_pianoKeysVisible - 1, NumKeys - 1); - topNote = topKey % KeysPerOctave; + int topKey = std::clamp(m_startKey + m_pianoKeysVisible - 1, 0, NumKeys - 1); + int topNote = topKey % KeysPerOctave; // if not resizing the note edit area, we can change m_notesEditHeight if (m_action != Action::ResizeNoteEditArea && partialKeyVisible != 0) { diff --git a/src/gui/editors/SongEditor.cpp b/src/gui/editors/SongEditor.cpp index 400c03aa90c..1806f29312f 100644 --- a/src/gui/editors/SongEditor.cpp +++ b/src/gui/editors/SongEditor.cpp @@ -774,17 +774,9 @@ static inline void animateScroll( QScrollBar *scrollBar, int newVal, bool smooth void SongEditor::updatePosition( const TimePos & t ) { - int widgetWidth, trackOpWidth; - if( ConfigManager::inst()->value( "ui", "compacttrackbuttons" ).toInt() ) - { - widgetWidth = DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT; - trackOpWidth = TRACK_OP_WIDTH_COMPACT; - } - else - { - widgetWidth = DEFAULT_SETTINGS_WIDGET_WIDTH; - trackOpWidth = TRACK_OP_WIDTH; - } + const bool compactTrackButtons = ConfigManager::inst()->value("ui", "compacttrackbuttons").toInt(); + const auto widgetWidth = compactTrackButtons ? DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT : DEFAULT_SETTINGS_WIDGET_WIDTH; + const auto trackOpWidth = compactTrackButtons ? TRACK_OP_WIDTH_COMPACT : TRACK_OP_WIDTH; if( ( m_song->isPlaying() && m_song->m_playMode == Song::PlayMode::Song && m_timeLine->autoScroll() == TimeLineWidget::AutoScrollState::Enabled) || diff --git a/src/gui/modals/ControllerConnectionDialog.cpp b/src/gui/modals/ControllerConnectionDialog.cpp index 4d1090d5c88..12e26d03c47 100644 --- a/src/gui/modals/ControllerConnectionDialog.cpp +++ b/src/gui/modals/ControllerConnectionDialog.cpp @@ -299,9 +299,8 @@ void ControllerConnectionDialog::selectController() { if( m_midiControllerSpinBox->model()->value() > 0 ) { - MidiController * mc; - mc = m_midiController->copyToMidiController( Engine::getSong() ); - + auto mc = m_midiController->copyToMidiController(Engine::getSong()); + /* if( m_targetModel->getTrack() && !m_targetModel->getTrack()->displayName().isEmpty() ) diff --git a/src/gui/widgets/Fader.cpp b/src/gui/widgets/Fader.cpp index 6dbd9fbc337..840fe299133 100644 --- a/src/gui/widgets/Fader.cpp +++ b/src/gui/widgets/Fader.cpp @@ -199,15 +199,13 @@ void Fader::mousePressEvent( QMouseEvent* mouseEvent ) void Fader::mouseDoubleClickEvent( QMouseEvent* mouseEvent ) { bool ok; - float newValue; // TODO: dbV handling - newValue = QInputDialog::getDouble( this, tr( "Set value" ), - tr( "Please enter a new value between %1 and %2:" ). - arg( model()->minValue() * m_conversionFactor ). - arg( model()->maxValue() * m_conversionFactor ), - model()->getRoundedValue() * m_conversionFactor, - model()->minValue() * m_conversionFactor, - model()->maxValue() * m_conversionFactor, model()->getDigitCount(), &ok ) / m_conversionFactor; + auto minv = model()->minValue() * m_conversionFactor; + auto maxv = model()->maxValue() * m_conversionFactor; + float newValue = QInputDialog::getDouble(this, tr("Set value"), + tr("Please enter a new value between %1 and %2:").arg(minv).arg(maxv), + model()->getRoundedValue() * m_conversionFactor, minv, maxv, model()->getDigitCount(), &ok) + / m_conversionFactor; if( ok ) { diff --git a/src/gui/widgets/Graph.cpp b/src/gui/widgets/Graph.cpp index 922b98668fb..0781d4f1113 100644 --- a/src/gui/widgets/Graph.cpp +++ b/src/gui/widgets/Graph.cpp @@ -643,11 +643,10 @@ void graphModel::convolve(const float *convolution, // store values in temporary array QVector temp = m_samples; const int graphLength = length(); - float sum; // make a cyclic convolution for ( int i = 0; i < graphLength; i++ ) { - sum = 0; + float sum = 0.0f; for ( int j = 0; j < convolutionLength; j++ ) { sum += convolution[j] * temp[( i + j ) % graphLength]; diff --git a/src/gui/widgets/TimeDisplayWidget.cpp b/src/gui/widgets/TimeDisplayWidget.cpp index 3dad6b1b022..92eaf1efe2a 100644 --- a/src/gui/widgets/TimeDisplayWidget.cpp +++ b/src/gui/widgets/TimeDisplayWidget.cpp @@ -91,24 +91,25 @@ void TimeDisplayWidget::updateTime() switch( m_displayMode ) { case DisplayMode::MinutesSeconds: - int msec; - msec = s->getMilliseconds(); + { + int msec = s->getMilliseconds(); m_majorLCD.setValue(msec / 60000); m_minorLCD.setValue((msec / 1000) % 60); m_milliSecondsLCD.setValue(msec % 1000); break; - + } case DisplayMode::BarsTicks: - int tick; - tick = s->getPlayPos().getTicks(); + { + int tick = s->getPlayPos().getTicks(); m_majorLCD.setValue((int)(tick / s->ticksPerBar()) + 1); m_minorLCD.setValue((tick % s->ticksPerBar()) / (s->ticksPerBar() / s->getTimeSigModel().getNumerator() ) +1); m_milliSecondsLCD.setValue((tick % s->ticksPerBar()) % (s->ticksPerBar() / s->getTimeSigModel().getNumerator())); break; - - default: break; + } + default: + break; } } diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index cdd360e70e1..a32d301c420 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -772,17 +772,17 @@ bool InstrumentTrack::play( const TimePos & _start, const fpp_t _frames, } } - Note * cur_note; - while( nit != notes.end() && - ( cur_note = *nit )->pos() == cur_start ) + while (nit != notes.end() && (*nit)->pos() == cur_start) { + const auto currentNote = *nit; + // If the note is a Step Note, frames will be 0 so the NotePlayHandle // plays for the whole length of the sample - const auto note_frames = cur_note->type() == Note::Type::Step + const auto noteFrames = currentNote->type() == Note::Type::Step ? 0 - : cur_note->length().frames(frames_per_tick); + : currentNote->length().frames(frames_per_tick); - NotePlayHandle* notePlayHandle = NotePlayHandleManager::acquire( this, _offset, note_frames, *cur_note ); + NotePlayHandle* notePlayHandle = NotePlayHandleManager::acquire(this, _offset, noteFrames, *currentNote); notePlayHandle->setPatternTrack(pattern_track); // are we playing global song? if( _clip_num < 0 ) From bad57356d73c2ebfc147863a54e052fe83fe94a6 Mon Sep 17 00:00:00 2001 From: saker Date: Fri, 29 Mar 2024 12:36:20 -0400 Subject: [PATCH 20/31] Fix infinite loop in `InstrumentPlayHandle::play` (#7176) --- src/core/InstrumentPlayHandle.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/core/InstrumentPlayHandle.cpp b/src/core/InstrumentPlayHandle.cpp index 06b8837a8e2..ef7d78f3fbe 100644 --- a/src/core/InstrumentPlayHandle.cpp +++ b/src/core/InstrumentPlayHandle.cpp @@ -47,22 +47,21 @@ void InstrumentPlayHandle::play(sampleFrame * working_buffer) // ensure that all our nph's have been processed first auto nphv = NotePlayHandle::nphsOfInstrumentTrack(instrumentTrack, true); - bool nphsLeft = false; + bool nphsLeft; do { - for (const NotePlayHandle * constNotePlayHandle : nphv) + nphsLeft = false; + for (const auto& handle : nphv) { - if (constNotePlayHandle->state() != ThreadableJob::ProcessingState::Done && - !constNotePlayHandle->isFinished()) + if (handle->state() != ThreadableJob::ProcessingState::Done && !handle->isFinished()) { nphsLeft = true; - NotePlayHandle * notePlayHandle = const_cast(constNotePlayHandle); - notePlayHandle->process(); + const_cast(handle)->process(); } } } while (nphsLeft); - + m_instrument->play(working_buffer); // Process the audio buffer that the instrument has just worked on... From 03f885abc252f3e8207eabfbdca4dd9de5e34b99 Mon Sep 17 00:00:00 2001 From: Lost Robot <34612565+LostRobotMusic@users.noreply.github.com> Date: Fri, 29 Mar 2024 10:39:56 -0700 Subject: [PATCH 21/31] Fix B/B Track Label Button (#7177) * Fix Pattern Track Label Button --- src/gui/tracks/PatternTrackView.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/tracks/PatternTrackView.cpp b/src/gui/tracks/PatternTrackView.cpp index be039ba79e5..ac0b42e2dcc 100644 --- a/src/gui/tracks/PatternTrackView.cpp +++ b/src/gui/tracks/PatternTrackView.cpp @@ -26,6 +26,7 @@ #include "Engine.h" #include "GuiApplication.h" +#include "MainWindow.h" #include "PatternEditor.h" #include "PatternStore.h" #include "PatternTrack.h" @@ -74,8 +75,7 @@ bool PatternTrackView::close() void PatternTrackView::clickedTrackLabel() { Engine::patternStore()->setCurrentPattern(m_patternTrack->patternIndex()); - getGUI()->patternEditor()->parentWidget()->show(); - getGUI()->patternEditor()->setFocus(Qt::ActiveWindowFocusReason); + getGUI()->mainWindow()->togglePatternEditorWin(true); } From 9c591b178f95b5b9b461f00c6b2b7dc71e2c20b3 Mon Sep 17 00:00:00 2001 From: Kevin Zander Date: Sat, 30 Mar 2024 00:15:26 -0500 Subject: [PATCH 22/31] PianoRoll::paintEvent: don't shadow member variable (#7181) --- src/gui/editors/PianoRoll.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 9d22a21bd20..8623b5da76c 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -3031,7 +3031,7 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) if (hasValidMidiClip()) { int pianoAreaHeight = keyAreaBottom() - keyAreaTop(); - int m_pianoKeysVisible = pianoAreaHeight / m_keyLineHeight; + m_pianoKeysVisible = pianoAreaHeight / m_keyLineHeight; int partialKeyVisible = pianoAreaHeight % m_keyLineHeight; // check if we're below the minimum key area size if (m_pianoKeysVisible * m_keyLineHeight < KEY_AREA_MIN_HEIGHT) From a98c70091147008408ac208129ce3cf2909bc8ab Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Sat, 30 Mar 2024 08:53:08 +0100 Subject: [PATCH 23/31] Optimize map accesses in LadspaManager (#7173) Some methods in `LadspaManager` performed repeated searches through the map by first calling `contains` and then by actually fetching the entry. This is fixed by using `find` on the map. It returns an iterator which can directly provide the result or indicate that nothing was found. That way the map is only searched once. --- src/core/LadspaManager.cpp | 54 ++++++++++++++------------------------ 1 file changed, 19 insertions(+), 35 deletions(-) diff --git a/src/core/LadspaManager.cpp b/src/core/LadspaManager.cpp index cc63af63054..e4d472bd109 100644 --- a/src/core/LadspaManager.cpp +++ b/src/core/LadspaManager.cpp @@ -122,14 +122,8 @@ LadspaManager::~LadspaManager() LadspaManagerDescription * LadspaManager::getDescription( const ladspa_key_t & _plugin ) { - if( m_ladspaManagerMap.contains( _plugin ) ) - { - return( m_ladspaManagerMap[_plugin] ); - } - else - { - return( nullptr ); - } + auto const it = m_ladspaManagerMap.find(_plugin); + return it != m_ladspaManagerMap.end() ? *it : nullptr; } @@ -519,24 +513,16 @@ bool LadspaManager::isInteger( const ladspa_key_t & _plugin, bool LadspaManager::isEnum( const ladspa_key_t & _plugin, uint32_t _port ) { - if( m_ladspaManagerMap.contains( _plugin ) - && _port < getPortCount( _plugin ) ) + auto const * desc = getDescriptor(_plugin); + if (desc && _port < desc->PortCount) { - LADSPA_Descriptor_Function descriptorFunction = - m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor = - descriptorFunction( - m_ladspaManagerMap[_plugin]->index ); LADSPA_PortRangeHintDescriptor hintDescriptor = - descriptor->PortRangeHints[_port].HintDescriptor; + desc->PortRangeHints[_port].HintDescriptor; // This is an LMMS extension to ladspa - return( LADSPA_IS_HINT_INTEGER( hintDescriptor ) && - LADSPA_IS_HINT_TOGGLED( hintDescriptor ) ); - } - else - { - return( false ); + return LADSPA_IS_HINT_INTEGER(hintDescriptor) && LADSPA_IS_HINT_TOGGLED(hintDescriptor); } + + return false; } @@ -562,22 +548,20 @@ const void * LadspaManager::getImplementationData( -const LADSPA_Descriptor * LadspaManager::getDescriptor( - const ladspa_key_t & _plugin ) +const LADSPA_Descriptor * LadspaManager::getDescriptor(const ladspa_key_t & _plugin) { - if( m_ladspaManagerMap.contains( _plugin ) ) - { - LADSPA_Descriptor_Function descriptorFunction = - m_ladspaManagerMap[_plugin]->descriptorFunction; - const LADSPA_Descriptor * descriptor = - descriptorFunction( - m_ladspaManagerMap[_plugin]->index ); - return( descriptor ); - } - else + auto const it = m_ladspaManagerMap.find(_plugin); + if (it != m_ladspaManagerMap.end()) { - return( nullptr ); + auto const plugin = *it; + + LADSPA_Descriptor_Function descriptorFunction = plugin->descriptorFunction; + const LADSPA_Descriptor* descriptor = descriptorFunction(plugin->index); + + return descriptor; } + + return nullptr; } From b622fa22064727dd6bebce47b5c7da69cdfadcab Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Sat, 30 Mar 2024 16:30:21 +0100 Subject: [PATCH 24/31] Conditionally remove use of QApplication::desktop in ComboBox.cpp (#7179) Prepare the application for Qt6 by conditionally removing the use of `QApplication::desktop` in `ComboBox.cpp`. The method was already deprecated in Qt5 and is removed in Qt6. Instead the method `QWidget::screen` is used now if the Qt version is equal to or newer than 5.14 (because the method was only introduced with that version). Fall back to `QApplication::desktop` if an older version is detected during the build. This is for example the case for the CI builds which are based on Ubuntu 18.04. Generalize the check if the menu can be shown in the screen. The code now also does handles the case where the menu would go out of screen along the X axis. Also remove the unused include `embed.h`. --- src/gui/widgets/ComboBox.cpp | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/gui/widgets/ComboBox.cpp b/src/gui/widgets/ComboBox.cpp index b11990b273b..6e5eff58b03 100644 --- a/src/gui/widgets/ComboBox.cpp +++ b/src/gui/widgets/ComboBox.cpp @@ -26,16 +26,20 @@ #include "ComboBox.h" -#include -#include #include #include #include +#include #include "CaptionMenu.h" -#include "embed.h" #include "gui_templates.h" +#define QT_SUPPORTS_WIDGET_SCREEN (QT_VERSION >= QT_VERSION_CHECK(5,14,0)) +#if !QT_SUPPORTS_WIDGET_SCREEN +#include +#include +#endif + namespace lmms::gui { const int CB_ARROW_BTN_WIDTH = 18; @@ -116,15 +120,23 @@ void ComboBox::mousePressEvent( QMouseEvent* event ) a->setData( i ); } - QPoint gpos = mapToGlobal( QPoint( 0, height() ) ); - if( gpos.y() + m_menu.sizeHint().height() < qApp->desktop()->height() ) + QPoint gpos = mapToGlobal(QPoint(0, height())); + + #if (QT_SUPPORTS_WIDGET_SCREEN) + bool const menuCanBeFullyShown = screen()->geometry().contains(QRect(gpos, m_menu.sizeHint())); + #else + bool const menuCanBeFullyShown = gpos.y() + m_menu.sizeHint().height() < qApp->desktop()->height(); + #endif + + if (menuCanBeFullyShown) { - m_menu.exec( gpos ); + m_menu.exec(gpos); } else { - m_menu.exec( mapToGlobal( QPoint( width(), 0 ) ) ); + m_menu.exec(mapToGlobal(QPoint(width(), 0))); } + m_pressed = false; update(); } From c271d2831458d4d33610ebccd3517319a916d014 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Sat, 30 Mar 2024 19:04:57 +0100 Subject: [PATCH 25/31] Ensure that build and target are directories in .gitignore (#6884) Ensure that `build` and `target` are directories in `.gitignore`. --- .gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 1b855f204cb..cc2823ba06a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ -/build -/target +/build/ +/target/ .*.sw? .DS_Store *~ From 5d5d8f8f1424949fcd77d1a4a39eeb5479a0a10a Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Mon, 1 Apr 2024 14:57:43 +0200 Subject: [PATCH 26/31] Only repaint LcdWidget if necessary (#7187) Some analysis done with Callgrind showed that the `LcdWidget` spends quite some time repainting itself even when nothing has changed. Some widget instances are used in song update contexts where `LcdWidget::setValue` is called 60 times per second. This commit fixes the problem by only updating the `LcdWidget` if its value really has changed. Adjust the condition in the if-clause so that it becomes clearer what's the interval of interest. --- src/gui/widgets/LcdWidget.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/gui/widgets/LcdWidget.cpp b/src/gui/widgets/LcdWidget.cpp index fa7dea1da07..b30195d6c3c 100644 --- a/src/gui/widgets/LcdWidget.cpp +++ b/src/gui/widgets/LcdWidget.cpp @@ -78,20 +78,26 @@ void LcdWidget::setValue(int value) } } - m_display = s; + if (m_display != s) + { + m_display = s; - update(); + update(); + } } void LcdWidget::setValue(float value) { - if (value < 0 && value > -1) + if (-1 < value && value < 0) { QString s = QString::number(static_cast(value)); s.prepend('-'); - m_display = s; - update(); + if (m_display != s) + { + m_display = s; + update(); + } } else { From 9dd7f4dde456efa95586a0c4744255039f965c78 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Mon, 1 Apr 2024 20:06:18 +0200 Subject: [PATCH 27/31] Remove "GENERAL SETTINGS" tab (#7188) Remove the "GENERAL SETTINGS" tab from the instrument track and sample track window. This removes clutter as well as dependencies to the non-scalable `TabWidget`. Remove superfluous calls to `setSpacing` which have set the default value of 6. Use the default content margins of (9, 9, 9, 9) instead of (8, 8, 8, 8). --- src/gui/SampleTrackWindow.cpp | 7 +------ src/gui/instrument/InstrumentTrackWindow.cpp | 6 +----- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/src/gui/SampleTrackWindow.cpp b/src/gui/SampleTrackWindow.cpp index 630119253aa..81a2ca89b60 100644 --- a/src/gui/SampleTrackWindow.cpp +++ b/src/gui/SampleTrackWindow.cpp @@ -40,7 +40,6 @@ #include "SampleTrackView.h" #include "Song.h" #include "SubWindow.h" -#include "TabWidget.h" #include "TrackLabelButton.h" namespace lmms::gui @@ -69,13 +68,9 @@ SampleTrackWindow::SampleTrackWindow(SampleTrackView * tv) : vlayout->setContentsMargins(0, 0, 0, 0); vlayout->setSpacing(0); - auto generalSettingsWidget = new TabWidget(tr("GENERAL SETTINGS"), this); - + auto generalSettingsWidget = new QWidget(this); auto generalSettingsLayout = new QVBoxLayout(generalSettingsWidget); - generalSettingsLayout->setContentsMargins(8, 18, 8, 8); - generalSettingsLayout->setSpacing(6); - auto nameWidget = new QWidget(generalSettingsWidget); auto nameLayout = new QHBoxLayout(nameWidget); nameLayout->setContentsMargins(0, 0, 0, 0); diff --git a/src/gui/instrument/InstrumentTrackWindow.cpp b/src/gui/instrument/InstrumentTrackWindow.cpp index b6a51624b26..5387346a93f 100644 --- a/src/gui/instrument/InstrumentTrackWindow.cpp +++ b/src/gui/instrument/InstrumentTrackWindow.cpp @@ -93,13 +93,9 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) : vlayout->setContentsMargins(0, 0, 0, 0); vlayout->setSpacing( 0 ); - auto generalSettingsWidget = new TabWidget(tr("GENERAL SETTINGS"), this); - + auto generalSettingsWidget = new QWidget(this); auto generalSettingsLayout = new QVBoxLayout(generalSettingsWidget); - generalSettingsLayout->setContentsMargins( 8, 18, 8, 8 ); - generalSettingsLayout->setSpacing( 6 ); - auto nameAndChangeTrackWidget = new QWidget(generalSettingsWidget); auto nameAndChangeTrackLayout = new QHBoxLayout(nameAndChangeTrackWidget); nameAndChangeTrackLayout->setContentsMargins( 0, 0, 0, 0 ); From b14f8ab8fd1f675cd0c69793219e5a70c0248a91 Mon Sep 17 00:00:00 2001 From: Oskar Wallgren Date: Thu, 4 Apr 2024 01:14:00 +0200 Subject: [PATCH 28/31] Refactor ArpDirection::Down and ArpDirection::DownAndUp (#7007) Fixes an issue with the arpeggiation when it is set to go downwards and the cycle is over 0. --- src/core/InstrumentFunctions.cpp | 34 +++++++++++--------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/src/core/InstrumentFunctions.cpp b/src/core/InstrumentFunctions.cpp index 976363d3d08..39c994ab68c 100644 --- a/src/core/InstrumentFunctions.cpp +++ b/src/core/InstrumentFunctions.cpp @@ -433,42 +433,24 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n ) int cur_arp_idx = 0; // process according to arpeggio-direction... - if( dir == ArpDirection::Up ) + if (dir == ArpDirection::Up || dir == ArpDirection::Down) { cur_arp_idx = ( cur_frame / arp_frames ) % range; } - else if( dir == ArpDirection::Down ) - { - cur_arp_idx = range - ( cur_frame / arp_frames ) % - range - 1; - } - else if( dir == ArpDirection::UpAndDown && range > 1 ) + else if ((dir == ArpDirection::UpAndDown || dir == ArpDirection::DownAndUp) && range > 1) { // imagine, we had to play the arp once up and then // once down -> makes 2 * range possible notes... // because we don't play the lower and upper notes // twice, we have to subtract 2 - cur_arp_idx = ( cur_frame / arp_frames ) % ( range * 2 - 2 ); + cur_arp_idx = (cur_frame / arp_frames) % (range * 2 - (2 * static_cast(m_arpRepeatsModel.value()))); // if greater than range, we have to play down... // looks like the code for arp_dir==DOWN... :) - if( cur_arp_idx >= range ) + if (cur_arp_idx >= range) { - cur_arp_idx = range - cur_arp_idx % ( range - 1 ) - 1; + cur_arp_idx = range - cur_arp_idx % (range - 1) - static_cast(m_arpRepeatsModel.value()); } } - else if( dir == ArpDirection::DownAndUp && range > 1 ) - { - // copied from ArpDirection::UpAndDown above - cur_arp_idx = ( cur_frame / arp_frames ) % ( range * 2 - 2 ); - // if greater than range, we have to play down... - // looks like the code for arp_dir==DOWN... :) - if( cur_arp_idx >= range ) - { - cur_arp_idx = range - cur_arp_idx % ( range - 1 ) - 1; - } - // inverts direction - cur_arp_idx = range - cur_arp_idx - 1; - } else if( dir == ArpDirection::Random ) { // just pick a random chord-index @@ -485,6 +467,12 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n ) cur_arp_idx %= static_cast( range / m_arpRepeatsModel.value() ); } + // If ArpDirection::Down or ArpDirection::DownAndUp, invert the final range. + if (dir == ArpDirection::Down || dir == ArpDirection::DownAndUp) + { + cur_arp_idx = static_cast(range / m_arpRepeatsModel.value()) - cur_arp_idx - 1; + } + // now calculate final key for our arp-note const int sub_note_key = base_note_key + (cur_arp_idx / cur_chord_size ) * KeysPerOctave + chord_table.chords()[selected_arp][cur_arp_idx % cur_chord_size]; From 20fec28befe95f5bc08453f776f7b5252877407d Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Thu, 4 Apr 2024 21:40:31 +0200 Subject: [PATCH 29/31] Font size adjustments (#7185) Adjust and rename the function `pointSize` so that it sets the font size in pixels. Rename `pointSize` to `adjustedToPixelSize` because that's what it does now. It returns a font adjusted to a given pixel size. Rename `fontPointer` to `font` because it's not a pointer but a copy. Rename `fontSize` to simply `size`. This works if the intended model is that users use global fractional scaling. In that case pixel sized fonts are also scaled so that they should stay legible for different screen sizes and pixel densities. ## Adjust plugins with regards to adjustedToPixelSize Adjust the plugins with regards to the use of `adjustedToPixelSize`. Remove the explicit setting of the font size of combo boxes in the following places to make the combo boxes consistent: * `AudioFileProcessorView.cpp` * `DualFilterControlDialog.cpp` * `Monstro.cpp` (does not even seem to use text) * `Mallets.cpp` Remove calls to `adjustedToPixelSize` in the following places because they can deal with different font sizes: * `LadspaBrowser.cpp` Set an explicit point sized font size for the "Show GUI" button in `ZynAddSubFx.cpp` Increase the font size of the buttons in the Vestige plugin and reduce code repetition by introducing a single variable for the font size. I was not able to find out where the font in `VstEffectControlDialog.cpp` is shown. So it is left as is for now. ## Adjust the font sizes in the area of GUI editors and instruments. Increase the font size to 10 pixels in the following places: * Effect view: "Controls" button and the display of the effect name at the bottom * Automation editor: Min and max value display to the left of the editor * InstrumentFunctionViews: Labels "Chord:", "Direction:" and "Mode:" * InstrumentMidiIOView: Message display "Specify the velocity normalization base for MIDI-based instruments at 100% note velocity." * InstrumentSoundShapingView: Message display "Envelopes, LFOs and filters are not supported by the current instrument." * InstrumentTuningView: Message display "Enables the use of global transposition" Increase the font size to 12 pixels in the mixer channel view, i.e. the display of the channel name. Render messages in system font size in the following areas because there should be enough space for almost all sizes: * Automation editor: Message display "Please open an automation clip by double-clicking on it!" * Piano roll: Message display "Please open a clip by double-clicking on it!" Use the application font for the line edit that can be used to change the instrument name. Remove overrides which explicitly set the font size for LED check boxes in: * EnvelopeAndLfoView: Labels "FREQ x 100" and "MODULATE ENV AMOUNT" Remove overrides which explicitly set the font size for combo boxes in: * InstrumentSoundShapingView: Filter combo box ## Adjust font sizes in widgets Adjust the font sizes in the area of the custom GUI widgets. Increase and unify the pixel font size to 10 pixels in the following classes: * `ComboBox` * `GroupBox` * `Knob` * `LcdFloatSpinBox` * `LcdWidget` * `LedCheckBox` * `Oscilloscope`: Display of "Click to enable" * `TabWidget` Shorten the text in `EnvelopeAndLfoView` from "MODULATE ENV AMOUNT" to "MOD ENV AMOUNT" to make it fit with the new font size of `LedCheckBox`. Remove the setting of the font size in pixels from `MeterDialog` because it's displayed in a layout and can accommodate all font sizes. Note: the dialog can be triggered from a LADSPA plugin with tempo sync, e.g. "Allpass delay line". Right click on the time parameter and select "Tempo Sync > Custom..." from the context menu. Remove the setting of the font size in `TabBar` as none of the added `TabButton` instances displays text in the first place. Remove the setting of the font size in `TabWidget::addTab` because the font size is already set in the constructor. It would be an unexpected size effect of setting a tab anyway. Remove a duplicate call to setting the font size in `TabWidget::paintEvent`. Remove unnecessary includes of `gui_templates.h` wherever this is possible now. ## Direct use of setPixelSize Directly use `setPixelSize` when drawing the "Note Velocity" and "Note Panning" strings as they will likely never be drawn using point sizes. --- include/gui_templates.h | 24 ++++--------------- .../AudioFileProcessorView.cpp | 3 +-- .../AudioFileProcessorWaveView.cpp | 2 +- plugins/CarlaBase/Carla.cpp | 4 ++-- .../DualFilter/DualFilterControlDialog.cpp | 3 --- plugins/LadspaBrowser/LadspaBrowser.cpp | 2 -- plugins/Monstro/Monstro.cpp | 6 ----- plugins/Patman/Patman.cpp | 4 ++-- plugins/Stk/Mallets/Mallets.cpp | 2 -- plugins/Vestige/Vestige.cpp | 9 +++---- plugins/VstEffect/VstEffectControlDialog.cpp | 2 +- plugins/ZynAddSubFx/ZynAddSubFx.cpp | 6 +++-- src/gui/EffectView.cpp | 4 ++-- src/gui/Lv2ViewBase.cpp | 2 +- src/gui/MixerChannelView.cpp | 2 +- src/gui/editors/AutomationEditor.cpp | 7 +++--- src/gui/editors/PianoRoll.cpp | 13 +++++----- src/gui/instrument/EnvelopeAndLfoView.cpp | 7 ++---- .../instrument/InstrumentFunctionViews.cpp | 9 +++---- src/gui/instrument/InstrumentMidiIOView.cpp | 2 +- .../instrument/InstrumentSoundShapingView.cpp | 4 ++-- src/gui/instrument/InstrumentTrackWindow.cpp | 2 -- src/gui/instrument/InstrumentTuningView.cpp | 2 +- src/gui/instrument/PianoView.cpp | 2 +- src/gui/widgets/ComboBox.cpp | 2 +- src/gui/widgets/GroupBox.cpp | 2 +- src/gui/widgets/Knob.cpp | 7 +++--- src/gui/widgets/LcdFloatSpinBox.cpp | 2 +- src/gui/widgets/LcdWidget.cpp | 4 ++-- src/gui/widgets/LedCheckBox.cpp | 4 ++-- src/gui/widgets/MeterDialog.cpp | 3 --- src/gui/widgets/Oscilloscope.cpp | 2 +- src/gui/widgets/TabBar.cpp | 3 --- src/gui/widgets/TabWidget.cpp | 7 ++---- 34 files changed, 59 insertions(+), 100 deletions(-) diff --git a/include/gui_templates.h b/include/gui_templates.h index 4833c6cdf1a..bbb5f80da67 100644 --- a/include/gui_templates.h +++ b/include/gui_templates.h @@ -25,35 +25,19 @@ #ifndef LMMS_GUI_TEMPLATES_H #define LMMS_GUI_TEMPLATES_H -#include "lmmsconfig.h" - -#include #include #include -#include - -// TODO: remove once qt5 support is dropped -#if (QT_VERSION < QT_VERSION_CHECK(6,0,0)) - #include -#endif namespace lmms::gui { - -// return DPI-independent font-size - font with returned font-size has always -// the same size in pixels -inline QFont pointSize(QFont fontPointer, float fontSize) +// Convenience method to set the font size in pixels +inline QFont adjustedToPixelSize(QFont font, int size) { - // to calculate DPI of a screen to make it HiDPI ready - qreal devicePixelRatio = QGuiApplication::primaryScreen()->devicePixelRatio(); - qreal scaleFactor = std::max(devicePixelRatio, 1.0); // Ensure scaleFactor is at least 1.0 - - fontPointer.setPointSizeF(fontSize * scaleFactor); - return fontPointer; + font.setPixelSize(size); + return font; } - } // namespace lmms::gui #endif // LMMS_GUI_TEMPLATES_H diff --git a/plugins/AudioFileProcessor/AudioFileProcessorView.cpp b/plugins/AudioFileProcessor/AudioFileProcessorView.cpp index 94f0da4fb67..b7d5802dc44 100644 --- a/plugins/AudioFileProcessor/AudioFileProcessorView.cpp +++ b/plugins/AudioFileProcessor/AudioFileProcessorView.cpp @@ -134,7 +134,6 @@ AudioFileProcessorView::AudioFileProcessorView(Instrument* instrument, // interpolation selector m_interpBox = new ComboBox(this); m_interpBox->setGeometry(142, 62, 82, ComboBox::DEFAULT_HEIGHT); - m_interpBox->setFont(pointSize(m_interpBox->font(), 8)); // wavegraph m_waveView = 0; @@ -228,7 +227,7 @@ void AudioFileProcessorView::paintEvent(QPaintEvent*) int idx = a->sample().sampleFile().length(); - p.setFont(pointSize(font(), 8)); + p.setFont(adjustedToPixelSize(font(), 8)); QFontMetrics fm(p.font()); diff --git a/plugins/AudioFileProcessor/AudioFileProcessorWaveView.cpp b/plugins/AudioFileProcessor/AudioFileProcessorWaveView.cpp index 89e328972f2..1742ee3a7cd 100644 --- a/plugins/AudioFileProcessor/AudioFileProcessorWaveView.cpp +++ b/plugins/AudioFileProcessor/AudioFileProcessorWaveView.cpp @@ -273,7 +273,7 @@ void AudioFileProcessorWaveView::paintEvent(QPaintEvent * pe) p.fillRect(s_padding, s_padding, m_graph.width(), 14, g); p.setPen(QColor(255, 255, 255)); - p.setFont(pointSize(font(), 8)); + p.setFont(adjustedToPixelSize(font(), 8)); QString length_text; const int length = m_sample->sampleDuration().count(); diff --git a/plugins/CarlaBase/Carla.cpp b/plugins/CarlaBase/Carla.cpp index cb52fe25e8c..c95a965c96b 100644 --- a/plugins/CarlaBase/Carla.cpp +++ b/plugins/CarlaBase/Carla.cpp @@ -632,7 +632,7 @@ CarlaInstrumentView::CarlaInstrumentView(CarlaInstrument* const instrument, QWid m_toggleUIButton->setCheckable( true ); m_toggleUIButton->setChecked( false ); m_toggleUIButton->setIcon( embed::getIconPixmap( "zoom" ) ); - m_toggleUIButton->setFont(pointSize(m_toggleUIButton->font(), 8)); + m_toggleUIButton->setFont(adjustedToPixelSize(m_toggleUIButton->font(), 8)); connect( m_toggleUIButton, SIGNAL( clicked(bool) ), this, SLOT( toggleUI( bool ) ) ); m_toggleUIButton->setToolTip( @@ -642,7 +642,7 @@ CarlaInstrumentView::CarlaInstrumentView(CarlaInstrument* const instrument, QWid m_toggleParamsWindowButton = new QPushButton(tr("Params"), this); m_toggleParamsWindowButton->setIcon(embed::getIconPixmap("controller")); m_toggleParamsWindowButton->setCheckable(true); - m_toggleParamsWindowButton->setFont(pointSize(m_toggleParamsWindowButton->font(), 8)); + m_toggleParamsWindowButton->setFont(adjustedToPixelSize(m_toggleParamsWindowButton->font(), 8)); #if CARLA_VERSION_HEX < CARLA_MIN_PARAM_VERSION m_toggleParamsWindowButton->setEnabled(false); m_toggleParamsWindowButton->setToolTip(tr("Available from Carla version 2.1 and up.")); diff --git a/plugins/DualFilter/DualFilterControlDialog.cpp b/plugins/DualFilter/DualFilterControlDialog.cpp index 5a912ac8551..a674a4a42c2 100644 --- a/plugins/DualFilter/DualFilterControlDialog.cpp +++ b/plugins/DualFilter/DualFilterControlDialog.cpp @@ -29,7 +29,6 @@ #include "Knob.h" #include "LedCheckBox.h" #include "ComboBox.h" -#include "gui_templates.h" namespace lmms::gui { @@ -76,12 +75,10 @@ DualFilterControlDialog::DualFilterControlDialog( DualFilterControls* controls ) auto m_filter1ComboBox = new ComboBox(this); m_filter1ComboBox->setGeometry( 19, 70, 137, ComboBox::DEFAULT_HEIGHT ); - m_filter1ComboBox->setFont(pointSize(m_filter1ComboBox->font(), 8)); m_filter1ComboBox->setModel( &controls->m_filter1Model ); auto m_filter2ComboBox = new ComboBox(this); m_filter2ComboBox->setGeometry( 217, 70, 137, ComboBox::DEFAULT_HEIGHT ); - m_filter2ComboBox->setFont(pointSize(m_filter2ComboBox->font(), 8)); m_filter2ComboBox->setModel( &controls->m_filter2Model ); } diff --git a/plugins/LadspaBrowser/LadspaBrowser.cpp b/plugins/LadspaBrowser/LadspaBrowser.cpp index 54d019aad32..e6a31e15a3c 100644 --- a/plugins/LadspaBrowser/LadspaBrowser.cpp +++ b/plugins/LadspaBrowser/LadspaBrowser.cpp @@ -32,7 +32,6 @@ #include -#include "gui_templates.h" #include "LadspaDescription.h" #include "LadspaPortDialog.h" #include "TabBar.h" @@ -172,7 +171,6 @@ QWidget * LadspaBrowserView::createTab( QWidget * _parent, const QString & _txt, auto title = new QLabel(type + _txt, tab); QFont f = title->font(); f.setBold( true ); - title->setFont(pointSize(f, 12)); layout->addSpacing( 5 ); layout->addWidget( title ); diff --git a/plugins/Monstro/Monstro.cpp b/plugins/Monstro/Monstro.cpp index 76ab6e47790..3de9fbce691 100644 --- a/plugins/Monstro/Monstro.cpp +++ b/plugins/Monstro/Monstro.cpp @@ -30,7 +30,6 @@ #include "ComboBox.h" #include "Engine.h" #include "InstrumentTrack.h" -#include "gui_templates.h" #include "lmms_math.h" #include "interpolation.h" @@ -1694,7 +1693,6 @@ QWidget * MonstroView::setupOperatorsView( QWidget * _parent ) m_osc2WaveBox = new ComboBox( view ); m_osc2WaveBox -> setGeometry( 204, O2ROW + 7, 42, ComboBox::DEFAULT_HEIGHT ); - m_osc2WaveBox->setFont(pointSize(m_osc2WaveBox->font(), 8)); maketinyled( m_osc2SyncHButton, 212, O2ROW - 3, tr( "Hard sync oscillator 2" ) ) maketinyled( m_osc2SyncRButton, 191, O2ROW - 3, tr( "Reverse sync oscillator 2" ) ) @@ -1709,18 +1707,15 @@ QWidget * MonstroView::setupOperatorsView( QWidget * _parent ) m_osc3Wave1Box = new ComboBox( view ); m_osc3Wave1Box -> setGeometry( 160, O3ROW + 7, 42, ComboBox::DEFAULT_HEIGHT ); - m_osc3Wave1Box->setFont(pointSize(m_osc3Wave1Box->font(), 8)); m_osc3Wave2Box = new ComboBox( view ); m_osc3Wave2Box -> setGeometry( 204, O3ROW + 7, 42, ComboBox::DEFAULT_HEIGHT ); - m_osc3Wave2Box->setFont(pointSize(m_osc3Wave2Box->font(), 8)); maketinyled( m_osc3SyncHButton, 212, O3ROW - 3, tr( "Hard sync oscillator 3" ) ) maketinyled( m_osc3SyncRButton, 191, O3ROW - 3, tr( "Reverse sync oscillator 3" ) ) m_lfo1WaveBox = new ComboBox( view ); m_lfo1WaveBox -> setGeometry( 2, LFOROW + 7, 42, ComboBox::DEFAULT_HEIGHT ); - m_lfo1WaveBox->setFont(pointSize(m_lfo1WaveBox->font(), 8)); maketsknob( m_lfo1AttKnob, LFOCOL1, LFOROW, tr( "Attack" ), " ms", "lfoKnob" ) maketsknob( m_lfo1RateKnob, LFOCOL2, LFOROW, tr( "Rate" ), " ms", "lfoKnob" ) @@ -1728,7 +1723,6 @@ QWidget * MonstroView::setupOperatorsView( QWidget * _parent ) m_lfo2WaveBox = new ComboBox( view ); m_lfo2WaveBox -> setGeometry( 127, LFOROW + 7, 42, ComboBox::DEFAULT_HEIGHT ); - m_lfo2WaveBox->setFont(pointSize(m_lfo2WaveBox->font(), 8)); maketsknob(m_lfo2AttKnob, LFOCOL4, LFOROW, tr("Attack"), " ms", "lfoKnob") maketsknob(m_lfo2RateKnob, LFOCOL5, LFOROW, tr("Rate"), " ms", "lfoKnob") diff --git a/plugins/Patman/Patman.cpp b/plugins/Patman/Patman.cpp index a503637772a..d2f4aee4ee9 100644 --- a/plugins/Patman/Patman.cpp +++ b/plugins/Patman/Patman.cpp @@ -545,7 +545,7 @@ void PatmanView::updateFilename() m_displayFilename = ""; int idx = m_pi->m_patchFile.length(); - QFontMetrics fm(pointSize(font(), 8)); + QFontMetrics fm(adjustedToPixelSize(font(), 8)); // simple algorithm for creating a text from the filename that // matches in the white rectangle @@ -615,7 +615,7 @@ void PatmanView::paintEvent( QPaintEvent * ) { QPainter p( this ); - p.setFont(pointSize(font() ,8)); + p.setFont(adjustedToPixelSize(font() ,8)); p.drawText( 8, 116, 235, 16, Qt::AlignLeft | Qt::TextSingleLine | Qt::AlignVCenter, m_displayFilename ); diff --git a/plugins/Stk/Mallets/Mallets.cpp b/plugins/Stk/Mallets/Mallets.cpp index 1d7cbd86bad..3fb7fc0ff3f 100644 --- a/plugins/Stk/Mallets/Mallets.cpp +++ b/plugins/Stk/Mallets/Mallets.cpp @@ -37,7 +37,6 @@ #include "AudioEngine.h" #include "ConfigManager.h" #include "Engine.h" -#include "gui_templates.h" #include "GuiApplication.h" #include "InstrumentTrack.h" @@ -450,7 +449,6 @@ MalletsInstrumentView::MalletsInstrumentView( MalletsInstrument * _instrument, m_presetsCombo = new ComboBox( this, tr( "Instrument" ) ); m_presetsCombo->setGeometry( 140, 50, 99, ComboBox::DEFAULT_HEIGHT ); - m_presetsCombo->setFont(pointSize(m_presetsCombo->font(), 8)); connect( &_instrument->m_presetsModel, SIGNAL( dataChanged() ), this, SLOT( changePreset() ) ); diff --git a/plugins/Vestige/Vestige.cpp b/plugins/Vestige/Vestige.cpp index 552b1f3ff37..834b583ed06 100644 --- a/plugins/Vestige/Vestige.cpp +++ b/plugins/Vestige/Vestige.cpp @@ -583,11 +583,12 @@ VestigeInstrumentView::VestigeInstrumentView( Instrument * _instrument, m_selPresetButton->setMenu(menu); + constexpr int buttonFontSize = 12; m_toggleGUIButton = new QPushButton( tr( "Show/hide GUI" ), this ); m_toggleGUIButton->setGeometry( 20, 130, 200, 24 ); m_toggleGUIButton->setIcon( embed::getIconPixmap( "zoom" ) ); - m_toggleGUIButton->setFont(pointSize(m_toggleGUIButton->font(), 8)); + m_toggleGUIButton->setFont(adjustedToPixelSize(m_toggleGUIButton->font(), buttonFontSize)); connect( m_toggleGUIButton, SIGNAL( clicked() ), this, SLOT( toggleGUI() ) ); @@ -596,7 +597,7 @@ VestigeInstrumentView::VestigeInstrumentView( Instrument * _instrument, this); note_off_all_btn->setGeometry( 20, 160, 200, 24 ); note_off_all_btn->setIcon( embed::getIconPixmap( "stop" ) ); - note_off_all_btn->setFont(pointSize(note_off_all_btn->font(), 8)); + note_off_all_btn->setFont(adjustedToPixelSize(note_off_all_btn->font(), buttonFontSize)); connect( note_off_all_btn, SIGNAL( clicked() ), this, SLOT( noteOffAll() ) ); @@ -881,7 +882,7 @@ void VestigeInstrumentView::paintEvent( QPaintEvent * ) tr( "No VST plugin loaded" ); QFont f = p.font(); f.setBold( true ); - p.setFont(pointSize(f, 10)); + p.setFont(adjustedToPixelSize(f, 10)); p.setPen( QColor( 255, 255, 255 ) ); p.drawText( 10, 100, plugin_name ); @@ -893,7 +894,7 @@ void VestigeInstrumentView::paintEvent( QPaintEvent * ) { p.setPen( QColor( 0, 0, 0 ) ); f.setBold( false ); - p.setFont(pointSize(f, 8)); + p.setFont(adjustedToPixelSize(f, 8)); p.drawText( 10, 114, tr( "by " ) + m_vi->m_plugin->vendorString() ); p.setPen( QColor( 255, 255, 255 ) ); diff --git a/plugins/VstEffect/VstEffectControlDialog.cpp b/plugins/VstEffect/VstEffectControlDialog.cpp index 671eef56191..0fb4913a338 100644 --- a/plugins/VstEffect/VstEffectControlDialog.cpp +++ b/plugins/VstEffect/VstEffectControlDialog.cpp @@ -246,7 +246,7 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) : tb->addWidget(space1); tbLabel = new QLabel( tr( "Effect by: " ), this ); - tbLabel->setFont(pointSize(f, 7)); + tbLabel->setFont(adjustedToPixelSize(f, 7)); tbLabel->setTextFormat(Qt::RichText); tbLabel->setAlignment( Qt::AlignTop | Qt::AlignLeft ); tb->addWidget( tbLabel ); diff --git a/plugins/ZynAddSubFx/ZynAddSubFx.cpp b/plugins/ZynAddSubFx/ZynAddSubFx.cpp index 4988e1b8bde..c406e04e03f 100644 --- a/plugins/ZynAddSubFx/ZynAddSubFx.cpp +++ b/plugins/ZynAddSubFx/ZynAddSubFx.cpp @@ -40,7 +40,6 @@ #include "DataFile.h" #include "InstrumentPlayHandle.h" #include "InstrumentTrack.h" -#include "gui_templates.h" #include "Song.h" #include "StringPairDrag.h" #include "RemoteZynAddSubFx.h" @@ -541,7 +540,10 @@ ZynAddSubFxView::ZynAddSubFxView( Instrument * _instrument, QWidget * _parent ) m_toggleUIButton->setCheckable( true ); m_toggleUIButton->setChecked( false ); m_toggleUIButton->setIcon( embed::getIconPixmap( "zoom" ) ); - m_toggleUIButton->setFont(pointSize(m_toggleUIButton->font(), 8)); + QFont f = m_toggleUIButton->font(); + f.setPointSizeF(12); + m_toggleUIButton->setFont(f); + connect( m_toggleUIButton, SIGNAL( toggled( bool ) ), this, SLOT( toggleUI() ) ); diff --git a/src/gui/EffectView.cpp b/src/gui/EffectView.cpp index cbe2e4e95ed..76010232a30 100644 --- a/src/gui/EffectView.cpp +++ b/src/gui/EffectView.cpp @@ -90,7 +90,7 @@ EffectView::EffectView( Effect * _model, QWidget * _parent ) : { auto ctls_btn = new QPushButton(tr("Controls"), this); QFont f = ctls_btn->font(); - ctls_btn->setFont(pointSize(f, 8)); + ctls_btn->setFont(adjustedToPixelSize(f, 10)); ctls_btn->setGeometry( 150, 14, 50, 20 ); connect( ctls_btn, SIGNAL(clicked()), this, SLOT(editControls())); @@ -257,7 +257,7 @@ void EffectView::paintEvent( QPaintEvent * ) QPainter p( this ); p.drawPixmap( 0, 0, m_bg ); - QFont f = pointSize(font(), 7.5f); + QFont f = adjustedToPixelSize(font(), 10); f.setBold( true ); p.setFont( f ); diff --git a/src/gui/Lv2ViewBase.cpp b/src/gui/Lv2ViewBase.cpp index 6de47f450b9..4fcf6b77ba1 100644 --- a/src/gui/Lv2ViewBase.cpp +++ b/src/gui/Lv2ViewBase.cpp @@ -157,7 +157,7 @@ Lv2ViewBase::Lv2ViewBase(QWidget* meAsWidget, Lv2ControlBase *ctrlBase) : m_toggleUIButton->setCheckable(true); m_toggleUIButton->setChecked(false); m_toggleUIButton->setIcon(embed::getIconPixmap("zoom")); - m_toggleUIButton->setFont(pointSize(m_toggleUIButton->font(), 8)); + m_toggleUIButton->setFont(adjustedToPixelSize(m_toggleUIButton->font(), 8)); btnBox->addWidget(m_toggleUIButton, 0); } btnBox->addStretch(1); diff --git a/src/gui/MixerChannelView.cpp b/src/gui/MixerChannelView.cpp index 9b43991d3b6..8a1ed2e8fe4 100644 --- a/src/gui/MixerChannelView.cpp +++ b/src/gui/MixerChannelView.cpp @@ -76,7 +76,7 @@ namespace lmms::gui m_renameLineEdit = new QLineEdit{mixerName, nullptr}; m_renameLineEdit->setFixedWidth(65); - m_renameLineEdit->setFont(pointSize(font(), 7.5f)); + m_renameLineEdit->setFont(adjustedToPixelSize(font(), 12)); m_renameLineEdit->setReadOnly(true); m_renameLineEdit->installEventFilter(this); diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index d23682d6e33..46521b3f02b 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -1040,8 +1040,7 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) QBrush bgColor = p.background(); p.fillRect( 0, 0, width(), height(), bgColor ); - // set font-size to 8 - p.setFont(pointSize(p.font(), 8)); + p.setFont(adjustedToPixelSize(p.font(), 10)); int grid_height = height() - TOP_MARGIN - SCROLLBAR_SIZE; @@ -1383,9 +1382,9 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) } else { - QFont f = p.font(); + QFont f = font(); f.setBold( true ); - p.setFont(pointSize(f, 14)); + p.setFont(f); p.setPen( QApplication::palette().color( QPalette::Active, QPalette::BrightText ) ); p.drawText( VALUES_WIDTH + 20, TOP_MARGIN + 40, diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 8623b5da76c..3b9273ade7d 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -59,7 +59,6 @@ #include "DetuningHelper.h" #include "embed.h" #include "GuiApplication.h" -#include "gui_templates.h" #include "InstrumentTrack.h" #include "MainWindow.h" #include "MidiClip.h" @@ -3335,9 +3334,9 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) m_whiteKeyWidth, noteEditBottom() - keyAreaBottom()), bgColor); // display note editing info - //QFont f = p.font(); - f.setBold( false ); - p.setFont(pointSize(f, 10)); + f.setBold(false); + f.setPixelSize(10); + p.setFont(f); p.setPen(m_noteModeColor); p.drawText( QRect( 0, keyAreaBottom(), m_whiteKeyWidth, noteEditBottom() - keyAreaBottom()), @@ -3598,9 +3597,9 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) } else { - QFont f = p.font(); - f.setBold( true ); - p.setFont(pointSize(f, 14)); + QFont f = font(); + f.setBold(true); + p.setFont(f); p.setPen( QApplication::palette().color( QPalette::Active, QPalette::BrightText ) ); p.drawText(m_whiteKeyWidth + 20, PR_TOP_MARGIN + 40, diff --git a/src/gui/instrument/EnvelopeAndLfoView.cpp b/src/gui/instrument/EnvelopeAndLfoView.cpp index 4043ea2295b..7f30f3ac197 100644 --- a/src/gui/instrument/EnvelopeAndLfoView.cpp +++ b/src/gui/instrument/EnvelopeAndLfoView.cpp @@ -207,15 +207,12 @@ EnvelopeAndLfoView::EnvelopeAndLfoView( QWidget * _parent ) : m_lfoWaveBtnGrp->addButton( random_lfo_btn ); m_x100Cb = new LedCheckBox( tr( "FREQ x 100" ), this ); - m_x100Cb->setFont(pointSize(m_x100Cb->font(), 6.5)); m_x100Cb->move( LFO_PREDELAY_KNOB_X, LFO_GRAPH_Y + 36 ); m_x100Cb->setToolTip(tr("Multiply LFO frequency by 100")); - m_controlEnvAmountCb = new LedCheckBox( tr( "MODULATE ENV AMOUNT" ), - this ); + m_controlEnvAmountCb = new LedCheckBox(tr("MOD ENV AMOUNT"), this); m_controlEnvAmountCb->move( LFO_PREDELAY_KNOB_X, LFO_GRAPH_Y + 54 ); - m_controlEnvAmountCb->setFont(pointSize(m_controlEnvAmountCb->font(), 6.5)); m_controlEnvAmountCb->setToolTip( tr( "Control envelope amount by this LFO" ) ); @@ -340,7 +337,7 @@ void EnvelopeAndLfoView::paintEvent( QPaintEvent * ) // draw LFO-graph p.drawPixmap(LFO_GRAPH_X, LFO_GRAPH_Y, m_lfoGraph); - p.setFont(pointSize(p.font(), 8)); + p.setFont(adjustedToPixelSize(p.font(), 8)); const float gray_amount = 1.0f - fabsf( m_amountKnob->value() ); diff --git a/src/gui/instrument/InstrumentFunctionViews.cpp b/src/gui/instrument/InstrumentFunctionViews.cpp index ea16486004c..ad8abe73524 100644 --- a/src/gui/instrument/InstrumentFunctionViews.cpp +++ b/src/gui/instrument/InstrumentFunctionViews.cpp @@ -57,7 +57,7 @@ InstrumentFunctionNoteStackingView::InstrumentFunctionNoteStackingView( Instrume mainLayout->setVerticalSpacing( 1 ); auto chordLabel = new QLabel(tr("Chord:")); - chordLabel->setFont(pointSize(chordLabel->font(), 8)); + chordLabel->setFont(adjustedToPixelSize(chordLabel->font(), 10)); m_chordRangeKnob->setLabel( tr( "RANGE" ) ); m_chordRangeKnob->setHintText( tr( "Chord range:" ), " " + tr( "octave(s)" ) ); @@ -145,14 +145,15 @@ InstrumentFunctionArpeggioView::InstrumentFunctionArpeggioView( InstrumentFuncti m_arpGateKnob->setLabel( tr( "GATE" ) ); m_arpGateKnob->setHintText( tr( "Arpeggio gate:" ), tr( "%" ) ); + constexpr int labelFontSize = 10; auto arpChordLabel = new QLabel(tr("Chord:")); - arpChordLabel->setFont(pointSize(arpChordLabel->font(), 8)); + arpChordLabel->setFont(adjustedToPixelSize(arpChordLabel->font(), labelFontSize)); auto arpDirectionLabel = new QLabel(tr("Direction:")); - arpDirectionLabel->setFont(pointSize(arpDirectionLabel->font(), 8)); + arpDirectionLabel->setFont(adjustedToPixelSize(arpDirectionLabel->font(), labelFontSize)); auto arpModeLabel = new QLabel(tr("Mode:")); - arpModeLabel->setFont(pointSize(arpModeLabel->font(), 8)); + arpModeLabel->setFont(adjustedToPixelSize(arpModeLabel->font(), labelFontSize)); mainLayout->addWidget( arpChordLabel, 0, 0 ); mainLayout->addWidget( m_arpComboBox, 1, 0 ); diff --git a/src/gui/instrument/InstrumentMidiIOView.cpp b/src/gui/instrument/InstrumentMidiIOView.cpp index 1e95751ead0..f5f4ae095e8 100644 --- a/src/gui/instrument/InstrumentMidiIOView.cpp +++ b/src/gui/instrument/InstrumentMidiIOView.cpp @@ -155,7 +155,7 @@ InstrumentMidiIOView::InstrumentMidiIOView( QWidget* parent ) : auto baseVelocityHelp = new QLabel(tr("Specify the velocity normalization base for MIDI-based instruments at 100% note velocity.")); baseVelocityHelp->setWordWrap( true ); - baseVelocityHelp->setFont(pointSize(baseVelocityHelp->font(), 8)); + baseVelocityHelp->setFont(adjustedToPixelSize(baseVelocityHelp->font(), 10)); baseVelocityLayout->addWidget( baseVelocityHelp ); diff --git a/src/gui/instrument/InstrumentSoundShapingView.cpp b/src/gui/instrument/InstrumentSoundShapingView.cpp index 59df3097cb2..b96db8495a9 100644 --- a/src/gui/instrument/InstrumentSoundShapingView.cpp +++ b/src/gui/instrument/InstrumentSoundShapingView.cpp @@ -77,7 +77,6 @@ InstrumentSoundShapingView::InstrumentSoundShapingView( QWidget * _parent ) : m_filterComboBox = new ComboBox( m_filterGroupBox ); m_filterComboBox->setGeometry( 14, 22, 120, ComboBox::DEFAULT_HEIGHT ); - m_filterComboBox->setFont(pointSize(m_filterComboBox->font(), 8)); m_filterCutKnob = new Knob( KnobType::Bright26, m_filterGroupBox ); @@ -94,7 +93,8 @@ InstrumentSoundShapingView::InstrumentSoundShapingView( QWidget * _parent ) : m_singleStreamInfoLabel = new QLabel( tr( "Envelopes, LFOs and filters are not supported by the current instrument." ), this ); m_singleStreamInfoLabel->setWordWrap( true ); - m_singleStreamInfoLabel->setFont(pointSize(m_singleStreamInfoLabel->font(), 8)); + // TODO Could also be rendered in system font size... + m_singleStreamInfoLabel->setFont(adjustedToPixelSize(m_singleStreamInfoLabel->font(), 10)); m_singleStreamInfoLabel->setGeometry( TARGETS_TABWIDGET_X, TARGETS_TABWIDGET_Y, diff --git a/src/gui/instrument/InstrumentTrackWindow.cpp b/src/gui/instrument/InstrumentTrackWindow.cpp index 5387346a93f..86d9086c8ba 100644 --- a/src/gui/instrument/InstrumentTrackWindow.cpp +++ b/src/gui/instrument/InstrumentTrackWindow.cpp @@ -44,7 +44,6 @@ #include "GroupBox.h" #include "MixerChannelLcdSpinBox.h" #include "GuiApplication.h" -#include "gui_templates.h" #include "Instrument.h" #include "InstrumentFunctions.h" #include "InstrumentFunctionViews.h" @@ -103,7 +102,6 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) : // setup line edit for changing instrument track name m_nameLineEdit = new QLineEdit; - m_nameLineEdit->setFont(pointSize(m_nameLineEdit->font(), 9)); connect( m_nameLineEdit, SIGNAL( textChanged( const QString& ) ), this, SLOT( textChanged( const QString& ) ) ); diff --git a/src/gui/instrument/InstrumentTuningView.cpp b/src/gui/instrument/InstrumentTuningView.cpp index 41c18213b5f..daa361aad6b 100644 --- a/src/gui/instrument/InstrumentTuningView.cpp +++ b/src/gui/instrument/InstrumentTuningView.cpp @@ -60,7 +60,7 @@ InstrumentTuningView::InstrumentTuningView(InstrumentTrack *it, QWidget *parent) auto tlabel = new QLabel(tr("Enables the use of global transposition")); tlabel->setWordWrap(true); - tlabel->setFont(pointSize(tlabel->font(), 8)); + tlabel->setFont(adjustedToPixelSize(tlabel->font(), 10)); masterPitchLayout->addWidget(tlabel); // Microtuner settings diff --git a/src/gui/instrument/PianoView.cpp b/src/gui/instrument/PianoView.cpp index 87ee6af9bed..13628d97eea 100644 --- a/src/gui/instrument/PianoView.cpp +++ b/src/gui/instrument/PianoView.cpp @@ -807,7 +807,7 @@ void PianoView::paintEvent( QPaintEvent * ) QPainter p( this ); // set smaller font for printing number of every octave - p.setFont(pointSize(p.font(), LABEL_TEXT_SIZE)); + p.setFont(adjustedToPixelSize(p.font(), LABEL_TEXT_SIZE)); // draw bar above the keyboard (there will be the labels diff --git a/src/gui/widgets/ComboBox.cpp b/src/gui/widgets/ComboBox.cpp index 6e5eff58b03..eb019876a06 100644 --- a/src/gui/widgets/ComboBox.cpp +++ b/src/gui/widgets/ComboBox.cpp @@ -53,7 +53,7 @@ ComboBox::ComboBox( QWidget * _parent, const QString & _name ) : { setFixedHeight( ComboBox::DEFAULT_HEIGHT ); - setFont(pointSize(font(), 9)); + setFont(adjustedToPixelSize(font(), 10)); connect( &m_menu, SIGNAL(triggered(QAction*)), this, SLOT(setItem(QAction*))); diff --git a/src/gui/widgets/GroupBox.cpp b/src/gui/widgets/GroupBox.cpp index 229ab13cd45..e7d78acb9dd 100644 --- a/src/gui/widgets/GroupBox.cpp +++ b/src/gui/widgets/GroupBox.cpp @@ -111,7 +111,7 @@ void GroupBox::paintEvent( QPaintEvent * pe ) // draw text p.setPen( palette().color( QPalette::Active, QPalette::Text ) ); - p.setFont(pointSize(font(), 8)); + p.setFont(adjustedToPixelSize(font(), 10)); int const captionX = ledButtonShown() ? 22 : 6; p.drawText(captionX, m_titleBarHeight, m_caption); diff --git a/src/gui/widgets/Knob.cpp b/src/gui/widgets/Knob.cpp index a6411d6cf07..d282f72c20f 100644 --- a/src/gui/widgets/Knob.cpp +++ b/src/gui/widgets/Knob.cpp @@ -139,7 +139,7 @@ void Knob::setLabel( const QString & txt ) if( m_knobPixmap ) { setFixedSize(qMax( m_knobPixmap->width(), - horizontalAdvance(QFontMetrics(pointSize(font(), 6.5)), m_label)), + horizontalAdvance(QFontMetrics(adjustedToPixelSize(font(), 10)), m_label)), m_knobPixmap->height() + 10); } @@ -459,7 +459,7 @@ void Knob::paintEvent( QPaintEvent * _me ) { if (!m_isHtmlLabel) { - p.setFont(pointSize(p.font(), 6.5f)); + p.setFont(adjustedToPixelSize(p.font(), 10)); p.setPen(textColor()); p.drawText(width() / 2 - horizontalAdvance(p.fontMetrics(), m_label) / 2, @@ -467,7 +467,8 @@ void Knob::paintEvent( QPaintEvent * _me ) } else { - m_tdRenderer->setDefaultFont(pointSize(p.font(), 6.5f)); + // TODO setHtmlLabel is never called so this will never be executed. Remove functionality? + m_tdRenderer->setDefaultFont(adjustedToPixelSize(p.font(), 10)); p.translate((width() - m_tdRenderer->idealWidth()) / 2, (height() - m_tdRenderer->pageSize().height()) / 2); m_tdRenderer->drawContents(&p); } diff --git a/src/gui/widgets/LcdFloatSpinBox.cpp b/src/gui/widgets/LcdFloatSpinBox.cpp index 667a034815b..c71d665689e 100644 --- a/src/gui/widgets/LcdFloatSpinBox.cpp +++ b/src/gui/widgets/LcdFloatSpinBox.cpp @@ -245,7 +245,7 @@ void LcdFloatSpinBox::paintEvent(QPaintEvent*) // Label if (!m_label.isEmpty()) { - p.setFont(pointSize(p.font(), 6.5f)); + p.setFont(adjustedToPixelSize(p.font(), 10)); p.setPen(m_wholeDisplay.textShadowColor()); p.drawText(width() / 2 - p.fontMetrics().boundingRect(m_label).width() / 2 + 1, height(), m_label); p.setPen(m_wholeDisplay.textColor()); diff --git a/src/gui/widgets/LcdWidget.cpp b/src/gui/widgets/LcdWidget.cpp index b30195d6c3c..7370a939fe3 100644 --- a/src/gui/widgets/LcdWidget.cpp +++ b/src/gui/widgets/LcdWidget.cpp @@ -209,7 +209,7 @@ void LcdWidget::paintEvent( QPaintEvent* ) // Label if( !m_label.isEmpty() ) { - p.setFont(pointSize(p.font(), 6.5f)); + p.setFont(adjustedToPixelSize(p.font(), 10)); p.setPen( textShadowColor() ); p.drawText(width() / 2 - horizontalAdvance(p.fontMetrics(), m_label) / 2 + 1, @@ -261,7 +261,7 @@ void LcdWidget::updateSize() setFixedSize( qMax( m_cellWidth * m_numDigits + marginX1 + marginX2, - horizontalAdvance(QFontMetrics(pointSize(font(), 6.5f)), m_label) + horizontalAdvance(QFontMetrics(adjustedToPixelSize(font(), 10)), m_label) ), m_cellHeight + (2 * marginY) + 9 ); diff --git a/src/gui/widgets/LedCheckBox.cpp b/src/gui/widgets/LedCheckBox.cpp index 3cb85deff08..42e49a8ae2b 100644 --- a/src/gui/widgets/LedCheckBox.cpp +++ b/src/gui/widgets/LedCheckBox.cpp @@ -92,7 +92,7 @@ void LedCheckBox::initUi( LedColor _color ) m_ledOnPixmap = embed::getIconPixmap(names[static_cast(_color)].toUtf8().constData()); m_ledOffPixmap = embed::getIconPixmap("led_off"); - if (m_legacyMode){ setFont(pointSize(font(), 7)); } + if (m_legacyMode){ setFont(adjustedToPixelSize(font(), 10)); } setText( m_text ); } @@ -113,7 +113,7 @@ void LedCheckBox::onTextUpdated() void LedCheckBox::paintLegacy(QPaintEvent * pe) { QPainter p( this ); - p.setFont(pointSize(font(), 7)); + p.setFont(adjustedToPixelSize(font(), 10)); p.drawPixmap(0, 0, model()->value() ? m_ledOnPixmap : m_ledOffPixmap); diff --git a/src/gui/widgets/MeterDialog.cpp b/src/gui/widgets/MeterDialog.cpp index eb8e5435376..d01dca9a866 100644 --- a/src/gui/widgets/MeterDialog.cpp +++ b/src/gui/widgets/MeterDialog.cpp @@ -30,7 +30,6 @@ #include "MeterDialog.h" #include "MeterModel.h" -#include "gui_templates.h" #include "LcdSpinBox.h" namespace lmms::gui @@ -60,7 +59,6 @@ MeterDialog::MeterDialog( QWidget * _parent, bool _simple ) : { auto num_label = new QLabel(tr("Meter Numerator"), num); QFont f = num_label->font(); - num_label->setFont(pointSize(f, 7)); num_layout->addSpacing( 5 ); num_layout->addWidget( num_label ); } @@ -84,7 +82,6 @@ MeterDialog::MeterDialog( QWidget * _parent, bool _simple ) : { auto den_label = new QLabel(tr("Meter Denominator"), den); QFont f = den_label->font(); - den_label->setFont(pointSize(f, 7)); den_layout->addSpacing( 5 ); den_layout->addWidget( den_label ); } diff --git a/src/gui/widgets/Oscilloscope.cpp b/src/gui/widgets/Oscilloscope.cpp index bd944937a7d..8c342cc349f 100644 --- a/src/gui/widgets/Oscilloscope.cpp +++ b/src/gui/widgets/Oscilloscope.cpp @@ -203,7 +203,7 @@ void Oscilloscope::paintEvent( QPaintEvent * ) else { p.setPen( QColor( 192, 192, 192 ) ); - p.setFont(pointSize(p.font(), 7)); + p.setFont(adjustedToPixelSize(p.font(), 10)); p.drawText( 6, height()-5, tr( "Click to enable" ) ); } } diff --git a/src/gui/widgets/TabBar.cpp b/src/gui/widgets/TabBar.cpp index ce706d5f80b..d77573a9218 100644 --- a/src/gui/widgets/TabBar.cpp +++ b/src/gui/widgets/TabBar.cpp @@ -25,7 +25,6 @@ #include "TabBar.h" #include "TabButton.h" -#include "gui_templates.h" namespace lmms::gui @@ -90,8 +89,6 @@ TabButton * TabBar::addTab( QWidget * _w, const QString & _text, int _id, _w->setFixedSize( _w->parentWidget()->size() ); } - b->setFont(pointSize(b->font(), 8)); - return( b ); } diff --git a/src/gui/widgets/TabWidget.cpp b/src/gui/widgets/TabWidget.cpp index 2c93dba3e22..a370c1ea9fb 100644 --- a/src/gui/widgets/TabWidget.cpp +++ b/src/gui/widgets/TabWidget.cpp @@ -58,7 +58,7 @@ TabWidget::TabWidget(const QString& caption, QWidget* parent, bool usePixmap, m_tabheight = caption.isEmpty() ? m_tabbarHeight - 3 : m_tabbarHeight - 4; - setFont(pointSize(font(), 8)); + setFont(adjustedToPixelSize(font(), 10)); setAutoFillBackground(true); QColor bg_color = QApplication::palette().color(QPalette::Active, QPalette::Window).darker(132); @@ -70,8 +70,6 @@ TabWidget::TabWidget(const QString& caption, QWidget* parent, bool usePixmap, void TabWidget::addTab(QWidget* w, const QString& name, const char* pixmap, int idx) { - setFont(pointSize(font(), 8)); - // Append tab when position is not given if (idx < 0/* || m_widgets.contains(idx) == true*/) { @@ -216,7 +214,7 @@ void TabWidget::resizeEvent(QResizeEvent*) void TabWidget::paintEvent(QPaintEvent* pe) { QPainter p(this); - p.setFont(pointSize(font(), 7)); + p.setFont(adjustedToPixelSize(font(), 10)); // Draw background QBrush bg_color = p.background(); @@ -232,7 +230,6 @@ void TabWidget::paintEvent(QPaintEvent* pe) // Draw title, if any if (!m_caption.isEmpty()) { - p.setFont(pointSize(p.font(), 8)); p.setPen(tabTitleText()); p.drawText(5, 11, m_caption); } From d447cb0648cff249f0f4c2311ea17217576354e4 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Fri, 5 Apr 2024 11:25:39 +0200 Subject: [PATCH 30/31] Use layouts for the instrument sound shaping tab / Extract classes for Envelope and LFO graphs (#7193) Move the envelope and LFO graphs into their own classes. Besides the improved code organization this step had to be done to be able to use layouts in `EnvelopeAndLfoView`. The class previously had fixed layouts mixed with custom rendering in the paint event. Mouse events are now also handled in both new classes instead of in `EnvelopeAndLfoView`. ## Layouts in EnvelopeAndLfoView Use layouts to align the elements of the `EnvelopeAndLfoView`. This removes lots of hard-coded values. Add helper lambdas for the repeated creation of `Knob` and `PixmapButton` instances. The spacing that is explicitly introduced between the envelope and LFO should be removed once there is a more open layout. ## Layouts for InstrumentSoundShapingView Use layouts to align the elements of the `InstrumentSoundShapingView`. ## Info text improvements in LFO graph Draw the info text at around 20% of the LFO graph's height. This prepares the dialog to be scaled later. Write "1000 ms/LFO" instead of "ms/LFO: 1000" with a larger gap. ## Accessors for EnvelopeAndLfoParameters Make the enum `LfoShape` in `EnvelopeAndLfoParameters` public so that it can be used without friend declarations. Add accessor methods for the model of the LFO. ## Other improvements * Adjust include orders * Variable initialization in headers * Prevention of most vexing parses --- include/EnvelopeAndLfoParameters.h | 45 +- include/EnvelopeAndLfoView.h | 16 +- include/EnvelopeGraph.h | 66 +++ include/InstrumentSoundShapingView.h | 2 +- include/LfoGraph.h | 68 +++ src/gui/CMakeLists.txt | 2 + src/gui/instrument/EnvelopeAndLfoView.cpp | 451 +++++------------- src/gui/instrument/EnvelopeGraph.cpp | 157 ++++++ .../instrument/InstrumentSoundShapingView.cpp | 83 ++-- src/gui/instrument/LfoGraph.cpp | 168 +++++++ 10 files changed, 646 insertions(+), 412 deletions(-) create mode 100644 include/EnvelopeGraph.h create mode 100644 include/LfoGraph.h create mode 100644 src/gui/instrument/EnvelopeGraph.cpp create mode 100644 src/gui/instrument/LfoGraph.cpp diff --git a/include/EnvelopeAndLfoParameters.h b/include/EnvelopeAndLfoParameters.h index 2a8d3a685e6..50bfdf78709 100644 --- a/include/EnvelopeAndLfoParameters.h +++ b/include/EnvelopeAndLfoParameters.h @@ -71,7 +71,18 @@ class LMMS_EXPORT EnvelopeAndLfoParameters : public Model, public JournallingObj using LfoList = QList; LfoList m_lfos; - } ; + }; + + enum class LfoShape + { + SineWave, + TriangleWave, + SawWave, + SquareWave, + UserDefinedWave, + RandomWave, + Count + }; EnvelopeAndLfoParameters( float _value_for_zero_amount, Model * _parent ); @@ -114,6 +125,28 @@ class LMMS_EXPORT EnvelopeAndLfoParameters : public Model, public JournallingObj return m_rFrames; } + // Envelope + const FloatModel& getPredelayModel() const { return m_predelayModel; } + const FloatModel& getAttackModel() const { return m_attackModel; } + const FloatModel& getHoldModel() const { return m_holdModel; } + const FloatModel& getDecayModel() const { return m_decayModel; } + const FloatModel& getSustainModel() const { return m_sustainModel; } + const FloatModel& getReleaseModel() const { return m_releaseModel; } + const FloatModel& getAmountModel() const { return m_amountModel; } + FloatModel& getAmountModel() { return m_amountModel; } + + + // LFO + inline f_cnt_t getLfoPredelayFrames() const { return m_lfoPredelayFrames; } + inline f_cnt_t getLfoAttackFrames() const { return m_lfoAttackFrames; } + inline f_cnt_t getLfoOscillationFrames() const { return m_lfoOscillationFrames; } + + const FloatModel& getLfoAmountModel() const { return m_lfoAmountModel; } + FloatModel& getLfoAmountModel() { return m_lfoAmountModel; } + const TempoSyncKnobModel& getLfoSpeedModel() const { return m_lfoSpeedModel; } + const BoolModel& getX100Model() const { return m_x100Model; } + const IntModel& getLfoWaveModel() const { return m_lfoWaveModel; } + std::shared_ptr getLfoUserWave() const { return m_userWave; } public slots: void updateSampleVars(); @@ -170,16 +203,6 @@ public slots: bool m_bad_lfoShapeData; std::shared_ptr m_userWave = SampleBuffer::emptyBuffer(); - enum class LfoShape - { - SineWave, - TriangleWave, - SawWave, - SquareWave, - UserDefinedWave, - RandomWave, - Count - } ; constexpr static auto NumLfoShapes = static_cast(LfoShape::Count); sample_t lfoShapeSample( fpp_t _frame_offset ); diff --git a/include/EnvelopeAndLfoView.h b/include/EnvelopeAndLfoView.h index d545aaa0687..0063dc78815 100644 --- a/include/EnvelopeAndLfoView.h +++ b/include/EnvelopeAndLfoView.h @@ -29,10 +29,6 @@ #include #include "ModelView.h" -#include "embed.h" - -class QPaintEvent; -class QPixmap; namespace lmms { @@ -47,6 +43,8 @@ class Knob; class LedCheckBox; class PixmapButton; class TempoSyncKnob; +class EnvelopeGraph; +class LfoGraph; @@ -63,8 +61,6 @@ class EnvelopeAndLfoView : public QWidget, public ModelView void dragEnterEvent( QDragEnterEvent * _dee ) override; void dropEvent( QDropEvent * _de ) override; - void mousePressEvent( QMouseEvent * _me ) override; - void paintEvent( QPaintEvent * _pe ) override; protected slots: @@ -72,13 +68,10 @@ protected slots: private: - QPixmap m_envGraph = embed::getIconPixmap("envelope_graph"); - QPixmap m_lfoGraph = embed::getIconPixmap("lfo_graph"); - EnvelopeAndLfoParameters * m_params; - // envelope stuff + EnvelopeGraph* m_envelopeGraph; Knob * m_predelayKnob; Knob * m_attackKnob; Knob * m_holdKnob; @@ -88,6 +81,7 @@ protected slots: Knob * m_amountKnob; // LFO stuff + LfoGraph* m_lfoGraph; Knob * m_lfoPredelayKnob; Knob * m_lfoAttackKnob; TempoSyncKnob * m_lfoSpeedKnob; @@ -97,8 +91,6 @@ protected slots: LedCheckBox * m_x100Cb; LedCheckBox * m_controlEnvAmountCb; - - float m_randomGraph; } ; } // namespace gui diff --git a/include/EnvelopeGraph.h b/include/EnvelopeGraph.h new file mode 100644 index 00000000000..8cfeaf11f2d --- /dev/null +++ b/include/EnvelopeGraph.h @@ -0,0 +1,66 @@ +/* + * EnvelopeGraph.h - Displays envelope graphs + * + * Copyright (c) 2004-2009 Tobias Doerffel + * Copyright (c) 2024- Michael Gregorius + * + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#ifndef LMMS_GUI_ENVELOPE_GRAPH_H +#define LMMS_GUI_ENVELOPE_GRAPH_H + +#include + +#include "ModelView.h" +#include "embed.h" + +namespace lmms +{ + +class EnvelopeAndLfoParameters; + +namespace gui +{ + +class EnvelopeGraph : public QWidget, public ModelView +{ +public: + EnvelopeGraph(QWidget* parent); + +protected: + void modelChanged() override; + + void mousePressEvent(QMouseEvent* me) override; + void paintEvent(QPaintEvent* pe) override; + +private: + void toggleAmountModel(); + +private: + QPixmap m_envGraph = embed::getIconPixmap("envelope_graph"); + + EnvelopeAndLfoParameters* m_params; +}; + +} // namespace gui + +} // namespace lmms + +#endif // LMMS_GUI_ENVELOPE_GRAPH_H diff --git a/include/InstrumentSoundShapingView.h b/include/InstrumentSoundShapingView.h index 8f671514a89..c9caea28c37 100644 --- a/include/InstrumentSoundShapingView.h +++ b/include/InstrumentSoundShapingView.h @@ -56,7 +56,7 @@ class InstrumentSoundShapingView : public QWidget, public ModelView void modelChanged() override; - InstrumentSoundShaping * m_ss; + InstrumentSoundShaping * m_ss = nullptr; TabWidget * m_targetsTabWidget; EnvelopeAndLfoView * m_envLfoViews[InstrumentSoundShaping::NumTargets]; diff --git a/include/LfoGraph.h b/include/LfoGraph.h new file mode 100644 index 00000000000..733db3a349c --- /dev/null +++ b/include/LfoGraph.h @@ -0,0 +1,68 @@ +/* + * LfoGraph.h - Displays LFO graphs + * + * Copyright (c) 2004-2009 Tobias Doerffel + * Copyright (c) 2024- Michael Gregorius + * + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#ifndef LMMS_GUI_LFO_GRAPH_H +#define LMMS_GUI_LFO_GRAPH_H + +#include + +#include "ModelView.h" +#include "embed.h" + +namespace lmms +{ + +class EnvelopeAndLfoParameters; + +namespace gui +{ + +class LfoGraph : public QWidget, public ModelView +{ +public: + LfoGraph(QWidget* parent); + +protected: + void modelChanged() override; + + void mousePressEvent(QMouseEvent* me) override; + void paintEvent(QPaintEvent* pe) override; + +private: + void toggleAmountModel(); + +private: + QPixmap m_lfoGraph = embed::getIconPixmap("lfo_graph"); + + EnvelopeAndLfoParameters* m_params = nullptr; + + float m_randomGraph {0.}; +}; + +} // namespace gui + +} // namespace lmms + +#endif // LMMS_GUI_LFO_GRAPH_H diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index e2342b46548..791d6fbff1d 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -62,12 +62,14 @@ SET(LMMS_SRCS gui/editors/TrackContainerView.cpp gui/instrument/EnvelopeAndLfoView.cpp + gui/instrument/EnvelopeGraph.cpp gui/instrument/InstrumentFunctionViews.cpp gui/instrument/InstrumentMidiIOView.cpp gui/instrument/InstrumentTuningView.cpp gui/instrument/InstrumentSoundShapingView.cpp gui/instrument/InstrumentTrackWindow.cpp gui/instrument/InstrumentView.cpp + gui/instrument/LfoGraph.cpp gui/instrument/PianoView.cpp gui/menus/MidiPortMenu.cpp diff --git a/src/gui/instrument/EnvelopeAndLfoView.cpp b/src/gui/instrument/EnvelopeAndLfoView.cpp index 7f30f3ac197..c2e642b015e 100644 --- a/src/gui/instrument/EnvelopeAndLfoView.cpp +++ b/src/gui/instrument/EnvelopeAndLfoView.cpp @@ -23,202 +23,170 @@ * */ -#include -#include - #include "EnvelopeAndLfoView.h" + +#include "EnvelopeGraph.h" +#include "LfoGraph.h" #include "EnvelopeAndLfoParameters.h" #include "SampleLoader.h" -#include "embed.h" -#include "Engine.h" #include "gui_templates.h" #include "Knob.h" #include "LedCheckBox.h" -#include "AudioEngine.h" #include "DataFile.h" -#include "Oscillator.h" #include "PixmapButton.h" #include "StringPairDrag.h" #include "TempoSyncKnob.h" #include "TextFloat.h" #include "Track.h" -namespace lmms -{ +#include -extern const float SECS_PER_ENV_SEGMENT; -extern const float SECS_PER_LFO_OSCILLATION; +namespace lmms +{ namespace gui { - -const int ENV_GRAPH_X = 6; -const int ENV_GRAPH_Y = 6; - -const int ENV_KNOBS_Y = 43; -const int ENV_KNOBS_LBL_Y = ENV_KNOBS_Y+35; -const int KNOB_X_SPACING = 32; -const int PREDELAY_KNOB_X = 6; -const int ATTACK_KNOB_X = PREDELAY_KNOB_X+KNOB_X_SPACING; -const int HOLD_KNOB_X = ATTACK_KNOB_X+KNOB_X_SPACING; -const int DECAY_KNOB_X = HOLD_KNOB_X+KNOB_X_SPACING; -const int SUSTAIN_KNOB_X = DECAY_KNOB_X+KNOB_X_SPACING; -const int RELEASE_KNOB_X = SUSTAIN_KNOB_X+KNOB_X_SPACING; -const int AMOUNT_KNOB_X = RELEASE_KNOB_X+KNOB_X_SPACING; - -const int TIME_UNIT_WIDTH = 40; - -const int LFO_GRAPH_X = 6; -const int LFO_GRAPH_Y = ENV_KNOBS_LBL_Y+14; -const int LFO_KNOB_Y = LFO_GRAPH_Y-2; -const int LFO_PREDELAY_KNOB_X = LFO_GRAPH_X + 100; -const int LFO_ATTACK_KNOB_X = LFO_PREDELAY_KNOB_X+KNOB_X_SPACING; -const int LFO_SPEED_KNOB_X = LFO_ATTACK_KNOB_X+KNOB_X_SPACING; -const int LFO_AMOUNT_KNOB_X = LFO_SPEED_KNOB_X+KNOB_X_SPACING; -const int LFO_SHAPES_X = LFO_GRAPH_X;//PREDELAY_KNOB_X; -const int LFO_SHAPES_Y = LFO_GRAPH_Y + 50; - -EnvelopeAndLfoView::EnvelopeAndLfoView( QWidget * _parent ) : - QWidget( _parent ), - ModelView( nullptr, this ), - m_params( nullptr ) +EnvelopeAndLfoView::EnvelopeAndLfoView(QWidget * parent) : + QWidget(parent), + ModelView(nullptr, this), + m_params(nullptr) { + // Helper lambdas for consistent repeated buiding of certain widgets + auto buildKnob = [&](const QString& label, const QString& hintText) + { + auto knob = new Knob(KnobType::Bright26, this); + knob->setLabel(label); + knob->setHintText(hintText, ""); + + return knob; + }; + + auto buildPixmapButton = [&](const QString& activePixmap, const QString& inactivePixmap) + { + auto button = new PixmapButton(this, nullptr); + button->setActiveGraphic(embed::getIconPixmap(activePixmap)); + button->setInactiveGraphic(embed::getIconPixmap(inactivePixmap)); - m_predelayKnob = new Knob( KnobType::Bright26, this ); - m_predelayKnob->setLabel( tr( "DEL" ) ); - m_predelayKnob->move( PREDELAY_KNOB_X, ENV_KNOBS_Y ); - m_predelayKnob->setHintText( tr( "Pre-delay:" ), "" ); - + return button; + }; - m_attackKnob = new Knob( KnobType::Bright26, this ); - m_attackKnob->setLabel( tr( "ATT" ) ); - m_attackKnob->move( ATTACK_KNOB_X, ENV_KNOBS_Y ); - m_attackKnob->setHintText( tr( "Attack:" ), "" ); + QVBoxLayout* mainLayout = new QVBoxLayout(this); + mainLayout->setContentsMargins(5, 5, 5, 5); + // Envelope - m_holdKnob = new Knob( KnobType::Bright26, this ); - m_holdKnob->setLabel( tr( "HOLD" ) ); - m_holdKnob->move( HOLD_KNOB_X, ENV_KNOBS_Y ); - m_holdKnob->setHintText( tr( "Hold:" ), "" ); + QVBoxLayout* envelopeLayout = new QVBoxLayout(); + mainLayout->addLayout(envelopeLayout); + QHBoxLayout* graphAndAmountLayout = new QHBoxLayout(); + envelopeLayout->addLayout(graphAndAmountLayout); - m_decayKnob = new Knob( KnobType::Bright26, this ); - m_decayKnob->setLabel( tr( "DEC" ) ); - m_decayKnob->move( DECAY_KNOB_X, ENV_KNOBS_Y ); - m_decayKnob->setHintText( tr( "Decay:" ), "" ); + m_envelopeGraph = new EnvelopeGraph(this); + graphAndAmountLayout->addWidget(m_envelopeGraph); + m_amountKnob = buildKnob(tr("AMT"), tr("Modulation amount:")); + graphAndAmountLayout->addWidget(m_amountKnob, 0, Qt::AlignCenter); - m_sustainKnob = new Knob( KnobType::Bright26, this ); - m_sustainKnob->setLabel( tr( "SUST" ) ); - m_sustainKnob->move( SUSTAIN_KNOB_X, ENV_KNOBS_Y ); - m_sustainKnob->setHintText( tr( "Sustain:" ), "" ); + QHBoxLayout* envKnobsLayout = new QHBoxLayout(); + envelopeLayout->addLayout(envKnobsLayout); + m_predelayKnob = buildKnob(tr("DEL"), tr("Pre-delay:")); + envKnobsLayout->addWidget(m_predelayKnob); - m_releaseKnob = new Knob( KnobType::Bright26, this ); - m_releaseKnob->setLabel( tr( "REL" ) ); - m_releaseKnob->move( RELEASE_KNOB_X, ENV_KNOBS_Y ); - m_releaseKnob->setHintText( tr( "Release:" ), "" ); + m_attackKnob = buildKnob(tr("ATT"), tr("Attack:")); + envKnobsLayout->addWidget(m_attackKnob); + m_holdKnob = buildKnob(tr("HOLD"), tr("Hold:")); + envKnobsLayout->addWidget(m_holdKnob); - m_amountKnob = new Knob( KnobType::Bright26, this ); - m_amountKnob->setLabel( tr( "AMT" ) ); - m_amountKnob->move( AMOUNT_KNOB_X, ENV_GRAPH_Y ); - m_amountKnob->setHintText( tr( "Modulation amount:" ), "" ); + m_decayKnob = buildKnob(tr("DEC"), tr("Decay:")); + envKnobsLayout->addWidget(m_decayKnob); + m_sustainKnob = buildKnob(tr("SUST"), tr("Sustain:")); + envKnobsLayout->addWidget(m_sustainKnob); + m_releaseKnob = buildKnob(tr("REL"), tr("Release:")); + envKnobsLayout->addWidget(m_releaseKnob); - m_lfoPredelayKnob = new Knob( KnobType::Bright26, this ); - m_lfoPredelayKnob->setLabel( tr( "DEL" ) ); - m_lfoPredelayKnob->move( LFO_PREDELAY_KNOB_X, LFO_KNOB_Y ); - m_lfoPredelayKnob->setHintText( tr( "Pre-delay:" ), "" ); + // Add some space between the envelope and LFO section + mainLayout->addSpacing(10); - m_lfoAttackKnob = new Knob( KnobType::Bright26, this ); - m_lfoAttackKnob->setLabel( tr( "ATT" ) ); - m_lfoAttackKnob->move( LFO_ATTACK_KNOB_X, LFO_KNOB_Y ); - m_lfoAttackKnob->setHintText( tr( "Attack:" ), "" ); + // LFO + QHBoxLayout* lfoLayout = new QHBoxLayout(); + mainLayout->addLayout(lfoLayout); - m_lfoSpeedKnob = new TempoSyncKnob( KnobType::Bright26, this ); - m_lfoSpeedKnob->setLabel( tr( "SPD" ) ); - m_lfoSpeedKnob->move( LFO_SPEED_KNOB_X, LFO_KNOB_Y ); - m_lfoSpeedKnob->setHintText( tr( "Frequency:" ), "" ); + QVBoxLayout* graphAndTypesLayout = new QVBoxLayout(); + lfoLayout->addLayout(graphAndTypesLayout); + m_lfoGraph = new LfoGraph(this); + graphAndTypesLayout->addWidget(m_lfoGraph); - m_lfoAmountKnob = new Knob( KnobType::Bright26, this ); - m_lfoAmountKnob->setLabel( tr( "AMT" ) ); - m_lfoAmountKnob->move( LFO_AMOUNT_KNOB_X, LFO_KNOB_Y ); - m_lfoAmountKnob->setHintText( tr( "Modulation amount:" ), "" ); + QHBoxLayout* typesLayout = new QHBoxLayout(); + graphAndTypesLayout->addLayout(typesLayout); + typesLayout->setContentsMargins(0, 0, 0, 0); + typesLayout->setSpacing(0); - auto sin_lfo_btn = new PixmapButton(this, nullptr); - sin_lfo_btn->move( LFO_SHAPES_X, LFO_SHAPES_Y ); - sin_lfo_btn->setActiveGraphic( embed::getIconPixmap( - "sin_wave_active" ) ); - sin_lfo_btn->setInactiveGraphic( embed::getIconPixmap( - "sin_wave_inactive" ) ); + auto sin_lfo_btn = buildPixmapButton("sin_wave_active", "sin_wave_inactive"); + auto triangle_lfo_btn = buildPixmapButton("triangle_wave_active", "triangle_wave_inactive"); + auto saw_lfo_btn = buildPixmapButton("saw_wave_active", "saw_wave_inactive"); + auto sqr_lfo_btn = buildPixmapButton("square_wave_active","square_wave_inactive"); + auto random_lfo_btn = buildPixmapButton("random_wave_active", "random_wave_inactive"); + m_userLfoBtn = buildPixmapButton("usr_wave_active", "usr_wave_inactive"); - auto triangle_lfo_btn = new PixmapButton(this, nullptr); - triangle_lfo_btn->move( LFO_SHAPES_X+15, LFO_SHAPES_Y ); - triangle_lfo_btn->setActiveGraphic( embed::getIconPixmap( - "triangle_wave_active" ) ); - triangle_lfo_btn->setInactiveGraphic( embed::getIconPixmap( - "triangle_wave_inactive" ) ); + connect(m_userLfoBtn, SIGNAL(toggled(bool)), this, SLOT(lfoUserWaveChanged())); - auto saw_lfo_btn = new PixmapButton(this, nullptr); - saw_lfo_btn->move( LFO_SHAPES_X+30, LFO_SHAPES_Y ); - saw_lfo_btn->setActiveGraphic( embed::getIconPixmap( - "saw_wave_active" ) ); - saw_lfo_btn->setInactiveGraphic( embed::getIconPixmap( - "saw_wave_inactive" ) ); + typesLayout->addWidget(sin_lfo_btn); + typesLayout->addWidget(triangle_lfo_btn); + typesLayout->addWidget(saw_lfo_btn); + typesLayout->addWidget(sqr_lfo_btn); + typesLayout->addWidget(random_lfo_btn); + typesLayout->addWidget(m_userLfoBtn); - auto sqr_lfo_btn = new PixmapButton(this, nullptr); - sqr_lfo_btn->move( LFO_SHAPES_X+45, LFO_SHAPES_Y ); - sqr_lfo_btn->setActiveGraphic( embed::getIconPixmap( - "square_wave_active" ) ); - sqr_lfo_btn->setInactiveGraphic( embed::getIconPixmap( - "square_wave_inactive" ) ); + m_lfoWaveBtnGrp = new automatableButtonGroup(this); + m_lfoWaveBtnGrp->addButton(sin_lfo_btn); + m_lfoWaveBtnGrp->addButton(triangle_lfo_btn); + m_lfoWaveBtnGrp->addButton(saw_lfo_btn); + m_lfoWaveBtnGrp->addButton(sqr_lfo_btn); + m_lfoWaveBtnGrp->addButton(m_userLfoBtn); + m_lfoWaveBtnGrp->addButton(random_lfo_btn); - m_userLfoBtn = new PixmapButton( this, nullptr ); - m_userLfoBtn->move( LFO_SHAPES_X+75, LFO_SHAPES_Y ); - m_userLfoBtn->setActiveGraphic( embed::getIconPixmap( - "usr_wave_active" ) ); - m_userLfoBtn->setInactiveGraphic( embed::getIconPixmap( - "usr_wave_inactive" ) ); + QVBoxLayout* knobsAndCheckBoxesLayout = new QVBoxLayout(); + lfoLayout->addLayout(knobsAndCheckBoxesLayout); - connect( m_userLfoBtn, SIGNAL(toggled(bool)), - this, SLOT(lfoUserWaveChanged())); + QHBoxLayout* lfoKnobsLayout = new QHBoxLayout(); + knobsAndCheckBoxesLayout->addLayout(lfoKnobsLayout); - auto random_lfo_btn = new PixmapButton(this, nullptr); - random_lfo_btn->move( LFO_SHAPES_X+60, LFO_SHAPES_Y ); - random_lfo_btn->setActiveGraphic( embed::getIconPixmap( - "random_wave_active" ) ); - random_lfo_btn->setInactiveGraphic( embed::getIconPixmap( - "random_wave_inactive" ) ); + m_lfoPredelayKnob = buildKnob(tr("DEL"), tr("Pre-delay:")); + lfoKnobsLayout->addWidget(m_lfoPredelayKnob); - m_lfoWaveBtnGrp = new automatableButtonGroup( this ); - m_lfoWaveBtnGrp->addButton( sin_lfo_btn ); - m_lfoWaveBtnGrp->addButton( triangle_lfo_btn ); - m_lfoWaveBtnGrp->addButton( saw_lfo_btn ); - m_lfoWaveBtnGrp->addButton( sqr_lfo_btn ); - m_lfoWaveBtnGrp->addButton( m_userLfoBtn ); - m_lfoWaveBtnGrp->addButton( random_lfo_btn ); + m_lfoAttackKnob = buildKnob(tr("ATT"), tr("Attack:")); + lfoKnobsLayout->addWidget(m_lfoAttackKnob); - m_x100Cb = new LedCheckBox( tr( "FREQ x 100" ), this ); - m_x100Cb->move( LFO_PREDELAY_KNOB_X, LFO_GRAPH_Y + 36 ); - m_x100Cb->setToolTip(tr("Multiply LFO frequency by 100")); + m_lfoSpeedKnob = new TempoSyncKnob(KnobType::Bright26, this); + m_lfoSpeedKnob->setLabel(tr("SPD")); + m_lfoSpeedKnob->setHintText(tr("Frequency:"), ""); + lfoKnobsLayout->addWidget(m_lfoSpeedKnob); + m_lfoAmountKnob = buildKnob(tr("AMT"), tr("Modulation amount:")); + lfoKnobsLayout->addWidget(m_lfoAmountKnob); - m_controlEnvAmountCb = new LedCheckBox(tr("MOD ENV AMOUNT"), this); - m_controlEnvAmountCb->move( LFO_PREDELAY_KNOB_X, LFO_GRAPH_Y + 54 ); - m_controlEnvAmountCb->setToolTip( - tr( "Control envelope amount by this LFO" ) ); + QVBoxLayout* checkBoxesLayout = new QVBoxLayout(); + knobsAndCheckBoxesLayout->addLayout(checkBoxesLayout); + m_x100Cb = new LedCheckBox(tr("FREQ x 100"), this); + m_x100Cb->setToolTip(tr("Multiply LFO frequency by 100")); + checkBoxesLayout->addWidget(m_x100Cb); - setAcceptDrops( true ); + m_controlEnvAmountCb = new LedCheckBox(tr("MOD ENV AMOUNT"), this); + m_controlEnvAmountCb->setToolTip(tr("Control envelope amount by this LFO")); + checkBoxesLayout->addWidget(m_controlEnvAmountCb); + setAcceptDrops(true); } @@ -235,6 +203,7 @@ EnvelopeAndLfoView::~EnvelopeAndLfoView() void EnvelopeAndLfoView::modelChanged() { m_params = castModel(); + m_envelopeGraph->setModel(m_params); m_predelayKnob->setModel( &m_params->m_predelayModel ); m_attackKnob->setModel( &m_params->m_attackModel ); m_holdKnob->setModel( &m_params->m_holdModel ); @@ -242,6 +211,8 @@ void EnvelopeAndLfoView::modelChanged() m_sustainKnob->setModel( &m_params->m_sustainModel ); m_releaseKnob->setModel( &m_params->m_releaseModel ); m_amountKnob->setModel( &m_params->m_amountModel ); + + m_lfoGraph->setModel(m_params); m_lfoPredelayKnob->setModel( &m_params->m_lfoPredelayModel ); m_lfoAttackKnob->setModel( &m_params->m_lfoAttackModel ); m_lfoSpeedKnob->setModel( &m_params->m_lfoSpeedModel ); @@ -254,40 +225,6 @@ void EnvelopeAndLfoView::modelChanged() -void EnvelopeAndLfoView::mousePressEvent( QMouseEvent * _me ) -{ - if( _me->button() != Qt::LeftButton ) - { - return; - } - - if (QRect(ENV_GRAPH_X, ENV_GRAPH_Y, m_envGraph.width(), m_envGraph.height()).contains(_me->pos())) - { - if( m_params->m_amountModel.value() < 1.0f ) - { - m_params->m_amountModel.setValue( 1.0f ); - } - else - { - m_params->m_amountModel.setValue( 0.0f ); - } - } - else if (QRect(LFO_GRAPH_X, LFO_GRAPH_Y, m_lfoGraph.width(), m_lfoGraph.height()).contains(_me->pos())) - { - if( m_params->m_lfoAmountModel.value() < 1.0f ) - { - m_params->m_lfoAmountModel.setValue( 1.0f ); - } - else - { - m_params->m_lfoAmountModel.setValue( 0.0f ); - } - } -} - - - - void EnvelopeAndLfoView::dragEnterEvent( QDragEnterEvent * _dee ) { StringPairDrag::processDragEnterEvent( _dee, @@ -327,167 +264,6 @@ void EnvelopeAndLfoView::dropEvent( QDropEvent * _de ) -void EnvelopeAndLfoView::paintEvent( QPaintEvent * ) -{ - QPainter p( this ); - p.setRenderHint( QPainter::Antialiasing ); - - // draw envelope-graph - p.drawPixmap(ENV_GRAPH_X, ENV_GRAPH_Y, m_envGraph); - // draw LFO-graph - p.drawPixmap(LFO_GRAPH_X, LFO_GRAPH_Y, m_lfoGraph); - - p.setFont(adjustedToPixelSize(p.font(), 8)); - - const float gray_amount = 1.0f - fabsf( m_amountKnob->value() ); - - p.setPen( QPen( QColor( static_cast( 96 * gray_amount ), - static_cast( 255 - 159 * gray_amount ), - static_cast( 128 - 32 * gray_amount ) ), - 2 ) ); - - const QColor end_points_color( 0x99, 0xAF, 0xFF ); - const QColor end_points_bg_color( 0, 0, 2 ); - - const int y_base = ENV_GRAPH_Y + m_envGraph.height() - 3; - const int avail_height = m_envGraph.height() - 6; - - int x1 = static_cast( m_predelayKnob->value() * TIME_UNIT_WIDTH ); - int x2 = x1 + static_cast( m_attackKnob->value() * TIME_UNIT_WIDTH ); - int x3 = x2 + static_cast( m_holdKnob->value() * TIME_UNIT_WIDTH ); - int x4 = x3 + static_cast( ( m_decayKnob->value() * - ( 1 - m_sustainKnob->value() ) ) * TIME_UNIT_WIDTH ); - int x5 = x4 + static_cast( m_releaseKnob->value() * TIME_UNIT_WIDTH ); - - if( x5 > 174 ) - { - x1 = ( x1 * 174 ) / x5; - x2 = ( x2 * 174 ) / x5; - x3 = ( x3 * 174 ) / x5; - x4 = ( x4 * 174 ) / x5; - x5 = ( x5 * 174 ) / x5; - } - x1 += ENV_GRAPH_X + 2; - x2 += ENV_GRAPH_X + 2; - x3 += ENV_GRAPH_X + 2; - x4 += ENV_GRAPH_X + 2; - x5 += ENV_GRAPH_X + 2; - - p.drawLine( x1, y_base, x2, y_base - avail_height ); - p.fillRect( x1 - 1, y_base - 2, 4, 4, end_points_bg_color ); - p.fillRect( x1, y_base - 1, 2, 2, end_points_color ); - - p.drawLine( x2, y_base - avail_height, x3, y_base - avail_height ); - p.fillRect( x2 - 1, y_base - 2 - avail_height, 4, 4, - end_points_bg_color ); - p.fillRect( x2, y_base - 1 - avail_height, 2, 2, end_points_color ); - - p.drawLine( x3, y_base-avail_height, x4, static_cast( y_base - - avail_height + - ( 1 - m_sustainKnob->value() ) * avail_height ) ); - p.fillRect( x3 - 1, y_base - 2 - avail_height, 4, 4, - end_points_bg_color ); - p.fillRect( x3, y_base - 1 - avail_height, 2, 2, end_points_color ); - - p.drawLine( x4, static_cast( y_base - avail_height + - ( 1 - m_sustainKnob->value() ) * - avail_height ), x5, y_base ); - p.fillRect( x4 - 1, static_cast( y_base - avail_height + - ( 1 - m_sustainKnob->value() ) * - avail_height ) - 2, 4, 4, - end_points_bg_color ); - p.fillRect( x4, static_cast( y_base - avail_height + - ( 1 - m_sustainKnob->value() ) * - avail_height ) - 1, 2, 2, - end_points_color ); - p.fillRect( x5 - 1, y_base - 2, 4, 4, end_points_bg_color ); - p.fillRect( x5, y_base - 1, 2, 2, end_points_color ); - - int LFO_GRAPH_W = m_lfoGraph.width() - 3; // subtract border - int LFO_GRAPH_H = m_lfoGraph.height() - 6; // subtract border - int graph_x_base = LFO_GRAPH_X + 2; - int graph_y_base = LFO_GRAPH_Y + 3 + LFO_GRAPH_H / 2; - - const float frames_for_graph = SECS_PER_LFO_OSCILLATION * - Engine::audioEngine()->baseSampleRate() / 10; - - const float lfo_gray_amount = 1.0f - fabsf( m_lfoAmountKnob->value() ); - p.setPen( QPen( QColor( static_cast( 96 * lfo_gray_amount ), - static_cast( 255 - 159 * lfo_gray_amount ), - static_cast( 128 - 32 * - lfo_gray_amount ) ), - 1.5 ) ); - - - float osc_frames = m_params->m_lfoOscillationFrames; - - if( m_params->m_x100Model.value() ) - { - osc_frames *= 100.0f; - } - - float old_y = 0; - for( int x = 0; x <= LFO_GRAPH_W; ++x ) - { - float val = 0.0; - float cur_sample = x * frames_for_graph / LFO_GRAPH_W; - if( static_cast( cur_sample ) > - m_params->m_lfoPredelayFrames ) - { - float phase = ( cur_sample -= - m_params->m_lfoPredelayFrames ) / - osc_frames; - switch( static_cast(m_params->m_lfoWaveModel.value()) ) - { - case EnvelopeAndLfoParameters::LfoShape::SineWave: - default: - val = Oscillator::sinSample( phase ); - break; - case EnvelopeAndLfoParameters::LfoShape::TriangleWave: - val = Oscillator::triangleSample( - phase ); - break; - case EnvelopeAndLfoParameters::LfoShape::SawWave: - val = Oscillator::sawSample( phase ); - break; - case EnvelopeAndLfoParameters::LfoShape::SquareWave: - val = Oscillator::squareSample( phase ); - break; - case EnvelopeAndLfoParameters::LfoShape::RandomWave: - if( x % (int)( 900 * m_lfoSpeedKnob->value() + 1 ) == 0 ) - { - m_randomGraph = Oscillator::noiseSample( 0.0f ); - } - val = m_randomGraph; - break; - case EnvelopeAndLfoParameters::LfoShape::UserDefinedWave: - val = Oscillator::userWaveSample(m_params->m_userWave.get(), phase); - break; - } - if( static_cast( cur_sample ) <= - m_params->m_lfoAttackFrames ) - { - val *= cur_sample / m_params->m_lfoAttackFrames; - } - } - float cur_y = -LFO_GRAPH_H / 2.0f * val; - p.drawLine( QLineF( graph_x_base + x - 1, graph_y_base + old_y, - graph_x_base + x, - graph_y_base + cur_y ) ); - old_y = cur_y; - } - - p.setPen( QColor( 201, 201, 225 ) ); - int ms_per_osc = static_cast( SECS_PER_LFO_OSCILLATION * - m_lfoSpeedKnob->value() * - 1000.0f ); - p.drawText(LFO_GRAPH_X + 4, LFO_GRAPH_Y + m_lfoGraph.height() - 6, tr("ms/LFO:")); - p.drawText(LFO_GRAPH_X + 52, LFO_GRAPH_Y + m_lfoGraph.height() - 6, QString::number(ms_per_osc)); -} - - - - void EnvelopeAndLfoView::lfoUserWaveChanged() { if( static_cast(m_params->m_lfoWaveModel.value()) == @@ -502,11 +278,6 @@ void EnvelopeAndLfoView::lfoUserWaveChanged() } } - - - - - } // namespace gui } // namespace lmms diff --git a/src/gui/instrument/EnvelopeGraph.cpp b/src/gui/instrument/EnvelopeGraph.cpp new file mode 100644 index 00000000000..4d866b3ccd1 --- /dev/null +++ b/src/gui/instrument/EnvelopeGraph.cpp @@ -0,0 +1,157 @@ +/* + * EnvelopeGraph.cpp - Displays envelope graphs + * + * Copyright (c) 2004-2014 Tobias Doerffel + * Copyright (c) 2024- Michael Gregorius + * + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#include +#include + +#include "EnvelopeGraph.h" + +#include "EnvelopeAndLfoParameters.h" + +namespace lmms +{ + +namespace gui +{ + +const int TIME_UNIT_WIDTH = 40; + + +EnvelopeGraph::EnvelopeGraph(QWidget* parent) : + QWidget(parent), + ModelView(nullptr, this), + m_params(nullptr) +{ + setFixedSize(m_envGraph.size()); +} + +void EnvelopeGraph::modelChanged() +{ + m_params = castModel(); +} + +void EnvelopeGraph::mousePressEvent(QMouseEvent* me) +{ + if(me->button() == Qt::LeftButton) + { + toggleAmountModel(); + } +} + +void EnvelopeGraph::paintEvent(QPaintEvent*) +{ + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing); + + // Draw the graph background + p.drawPixmap(rect(), m_envGraph); + + const auto * params = castModel(); + if (!params) + { + return; + } + + const float amount = params->getAmountModel().value(); + const float predelay = params->getPredelayModel().value(); + const float attack = params->getAttackModel().value(); + const float hold = params->getHoldModel().value(); + const float decay = params->getDecayModel().value(); + const float sustain = params->getSustainModel().value(); + const float release = params->getReleaseModel().value(); + + const float gray_amount = 1.0f - fabsf(amount); + + p.setPen(QPen(QColor(static_cast(96 * gray_amount), + static_cast(255 - 159 * gray_amount), + static_cast(128 - 32 * gray_amount)), + 2)); + + const QColor end_points_color(0x99, 0xAF, 0xFF); + const QColor end_points_bg_color(0, 0, 2); + + const int y_base = m_envGraph.height() - 3; + const int avail_height = m_envGraph.height() - 6; + + int x1 = static_cast(predelay * TIME_UNIT_WIDTH); + int x2 = x1 + static_cast(attack * TIME_UNIT_WIDTH); + int x3 = x2 + static_cast(hold * TIME_UNIT_WIDTH); + int x4 = x3 + static_cast((decay * (1 - sustain)) * TIME_UNIT_WIDTH); + int x5 = x4 + static_cast(release * TIME_UNIT_WIDTH); + + if (x5 > 174) + { + x1 = (x1 * 174) / x5; + x2 = (x2 * 174) / x5; + x3 = (x3 * 174) / x5; + x4 = (x4 * 174) / x5; + x5 = (x5 * 174) / x5; + } + x1 += 2; + x2 += 2; + x3 += 2; + x4 += 2; + x5 += 2; + + p.drawLine(x1, y_base, x2, y_base - avail_height); + p.fillRect(x1 - 1, y_base - 2, 4, 4, end_points_bg_color); + p.fillRect(x1, y_base - 1, 2, 2, end_points_color); + + p.drawLine(x2, y_base - avail_height, x3, y_base - avail_height); + p.fillRect(x2 - 1, y_base - 2 - avail_height, 4, 4, + end_points_bg_color); + p.fillRect(x2, y_base - 1 - avail_height, 2, 2, end_points_color); + + const int sustainHeight = static_cast(y_base - avail_height + (1 - sustain) * avail_height); + + p.drawLine(x3, y_base-avail_height, x4, sustainHeight); + p.fillRect(x3 - 1, y_base - 2 - avail_height, 4, 4, end_points_bg_color); + p.fillRect(x3, y_base - 1 - avail_height, 2, 2, end_points_color); + + p.drawLine(x4, sustainHeight, x5, y_base); + p.fillRect(x4 - 1, sustainHeight - 2, 4, 4, end_points_bg_color); + p.fillRect(x4, sustainHeight - 1, 2, 2, end_points_color); + p.fillRect(x5 - 1, y_base - 2, 4, 4, end_points_bg_color); + p.fillRect(x5, y_base - 1, 2, 2, end_points_color); +} + +void EnvelopeGraph::toggleAmountModel() +{ + auto* params = castModel(); + auto& amountModel = params->getAmountModel(); + + if (amountModel.value() < 1.0f ) + { + amountModel.setValue( 1.0f ); + } + else + { + amountModel.setValue( 0.0f ); + } +} + +} // namespace gui + +} // namespace lmms diff --git a/src/gui/instrument/InstrumentSoundShapingView.cpp b/src/gui/instrument/InstrumentSoundShapingView.cpp index b96db8495a9..a3a78e25670 100644 --- a/src/gui/instrument/InstrumentSoundShapingView.cpp +++ b/src/gui/instrument/InstrumentSoundShapingView.cpp @@ -22,9 +22,11 @@ * */ +#include "InstrumentSoundShapingView.h" + #include +#include -#include "InstrumentSoundShapingView.h" #include "EnvelopeAndLfoParameters.h" #include "EnvelopeAndLfoView.h" #include "ComboBox.h" @@ -37,69 +39,54 @@ namespace lmms::gui { -const int TARGETS_TABWIDGET_X = 4; -const int TARGETS_TABWIDGET_Y = 5; -const int TARGETS_TABWIDGET_WIDTH = 242; -const int TARGETS_TABWIDGET_HEIGTH = 175; - -const int FILTER_GROUPBOX_X = TARGETS_TABWIDGET_X; -const int FILTER_GROUPBOX_Y = TARGETS_TABWIDGET_Y+TARGETS_TABWIDGET_HEIGTH+5; -const int FILTER_GROUPBOX_WIDTH = TARGETS_TABWIDGET_WIDTH; -const int FILTER_GROUPBOX_HEIGHT = 245-FILTER_GROUPBOX_Y; - - - -InstrumentSoundShapingView::InstrumentSoundShapingView( QWidget * _parent ) : - QWidget( _parent ), - ModelView( nullptr, this ), - m_ss( nullptr ) +InstrumentSoundShapingView::InstrumentSoundShapingView(QWidget* parent) : + QWidget(parent), + ModelView(nullptr, this) { - m_targetsTabWidget = new TabWidget( tr( "TARGET" ), this ); - m_targetsTabWidget->setGeometry( TARGETS_TABWIDGET_X, - TARGETS_TABWIDGET_Y, - TARGETS_TABWIDGET_WIDTH, - TARGETS_TABWIDGET_HEIGTH ); + QVBoxLayout* mainLayout = new QVBoxLayout(this); + mainLayout->setContentsMargins(5, 5, 5, 5); - for( int i = 0; i < InstrumentSoundShaping::NumTargets; ++i ) + m_targetsTabWidget = new TabWidget(tr("TARGET"), this); + + for (int i = 0; i < InstrumentSoundShaping::NumTargets; ++i) { - m_envLfoViews[i] = new EnvelopeAndLfoView( m_targetsTabWidget ); - m_targetsTabWidget->addTab( m_envLfoViews[i], - tr( InstrumentSoundShaping::targetNames[i][0] ), - nullptr ); + m_envLfoViews[i] = new EnvelopeAndLfoView(m_targetsTabWidget); + m_targetsTabWidget->addTab(m_envLfoViews[i], + tr(InstrumentSoundShaping::targetNames[i][0]), nullptr); } - - m_filterGroupBox = new GroupBox( tr( "FILTER" ), this ); - m_filterGroupBox->setGeometry( FILTER_GROUPBOX_X, FILTER_GROUPBOX_Y, - FILTER_GROUPBOX_WIDTH, - FILTER_GROUPBOX_HEIGHT ); + mainLayout->addWidget(m_targetsTabWidget, 1); - m_filterComboBox = new ComboBox( m_filterGroupBox ); - m_filterComboBox->setGeometry( 14, 22, 120, ComboBox::DEFAULT_HEIGHT ); + m_filterGroupBox = new GroupBox(tr("FILTER"), this); + QHBoxLayout* filterLayout = new QHBoxLayout(m_filterGroupBox); + QMargins filterMargins = filterLayout->contentsMargins(); + filterMargins.setTop(18); + filterLayout->setContentsMargins(filterMargins); + m_filterComboBox = new ComboBox(m_filterGroupBox); + filterLayout->addWidget(m_filterComboBox); - m_filterCutKnob = new Knob( KnobType::Bright26, m_filterGroupBox ); - m_filterCutKnob->setLabel( tr( "FREQ" ) ); - m_filterCutKnob->move( 140, 18 ); - m_filterCutKnob->setHintText( tr( "Cutoff frequency:" ), " " + tr( "Hz" ) ); + m_filterCutKnob = new Knob(KnobType::Bright26, m_filterGroupBox); + m_filterCutKnob->setLabel(tr("FREQ")); + m_filterCutKnob->setHintText(tr("Cutoff frequency:"), " " + tr("Hz")); + filterLayout->addWidget(m_filterCutKnob); + m_filterResKnob = new Knob(KnobType::Bright26, m_filterGroupBox); + m_filterResKnob->setLabel(tr("Q/RESO")); + m_filterResKnob->setHintText(tr("Q/Resonance:"), ""); + filterLayout->addWidget(m_filterResKnob); - m_filterResKnob = new Knob( KnobType::Bright26, m_filterGroupBox ); - m_filterResKnob->setLabel( tr( "Q/RESO" ) ); - m_filterResKnob->move( 196, 18 ); - m_filterResKnob->setHintText( tr( "Q/Resonance:" ), "" ); + mainLayout->addWidget(m_filterGroupBox); - m_singleStreamInfoLabel = new QLabel( tr( "Envelopes, LFOs and filters are not supported by the current instrument." ), this ); - m_singleStreamInfoLabel->setWordWrap( true ); + m_singleStreamInfoLabel = new QLabel(tr("Envelopes, LFOs and filters are not supported by the current instrument."), this); + m_singleStreamInfoLabel->setWordWrap(true); // TODO Could also be rendered in system font size... m_singleStreamInfoLabel->setFont(adjustedToPixelSize(m_singleStreamInfoLabel->font(), 10)); + m_singleStreamInfoLabel->setFixedWidth(242); - m_singleStreamInfoLabel->setGeometry( TARGETS_TABWIDGET_X, - TARGETS_TABWIDGET_Y, - TARGETS_TABWIDGET_WIDTH, - TARGETS_TABWIDGET_HEIGTH ); + mainLayout->addWidget(m_singleStreamInfoLabel, 0, Qt::AlignTop); } diff --git a/src/gui/instrument/LfoGraph.cpp b/src/gui/instrument/LfoGraph.cpp new file mode 100644 index 00000000000..d02f583d0c7 --- /dev/null +++ b/src/gui/instrument/LfoGraph.cpp @@ -0,0 +1,168 @@ +/* + * LfoGraph.cpp - Displays LFO graphs + * + * Copyright (c) 2004-2014 Tobias Doerffel + * Copyright (c) 2024- Michael Gregorius + * + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#include "LfoGraph.h" + +#include +#include + +#include "EnvelopeAndLfoParameters.h" +#include "Oscillator.h" + +#include "gui_templates.h" + +namespace lmms +{ + +extern const float SECS_PER_LFO_OSCILLATION; + +namespace gui +{ + +LfoGraph::LfoGraph(QWidget* parent) : + QWidget(parent), + ModelView(nullptr, this) +{ + setFixedSize(m_lfoGraph.size()); +} + +void LfoGraph::modelChanged() +{ + m_params = castModel(); +} + +void LfoGraph::mousePressEvent(QMouseEvent* me) +{ + if (me->button() == Qt::LeftButton) + { + toggleAmountModel(); + } +} + +void LfoGraph::paintEvent(QPaintEvent*) +{ + QPainter p{this}; + p.setRenderHint(QPainter::Antialiasing); + + // Draw the graph background + p.drawPixmap(rect(), m_lfoGraph); + + const auto* params = castModel(); + if (!params) { return; } + + const float amount = params->getLfoAmountModel().value(); + const float lfoSpeed = params->getLfoSpeedModel().value(); + const f_cnt_t predelayFrames = params->getLfoPredelayFrames(); + const f_cnt_t attackFrames = params->getLfoAttackFrames(); + const f_cnt_t oscillationFrames = params->getLfoOscillationFrames(); + const bool x100 = params->getX100Model().value(); + const int waveModel = params->getLfoWaveModel().value(); + + int LFO_GRAPH_W = m_lfoGraph.width() - 3; // subtract border + int LFO_GRAPH_H = m_lfoGraph.height() - 6; // subtract border + int graph_x_base = 2; + int graph_y_base = 3 + LFO_GRAPH_H / 2; + + const float frames_for_graph = + SECS_PER_LFO_OSCILLATION * Engine::audioEngine()->baseSampleRate() / 10; + + const float gray = 1.0 - fabsf(amount); + const auto red = static_cast(96 * gray); + const auto green = static_cast(255 - 159 * gray); + const auto blue = static_cast(128 - 32 * gray); + const QColor penColor(red, green, blue); + p.setPen(QPen(penColor, 1.5)); + + float osc_frames = oscillationFrames; + + if (x100) { osc_frames *= 100.0f; } + + float old_y = 0; + for (int x = 0; x <= LFO_GRAPH_W; ++x) + { + float val = 0.0; + float cur_sample = x * frames_for_graph / LFO_GRAPH_W; + if (static_cast(cur_sample) > predelayFrames) + { + float phase = (cur_sample -= predelayFrames) / osc_frames; + switch (static_cast(waveModel)) + { + case EnvelopeAndLfoParameters::LfoShape::SineWave: + default: + val = Oscillator::sinSample(phase); + break; + case EnvelopeAndLfoParameters::LfoShape::TriangleWave: + val = Oscillator::triangleSample(phase); + break; + case EnvelopeAndLfoParameters::LfoShape::SawWave: + val = Oscillator::sawSample(phase); + break; + case EnvelopeAndLfoParameters::LfoShape::SquareWave: + val = Oscillator::squareSample(phase); + break; + case EnvelopeAndLfoParameters::LfoShape::RandomWave: + if (x % (int)(900 * lfoSpeed + 1) == 0) + { + m_randomGraph = Oscillator::noiseSample(0.0); + } + val = m_randomGraph; + break; + case EnvelopeAndLfoParameters::LfoShape::UserDefinedWave: + val = Oscillator::userWaveSample(m_params->getLfoUserWave().get(), phase); + break; + } + + if (static_cast(cur_sample) <= attackFrames) + { + val *= cur_sample / attackFrames; + } + } + + float cur_y = -LFO_GRAPH_H / 2.0f * val; + p.drawLine(QLineF(graph_x_base + x - 1, graph_y_base + old_y, graph_x_base + x, graph_y_base + cur_y)); + old_y = cur_y; + } + + // Draw the info text + int ms_per_osc = static_cast(SECS_PER_LFO_OSCILLATION * lfoSpeed * 1000.0); + + QFont f = p.font(); + f.setPixelSize(height() * 0.2); + p.setFont(f); + p.setPen(QColor(201, 201, 225)); + p.drawText(4, m_lfoGraph.height() - 6, tr("%1 ms/LFO").arg(ms_per_osc)); +} + +void LfoGraph::toggleAmountModel() +{ + auto* params = castModel(); + auto& lfoAmountModel = params->getLfoAmountModel(); + + lfoAmountModel.setValue(lfoAmountModel.value() < 1.0 ? 1.0 : 0.0); +} + +} // namespace gui + +} // namespace lmms From ba4fda7c977926fd51664b99aca5e991019339d9 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Fri, 5 Apr 2024 12:48:46 +0200 Subject: [PATCH 31/31] Scalable consistent faders with themeable gradients, marker at unity, dbFS by default (#7045) * Render fader levels in code with a gradient Render the fader level in code using a gradient instead of using pixmaps. The problem with the pixmaps is that they don't "know" how a fader instance is configured with regards to the minimum and maximum value. This means that the display can give quite a wrong impression. The rendering of levels has been unified in the method `paintLevels`. It can render using dbFS and linear scale. The method `paintLinearLevels` has been removed completely, i.e. there's no more code that renders using pixmaps. Much of the previous code relied on the size of the background image `fader_background.png`, e.g. the initialization of the size. For now the `Fader` widget is initially resized to the size of that background image as it is present in the default and classic theme (see `Fader::init`). All rendering uses the size of the widget itself to determine where to draw what. This means that the widget is prepared to be resizable. The method `paintLevels` first renders the background of the level indicators and uses these as clipping paths for all other rendering operations, e.g. for the rendering of the levels themselves. Levels are rendered using a gradient which is defined with the following stops: * Two stops for the ok levels. * One stop for warning levels. * One stop for clipping levels. Peak indicators do not use the three distinct colors anymore but instead use the color of the gradient at that position of the peak. This makes everything look "smooth". The code now also renders a marker at unity position, i.e. at position 1.0 in linear levels and 0 dbFS in dbFS scale. The painting code makes lots of use of the class `PaintHelper`. This class is configured with a minimum and maximum value and can then return linear factors for given values. There are two supported modes: * Map min to 0 and max to 1 * Map min to 1 and max to 0 It can also compute rectangles that correspond to a given value. These methods can be given rectangles that are supposed to represent the span from min to max. The returned result is then a rectangle that fills the lower part of the source rectangle according to the given value with regards to min and max (`getMeterRect`). Another method returns a rectangle of height 1 which lies inside the given source rectangle at the corresponding level (`getPersistentPeakRect`). The method `paintLevels` uses a mapping function to map the amplitude values (current peak value, persistent peak, etc.) to the display values. There's one mapper that keeps the original value and it is used to display everything in a linear scale. Another mapper maps everything to dbFS and uses these values as display everything in a dbFS scale. The following values must be mapped for the left and right channel to make this work: * Min and max display values (min and max peak values) * The current peak value * The persistent peak value * The value for unity, i.e. 1.0 in linear levels and 0 dbFS in dbFS scale. Remove the method `calculateDisplayPeak` which was used in the old method to render linear levels. `Fader::setPeak` now uses `std::clamp` instead of doing "manual" comparisons. The LMMS plugins Compressor, EQ and Delay are still configured to use linear displays. It should be considered to switch them to dbFS/logarithmic displays as well and to remove the code that renders linearly. * Remove unused pixmaps from `Fader` Remove the now unused pixmaps for the background and the LEDs from the `Fader` class and remove the files from the default and classic theme directories. * Rename peak properties and use them to render levels Rename the peak properties as follows: * peakGreen -> peakOk * peakRed -> peakClip * peakYellow -> peakWarn The reasoning is that a style might for example use a different color than green to indicate levels that are ok. Use the properties to initialize the gradient that is used to render the levels. Initialize the properties to the colors of the current default theme so that it's not mandatory to set them in a style sheet. Up until now they have all been initialized as black. * Always render the knob in the middle of the fader Render the knob in the middle of the fader regardless of the width. The previous implementation was dependent on the fader pixmap having a matching width because it always rendered at x=0. * Set size policy of fader to minimum expanding Set the size policy of the fader to minimum expanding in both directions. This will make the fader grow in layouts if there is space. * Default dbFS levels and better peak values Default to dbFS levels for all faders and set some better minimum and maximum peak values. * Fix faders of Crossover EQ Fix the faders of the Crossover EQ which were initialized and rendered much too wide and with a line at unity. The large width also resulted in the knobs being rendered outside of view. Resize the fader to the minimum size so that it is constructed at a sane default. Introduce a property that allows to control if the unity line is rendered. The property is available in style sheets and defaults to the unity lines being rendered. Adjust the paint code to evaluate the property. Initialize the faders of the Crossover EQ such that the unity line is not drawn. * Remove EqFader constructor with pixmaps Remove the constructor of `EqFader` that takes the pixmaps to the fader background, leds and knob. The background and leds pixmaps are not used by the base class `Fader` for rendering anymore to make the `Fader` resizable. A pixmap is still used to render the knob but the constructor that takes the knob as an argument does not do anything meaningful with it, i.e. all faders are rendered with the default knob anyway. Remove the resources for the fader background, leds and knob as they are not used and the knob was the same image as the default knob anyway. Remove the static pixmaps from the constructor of `EqControlsDialog`. Switch the instantiations of the EQ's faders to use the remaining constructor of `EqFader`. This constructor sets a different fixed size of (23, 116) compared to the removed constructor which set a size of (23, 80). Therefore all faders that used the removed constructor are now set explicitly to a fixed size of (23, 80). The constructor that's now used also calls a different base constructor than the removed one. The difference between the two base constructors of `Fader` is that one of them sets the member `m_conversionFactor` to 100.0 whereas the other one keeps the default of 1.0. The adjusted faders in `EqControlsDialog` are thus now constructed with the conversion factor set to 100. However, all of them already call `setDisplayConversion` with `false` after construction which results in the conversion factor being reset to 1.0. So the result should be the same as before the changes. * Remove background and LEDs pixmap from Fader constructor Remove the parameters for the background and LEDs pixmap from the second `Fader` constructor. Make the knob pixmap parameter in the constructor a const reference. Assign the reference to the knob pixmap of the `Fader` itself. This enables clients to use their own fader knobs as is the case with the Crossover EQ. The EQ now renders using it's own knobs again. Make the second constructor delegate to the first one. This will additionally set the conversion factor to 100 but this is not a problem with the current code because the only user of the second constructor, the Crossover EQ, already calls `setDisplayConversion` with the parameter set to `false`, hence reinstating a conversion factor of 1. Remove the resources for the background and LEDs from the Crossover EQ as they are not used anymore. Remove the three QPixmap members from `CrossoverEQControlDialog` as they are not needed. The background and LEDs are not used anyway and the knob is passed in as a constant reference which is copied. Hence we can use a local variable in the constructor of `CrossoverEQControlDialog`. * Remove the init method from Fader Remove the `init` method from `Fader` as it is not needed anymore due to the constructor delegation. Tidy up the parameter lists and use of spaces in the constructor. * Introduce range with solid warn color Introduce a second point in the gradient for the warn colors so that we get a certain range with the full/solid warn color. The colors are distributed as follows now. The solid ok range goes from -inf dbFS to -12 dbFS. The warn range goes from -6 dbFS to 0 dbFS. In between the colors are interpolated. Values above 0 dbFS interpolate from the warn color to the clip color. This is now quite similar to the previous implementation. # Analysis of the previous pixmap implementation The pixmap implementation used pixmaps with a height of 116 pixels to map 51 dbFS (-42 dbFS to 9 dbFS) across the whole height. The pixels of the LED pixmap were distributed as follows along the Y-axis: * Margin: 4 * Red: 18 * Yellow: 14 * Green: 76 * Margin: 4 Due to the margins the actual red, yellow and green areas only represent a range of (1 - (4+4) / 116) * 51 ~ 47,48 dbFS. This range is distributed as follows across the colors: Red: 7.91 dbFS Yellow: 6.16 dbFS Green: 33.41 dbFS The borders between the colors are located along the following dbFS values: * Red/yellow: 9 - (4 + 18) / 116 * 51 dbFS ~ -0.67 dbFS * Yellow/green: 9 - (4 + 18 + 14) / 116 * 51 dbFS ~ -6.83 dbFS * The green marker is rendered for values above -40.24 dbFS. * Remove unused method Fader::clips * Fader: Correctly render arbitrary ranges Adjust the `Fader` so that it can correctly render arbitrary ranges of min and max peak values, e.g. that it would render a display range of [-12 dbFS, -42 dbFS] correctly. Until now the gradient was defined to start at the top of the levels rectangle and end at the bottom. As a result the top was always rendered in the "clip" color and the bottom in the "ok" color. However, this is wrong, e.g. if we configure the `Fader` with a max value of -12 dbFS and a min value of -42 dbFS. In that case the whole range of the fader should be rendered with the "ok" color. The fix is to compute the correct window coordinates of the start and end point of gradient using from the "window" of values that the `Fader` displays and then to map the in-between colors accordingly. See the added comments in the code for more details. Add the templated helper class `LinearMap` to `lmms_math.h`. The class defines a linear function/map which is initialized using two points. With the `map` function it is then possible to evaluate arbitrary X-coordinates. * Remove unused methods in PaintHelper Remove the now unused mapping methods from `PaintHelper`. Their functionality has been replaced with the usage of `LinearMap` in the code. * Fix some builds Include `cassert` for some builds that otherwise fail. * Opaque unity marker with styling option Make the unity marker opaque by default and enable to style it with the style sheets. None of the two style sheets uses this option though. * Darker default color for the unity line * Move code Move the computation of most mapped values at the top right after the definition of the mapper so that it is readily available in all phases of the painting code. * Render unity lines in background Render the unity lines before rendering the levels so that they get overdrawn and do not stick out when they are crossed. * Don't draw transparent white lines anymore Don't draw the transparent white lines anymore as they were mostly clipped anyway and only create "smudge". * Full on clip color at unity Adjust the gradient so that the full on clip color shows starting at unity. There is only a very short transition from the end of warning to clipping making it look like a solid color "standing" on top of a gradient. * Fix discrepancy between levels and unity markers This commit removes the helper class `PaintHelper` and now uses two lambdas to compute the rectangles for the peak indicators and levels. It uses the linear map which maps the peak values (in dbFS or linear) to window coordinates of the widget. The change fixes a discrepancy in the following implementation for which the full on clip rectangle rendered slightly below the unity marker. * Fix fader display for Equalizer shelves and peaks The peak values for the shelves and peaks of the Equalizer plugin are computed in `EqEffect::peakBand`. The previous implementation evaluated the bins of the corresponding frequency spectrum and determined the "loudest" one. The value of this bin was then converted to dbFS and mapped to the interval [0, inf[ where all values less or equal to -60 dbFS were mapped to 0 and a value of 40 dbFS was mapped to 1. So effectively everything was mapped somewhere into [0, 1] yet in a quite "distorted" way because a signal of 40 dbFS resulted in being displayed as unity in the fader. This commit directly returns the value of the maximum bin, i.e. it does not map first to dbFS and then linearize the result anymore. This should work because the `Fader` class assumes a "linear" input signal and if the value of the bin was previously mapped to dbFS it should have some "linear" character. Please note that this is still somewhat of a "proxy" value because ideally the summed amplitude of all relevant bins in the frequency range would be shown and not just the "loudest" one. ## Other changes Rename `peakBand` to `linearPeakBand` to make more clear that a linear value is returned. Handle a potential division by zero by checking the value of `fft->getEnergy()` before using it. Index into `fft->m_bands` so that no parallel incrementing of the pointer is needed. This also enables the removal of the local variable `b`. * Improve the rendering of the levels The levels rendering now more explicitly distinguished between the rendering of the level outline/border and the level meters. The level rectangles are "inset" with regards to the borders so that there is a margin between the level borders and the meter readings. This margin is now also applied to the top and bottom of the levels. Levels are now also rendered as rounded rectangles similar to the level borders. Only render the levels and peaks if their values are greater than the minimum level. Make the radius of the rounded rectangles more pronounced by increasing its value from 1 to 2. Decrease the margins so that the level readings become wider, i.e. so that they are rendered with more pixels. Add the lambda `computeLevelMarkerRect` so that the rendering of the level markers is more decoupled from the rendering of the peak markers. * Reduce code repetition Reduce code repetition in `EqEffect::setBandPeaks` by introducing a lambda. Adjust code formatting. * Code review changes Code review changes in `Fader.cpp`. Mostly whitespace adjustments. Split up the calculation of the meter width to make it more understandable. This also reduces the number of parentheses. * Use MEMBER instead of READ/WRITE Use `MEMBER` instead of `READ`/`WRITE` for some properties that are not called explicitly from outside of the class. * Use default member initializers for Fader Use default member initializers for the members in `Fader` that have previously been initialized in the constructor list. * Make code clearer Make code clearer in `Fader::FadermouseDoubleClickEvent`. Only divide if the dialog was accepted with OK. --- data/themes/classic/fader_background.png | Bin 1391 -> 0 bytes data/themes/classic/fader_leds.png | Bin 3638 -> 0 bytes data/themes/classic/style.css | 6 +- data/themes/default/fader_background.png | Bin 905 -> 0 bytes data/themes/default/fader_leds.png | Bin 295 -> 0 bytes data/themes/default/style.css | 6 +- include/Fader.h | 101 ++--- include/lmms_math.h | 31 +- .../CrossoverEQ/CrossoverEQControlDialog.cpp | 19 +- .../CrossoverEQ/CrossoverEQControlDialog.h | 6 - plugins/CrossoverEQ/fader_bg.png | Bin 340 -> 0 bytes plugins/CrossoverEQ/fader_empty.png | Bin 230 -> 0 bytes plugins/Eq/EqControls.h | 2 + plugins/Eq/EqControlsDialog.cpp | 17 +- plugins/Eq/EqEffect.cpp | 62 ++- plugins/Eq/EqEffect.h | 2 +- plugins/Eq/EqFader.h | 14 - plugins/Eq/faderback.png | Bin 700 -> 0 bytes plugins/Eq/faderknob.png | Bin 350 -> 0 bytes plugins/Eq/faderleds.png | Bin 280 -> 0 bytes src/gui/MixerChannelView.cpp | 3 - src/gui/widgets/Fader.cpp | 425 ++++++++---------- 22 files changed, 323 insertions(+), 371 deletions(-) delete mode 100644 data/themes/classic/fader_background.png delete mode 100644 data/themes/classic/fader_leds.png delete mode 100644 data/themes/default/fader_background.png delete mode 100644 data/themes/default/fader_leds.png delete mode 100644 plugins/CrossoverEQ/fader_bg.png delete mode 100644 plugins/CrossoverEQ/fader_empty.png delete mode 100644 plugins/Eq/faderback.png delete mode 100755 plugins/Eq/faderknob.png delete mode 100644 plugins/Eq/faderleds.png diff --git a/data/themes/classic/fader_background.png b/data/themes/classic/fader_background.png deleted file mode 100644 index 682ff4c92815efe638b9adfd9b7ef723639ccd3d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1391 zcmV-#1(5oQP))#srQ|EuLfBj_~LCj!sG-WQZtWe9i zyuJNU$LV|qlYoSghU9N)8K#Qc_4?`TPe%SSf|(t?2#Og@6{?EMUoSk{gIDj>v0lp-I7glz0>F8`3#|@TfE-h>j(6?2#6RgwdPMuXx%MYVW!Z0NX^-i z3o~pk(5z5XT;Kk_Q}b7Fyd@0@Sp&KDulWRK0*Qc$QHuAun&EN>`E-5-6M3Jf1T}@_ z3{}JJcIk-xH2PNbUuB{U+d)p`tW}vvV=KOQt@&v+q0EFb&y5!^mpjO(*T%PL7@%rx zLOUaW86oTw$IO_EdGGEp5wXw2kO&%QgZ;Zs=;RX@TX8l=t~>jjEAmfUQE|IoI@g?o zKZyl%DUSTXZt~}`^wxPoC!fyP7q#Z5 zd8f~%)m&qP`fj-#uvOQw%|L$9{_BgYIZh2BG z#)Q^hfA8;!!c{Pd`_SOTO?@7mn}*apsOH{o?i4<>PH8EwavyC)mRfV4PSxHucirNh z!pyKzT)FCYw-CD`riwh=-x0`HZmyK3T=zJXL!VdOa)jbq^!aD@w{6|R^qKu@YH>{7 zA~B(*KtqdcbEuznPn28TJ5OlTTq3txJkj<(uNyRxcT0}C_h$deC$!})*4)CLv*4Oq z#76W9y>#vtlGrUxab=k9_)xBH&K-&$OIvA_K(DE zJ1L4cP03w|+7Y?pI)$dC&uvHLRxO{>;^z9N(5F@2BH=7l?V&zrj^tmLyrr*$UiSHl z{g)fAjihL`TY^9P@AHbhvj1!)lAlMnEsSBs{s$nhcXRA$JU{mgWjo^{pX#A{|0C|^ z+=ohY#Wg>FeA^;zLRA&HdunltJBvD{rQTVn;(8~A9;erEf9v~DulxH!`rOekiRiY2 zW?H3l?atz;`%rfaj53?==Lh;+gpmgFdLMHi8qT7+1yBC%i4>Y5`OmG_kC;%OxR!B6 zs=TLiNmdz`<^z%<=TK@|agNkNcT$Tw(VqOfR#da@96Gt$TB}^m$k{e`i%8rmu2pXT zTgBMt6uoO@{vTR#KvoOYb%-aDCF3f^pxL}zHop=Puu$uBJ*dyemim+UO>Rwp_EYGZ zTI81gA8=>!MW366o7>EC1Nlmys~*Ar68l_O+7}DYWV!yuLgeS&YrZhil0sJ`n?AJN xS)|pS#g9z%@c_lg7v#^L|9Kzg{d(>`{{j1^Dm5N5f$IPO002ovPDHLkV1jua!}|aL diff --git a/data/themes/classic/fader_leds.png b/data/themes/classic/fader_leds.png deleted file mode 100644 index 6c673cf36d1841a9c2206f6ac523fe3618405624..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3638 zcmV-64$1L}P)Q6o|MY)b}5;%bD#OBbOk&Foz;4Hagk^$&%x;w*FW30GCX9+ zTTSv~!0Q#{XM=Q_ zBw1i!I>q$|23Lj$KzfXsd+g}pi!cKGPX+mzOY$mE704{;@_ry;mhb)4Ch2bW5)Rbh zt*JuO6cU9ZBeMlA`Hx>&!k_(zGi7bPi=fMnswiaU7KkS27?{X%!;g-v4EKX<0ov@~ zap>}RUYGy6g8Ymnxl5O)=V5FS27shl{*5a?B;73@!T~4VT2*gLZh>R71$OT3vxGl= zL$7q!I|;b#s48UU%8VuE7#PoT;}3tkGTaB!4TN3bt%b4%$sCN7;9v#$Hjs{L2)fb3 z3ousDTf(2ZWs7t))DUo28#7;IEH=mB zSe~07A6^;m1=$RQ{or*jlV_p7g1iT0tp@@gqv!K5mVm>0=U0Y*{d4Wo-RdG7a^QB^ z(KL-jc9G*J=DGadH!a~$-nKzHR@V^lRG}&g*}@{@@gf6}JYV?k=*n<6$QB#4)PtuM zGz}7YI39z+3i8b$9YI5`LaqSgvoKhOoLT<0-C^0>?xbavLvM?wx8?YBiBH`%WC{P# zon6wg+JWC|$EGM`3uVS)MGlV^_~QPtmElg1&9%_73Or6-p3K7WX*eQQ`6dPFSOb1T zo-M%mNjN+Q1+)As*EY%K_F9@(RpW81Xqu4Blo_2a^4E8aTEd^WyF)tGI0$%D6q`aW zS7zem0)xlrxb@qUE5mC*HhH0C^)h(|MyKG-l2yK;8fkBYfEN@Ma(Nh=fg>51H_Pw6 zVYO^rTSH4j6&|;WXb{ho8J$?*%G<^);s1GWSlXJa2zaYdRfTN6%=n2#j*iT6+uoU# z;ng6ULeRV#JT4Fo5*ZksfVcBj`Fa=9-lDffQ6Za$i4$-n1|_rno|{9mxywQ0YCB%H zif9_~v_^Ddkx$<|WeNYm{f*MrWG7Ikpr{I&oG>-Lz~N&>ZofaaGQ0|8W1}H=0|N0h zM8;t_X_a^Rk+xiStr_~Q@O zOM8nQzfVO`AeYw|pDuHBsKmd0CAl)(2C}gYnj67o%siEb(Qz1=vC7vrAZ;z+_hE#? zvoT9TyLkT$%fmdA_B=&nbEN_f43)T34d&#U)sVp{B^c>Kkgtx#vk^Ldz@grmbCX8D)ybjrpJRWvoJ zxZNruLMo{diE4cI>Z~RFdyjghwN=6IH)fs_CMPwHzFFqWcjZlT1^LhhXl@3#TR%e+ zNf?Vjbkr(uZ9~Fs5bzs+p*dat)=@xA@;mQ#$e(Sn(bTNq_9&o1A}K^88h?M)oF)9x z$7?0ruHdgzQ54a`Cxo}&EOXZ#MU&i)tlI=l&EWFrJx?Vd8iDb*t@4)jy4)YoXP(W% z)C3G20TxX1JN~^&Hf&N@6IO70Ks1F^LL)i~yZ>gv68^{&c4=)_sPluODCDxj^aQ+l zSmW-0Sv1L=NY`dq(}EEWsU$>?!_*P0ym1rK+JPRfLM{u_V=#OKD4688e_fIF-O$vc zk3}?nEMp_E=aXUy-}j^<;STUG`$DJ2;kN^D&lkib_aNVihkvoJXZkwGA9lHYn?m8{>Q&)j9)L#GnL_y}CL%R2K157;H#0luJuqC!3cC&q-g z28FNQVxGAdY1*RC+~or)LplNDBao;d_ix1r*T<4i!}K^z4gwjI{FeJ`WZf1UtHUZT zuYSyB62kb1aMNXZOZWp%Ii;mT#T!tt*&v%1X2yh}L5=%vo-@gP$g0h-I*cAJkdDLT zame;r<({obQz!WRpxTzk0w)K7v`PN?2i(%R#ZE(5#qHHk|8zoQ@_3nl-kG+9fAuM! zG_AGa3#cfnLO!c;B3kCy;39i(%30-g-OvyQr&phOCIOQpP^=(#Y(tvXf;XVwx8&0> zGXbgo3i9h7sFRK!2MsMMPM^&PUu1G*kvn$AEa7)Q9g?O_JKlf|Re^k_%*>d^$UupQ zZ!(=k)FIAga!rG50;Z0EcF-zUw;_#d!E3aokb#*oC=388lYGxN>ZQHML48XVPOlBo zG%`tHdbq@wcUn*XFFn&Jjh)qa0xGJikWXuz94`^+FR|~&S(Dt4*tbA^>q_~o{!nBI z=M1F26FkPu3mKS=!onbsG|8|2W}~!q*ANQZarta$Wg(j^GjpuOJ(or-;s5$fo2>4t z#uKois0wqLGPBVVk%1zQetya-rw4*dZ4t=EA${y!@rc5kaB05muu^UYH=LB@Q zXQ?d$xfsli0KcjrKNG243m#+PGM9#I6#a27VUmA(Z-<0?Tm)NdsP$H%X+l1>z|6=z z-@N3gCH%%`H^{0^C+?sz^K_ZS*gVnxJU_VMxJe$=<<(1VDMKy++VH!})h>PJ*mQYm zNgg-JulUw_Y3gwkY^}lJtpW{l@e;Gg=6Lwy{g&|Se%vGVolaaqJBkYPnMLB!c_#aF zJn>I&o8%#cZhdW0Yn(*$31i{%Mg{qwBXohoIEjiGkfpVSS$_G08>Okoi@&vo8m}Eq zgF?JSY^1;=7hAU$yMJ<~ggTu#gViW16f+AXBlAoQWH@mB(RY!zgW}cY#L(9kuUC+t zh0qC#@xMjO8cVKzAZC*9e5hO2bl2f;bK>yoo1#LjMEqEm?_F%&6n*xm=SZ;2g)`{T z<>^I|kpk2GDW1N5z$CBN+fs2oS4n=hK6A@@t{<2+$v^(k8Pd>GM_s!Mhu4mjVJ==I zF`VW57r$f)|J$FQFM%!(wIPS`g)Wea=9%eF^5bg{n&hkAL;lMO@{d%IN8ed2t_;8E z;j?7*)*zlXw?1Asq3nv zCgea-6-wzMnMjV=z8EiE_v(Ad>rC=jE6BH3nEB|t$hSXyzJ#`}!rktr+Ehg&$AIW{%+#O?wei$verSrr*PQmYY-_@K3Oz4Gl4K74A=>gs+VlOFi?_G&)MwsTsVz%q=&8#4 zDx9Hz#691?OT1g(hqnAd&QNdf`!Msq(|!_t06qWH_5bYpU-z~ZuJTmYET1PB!+c&g zSXQ@K)2AvIgQYT|OgX1++byuee-fHtjB!HD&Ipa;4a?(APVVmwGqmuEtMfo& zs*>@Zl|}9jP8e?~Z?F!{ZDzv~*l)?*T+rgCKlxyuaWWuzgxsHG00000NkvXXu0mjfa1gIE diff --git a/data/themes/default/fader_leds.png b/data/themes/default/fader_leds.png deleted file mode 100644 index 707902e04c62f0158a7e6690497d68a1f00e20c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 295 zcmeAS@N?(olHy`uVBq!ia0vp^;y_%&!3HGryjF$)DVAa<&kznEsNqQI0P;BtJR*yM z>aT+^qm#z$3ZS55iEBhjaDG}zd16s2LwR|*US?i)adKios$PCk`s{Z$Qb0vZJY5_^ zG8*6BQsg^iAj0-w+JX%%&5!vwM8x{e=x`mB-4MeNdu3W{?~-Im&&}^wK70Cp`m@e! zCd;NA3fVftM^7sLTKDUB1)PfWc1;YCmEZn3-CX^?Rb_lZ%>Fww4?irh*b{r!d&|yz z_S`ckr(26z$k;{i*(v({{MG9hvhTiq`sB1Mw+vr9NFgd!^Q~glFXjE;7ys|7KYrge XUC}b^)r6lw_cD08`njxgN@xNA2mo}K diff --git a/data/themes/default/style.css b/data/themes/default/style.css index 89c14f20a2a..f13ec09d816 100644 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -694,9 +694,9 @@ lmms--gui--MixerChannelView QGraphicsView { /* persistent peak markers for fx peak meters */ lmms--gui--Fader { - qproperty-peakGreen: #0ad45c; - qproperty-peakYellow: #d6ec52; - qproperty-peakRed: #c12038; + qproperty-peakOk: #0ad45c; + qproperty-peakWarn: #d6ec52; + qproperty-peakClip: #c12038; } lmms--gui--TimeLineWidget { diff --git a/include/Fader.h b/include/Fader.h index 20132f71db2..a3158a8b436 100644 --- a/include/Fader.h +++ b/include/Fader.h @@ -54,6 +54,7 @@ #include "AutomatableModelView.h" #include "embed.h" +#include "lmms_math.h" namespace lmms::gui @@ -66,21 +67,21 @@ class LMMS_EXPORT Fader : public QWidget, public FloatModelView { Q_OBJECT public: - Q_PROPERTY( QColor peakGreen READ peakGreen WRITE setPeakGreen ) - Q_PROPERTY( QColor peakRed READ peakRed WRITE setPeakRed ) - Q_PROPERTY( QColor peakYellow READ peakYellow WRITE setPeakYellow ) - Q_PROPERTY( bool levelsDisplayedInDBFS READ getLevelsDisplayedInDBFS WRITE setLevelsDisplayedInDBFS ) - - Fader( FloatModel * _model, const QString & _name, QWidget * _parent ); - Fader( FloatModel * _model, const QString & _name, QWidget * _parent, QPixmap * back, QPixmap * leds, QPixmap * knob ); + Q_PROPERTY(QColor peakOk MEMBER m_peakOk) + Q_PROPERTY(QColor peakClip MEMBER m_peakClip) + Q_PROPERTY(QColor peakWarn MEMBER m_peakWarn) + Q_PROPERTY(bool levelsDisplayedInDBFS MEMBER m_levelsDisplayedInDBFS) + Q_PROPERTY(bool renderUnityLine READ getRenderUnityLine WRITE setRenderUnityLine) + Q_PROPERTY(QColor unityMarker MEMBER m_unityMarker) + + Fader(FloatModel* model, const QString& name, QWidget* parent); + Fader(FloatModel* model, const QString& name, QWidget* parent, const QPixmap& knob); ~Fader() override = default; - void init(FloatModel * model, QString const & name); - - void setPeak_L( float fPeak ); + void setPeak_L(float fPeak); float getPeak_L() { return m_fPeakValue_L; } - void setPeak_R( float fPeak ); + void setPeak_R(float fPeak); float getPeak_R() { return m_fPeakValue_R; } inline float getMinPeak() const { return m_fMinPeak; } @@ -89,43 +90,31 @@ class LMMS_EXPORT Fader : public QWidget, public FloatModelView inline float getMaxPeak() const { return m_fMaxPeak; } inline void setMaxPeak(float maxPeak) { m_fMaxPeak = maxPeak; } - QColor const & peakGreen() const; - void setPeakGreen( const QColor & c ); - - QColor const & peakRed() const; - void setPeakRed( const QColor & c ); - - QColor const & peakYellow() const; - void setPeakYellow( const QColor & c ); + inline bool getRenderUnityLine() const { return m_renderUnityLine; } + inline void setRenderUnityLine(bool value = true) { m_renderUnityLine = value; } - inline bool getLevelsDisplayedInDBFS() const { return m_levelsDisplayedInDBFS; } - inline void setLevelsDisplayedInDBFS(bool value = true) { m_levelsDisplayedInDBFS = value; } - - void setDisplayConversion( bool b ) + void setDisplayConversion(bool b) { m_conversionFactor = b ? 100.0 : 1.0; } - inline void setHintText( const QString & _txt_before, - const QString & _txt_after ) + inline void setHintText(const QString& txt_before, + const QString& txt_after) { - setDescription( _txt_before ); - setUnit( _txt_after ); + setDescription(txt_before); + setUnit(txt_after); } private: - void contextMenuEvent( QContextMenuEvent * _me ) override; - void mousePressEvent( QMouseEvent *ev ) override; - void mouseDoubleClickEvent( QMouseEvent* mouseEvent ) override; - void mouseMoveEvent( QMouseEvent *ev ) override; - void mouseReleaseEvent( QMouseEvent * _me ) override; - void wheelEvent( QWheelEvent *ev ) override; - void paintEvent( QPaintEvent *ev ) override; - - inline bool clips(float const & value) const { return value >= 1.0f; } + void contextMenuEvent(QContextMenuEvent* me) override; + void mousePressEvent(QMouseEvent* ev) override; + void mouseDoubleClickEvent(QMouseEvent* mouseEvent) override; + void mouseMoveEvent(QMouseEvent* ev) override; + void mouseReleaseEvent(QMouseEvent* me) override; + void wheelEvent(QWheelEvent* ev) override; + void paintEvent(QPaintEvent* ev) override; - void paintDBFSLevels(QPaintEvent *ev, QPainter & painter); - void paintLinearLevels(QPaintEvent *ev, QPainter & painter); + void paintLevels(QPaintEvent* ev, QPainter& painter, bool linear = false); int knobPosY() const { @@ -135,37 +124,37 @@ class LMMS_EXPORT Fader : public QWidget, public FloatModelView return height() - ((height() - m_knob.height()) * (realVal / fRange)); } - void setPeak( float fPeak, float &targetPeak, float &persistentPeak, QElapsedTimer &lastPeakTimer ); - int calculateDisplayPeak( float fPeak ); + void setPeak(float fPeak, float& targetPeak, float& persistentPeak, QElapsedTimer& lastPeakTimer); void updateTextFloat(); // Private members private: - float m_fPeakValue_L; - float m_fPeakValue_R; - float m_persistentPeak_L; - float m_persistentPeak_R; - float m_fMinPeak; - float m_fMaxPeak; + float m_fPeakValue_L {0.}; + float m_fPeakValue_R {0.}; + float m_persistentPeak_L {0.}; + float m_persistentPeak_R {0.}; + float m_fMinPeak {dbfsToAmp(-42)}; + float m_fMaxPeak {dbfsToAmp(9)}; QElapsedTimer m_lastPeakTimer_L; QElapsedTimer m_lastPeakTimer_R; - QPixmap m_back; - QPixmap m_leds; - QPixmap m_knob; + QPixmap m_knob {embed::getIconPixmap("fader_knob")}; + + bool m_levelsDisplayedInDBFS {true}; - bool m_levelsDisplayedInDBFS; + int m_moveStartPoint {-1}; + float m_startValue {0.}; - int m_moveStartPoint; - float m_startValue; + static SimpleTextFloat* s_textFloat; - static SimpleTextFloat * s_textFloat; + QColor m_peakOk {10, 212, 92}; + QColor m_peakClip {193, 32, 56}; + QColor m_peakWarn {214, 236, 82}; + QColor m_unityMarker {63, 63, 63, 255}; - QColor m_peakGreen; - QColor m_peakRed; - QColor m_peakYellow; + bool m_renderUnityLine {true}; } ; diff --git a/include/lmms_math.h b/include/lmms_math.h index f6455d6931f..3f58e3b75d4 100644 --- a/include/lmms_math.h +++ b/include/lmms_math.h @@ -32,6 +32,7 @@ #include "lmms_constants.h" #include "lmmsconfig.h" +#include namespace lmms { @@ -269,18 +270,18 @@ static inline float safeDbfsToAmp( float dbfs ) //! @brief Converts linear amplitude (>0-1.0) to dBFS scale. //! @param amp Linear amplitude, where 1.0 = 0dBFS. ** Must be larger than zero! ** //! @return Amplitude in dBFS. -static inline float ampToDbfs( float amp ) +static inline float ampToDbfs(float amp) { - return log10f( amp ) * 20.0f; + return log10f(amp) * 20.0f; } //! @brief Converts dBFS-scale to linear amplitude with 0dBFS = 1.0 //! @param dbfs The dBFS value to convert. ** Must be a real number - not inf/nan! ** //! @return Linear amplitude -static inline float dbfsToAmp( float dbfs ) +static inline float dbfsToAmp(float dbfs) { - return std::pow(10.f, dbfs * 0.05f ); + return std::pow(10.f, dbfs * 0.05f); } @@ -352,6 +353,28 @@ static inline int numDigitsAsInt(float f) return digits; } +template +class LinearMap +{ +public: + LinearMap(T x1, T y1, T x2, T y2) + { + T const dx = x2 - x1; + assert (dx != T(0)); + + m_a = (y2 - y1) / dx; + m_b = y1 - m_a * x1; + } + + T map(T x) const + { + return m_a * x + m_b; + } + +private: + T m_a; + T m_b; +}; } // namespace lmms diff --git a/plugins/CrossoverEQ/CrossoverEQControlDialog.cpp b/plugins/CrossoverEQ/CrossoverEQControlDialog.cpp index 12b560b2370..a4f44f5d305 100644 --- a/plugins/CrossoverEQ/CrossoverEQControlDialog.cpp +++ b/plugins/CrossoverEQ/CrossoverEQControlDialog.cpp @@ -32,6 +32,9 @@ #include "Knob.h" #include "Fader.h" +#include + + namespace lmms::gui { @@ -64,30 +67,32 @@ CrossoverEQControlDialog::CrossoverEQControlDialog( CrossoverEQControls * contro xover34->setLabel( "3/4" ); xover34->setHintText( tr( "Band 3/4 crossover:" ), " Hz" ); - m_fader_bg = QPixmap( PLUGIN_NAME::getIconPixmap( "fader_bg" ) ); - m_fader_empty = QPixmap( PLUGIN_NAME::getIconPixmap( "fader_empty" ) ); - m_fader_knob = QPixmap( PLUGIN_NAME::getIconPixmap( "fader_knob2" ) ); + QPixmap const fader_knob(PLUGIN_NAME::getIconPixmap("fader_knob2")); // faders - auto gain1 = new Fader(&controls->m_gain1, tr("Band 1 gain"), this, &m_fader_bg, &m_fader_empty, &m_fader_knob); + auto gain1 = new Fader(&controls->m_gain1, tr("Band 1 gain"), this, fader_knob); gain1->move( 7, 56 ); gain1->setDisplayConversion( false ); gain1->setHintText( tr( "Band 1 gain:" ), " dBFS" ); + gain1->setRenderUnityLine(false); - auto gain2 = new Fader(&controls->m_gain2, tr("Band 2 gain"), this, &m_fader_bg, &m_fader_empty, &m_fader_knob); + auto gain2 = new Fader(&controls->m_gain2, tr("Band 2 gain"), this, fader_knob); gain2->move( 47, 56 ); gain2->setDisplayConversion( false ); gain2->setHintText( tr( "Band 2 gain:" ), " dBFS" ); + gain2->setRenderUnityLine(false); - auto gain3 = new Fader(&controls->m_gain3, tr("Band 3 gain"), this, &m_fader_bg, &m_fader_empty, &m_fader_knob); + auto gain3 = new Fader(&controls->m_gain3, tr("Band 3 gain"), this, fader_knob); gain3->move( 87, 56 ); gain3->setDisplayConversion( false ); gain3->setHintText( tr( "Band 3 gain:" ), " dBFS" ); + gain3->setRenderUnityLine(false); - auto gain4 = new Fader(&controls->m_gain4, tr("Band 4 gain"), this, &m_fader_bg, &m_fader_empty, &m_fader_knob); + auto gain4 = new Fader(&controls->m_gain4, tr("Band 4 gain"), this, fader_knob); gain4->move( 127, 56 ); gain4->setDisplayConversion( false ); gain4->setHintText( tr( "Band 4 gain:" ), " dBFS" ); + gain4->setRenderUnityLine(false); // leds auto mute1 = new LedCheckBox("", this, tr("Band 1 mute"), LedCheckBox::LedColor::Green); diff --git a/plugins/CrossoverEQ/CrossoverEQControlDialog.h b/plugins/CrossoverEQ/CrossoverEQControlDialog.h index 9ddb5d9bfb2..0f25600f9f0 100644 --- a/plugins/CrossoverEQ/CrossoverEQControlDialog.h +++ b/plugins/CrossoverEQ/CrossoverEQControlDialog.h @@ -27,7 +27,6 @@ #ifndef CROSSOVEREQ_CONTROL_DIALOG_H #define CROSSOVEREQ_CONTROL_DIALOG_H -#include #include "EffectControlDialog.h" namespace lmms @@ -46,11 +45,6 @@ class CrossoverEQControlDialog : public EffectControlDialog public: CrossoverEQControlDialog( CrossoverEQControls * controls ); ~CrossoverEQControlDialog() override = default; - -private: - QPixmap m_fader_bg; - QPixmap m_fader_empty; - QPixmap m_fader_knob; }; diff --git a/plugins/CrossoverEQ/fader_bg.png b/plugins/CrossoverEQ/fader_bg.png deleted file mode 100644 index ca4eedafdc951c9741a3a9b3e520de47f1c8adc1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 340 zcmeAS@N?(olHy`uVBq!ia0vp^3P7B~!3HFsZ#L=!QY^(zo*^7SP{WbZ0pxQQctjQh z)n5l;MkkHg6+l7B64!{5;QX|b^2DN4hVt@qz0ADq;^f4FRK5J7^x5xhq=1Spdb&7< zWHi3L<;d0Kz~FGPr|-&4tB~|pe%mr1F3MpO*MD)|Es)**-}wU#r+2MWw>vKc_^l17D?|1H qmxTi^lYZPQczOR51JjS{2KC%hoB3*oLR^5JWAJqKb6Mw<&;$U+GI-kn diff --git a/plugins/CrossoverEQ/fader_empty.png b/plugins/CrossoverEQ/fader_empty.png deleted file mode 100644 index 797a0d3bc2d06622281319ac066f484753e8cb6c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 230 zcmeAS@N?(olHy`uVBq!ia0vp^3P7B~!3HFsZ#L=!Qfx`y?k)`fL2$v|<&%LToCO|{ z#S9GG!XV7ZFl&wkP>{XE)7O>#0f(rF9y@dPsa&9tWQl7;iF1B#Zfaf$gL6@8Vo7R> zLV0FMhJw4NZ$Nk>pEyvFpQnpsNXEUl=L{Jc7&w?0Wd1*A+{UkxaO>ISXEPf}1P2(a XT$qnaRDQSyG?~HE)z4*}Q$iB}YtT!* diff --git a/plugins/Eq/EqControls.h b/plugins/Eq/EqControls.h index 6db82f3e33f..80680c7fb5a 100644 --- a/plugins/Eq/EqControls.h +++ b/plugins/Eq/EqControls.h @@ -66,6 +66,8 @@ class EqControls : public EffectControls float m_inPeakR; float m_outPeakL; float m_outPeakR; + + // The following are linear peaks float m_lowShelfPeakL, m_lowShelfPeakR; float m_para1PeakL, m_para1PeakR; float m_para2PeakL, m_para2PeakR; diff --git a/plugins/Eq/EqControlsDialog.cpp b/plugins/Eq/EqControlsDialog.cpp index 634bde846bc..17de9ce98a9 100644 --- a/plugins/Eq/EqControlsDialog.cpp +++ b/plugins/Eq/EqControlsDialog.cpp @@ -72,18 +72,16 @@ EqControlsDialog::EqControlsDialog( EqControls *controls ) : setBand( 6, &controls->m_highShelfActiveModel, &controls->m_highShelfFreqModel, &controls->m_highShelfResModel, &controls->m_highShelfGainModel, QColor(255 ,255, 255), tr( "High-shelf" ), &controls->m_highShelfPeakL, &controls->m_highShelfPeakR,0,0,0,0,0,0 ); setBand( 7, &controls->m_lpActiveModel, &controls->m_lpFreqModel, &controls->m_lpResModel, 0, QColor(255 ,255, 255), tr( "LP" ) ,0,0,0,0,0, &controls->m_lp12Model, &controls->m_lp24Model, &controls->m_lp48Model); - static auto s_faderBg = PLUGIN_NAME::getIconPixmap("faderback"); - static auto s_faderLeds = PLUGIN_NAME::getIconPixmap("faderleds"); - static auto s_faderKnob = PLUGIN_NAME::getIconPixmap("faderknob"); + QSize const faderSize(23, 80); - auto GainFaderIn = new EqFader(&controls->m_inGainModel, tr("Input gain"), this, &s_faderBg, &s_faderLeds, &s_faderKnob, - &controls->m_inPeakL, &controls->m_inPeakR); + auto GainFaderIn = new EqFader(&controls->m_inGainModel, tr("Input gain"), this, &controls->m_inPeakL, &controls->m_inPeakR); + GainFaderIn->setFixedSize(faderSize); GainFaderIn->move( 23, 295 ); GainFaderIn->setDisplayConversion( false ); GainFaderIn->setHintText( tr( "Gain" ), "dBv"); - auto GainFaderOut = new EqFader(&controls->m_outGainModel, tr("Output gain"), this, &s_faderBg, &s_faderLeds, &s_faderKnob, - &controls->m_outPeakL, &controls->m_outPeakR); + auto GainFaderOut = new EqFader(&controls->m_outGainModel, tr("Output gain"), this, &controls->m_outPeakL, &controls->m_outPeakR); + GainFaderOut->setFixedSize(faderSize); GainFaderOut->move( 453, 295); GainFaderOut->setDisplayConversion( false ); GainFaderOut->setHintText( tr( "Gain" ), "dBv" ); @@ -92,8 +90,9 @@ EqControlsDialog::EqControlsDialog( EqControls *controls ) : int distance = 126; for( int i = 1; i < m_parameterWidget->bandCount() - 1; i++ ) { - auto gainFader = new EqFader(m_parameterWidget->getBandModels(i)->gain, tr(""), this, &s_faderBg, &s_faderLeds, - &s_faderKnob, m_parameterWidget->getBandModels(i)->peakL, m_parameterWidget->getBandModels(i)->peakR); + auto gainFader = new EqFader(m_parameterWidget->getBandModels(i)->gain, tr(""), this, + m_parameterWidget->getBandModels(i)->peakL, m_parameterWidget->getBandModels(i)->peakR); + gainFader->setFixedSize(faderSize); gainFader->move( distance, 295 ); distance += 44; gainFader->setMinimumHeight(80); diff --git a/plugins/Eq/EqEffect.cpp b/plugins/Eq/EqEffect.cpp index 31be4d0f5b6..d8d2b2b29e2 100644 --- a/plugins/Eq/EqEffect.cpp +++ b/plugins/Eq/EqEffect.cpp @@ -287,24 +287,23 @@ bool EqEffect::processAudioBuffer( sampleFrame *buf, const fpp_t frames ) -float EqEffect::peakBand( float minF, float maxF, EqAnalyser *fft, int sr ) +float EqEffect::linearPeakBand(float minF, float maxF, EqAnalyser* fft, int sr) { auto const fftEnergy = fft->getEnergy(); if (fftEnergy == 0.) { return 0.; } - float peak = -60; - float *b = fft->m_bands; - float h = 0; - for( int x = 0; x < MAX_BANDS; x++, b++ ) + + float peakLinear = 0.; + + for (int i = 0; i < MAX_BANDS; ++i) { - if( bandToFreq( x ,sr) >= minF && bandToFreq( x,sr ) <= maxF ) + if (bandToFreq(i, sr) >= minF && bandToFreq(i, sr) <= maxF) { - h = 20. * log10(*b / fftEnergy); - peak = h > peak ? h : peak; + peakLinear = std::max(peakLinear, fft->m_bands[i] / fftEnergy); } } - return ( peak + 60 ) / 100; + return peakLinear; } @@ -312,45 +311,34 @@ float EqEffect::peakBand( float minF, float maxF, EqAnalyser *fft, int sr ) void EqEffect::setBandPeaks( EqAnalyser *fft, int samplerate ) { + auto computePeakBand = [&](const FloatModel& freqModel, const FloatModel& bwModel) + { + float const freq = freqModel.value(); + float const bw = bwModel.value(); + + return linearPeakBand(freq * (1 - bw * 0.5), freq * (1 + bw * 0.5), fft, samplerate); + }; + m_eqControls.m_lowShelfPeakR = m_eqControls.m_lowShelfPeakL = - peakBand( m_eqControls.m_lowShelfFreqModel.value() - * ( 1 - m_eqControls.m_lowShelfResModel.value() * 0.5 ), - m_eqControls.m_lowShelfFreqModel.value(), - fft , samplerate ); + linearPeakBand(m_eqControls.m_lowShelfFreqModel.value() * (1 - m_eqControls.m_lowShelfResModel.value() * 0.5), + m_eqControls.m_lowShelfFreqModel.value(), fft , samplerate); m_eqControls.m_para1PeakL = m_eqControls.m_para1PeakR = - peakBand( m_eqControls.m_para1FreqModel.value() - * ( 1 - m_eqControls.m_para1BwModel.value() * 0.5 ), - m_eqControls.m_para1FreqModel.value() - * ( 1 + m_eqControls.m_para1BwModel.value() * 0.5 ), - fft , samplerate ); + computePeakBand(m_eqControls.m_para1FreqModel, m_eqControls.m_para1BwModel); m_eqControls.m_para2PeakL = m_eqControls.m_para2PeakR = - peakBand( m_eqControls.m_para2FreqModel.value() - * ( 1 - m_eqControls.m_para2BwModel.value() * 0.5 ), - m_eqControls.m_para2FreqModel.value() - * ( 1 + m_eqControls.m_para2BwModel.value() * 0.5 ), - fft , samplerate ); + computePeakBand(m_eqControls.m_para2FreqModel, m_eqControls.m_para2BwModel); m_eqControls.m_para3PeakL = m_eqControls.m_para3PeakR = - peakBand( m_eqControls.m_para3FreqModel.value() - * ( 1 - m_eqControls.m_para3BwModel.value() * 0.5 ), - m_eqControls.m_para3FreqModel.value() - * ( 1 + m_eqControls.m_para3BwModel.value() * 0.5 ), - fft , samplerate ); + computePeakBand(m_eqControls.m_para3FreqModel, m_eqControls.m_para3BwModel); m_eqControls.m_para4PeakL = m_eqControls.m_para4PeakR = - peakBand( m_eqControls.m_para4FreqModel.value() - * ( 1 - m_eqControls.m_para4BwModel.value() * 0.5 ), - m_eqControls.m_para4FreqModel.value() - * ( 1 + m_eqControls.m_para4BwModel.value() * 0.5 ), - fft , samplerate ); + computePeakBand(m_eqControls.m_para4FreqModel, m_eqControls.m_para4BwModel); m_eqControls.m_highShelfPeakL = m_eqControls.m_highShelfPeakR = - peakBand( m_eqControls.m_highShelfFreqModel.value(), - m_eqControls.m_highShelfFreqModel.value() - * ( 1 + m_eqControls.m_highShelfResModel.value() * 0.5 ), - fft, samplerate ); + linearPeakBand(m_eqControls.m_highShelfFreqModel.value(), + m_eqControls.m_highShelfFreqModel.value() * (1 + m_eqControls.m_highShelfResModel.value() * 0.5), + fft, samplerate); } extern "C" diff --git a/plugins/Eq/EqEffect.h b/plugins/Eq/EqEffect.h index 9b23b51b57e..7e91ee40142 100644 --- a/plugins/Eq/EqEffect.h +++ b/plugins/Eq/EqEffect.h @@ -87,7 +87,7 @@ class EqEffect : public Effect float m_inGain; float m_outGain; - float peakBand( float minF, float maxF, EqAnalyser *, int ); + float linearPeakBand(float minF, float maxF, EqAnalyser*, int); inline float bandToFreq ( int index , int sampleRate ) { diff --git a/plugins/Eq/EqFader.h b/plugins/Eq/EqFader.h index 9db0fbe2d82..d8897af5c90 100644 --- a/plugins/Eq/EqFader.h +++ b/plugins/Eq/EqFader.h @@ -42,20 +42,6 @@ class EqFader : public Fader public: Q_OBJECT public: - EqFader( FloatModel * model, const QString & name, QWidget * parent, QPixmap * backg, QPixmap * leds, QPixmap * knobpi, float* lPeak, float* rPeak ) : - Fader( model, name, parent, backg, leds, knobpi ) - { - setMinimumSize( 23, 80 ); - setMaximumSize( 23, 80 ); - resize( 23, 80 ); - m_lPeak = lPeak; - m_rPeak = rPeak; - connect( getGUI()->mainWindow(), SIGNAL( periodicUpdate() ), this, SLOT( updateVuMeters() ) ); - m_model = model; - setPeak_L( 0 ); - setPeak_R( 0 ); - } - EqFader( FloatModel * model, const QString & name, QWidget * parent, float* lPeak, float* rPeak ) : Fader( model, name, parent ) { diff --git a/plugins/Eq/faderback.png b/plugins/Eq/faderback.png deleted file mode 100644 index 2a03c3a5c1e6c1469d3f3bc9887f0340cf909ee0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 700 zcmV;t0z>_YP)Uq`u<52<($j6>xy;fp;+A#SwQ6_&36G;FNc~XQEBlrzui)v z^6&q*w<|3Q^4)SyysuRh=o$XU%tWY}pngEd_1Jhs9jfMkh|epJTb9oS5mfx*4RiSQ z`n*v<32^GSV-vF@Yl%0gv;2wjt*hKQ+ZK5~za^rP48LBVhx;wg_Nk(X&hYEaP%EIt z3d##;nO|?k^a&Gw;S3Jv>v;f47-NnA&evzuyaDk3_;CL+J>VV2nB(Ka{R@EcUqv;48Oz86fDPhF iH30Y!k<;W3CI1EQEiz6+DKUQl0000aT+^qm#z$3ZS55iEBhjaDG}zd16s2LwR|*US?i)adKios$PCk`s{Z$Qb0wwJzX3_ zJUZWAv*uzl6li!@pHiEk9#zTB9nP};k?Wehv)@EjFiUI4N38v!l)P5W?IH&wyHl4+ ze49awV5n-yl%|sl3q!spGB7JJe`%e_$UIwlo4NSJHJ9Hm?@c>B`%d2OM6)X@UuU;+{nNVKt=T|tGI+ZBxvX1LivkZ+cTDT%wSn;@#WCY;2kpdD$y#d zgMS>Z$ez2zeM!OL-#6D^x2)Y6(Y{cn_Nr=K&Sw3^2R)hP=62hgtk2%H>TsxE{`aT@ z2jSp9`~3O3-~G3~K0N2%yR8k)a3FsycF|0s-+T8i{K>c=Qk3C$4c~g80~tJB{an^L HB{Ts5T`6*6 diff --git a/src/gui/MixerChannelView.cpp b/src/gui/MixerChannelView.cpp index 8a1ed2e8fe4..22251d55133 100644 --- a/src/gui/MixerChannelView.cpp +++ b/src/gui/MixerChannelView.cpp @@ -122,9 +122,6 @@ namespace lmms::gui soloMuteLayout->addWidget(m_muteButton, 0, Qt::AlignHCenter); m_fader = new Fader{&mixerChannel->m_volumeModel, tr("Fader %1").arg(channelIndex), this}; - m_fader->setLevelsDisplayedInDBFS(); - m_fader->setMinPeak(dbfsToAmp(-42)); - m_fader->setMaxPeak(dbfsToAmp(9)); m_effectRackView = new EffectRackView{&mixerChannel->m_fxChain, mixerView->m_racksWidget}; m_effectRackView->setFixedWidth(EffectRackView::DEFAULT_WIDTH); diff --git a/src/gui/widgets/Fader.cpp b/src/gui/widgets/Fader.cpp index 840fe299133..370cc750291 100644 --- a/src/gui/widgets/Fader.cpp +++ b/src/gui/widgets/Fader.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #include "lmms_math.h" #include "embed.h" @@ -59,100 +60,60 @@ namespace lmms::gui { -SimpleTextFloat * Fader::s_textFloat = nullptr; - -Fader::Fader( FloatModel * _model, const QString & _name, QWidget * _parent ) : - QWidget( _parent ), - FloatModelView( _model, this ), - m_fPeakValue_L( 0.0 ), - m_fPeakValue_R( 0.0 ), - m_persistentPeak_L( 0.0 ), - m_persistentPeak_R( 0.0 ), - m_fMinPeak( 0.01f ), - m_fMaxPeak( 1.1 ), - m_back(embed::getIconPixmap("fader_background")), - m_leds(embed::getIconPixmap("fader_leds")), - m_knob(embed::getIconPixmap("fader_knob")), - m_levelsDisplayedInDBFS(false), - m_moveStartPoint( -1 ), - m_startValue( 0 ), - m_peakGreen( 0, 0, 0 ), - m_peakRed( 0, 0, 0 ), - m_peakYellow( 0, 0, 0 ) +SimpleTextFloat* Fader::s_textFloat = nullptr; + +Fader::Fader(FloatModel* model, const QString& name, QWidget* parent) : + QWidget(parent), + FloatModelView(model, this) { - if( s_textFloat == nullptr ) + if (s_textFloat == nullptr) { s_textFloat = new SimpleTextFloat; } - init(_model, _name); + setWindowTitle(name); + setAttribute(Qt::WA_OpaquePaintEvent, false); + // For now resize the widget to the size of the previous background image "fader_background.png" as it was found in the classic and default theme + constexpr QSize minimumSize(23, 116); + setMinimumSize(minimumSize); + resize(minimumSize); + setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + setModel(model); + setHintText("Volume:", "%"); m_conversionFactor = 100.0; } -Fader::Fader( FloatModel * model, const QString & name, QWidget * parent, QPixmap * back, QPixmap * leds, QPixmap * knob ) : - QWidget( parent ), - FloatModelView( model, this ), - m_fPeakValue_L( 0.0 ), - m_fPeakValue_R( 0.0 ), - m_persistentPeak_L( 0.0 ), - m_persistentPeak_R( 0.0 ), - m_fMinPeak( 0.01f ), - m_fMaxPeak( 1.1 ), - m_back(*back), - m_leds(*leds), - m_knob(*knob), - m_levelsDisplayedInDBFS(false), - m_moveStartPoint( -1 ), - m_startValue( 0 ), - m_peakGreen( 0, 0, 0 ), - m_peakRed( 0, 0, 0 ) +Fader::Fader(FloatModel* model, const QString& name, QWidget* parent, const QPixmap& knob) : + Fader(model, name, parent) { - if( s_textFloat == nullptr ) - { - s_textFloat = new SimpleTextFloat; - } - - init(model, name); + m_knob = knob; } -void Fader::init(FloatModel * model, QString const & name) -{ - setWindowTitle( name ); - setAttribute( Qt::WA_OpaquePaintEvent, false ); - QSize backgroundSize = m_back.size(); - setMinimumSize( backgroundSize ); - setMaximumSize( backgroundSize ); - resize( backgroundSize ); - setModel( model ); - setHintText( "Volume:","%"); -} - - -void Fader::contextMenuEvent( QContextMenuEvent * _ev ) +void Fader::contextMenuEvent(QContextMenuEvent* ev) { - CaptionMenu contextMenu( windowTitle() ); - addDefaultActions( &contextMenu ); - contextMenu.exec( QCursor::pos() ); - _ev->accept(); + CaptionMenu contextMenu(windowTitle()); + addDefaultActions(&contextMenu); + contextMenu.exec(QCursor::pos()); + ev->accept(); } -void Fader::mouseMoveEvent( QMouseEvent *mouseEvent ) +void Fader::mouseMoveEvent(QMouseEvent* mouseEvent) { - if( m_moveStartPoint >= 0 ) + if (m_moveStartPoint >= 0) { int dy = m_moveStartPoint - mouseEvent->globalY(); float delta = dy * (model()->maxValue() - model()->minValue()) / (float)(height() - (m_knob).height()); const auto step = model()->step(); - float newValue = static_cast( static_cast( ( m_startValue + delta ) / step + 0.5 ) ) * step; - model()->setValue( newValue ); + float newValue = static_cast(static_cast((m_startValue + delta) / step + 0.5)) * step; + model()->setValue(newValue); updateTextFloat(); } @@ -161,16 +122,16 @@ void Fader::mouseMoveEvent( QMouseEvent *mouseEvent ) -void Fader::mousePressEvent( QMouseEvent* mouseEvent ) +void Fader::mousePressEvent(QMouseEvent* mouseEvent) { - if( mouseEvent->button() == Qt::LeftButton && - ! ( mouseEvent->modifiers() & Qt::ControlModifier ) ) + if (mouseEvent->button() == Qt::LeftButton && + !(mouseEvent->modifiers() & Qt::ControlModifier)) { - AutomatableModel *thisModel = model(); - if( thisModel ) + AutomatableModel* thisModel = model(); + if (thisModel) { thisModel->addJournalCheckPoint(); - thisModel->saveJournallingState( false ); + thisModel->saveJournallingState(false); } if (mouseEvent->y() >= knobPosY() - (m_knob).height() && mouseEvent->y() < knobPosY()) @@ -190,37 +151,36 @@ void Fader::mousePressEvent( QMouseEvent* mouseEvent ) } else { - AutomatableModelView::mousePressEvent( mouseEvent ); + AutomatableModelView::mousePressEvent(mouseEvent); } } -void Fader::mouseDoubleClickEvent( QMouseEvent* mouseEvent ) +void Fader::mouseDoubleClickEvent(QMouseEvent* mouseEvent) { bool ok; - // TODO: dbV handling + // TODO: dbFS handling auto minv = model()->minValue() * m_conversionFactor; auto maxv = model()->maxValue() * m_conversionFactor; - float newValue = QInputDialog::getDouble(this, tr("Set value"), + float enteredValue = QInputDialog::getDouble(this, tr("Set value"), tr("Please enter a new value between %1 and %2:").arg(minv).arg(maxv), - model()->getRoundedValue() * m_conversionFactor, minv, maxv, model()->getDigitCount(), &ok) - / m_conversionFactor; + model()->getRoundedValue() * m_conversionFactor, minv, maxv, model()->getDigitCount(), &ok); - if( ok ) + if (ok) { - model()->setValue( newValue ); + model()->setValue(enteredValue / m_conversionFactor); } } -void Fader::mouseReleaseEvent( QMouseEvent * mouseEvent ) +void Fader::mouseReleaseEvent(QMouseEvent* mouseEvent) { - if( mouseEvent && mouseEvent->button() == Qt::LeftButton ) + if (mouseEvent && mouseEvent->button() == Qt::LeftButton) { - AutomatableModel *thisModel = model(); - if( thisModel ) + AutomatableModel* thisModel = model(); + if (thisModel) { thisModel->restoreJournallingState(); } @@ -230,20 +190,20 @@ void Fader::mouseReleaseEvent( QMouseEvent * mouseEvent ) } -void Fader::wheelEvent ( QWheelEvent *ev ) +void Fader::wheelEvent (QWheelEvent* ev) { ev->accept(); if (ev->angleDelta().y() > 0) { - model()->incValue( 1 ); + model()->incValue(1); } else { - model()->incValue( -1 ); + model()->incValue(-1); } updateTextFloat(); - s_textFloat->setVisibilityTimeOut( 1000 ); + s_textFloat->setVisibilityTimeOut(1000); } @@ -251,21 +211,14 @@ void Fader::wheelEvent ( QWheelEvent *ev ) /// /// Set peak value (0.0 .. 1.0) /// -void Fader::setPeak( float fPeak, float &targetPeak, float &persistentPeak, QElapsedTimer &lastPeakTimer ) +void Fader::setPeak(float fPeak, float& targetPeak, float& persistentPeak, QElapsedTimer& lastPeakTimer) { - if( fPeak < m_fMinPeak ) - { - fPeak = m_fMinPeak; - } - else if( fPeak > m_fMaxPeak ) - { - fPeak = m_fMaxPeak; - } + fPeak = std::clamp(fPeak, m_fMinPeak, m_fMaxPeak); - if( targetPeak != fPeak) + if (targetPeak != fPeak) { targetPeak = fPeak; - if( targetPeak >= persistentPeak ) + if (targetPeak >= persistentPeak) { persistentPeak = targetPeak; lastPeakTimer.restart(); @@ -273,25 +226,25 @@ void Fader::setPeak( float fPeak, float &targetPeak, float &persistentPeak, QEla update(); } - if( persistentPeak > 0 && lastPeakTimer.elapsed() > 1500 ) + if (persistentPeak > 0 && lastPeakTimer.elapsed() > 1500) { - persistentPeak = qMax( 0, persistentPeak-0.05 ); + persistentPeak = qMax(0, persistentPeak-0.05); update(); } } -void Fader::setPeak_L( float fPeak ) +void Fader::setPeak_L(float fPeak) { - setPeak( fPeak, m_fPeakValue_L, m_persistentPeak_L, m_lastPeakTimer_L ); + setPeak(fPeak, m_fPeakValue_L, m_persistentPeak_L, m_lastPeakTimer_L); } -void Fader::setPeak_R( float fPeak ) +void Fader::setPeak_R(float fPeak) { - setPeak( fPeak, m_fPeakValue_R, m_persistentPeak_R, m_lastPeakTimer_R ); + setPeak(fPeak, m_fPeakValue_R, m_persistentPeak_R, m_lastPeakTimer_R); } @@ -299,169 +252,185 @@ void Fader::setPeak_R( float fPeak ) // update tooltip showing value and adjust position while changing fader value void Fader::updateTextFloat() { - if( ConfigManager::inst()->value( "app", "displaydbfs" ).toInt() && m_conversionFactor == 100.0 ) + if (ConfigManager::inst()->value("app", "displaydbfs").toInt() && m_conversionFactor == 100.0) { - s_textFloat->setText( QString("Volume: %1 dBFS"). - arg( ampToDbfs( model()->value() ), 3, 'f', 2 ) ); + s_textFloat->setText(QString("Volume: %1 dBFS"). + arg(ampToDbfs(model()->value()), 3, 'f', 2)); } else { - s_textFloat->setText( m_description + " " + QString("%1 ").arg( model()->value() * m_conversionFactor ) + " " + m_unit ); + s_textFloat->setText(m_description + " " + QString("%1 ").arg(model()->value() * m_conversionFactor) + " " + m_unit); } s_textFloat->moveGlobal(this, QPoint(width() + 2, knobPosY() - s_textFloat->height() / 2)); } -inline int Fader::calculateDisplayPeak( float fPeak ) +void Fader::paintEvent(QPaintEvent* ev) { - int peak = static_cast(m_back.height() - (fPeak / (m_fMaxPeak - m_fMinPeak)) * m_back.height()); + QPainter painter(this); - return qMin(peak, m_back.height()); -} + // Draw the levels with peaks + paintLevels(ev, painter, !m_levelsDisplayedInDBFS); + // Draw the knob + painter.drawPixmap((width() - m_knob.width()) / 2, knobPosY() - m_knob.height(), m_knob); +} -void Fader::paintEvent( QPaintEvent * ev) +void Fader::paintLevels(QPaintEvent* ev, QPainter& painter, bool linear) { - QPainter painter(this); - - // Draw the background - painter.drawPixmap(ev->rect(), m_back, ev->rect()); + std::function mapper = [this](float value) { return ampToDbfs(qMax(0.0001, value)); }; - // Draw the levels with peaks - if (getLevelsDisplayedInDBFS()) + if (linear) { - paintDBFSLevels(ev, painter); - } - else - { - paintLinearLevels(ev, painter); + mapper = [this](float value) { return value; }; } - // Draw the knob - painter.drawPixmap(0, knobPosY() - m_knob.height(), m_knob); -} + const float mappedMinPeak(mapper(m_fMinPeak)); + const float mappedMaxPeak(mapper(m_fMaxPeak)); + const float mappedPeakL(mapper(m_fPeakValue_L)); + const float mappedPeakR(mapper(m_fPeakValue_R)); + const float mappedPersistentPeakL(mapper(m_persistentPeak_L)); + const float mappedPersistentPeakR(mapper(m_persistentPeak_R)); + const float mappedUnity(mapper(1.f)); -void Fader::paintDBFSLevels(QPaintEvent * ev, QPainter & painter) -{ - int height = m_back.height(); - int width = m_back.width() / 2; - int center = m_back.width() - width; + painter.save(); - float const maxDB(ampToDbfs(m_fMaxPeak)); - float const minDB(ampToDbfs(m_fMinPeak)); + const QRect baseRect = rect(); - // We will need to divide by the span between min and max several times. It's more - // efficient to calculate the reciprocal once and then to multiply. - float const fullSpanReciprocal = 1 / (maxDB - minDB); + const int height = baseRect.height(); + const int margin = 1; + const int distanceBetweenMeters = 2; - // Draw left levels - float const leftSpan = ampToDbfs(qMax(0.0001, m_fPeakValue_L)) - minDB; - int peak_L = height * leftSpan * fullSpanReciprocal; - QRect drawRectL( 0, height - peak_L, width, peak_L ); // Source and target are identical - painter.drawPixmap(drawRectL, m_leds, drawRectL); - - float const persistentLeftPeakDBFS = ampToDbfs(qMax(0.0001, m_persistentPeak_L)); - int persistentPeak_L = height * (1 - (persistentLeftPeakDBFS - minDB) * fullSpanReciprocal); - // the LED's have a 4px padding and we don't want the peaks - // to draw on the fader background - if( persistentPeak_L <= 4 ) - { - persistentPeak_L = 4; - } - if( persistentLeftPeakDBFS > minDB ) - { - QColor const & peakColor = clips(m_persistentPeak_L) ? peakRed() : - persistentLeftPeakDBFS >= -6 ? peakYellow() : peakGreen(); - painter.fillRect( QRect( 2, persistentPeak_L, 7, 1 ), peakColor ); - } + const int numberOfMeters = 2; + // Compute the width of a single meter by removing the margins and the space between meters + const int leftAndRightMargin = 2 * margin; + const int pixelsBetweenAllMeters = distanceBetweenMeters * (numberOfMeters - 1); + const int remainingPixelsForMeters = baseRect.width() - leftAndRightMargin - pixelsBetweenAllMeters; + const int meterWidth = remainingPixelsForMeters / numberOfMeters; - // Draw right levels - float const rightSpan = ampToDbfs(qMax(0.0001, m_fPeakValue_R)) - minDB; - int peak_R = height * rightSpan * fullSpanReciprocal; - QRect const drawRectR( center, height - peak_R, width, peak_R ); // Source and target are identical - painter.drawPixmap(drawRectR, m_leds, drawRectR); - - float const persistentRightPeakDBFS = ampToDbfs(qMax(0.0001, m_persistentPeak_R)); - int persistentPeak_R = height * (1 - (persistentRightPeakDBFS - minDB) * fullSpanReciprocal); - // the LED's have a 4px padding and we don't want the peaks - // to draw on the fader background - if( persistentPeak_R <= 4 ) - { - persistentPeak_R = 4; - } - if( persistentRightPeakDBFS > minDB ) - { - QColor const & peakColor = clips(m_persistentPeak_R) ? peakRed() : - persistentRightPeakDBFS >= -6 ? peakYellow() : peakGreen(); - painter.fillRect( QRect( 14, persistentPeak_R, 7, 1 ), peakColor ); - } -} + QRect leftMeterOutlineRect(margin, margin, meterWidth, height - 2 * margin); + QRect rightMeterOutlineRect(baseRect.width() - margin - meterWidth, margin, meterWidth, height - 2 * margin); -void Fader::paintLinearLevels(QPaintEvent * ev, QPainter & painter) -{ - // peak leds - //float fRange = abs( m_fMaxPeak ) + abs( m_fMinPeak ); + QMargins removedMargins(1, 1, 1, 1); + QRect leftMeterRect = leftMeterOutlineRect.marginsRemoved(removedMargins); + QRect rightMeterRect = rightMeterOutlineRect.marginsRemoved(removedMargins); + + QPainterPath path; + qreal radius = 2; + path.addRoundedRect(leftMeterOutlineRect, radius, radius); + path.addRoundedRect(rightMeterOutlineRect, radius, radius); + painter.fillPath(path, Qt::black); - int height = m_back.height(); - int width = m_back.width() / 2; - int center = m_back.width() - width; + // Now clip everything to the paths of the meters + painter.setClipPath(path); - int peak_L = calculateDisplayPeak( m_fPeakValue_L - m_fMinPeak ); - int persistentPeak_L = qMax( 3, calculateDisplayPeak( m_persistentPeak_L - m_fMinPeak ) ); - painter.drawPixmap(QRect(0, peak_L, width, height - peak_L), m_leds, QRect(0, peak_L, width, height - peak_L)); + // This linear map performs the following mapping: + // Value (dbFS or linear) -> window coordinates of the widget + // It is for example used to determine the height of peaks, markers and to define the gradient for the levels + const LinearMap valuesToWindowCoordinates(mappedMaxPeak, leftMeterRect.y(), mappedMinPeak, leftMeterRect.y() + leftMeterRect.height()); - if( m_persistentPeak_L > 0.05 ) + // This lambda takes a value (in dbFS or linear) and a rectangle and computes a rectangle + // that represent the value within the rectangle. It is for example used to compute the unity indicators. + const auto computeLevelMarkerRect = [&valuesToWindowCoordinates](const QRect& rect, float peak) -> QRect { - painter.fillRect( QRect( 2, persistentPeak_L, 7, 1 ), ( m_persistentPeak_L < 1.0 ) - ? peakGreen() - : peakRed() ); - } + return QRect(rect.x(), valuesToWindowCoordinates.map(peak), rect.width(), 1); + }; - int peak_R = calculateDisplayPeak( m_fPeakValue_R - m_fMinPeak ); - int persistentPeak_R = qMax( 3, calculateDisplayPeak( m_persistentPeak_R - m_fMinPeak ) ); - painter.drawPixmap(QRect(center, peak_R, width, height - peak_R), m_leds, QRect(center, peak_R, width, height - peak_R)); + // This lambda takes a peak value (in dbFS or linear) and a rectangle and computes a rectangle + // that represent the peak value within the rectangle. It's used to compute the peak indicators + // which "dance" on top of the level meters. + const auto computePeakRect = [&valuesToWindowCoordinates](const QRect& rect, float peak) -> QRect + { + return QRect(rect.x(), valuesToWindowCoordinates.map(peak), rect.width(), 1); + }; - if( m_persistentPeak_R > 0.05 ) + // This lambda takes a peak value (in dbFS or linear) and a rectangle and returns an adjusted copy of the + // rectangle that represents the peak value. It is used to compute the level meters themselves. + const auto computeLevelRect = [&valuesToWindowCoordinates](const QRect& rect, float peak) -> QRect { - painter.fillRect( QRect( 14, persistentPeak_R, 7, 1 ), ( m_persistentPeak_R < 1.0 ) - ? peakGreen() - : peakRed() ); - } -} + QRect result(rect); + result.setTop(valuesToWindowCoordinates.map(peak)); + return result; + }; -QColor const & Fader::peakGreen() const -{ - return m_peakGreen; -} + // Draw left and right level markers for the unity lines (0 dbFS, 1.0 amplitude) + if (getRenderUnityLine()) + { + const auto unityRectL = computeLevelMarkerRect(leftMeterRect, mappedUnity); + painter.fillRect(unityRectL, m_unityMarker); -QColor const & Fader::peakRed() const -{ - return m_peakRed; -} + const auto unityRectR = computeLevelMarkerRect(rightMeterRect, mappedUnity); + painter.fillRect(unityRectR, m_unityMarker); + } -QColor const & Fader::peakYellow() const -{ - return m_peakYellow; -} + // These values define where the gradient changes values, i.e. the ranges + // for clipping, warning and ok. + // Please ensure that "clip starts" is the maximum value and that "ok ends" + // is the minimum value and that all other values lie inbetween. Otherwise + // there will be warnings when the gradient is defined. + const float mappedClipStarts(mapper(dbfsToAmp(0.f))); + const float mappedWarnEnd(mapper(dbfsToAmp(-0.01))); + const float mappedWarnStart(mapper(dbfsToAmp(-6.f))); + const float mappedOkEnd(mapper(dbfsToAmp(-12.f))); + + // Prepare the gradient for the meters + // + // The idea is the following. We want to be able to render arbitrary ranges of min and max values. + // Therefore we first compute the start and end point of the gradient in window coordinates. + // The gradient is assumed to start with the clip color and to end with the ok color with warning values in between. + // We know the min and max peaks that map to a rectangle where we draw the levels. We can use the values of the min and max peaks + // as well as the Y-coordinates of the rectangle to compute a map which will give us the coordinates of the value where the clipping + // starts and where the ok area end. These coordinates are used to initialize the gradient. Please note that the gradient might thus + // extend the rectangle into which we paint. + float clipStartYCoord = valuesToWindowCoordinates.map(mappedClipStarts); + float okEndYCoord = valuesToWindowCoordinates.map(mappedOkEnd); + + QLinearGradient linearGrad(0, clipStartYCoord, 0, okEndYCoord); + + // We already know for the gradient that the clip color will be at 0 and that the ok color is at 1. + // What's left to do is to map the inbetween values into the interval [0,1]. + const LinearMap mapBetweenClipAndOk(mappedClipStarts, 0.f, mappedOkEnd, 1.f); + + linearGrad.setColorAt(0, m_peakClip); + linearGrad.setColorAt(mapBetweenClipAndOk.map(mappedWarnEnd), m_peakWarn); + linearGrad.setColorAt(mapBetweenClipAndOk.map(mappedWarnStart), m_peakWarn); + linearGrad.setColorAt(1, m_peakOk); -void Fader::setPeakGreen( const QColor & c ) -{ - m_peakGreen = c; -} + // Draw left levels + if (mappedPeakL > mappedMinPeak) + { + QPainterPath leftMeterPath; + leftMeterPath.addRoundedRect(computeLevelRect(leftMeterRect, mappedPeakL), radius, radius); + painter.fillPath(leftMeterPath, linearGrad); + } -void Fader::setPeakRed( const QColor & c ) -{ - m_peakRed = c; -} + // Draw left peaks + if (mappedPersistentPeakL > mappedMinPeak) + { + const auto peakRectL = computePeakRect(leftMeterRect, mappedPersistentPeakL); + painter.fillRect(peakRectL, linearGrad); + } -void Fader::setPeakYellow( const QColor & c ) -{ - m_peakYellow = c; -} + // Draw right levels + if (mappedPeakR > mappedMinPeak) + { + QPainterPath rightMeterPath; + rightMeterPath.addRoundedRect(computeLevelRect(rightMeterRect, mappedPeakR), radius, radius); + painter.fillPath(rightMeterPath, linearGrad); + } + // Draw right peaks + if (mappedPersistentPeakR > mappedMinPeak) + { + const auto peakRectR = computePeakRect(rightMeterRect, mappedPersistentPeakR); + painter.fillRect(peakRectR, linearGrad); + } + + painter.restore(); +} } // namespace lmms::gui