diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2c2e8dd73..74134aabd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -72,11 +72,11 @@ jobs: arch: [ x86_64, arm64 ] include: - arch: x86_64 - os: macos-12 - xcode: "13.1" + os: macos-13 + xcode: "15.2" - arch: arm64 os: macos-14 - xcode: "14.3.1" + xcode: "15.4" name: macos-${{ matrix.arch }} runs-on: ${{ matrix.os }} env: diff --git a/include/AudioEngine.h b/include/AudioEngine.h index f6d8692b5..b22830221 100644 --- a/include/AudioEngine.h +++ b/include/AudioEngine.h @@ -33,6 +33,7 @@ #include #include +#include "AudioDevice.h" #include "lmms_basics.h" #include "SampleFrame.h" #include "LocklessList.h" @@ -235,9 +236,20 @@ public: } - sample_rate_t baseSampleRate() const; - sample_rate_t outputSampleRate() const; - sample_rate_t inputSampleRate() const; + sample_rate_t baseSampleRate() const { return m_baseSampleRate; } + + + sample_rate_t outputSampleRate() const + { + return m_audioDev != nullptr ? m_audioDev->sampleRate() : m_baseSampleRate; + } + + + sample_rate_t inputSampleRate() const + { + return m_audioDev != nullptr ? m_audioDev->sampleRate() : m_baseSampleRate; + } + inline float masterGain() const { @@ -361,6 +373,7 @@ private: SampleFrame* m_inputBuffer[2]; f_cnt_t m_inputBufferFrames[2]; f_cnt_t m_inputBufferSize[2]; + sample_rate_t m_baseSampleRate; int m_inputBufferRead; int m_inputBufferWrite; diff --git a/include/MixerChannelView.h b/include/MixerChannelView.h index 8074d4dce..6716aee09 100644 --- a/include/MixerChannelView.h +++ b/include/MixerChannelView.h @@ -1,7 +1,7 @@ /* - * MixerChannelView.h - the mixer channel view + * MixerChannelView.h * - * Copyright (c) 2022 saker + * Copyright (c) 2024 saker * * This file is part of LMMS - https://lmms.io * @@ -22,8 +22,8 @@ * */ -#ifndef MIXER_CHANNEL_VIEW_H -#define MIXER_CHANNEL_VIEW_H +#ifndef LMMS_GUI_MIXER_CHANNEL_VIEW_H +#define LMMS_GUI_MIXER_CHANNEL_VIEW_H #include #include @@ -46,8 +46,6 @@ class MixerChannel; namespace lmms::gui { class PeakIndicator; -constexpr int MIXER_CHANNEL_INNER_BORDER_SIZE = 3; -constexpr int MIXER_CHANNEL_OUTER_BORDER_SIZE = 1; class MixerChannelView : public QWidget { @@ -65,25 +63,24 @@ public: void mouseDoubleClickEvent(QMouseEvent*) override; bool eventFilter(QObject* dist, QEvent* event) override; - int channelIndex() const; + void reset(); + int channelIndex() const { return m_channelIndex; } void setChannelIndex(int index); - QBrush backgroundActive() const; - void setBackgroundActive(const QBrush& c); + QBrush backgroundActive() const { return m_backgroundActive; } + void setBackgroundActive(const QBrush& c) { m_backgroundActive = c; } - QColor strokeOuterActive() const; - void setStrokeOuterActive(const QColor& c); + QColor strokeOuterActive() const { return m_strokeOuterActive; } + void setStrokeOuterActive(const QColor& c) { m_strokeOuterActive = c; } - QColor strokeOuterInactive() const; - void setStrokeOuterInactive(const QColor& c); + QColor strokeOuterInactive() const { return m_strokeOuterInactive; } + void setStrokeOuterInactive(const QColor& c) { m_strokeOuterInactive = c; } - QColor strokeInnerActive() const; - void setStrokeInnerActive(const QColor& c); + QColor strokeInnerActive() const { return m_strokeInnerActive; } + void setStrokeInnerActive(const QColor& c) { m_strokeInnerActive = c; } - QColor strokeInnerInactive() const; - void setStrokeInnerInactive(const QColor& c); - - void reset(); + QColor strokeInnerInactive() const { return m_strokeInnerInactive; } + void setStrokeInnerInactive(const QColor& c) { m_strokeInnerInactive = c; } public slots: void renameChannel(); @@ -135,4 +132,4 @@ private: }; } // namespace lmms::gui -#endif // MIXER_CHANNEL_VIEW_H +#endif // LMMS_GUI_MIXER_CHANNEL_VIEW_H diff --git a/include/PeakController.h b/include/PeakController.h index de9da3b1c..a22257374 100644 --- a/include/PeakController.h +++ b/include/PeakController.h @@ -78,8 +78,7 @@ private: static int m_loadCount; static bool m_buggedFile; - float m_attackCoeff; - float m_decayCoeff; + float m_coeff; bool m_coeffNeedsUpdate; } ; diff --git a/include/RemotePluginBase.h b/include/RemotePluginBase.h index 5214b6f92..bbf14207a 100644 --- a/include/RemotePluginBase.h +++ b/include/RemotePluginBase.h @@ -398,7 +398,7 @@ public: message & addInt( int _i ) { char buf[32]; - sprintf( buf, "%d", _i ); + std::snprintf(buf, 32, "%d", _i); data.emplace_back( buf ); return *this; } @@ -406,7 +406,7 @@ public: message & addFloat( float _f ) { char buf[32]; - sprintf( buf, "%f", _f ); + std::snprintf(buf, 32, "%f", _f); data.emplace_back( buf ); return *this; } diff --git a/include/RemotePluginClient.h b/include/RemotePluginClient.h index 22158f1b8..241896506 100644 --- a/include/RemotePluginClient.h +++ b/include/RemotePluginClient.h @@ -309,7 +309,7 @@ bool RemotePluginClient::processMessage( const message & _m ) default: { char buf[64]; - sprintf( buf, "undefined message: %d\n", (int) _m.id ); + std::snprintf(buf, 64, "undefined message: %d\n", _m.id); debugMessage( buf ); break; } diff --git a/include/TimePos.h b/include/TimePos.h index b86d8eb0f..68f3bd01b 100644 --- a/include/TimePos.h +++ b/include/TimePos.h @@ -26,6 +26,8 @@ #ifndef LMMS_TIME_POS_H #define LMMS_TIME_POS_H +#include +#include #include "lmms_export.h" #include "lmms_basics.h" @@ -51,8 +53,8 @@ class LMMS_EXPORT TimeSig public: TimeSig( int num, int denom ); TimeSig( const MeterModel &model ); - int numerator() const; - int denominator() const; + int numerator() const { return m_num; } + int denominator() const { return m_denom; } private: int m_num; int m_denom; @@ -69,42 +71,72 @@ public: TimePos( const tick_t ticks = 0 ); TimePos quantize(float) const; - TimePos toAbsoluteBar() const; + TimePos toAbsoluteBar() const { return getBar() * s_ticksPerBar; } - TimePos& operator+=( const TimePos& time ); - TimePos& operator-=( const TimePos& time ); + TimePos& operator+=(const TimePos& time) + { + m_ticks += time.m_ticks; + return *this; + } + + TimePos& operator-=(const TimePos& time) + { + m_ticks -= time.m_ticks; + return *this; + } // return the bar, rounded down and 0-based - bar_t getBar() const; + bar_t getBar() const { return m_ticks / s_ticksPerBar; } + // return the bar, rounded up and 0-based - bar_t nextFullBar() const; + bar_t nextFullBar() const { return (m_ticks + (s_ticksPerBar - 1)) / s_ticksPerBar; } - void setTicks( tick_t ticks ); - tick_t getTicks() const; + void setTicks(tick_t ticks) { m_ticks = ticks; } + tick_t getTicks() const { return m_ticks; } - operator int() const; + operator int() const { return m_ticks; } + + tick_t ticksPerBeat(const TimeSig& sig) const { return ticksPerBar(sig) / sig.numerator(); } - tick_t ticksPerBeat( const TimeSig &sig ) const; // Remainder ticks after bar is removed - tick_t getTickWithinBar( const TimeSig &sig ) const; + tick_t getTickWithinBar(const TimeSig& sig) const { return m_ticks % ticksPerBar(sig); } + // Returns the beat position inside the bar, 0-based - tick_t getBeatWithinBar( const TimeSig &sig ) const; + tick_t getBeatWithinBar(const TimeSig& sig) const { return getTickWithinBar(sig) / ticksPerBeat(sig); } + // Remainder ticks after bar and beat are removed - tick_t getTickWithinBeat( const TimeSig &sig ) const; + tick_t getTickWithinBeat(const TimeSig& sig) const { return getTickWithinBar(sig) % ticksPerBeat(sig); } // calculate number of frame that are needed this time - f_cnt_t frames( const float framesPerTick ) const; + f_cnt_t frames(const float framesPerTick) const + { + // Before, step notes used to have negative length. This + // assert is a safeguard against negative length being + // introduced again (now using Note Types instead #5902) + assert(m_ticks >= 0); + return static_cast(m_ticks * framesPerTick); + } - double getTimeInMilliseconds( bpm_t beatsPerMinute ) const; + double getTimeInMilliseconds(bpm_t beatsPerMinute) const { return ticksToMilliseconds(getTicks(), beatsPerMinute); } - static TimePos fromFrames( const f_cnt_t frames, const float framesPerTick ); - static tick_t ticksPerBar(); - static tick_t ticksPerBar( const TimeSig &sig ); - static int stepsPerBar(); - static void setTicksPerBar( tick_t tpt ); - static TimePos stepPosition( int step ); - static double ticksToMilliseconds( tick_t ticks, bpm_t beatsPerMinute ); - static double ticksToMilliseconds( double ticks, bpm_t beatsPerMinute ); + static TimePos fromFrames(const f_cnt_t frames, const float framesPerTick) + { + return TimePos(static_cast(frames / framesPerTick)); + } + + static tick_t ticksPerBar() { return s_ticksPerBar; } + static tick_t ticksPerBar(const TimeSig& sig) { return DefaultTicksPerBar * sig.numerator() / sig.denominator(); } + + static int stepsPerBar() { return std::max(1, ticksPerBar() / DefaultBeatsPerBar); } + static void setTicksPerBar(tick_t ticks) { s_ticksPerBar = ticks; } + static TimePos stepPosition(int step) { return step * ticksPerBar() / stepsPerBar(); } + + static double ticksToMilliseconds(tick_t ticks, bpm_t beatsPerMinute) + { + return ticksToMilliseconds(static_cast(ticks), beatsPerMinute); + } + + static double ticksToMilliseconds(double ticks, bpm_t beatsPerMinute) { return (ticks * 1250) / beatsPerMinute; } private: tick_t m_ticks; diff --git a/plugins/HydrogenImport/CMakeLists.txt b/plugins/HydrogenImport/CMakeLists.txt index 27e8d6a4d..34f4d43ae 100644 --- a/plugins/HydrogenImport/CMakeLists.txt +++ b/plugins/HydrogenImport/CMakeLists.txt @@ -1,4 +1,4 @@ INCLUDE(BuildPlugin) -BUILD_PLUGIN(hydrogenimport HydrogenImport.cpp HydrogenImport.h local_file_mgr.cpp LocalFileMng.h) +BUILD_PLUGIN(hydrogenimport HydrogenImport.cpp HydrogenImport.h LocalFileMng.cpp LocalFileMng.h) diff --git a/plugins/HydrogenImport/HydrogenImport.cpp b/plugins/HydrogenImport/HydrogenImport.cpp index 144a2f5e7..6a81b507d 100644 --- a/plugins/HydrogenImport/HydrogenImport.cpp +++ b/plugins/HydrogenImport/HydrogenImport.cpp @@ -1,7 +1,8 @@ +#include "HydrogenImport.h" + #include #include "LocalFileMng.h" -#include "HydrogenImport.h" #include "Song.h" #include "Engine.h" #include "Instrument.h" diff --git a/plugins/HydrogenImport/local_file_mgr.cpp b/plugins/HydrogenImport/LocalFileMng.cpp similarity index 97% rename from plugins/HydrogenImport/local_file_mgr.cpp rename to plugins/HydrogenImport/LocalFileMng.cpp index 227440501..c4d11c7e2 100644 --- a/plugins/HydrogenImport/local_file_mgr.cpp +++ b/plugins/HydrogenImport/LocalFileMng.cpp @@ -1,12 +1,11 @@ -#include +#include "LocalFileMng.h" + #include #include #include #include -#include -#include "LocalFileMng.h" namespace lmms { @@ -197,10 +196,7 @@ QDomDocument LocalFileMng::openXmlDocument( const QString& filename ) return QDomDocument(); if( TinyXMLCompat ) { - QString enc = QTextCodec::codecForLocale()->name(); - if( enc == QString("System") ) { - enc = "UTF-8"; - } + const QString enc = "UTF-8"; // unknown encoding, so assume utf-8 and call it a day QByteArray line; QByteArray buf = QString("\n") .arg( enc ) diff --git a/plugins/HydrogenImport/LocalFileMng.h b/plugins/HydrogenImport/LocalFileMng.h index 0aaf7d1c8..1260dbfdd 100644 --- a/plugins/HydrogenImport/LocalFileMng.h +++ b/plugins/HydrogenImport/LocalFileMng.h @@ -14,12 +14,6 @@ namespace lmms class LocalFileMng { public: - LocalFileMng(); - ~LocalFileMng(); - std::vector getallPatternList(){ - return m_allPatternList; - } - static QString readXmlString( QDomNode , const QString& nodeName, const QString& defaultValue, bool bCanBeEmpty = false, bool bShouldExists = true , bool tinyXmlCompatMode = false); static float readXmlFloat( QDomNode , const QString& nodeName, float defaultValue, bool bCanBeEmpty = false, bool bShouldExists = true , bool tinyXmlCompatMode = false); static int readXmlInt( QDomNode , const QString& nodeName, int defaultValue, bool bCanBeEmpty = false, bool bShouldExists = true , bool tinyXmlCompatMode = false); @@ -27,7 +21,6 @@ public: static void convertFromTinyXMLString( QByteArray* str ); static bool checkTinyXMLCompatMode( const QString& filename ); static QDomDocument openXmlDocument( const QString& filename ); - std::vector m_allPatternList; }; diff --git a/plugins/PeakControllerEffect/PeakControllerEffect.cpp b/plugins/PeakControllerEffect/PeakControllerEffect.cpp index 394a80efd..b6d053257 100644 --- a/plugins/PeakControllerEffect/PeakControllerEffect.cpp +++ b/plugins/PeakControllerEffect/PeakControllerEffect.cpp @@ -132,8 +132,18 @@ Effect::ProcessStatus PeakControllerEffect::processImpl(SampleFrame* buf, const float curRMS = sqrt_neg(sum / frames); const float tres = c.m_tresholdModel.value(); const float amount = c.m_amountModel.value() * c.m_amountMultModel.value(); + const float attack = 1.0f - c.m_attackModel.value(); + const float decay = 1.0f - c.m_decayModel.value(); + curRMS = qAbs( curRMS ) < tres ? 0.0f : curRMS; - m_lastSample = qBound( 0.0f, c.m_baseModel.value() + amount * curRMS, 1.0f ); + float target = c.m_baseModel.value() + amount * curRMS; + // Use decay when the volume is decreasing, attack otherwise. + // Since direction can change as often as every sampleBuffer, it's difficult + // to witness attack/decay working in isolation unless using large buffer sizes. + const float t = target < m_lastSample ? decay : attack; + // Set m_lastSample to the interpolation between itself and target. + // When t is 1.0, m_lastSample snaps to target. When t is 0.0, m_lastSample shouldn't change. + m_lastSample = std::clamp(m_lastSample + t * (target - m_lastSample), 0.0f, 1.0f); return ProcessStatus::Continue; } diff --git a/plugins/Vestige/Vestige.cpp b/plugins/Vestige/Vestige.cpp index 5a7d4afa0..05716008e 100644 --- a/plugins/Vestige/Vestige.cpp +++ b/plugins/Vestige/Vestige.cpp @@ -226,7 +226,7 @@ void VestigeInstrument::loadSettings( const QDomElement & _this ) QStringList s_dumpValues; for( int i = 0; i < paramCount; i++ ) { - sprintf(paramStr.data(), "param%d", i); + std::snprintf(paramStr.data(), paramStr.size(), "param%d", i); s_dumpValues = dump[paramStr.data()].split(":"); knobFModel[i] = new FloatModel( 0.0f, 0.0f, 1.0f, 0.01f, this, QString::number(i) ); @@ -290,7 +290,7 @@ void VestigeInstrument::saveSettings( QDomDocument & _doc, QDomElement & _this ) for( int i = 0; i < paramCount; i++ ) { if (knobFModel[i]->isAutomated() || knobFModel[i]->controllerConnection()) { - sprintf(paramStr.data(), "param%d", i); + std::snprintf(paramStr.data(), paramStr.size(), "param%d", i); knobFModel[i]->saveSettings(_doc, _this, paramStr.data()); } @@ -987,7 +987,7 @@ ManageVestigeInstrumentView::ManageVestigeInstrumentView( Instrument * _instrume for( int i = 0; i < m_vi->paramCount; i++ ) { - sprintf(paramStr.data(), "param%d", i); + std::snprintf(paramStr.data(), paramStr.size(), "param%d", i); s_dumpValues = dump[paramStr.data()].split(":"); vstKnobs[ i ] = new CustomTextKnob( KnobType::Bright26, this, s_dumpValues.at( 1 ) ); @@ -996,7 +996,7 @@ ManageVestigeInstrumentView::ManageVestigeInstrumentView( Instrument * _instrume if( !hasKnobModel ) { - sprintf(paramStr.data(), "%d", i); + std::snprintf(paramStr.data(), paramStr.size(), "%d", i); m_vi->knobFModel[i] = new FloatModel(LocaleHelper::toFloat(s_dumpValues.at(2)), 0.0f, 1.0f, 0.01f, castModel(), paramStr.data()); } @@ -1059,8 +1059,8 @@ void ManageVestigeInstrumentView::syncPlugin( void ) // those auto-setted values are not jurnaled, tracked for undo / redo if( !( m_vi->knobFModel[ i ]->isAutomated() || m_vi->knobFModel[ i ]->controllerConnection() ) ) { - sprintf(paramStr.data(), "param%d", i); - s_dumpValues = dump[paramStr.data()].split(":"); + std::snprintf(paramStr.data(), paramStr.size(), "param%d", i); + s_dumpValues = dump[paramStr.data()].split(":"); 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/VstEffect/VstEffectControls.cpp b/plugins/VstEffect/VstEffectControls.cpp index c9eb49234..ef8bd38d0 100644 --- a/plugins/VstEffect/VstEffectControls.cpp +++ b/plugins/VstEffect/VstEffectControls.cpp @@ -87,7 +87,7 @@ void VstEffectControls::loadSettings( const QDomElement & _this ) QStringList s_dumpValues; for( int i = 0; i < paramCount; i++ ) { - sprintf(paramStr.data(), "param%d", i); + std::snprintf(paramStr.data(), paramStr.size(), "param%d", i); s_dumpValues = dump[paramStr.data()].split(":"); knobFModel[i] = new FloatModel( 0.0f, 0.0f, 1.0f, 0.01f, this, QString::number(i) ); @@ -137,7 +137,7 @@ void VstEffectControls::saveSettings( QDomDocument & _doc, QDomElement & _this ) for( int i = 0; i < paramCount; i++ ) { if (knobFModel[i]->isAutomated() || knobFModel[i]->controllerConnection()) { - sprintf(paramStr.data(), "param%d", i); + std::snprintf(paramStr.data(), paramStr.size(), "param%d", i); knobFModel[i]->saveSettings(_doc, _this, paramStr.data()); } } @@ -386,7 +386,7 @@ ManageVSTEffectView::ManageVSTEffectView( VstEffect * _eff, VstEffectControls * for( int i = 0; i < m_vi->paramCount; i++ ) { - sprintf(paramStr.data(), "param%d", i); + std::snprintf(paramStr.data(), paramStr.size(), "param%d", i); s_dumpValues = dump[paramStr.data()].split(":"); vstKnobs[ i ] = new CustomTextKnob( KnobType::Bright26, widget, s_dumpValues.at( 1 ) ); @@ -395,7 +395,7 @@ ManageVSTEffectView::ManageVSTEffectView( VstEffect * _eff, VstEffectControls * if( !hasKnobModel ) { - sprintf(paramStr.data(), "%d", i); + std::snprintf(paramStr.data(), paramStr.size(), "%d", i); m_vi->knobFModel[i] = new FloatModel(LocaleHelper::toFloat(s_dumpValues.at(2)), 0.0f, 1.0f, 0.01f, _eff, paramStr.data()); } @@ -460,7 +460,7 @@ void ManageVSTEffectView::syncPlugin() if( !( m_vi2->knobFModel[ i ]->isAutomated() || m_vi2->knobFModel[ i ]->controllerConnection() ) ) { - sprintf(paramStr.data(), "param%d", i); + std::snprintf(paramStr.data(), paramStr.size(), "param%d", i); s_dumpValues = dump[paramStr.data()].split(":"); float f_value = LocaleHelper::toFloat(s_dumpValues.at(2)); m_vi2->knobFModel[ i ]->setAutomatedValue( f_value ); diff --git a/src/core/AudioEngine.cpp b/src/core/AudioEngine.cpp index 0da65f426..435fa38fa 100644 --- a/src/core/AudioEngine.cpp +++ b/src/core/AudioEngine.cpp @@ -74,6 +74,7 @@ static thread_local bool s_renderingThread = false; AudioEngine::AudioEngine( bool renderOnly ) : m_renderOnly( renderOnly ), m_framesPerPeriod( DEFAULT_BUFFER_SIZE ), + m_baseSampleRate(std::max(ConfigManager::inst()->value("audioengine", "samplerate").toInt(), 44100)), m_inputBufferRead( 0 ), m_inputBufferWrite( 1 ), m_outputBufferRead(nullptr), @@ -241,34 +242,6 @@ void AudioEngine::stopProcessing() -sample_rate_t AudioEngine::baseSampleRate() const -{ - sample_rate_t sr = ConfigManager::inst()->value( "audioengine", "samplerate" ).toInt(); - if( sr < 44100 ) - { - sr = 44100; - } - return sr; -} - - - - -sample_rate_t AudioEngine::outputSampleRate() const -{ - return m_audioDev != nullptr ? m_audioDev->sampleRate() : - baseSampleRate(); -} - - - - -sample_rate_t AudioEngine::inputSampleRate() const -{ - return m_audioDev != nullptr ? m_audioDev->sampleRate() : - baseSampleRate(); -} - bool AudioEngine::criticalXRuns() const { return cpuLoad() >= 99 && Engine::getSong()->isExporting() == false; diff --git a/src/core/ComboBoxModel.cpp b/src/core/ComboBoxModel.cpp index f1b1c6b2e..80d1027de 100644 --- a/src/core/ComboBoxModel.cpp +++ b/src/core/ComboBoxModel.cpp @@ -29,20 +29,17 @@ namespace lmms { -using std::unique_ptr; -using std::move; - -void ComboBoxModel::addItem( QString item, unique_ptr loader ) +void ComboBoxModel::addItem(QString item, std::unique_ptr loader) { - m_items.emplace_back( move(item), move(loader) ); + m_items.emplace_back(std::move(item), std::move(loader)); setRange( 0, m_items.size() - 1 ); } -void ComboBoxModel::replaceItem(std::size_t index, QString item, unique_ptr loader) +void ComboBoxModel::replaceItem(std::size_t index, QString item, std::unique_ptr loader) { assert(index < m_items.size()); - m_items[index] = Item(move(item), move(loader)); + m_items[index] = Item(std::move(item), std::move(loader)); emit propertiesChanged(); } diff --git a/src/core/Keymap.cpp b/src/core/Keymap.cpp index 6683919fe..be422991a 100644 --- a/src/core/Keymap.cpp +++ b/src/core/Keymap.cpp @@ -147,7 +147,7 @@ void Keymap::loadSettings(const QDomElement &element) QDomNode node = element.firstChild(); m_map.clear(); - for (int i = 0; !node.isNull(); i++) + while (!node.isNull()) { m_map.push_back(node.toElement().attribute("value").toInt()); node = node.nextSibling(); diff --git a/src/core/PeakController.cpp b/src/core/PeakController.cpp index 1c38cf4cb..1b819982a 100644 --- a/src/core/PeakController.cpp +++ b/src/core/PeakController.cpp @@ -80,9 +80,7 @@ void PeakController::updateValueBuffer() { if( m_coeffNeedsUpdate ) { - const float ratio = 44100.0f / Engine::audioEngine()->outputSampleRate(); - m_attackCoeff = 1.0f - powf( 2.0f, -0.3f * ( 1.0f - m_peakEffect->attackModel()->value() ) * ratio ); - m_decayCoeff = 1.0f - powf( 2.0f, -0.3f * ( 1.0f - m_peakEffect->decayModel()->value() ) * ratio ); + m_coeff = 100.0f / Engine::audioEngine()->outputSampleRate(); m_coeffNeedsUpdate = false; } @@ -97,14 +95,7 @@ void PeakController::updateValueBuffer() for( f_cnt_t f = 0; f < frames; ++f ) { const float diff = ( targetSample - m_currentSample ); - if( m_currentSample < targetSample ) // going up... - { - m_currentSample += diff * m_attackCoeff; - } - else if( m_currentSample > targetSample ) // going down - { - m_currentSample += diff * m_decayCoeff; - } + m_currentSample += diff * m_coeff; values[f] = m_currentSample; } } diff --git a/src/core/ProjectRenderer.cpp b/src/core/ProjectRenderer.cpp index e5410e6f2..c56c34068 100644 --- a/src/core/ProjectRenderer.cpp +++ b/src/core/ProjectRenderer.cpp @@ -210,7 +210,7 @@ void ProjectRenderer::abortProcessing() void ProjectRenderer::updateConsoleProgress() { - const int cols = 50; + constexpr int cols = 50; static int rot = 0; auto buf = std::array{}; auto prog = std::array{}; @@ -221,9 +221,9 @@ void ProjectRenderer::updateConsoleProgress() } prog[cols] = 0; - const auto activity = (const char*)"|/-\\"; + const auto activity = "|/-\\"; std::fill(buf.begin(), buf.end(), 0); - sprintf(buf.data(), "\r|%s| %3d%% %c ", prog.data(), m_progress, + std::snprintf(buf.data(), buf.size(), "\r|%s| %3d%% %c ", prog.data(), m_progress, activity[rot] ); rot = ( rot+1 ) % 4; diff --git a/src/core/Scale.cpp b/src/core/Scale.cpp index df0effe6b..93279f2bc 100644 --- a/src/core/Scale.cpp +++ b/src/core/Scale.cpp @@ -116,7 +116,7 @@ void Scale::loadSettings(const QDomElement &element) QDomNode node = element.firstChild(); m_intervals.clear(); - for (int i = 0; !node.isNull(); i++) + while (!node.isNull()) { Interval temp; temp.restoreState(node.toElement()); diff --git a/src/core/TimePos.cpp b/src/core/TimePos.cpp index 09c1019bc..6e5e034fd 100644 --- a/src/core/TimePos.cpp +++ b/src/core/TimePos.cpp @@ -43,20 +43,6 @@ TimeSig::TimeSig( const MeterModel &model ) : { } - -int TimeSig::numerator() const -{ - return m_num; -} - -int TimeSig::denominator() const -{ - return m_denom; -} - - - - TimePos::TimePos( const bar_t bar, const tick_t ticks ) : m_ticks( bar * s_ticksPerBar + ticks ) { @@ -86,140 +72,4 @@ TimePos TimePos::quantize(float bars) const return (lowPos + snapUp) * interval; } - -TimePos TimePos::toAbsoluteBar() const -{ - return getBar() * s_ticksPerBar; -} - - -TimePos& TimePos::operator+=( const TimePos& time ) -{ - m_ticks += time.m_ticks; - return *this; -} - - -TimePos& TimePos::operator-=( const TimePos& time ) -{ - m_ticks -= time.m_ticks; - return *this; -} - - -bar_t TimePos::getBar() const -{ - return m_ticks / s_ticksPerBar; -} - - -bar_t TimePos::nextFullBar() const -{ - return ( m_ticks + ( s_ticksPerBar - 1 ) ) / s_ticksPerBar; -} - - -void TimePos::setTicks( tick_t ticks ) -{ - m_ticks = ticks; -} - - -tick_t TimePos::getTicks() const -{ - return m_ticks; -} - - -TimePos::operator int() const -{ - return m_ticks; -} - - -tick_t TimePos::ticksPerBeat( const TimeSig &sig ) const -{ - // (number of ticks per bar) divided by (number of beats per bar) - return ticksPerBar(sig) / sig.numerator(); -} - - -tick_t TimePos::getTickWithinBar( const TimeSig &sig ) const -{ - return m_ticks % ticksPerBar( sig ); -} - -tick_t TimePos::getBeatWithinBar( const TimeSig &sig ) const -{ - return getTickWithinBar( sig ) / ticksPerBeat( sig ); -} - -tick_t TimePos::getTickWithinBeat( const TimeSig &sig ) const -{ - return getTickWithinBar( sig ) % ticksPerBeat( sig ); -} - - -f_cnt_t TimePos::frames( const float framesPerTick ) const -{ - // Before, step notes used to have negative length. This - // assert is a safeguard against negative length being - // introduced again (now using Note Types instead #5902) - assert(m_ticks >= 0); - return static_cast(m_ticks * framesPerTick); -} - -double TimePos::getTimeInMilliseconds( bpm_t beatsPerMinute ) const -{ - return ticksToMilliseconds( getTicks(), beatsPerMinute ); -} - -TimePos TimePos::fromFrames( const f_cnt_t frames, const float framesPerTick ) -{ - return TimePos( static_cast( frames / framesPerTick ) ); -} - - -tick_t TimePos::ticksPerBar() -{ - return s_ticksPerBar; -} - - -tick_t TimePos::ticksPerBar( const TimeSig &sig ) -{ - return DefaultTicksPerBar * sig.numerator() / sig.denominator(); -} - - -int TimePos::stepsPerBar() -{ - int steps = ticksPerBar() / DefaultBeatsPerBar; - return std::max(1, steps); -} - - -void TimePos::setTicksPerBar( tick_t tpb ) -{ - s_ticksPerBar = tpb; -} - - -TimePos TimePos::stepPosition( int step ) -{ - return step * ticksPerBar() / stepsPerBar(); -} - -double TimePos::ticksToMilliseconds( tick_t ticks, bpm_t beatsPerMinute ) -{ - return TimePos::ticksToMilliseconds( static_cast(ticks), beatsPerMinute ); -} - -double TimePos::ticksToMilliseconds(double ticks, bpm_t beatsPerMinute) -{ - // 60 * 1000 / 48 = 1250 - return ( ticks * 1250 ) / beatsPerMinute; -} - - } // namespace lmms diff --git a/src/core/midi/MidiApple.cpp b/src/core/midi/MidiApple.cpp index 444f093e5..14930ed84 100644 --- a/src/core/midi/MidiApple.cpp +++ b/src/core/midi/MidiApple.cpp @@ -159,7 +159,7 @@ void MidiApple::removePort( MidiPort* port ) QString MidiApple::sourcePortName( const MidiEvent& event ) const { - qDebug("sourcePortName return '%s'?\n", event.sourcePort()); + qDebug("sourcePortName"); /* if( event.sourcePort() ) { @@ -501,7 +501,7 @@ void MidiApple::openDevices() void MidiApple::openMidiReference( MIDIEndpointRef reference, QString refName, bool isIn ) { char * registeredName = (char*) malloc(refName.length()+1); - sprintf(registeredName, "%s",refName.toLatin1().constData()); + std::snprintf(registeredName, refName.length() + 1, "%s",refName.toLatin1().constData()); qDebug("openMidiReference refName '%s'",refName.toLatin1().constData()); MIDIClientRef mClient = getMidiClientRef(); @@ -623,7 +623,7 @@ char * MidiApple::getFullName(MIDIEndpointRef &endpoint_ref) size_t deviceNameLen = deviceName == nullptr ? 0 : strlen(deviceName); size_t endPointNameLen = endPointName == nullptr ? 0 : strlen(endPointName); char * fullName = (char *)malloc(deviceNameLen + endPointNameLen + 2); - sprintf(fullName, "%s:%s", deviceName,endPointName); + std::snprintf(fullName, deviceNameLen + endPointNameLen + 2, "%s:%s", deviceName,endPointName); if (deviceName != nullptr) { free(deviceName); } if (endPointName != nullptr) { free(endPointName); } return fullName; diff --git a/src/gui/MixerChannelView.cpp b/src/gui/MixerChannelView.cpp index 2228c8508..1432a42cf 100644 --- a/src/gui/MixerChannelView.cpp +++ b/src/gui/MixerChannelView.cpp @@ -186,21 +186,18 @@ void MixerChannelView::contextMenuEvent(QContextMenuEvent*) delete contextMenu; } -void MixerChannelView::paintEvent(QPaintEvent* event) +void MixerChannelView::paintEvent(QPaintEvent*) { + static constexpr auto innerBorderSize = 3; + static constexpr auto outerBorderSize = 1; + const auto channel = mixerChannel(); - const bool muted = channel->m_muteModel.value(); - const auto name = channel->m_name; - const auto elidedName = elideName(name); const auto isActive = m_mixerView->currentMixerChannel() == this; - - if (!m_inRename && m_renameLineEdit->text() != elidedName) { m_renameLineEdit->setText(elidedName); } - const auto width = rect().width(); const auto height = rect().height(); auto painter = QPainter{this}; - if (channel->color().has_value() && !muted) + if (channel->color().has_value() && !channel->m_muteModel.value()) { painter.fillRect(rect(), channel->color()->darker(isActive ? 120 : 150)); } @@ -208,13 +205,11 @@ void MixerChannelView::paintEvent(QPaintEvent* event) // inner border painter.setPen(isActive ? strokeInnerActive() : strokeInnerInactive()); - painter.drawRect(1, 1, width - MIXER_CHANNEL_INNER_BORDER_SIZE, height - MIXER_CHANNEL_INNER_BORDER_SIZE); + painter.drawRect(1, 1, width - innerBorderSize, height - innerBorderSize); // outer border painter.setPen(isActive ? strokeOuterActive() : strokeOuterInactive()); - painter.drawRect(0, 0, width - MIXER_CHANNEL_OUTER_BORDER_SIZE, height - MIXER_CHANNEL_OUTER_BORDER_SIZE); - - QWidget::paintEvent(event); + painter.drawRect(0, 0, width - outerBorderSize, height - outerBorderSize); } void MixerChannelView::mousePressEvent(QMouseEvent*) @@ -227,7 +222,7 @@ void MixerChannelView::mouseDoubleClickEvent(QMouseEvent*) renameChannel(); } -bool MixerChannelView::eventFilter(QObject* dist, QEvent* event) +bool MixerChannelView::eventFilter(QObject*, QEvent* event) { // If we are in a rename, capture the enter/return events and handle them if (event->type() == QEvent::KeyPress) @@ -246,11 +241,6 @@ bool MixerChannelView::eventFilter(QObject* dist, QEvent* event) return false; } -int MixerChannelView::channelIndex() const -{ - return m_channelIndex; -} - void MixerChannelView::setChannelIndex(int index) { MixerChannel* mixerChannel = Engine::mixer()->mixerChannel(index); @@ -259,64 +249,10 @@ void MixerChannelView::setChannelIndex(int index) m_soloButton->setModel(&mixerChannel->m_soloModel); m_effectRackView->setModel(&mixerChannel->m_fxChain); m_channelNumberLcd->setValue(index); + m_renameLineEdit->setText(elideName(mixerChannel->m_name)); m_channelIndex = index; } -QBrush MixerChannelView::backgroundActive() const -{ - return m_backgroundActive; -} - -void MixerChannelView::setBackgroundActive(const QBrush& c) -{ - m_backgroundActive = c; -} - -QColor MixerChannelView::strokeOuterActive() const -{ - return m_strokeOuterActive; -} - -void MixerChannelView::setStrokeOuterActive(const QColor& c) -{ - m_strokeOuterActive = c; -} - -QColor MixerChannelView::strokeOuterInactive() const -{ - return m_strokeOuterInactive; -} - -void MixerChannelView::setStrokeOuterInactive(const QColor& c) -{ - m_strokeOuterInactive = c; -} - -QColor MixerChannelView::strokeInnerActive() const -{ - return m_strokeInnerActive; -} - -void MixerChannelView::setStrokeInnerActive(const QColor& c) -{ - m_strokeInnerActive = c; -} - -QColor MixerChannelView::strokeInnerInactive() const -{ - return m_strokeInnerInactive; -} - -void MixerChannelView::setStrokeInnerInactive(const QColor& c) -{ - m_strokeInnerInactive = c; -} - -void MixerChannelView::reset() -{ - m_peakIndicator->resetPeakToMinusInf(); -} - void MixerChannelView::renameChannel() { m_inRename = true; @@ -459,4 +395,9 @@ MixerChannel* MixerChannelView::mixerChannel() const return Engine::mixer()->mixerChannel(m_channelIndex); } +void MixerChannelView::reset() +{ + m_peakIndicator->resetPeakToMinusInf(); +} + } // namespace lmms::gui diff --git a/src/gui/widgets/Fader.cpp b/src/gui/widgets/Fader.cpp index 9a0da4db4..a647df416 100644 --- a/src/gui/widgets/Fader.cpp +++ b/src/gui/widgets/Fader.cpp @@ -282,20 +282,17 @@ void Fader::paintEvent(QPaintEvent* ev) void Fader::paintLevels(QPaintEvent* ev, QPainter& painter, bool linear) { - std::function mapper = [this](float value) { return ampToDbfs(qMax(0.0001f, value)); }; + const auto mapper = linear + ? +[](float value) -> float { return value; } + : +[](float value) -> float { return ampToDbfs(qMax(0.0001f, value)); }; - if (linear) - { - mapper = [this](float value) { return value; }; - } - - 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)); + 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); painter.save(); @@ -375,10 +372,10 @@ void Fader::paintLevels(QPaintEvent* ev, QPainter& painter, bool linear) // 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.01f))); - const float mappedWarnStart(mapper(dbfsToAmp(-6.f))); - const float mappedOkEnd(mapper(dbfsToAmp(-12.f))); + const float mappedClipStarts = mapper(dbfsToAmp(0.f)); + const float mappedWarnEnd = mapper(dbfsToAmp(-0.01f)); + const float mappedWarnStart = mapper(dbfsToAmp(-6.f)); + const float mappedOkEnd = mapper(dbfsToAmp(-12.f)); // Prepare the gradient for the meters //