From 858033c0c76e9c5212745a158f827c6436b20925 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Tue, 8 Jul 2014 15:56:20 -0400 Subject: [PATCH 1/3] Fix relative VST paths on Windows --- plugins/vestige/vestige.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/vestige/vestige.cpp b/plugins/vestige/vestige.cpp index 8f41b36c9..5723aafde 100644 --- a/plugins/vestige/vestige.cpp +++ b/plugins/vestige/vestige.cpp @@ -170,9 +170,10 @@ void vestigeInstrument::saveSettings( QDomDocument & _doc, QDomElement & _this ) { if( QFileInfo( m_pluginDLL ).isAbsolute() ) { - QString relativePath; - if( !( relativePath = m_pluginDLL.section( configManager:: - inst()->vstDir(), 1, 1 ) ).isEmpty() ) + QString f = QString( m_pluginDLL ).replace( QDir::separator(), '/' ); + QString vd = QString( configManager::inst()->vstDir() ).replace( QDir::separator(), '/' ); + QString relativePath; + if( !( relativePath = f.section( vd, 1, 1 ) ).isEmpty() ) { m_pluginDLL = relativePath; } From 4855634bf4dcea3713aee2d07dc23ed7cd4f9d46 Mon Sep 17 00:00:00 2001 From: Vesa Date: Thu, 10 Jul 2014 14:22:40 +0300 Subject: [PATCH 2/3] ProjectJournal: cap the number of undo states to prevent infinite memory buildup The cap is hardcoded to 100 for now, TODO: make this number configurable (or even better: use a max. memory amount instead of max number of states) --- include/ProjectJournal.h | 8 +++++--- src/core/ProjectJournal.cpp | 7 ++++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/include/ProjectJournal.h b/include/ProjectJournal.h index 011755e45..2de42c724 100644 --- a/include/ProjectJournal.h +++ b/include/ProjectJournal.h @@ -22,8 +22,8 @@ * */ -#ifndef _PROJECT_JOURNAL_H -#define _PROJECT_JOURNAL_H +#ifndef PROJECT_JOURNAL_H +#define PROJECT_JOURNAL_H #include #include @@ -37,6 +37,8 @@ class JournallingObject; class ProjectJournal { public: + static const int MAX_UNDO_STATES; + ProjectJournal(); virtual ~ProjectJournal(); @@ -88,7 +90,7 @@ private: struct CheckPoint { - CheckPoint( jo_id_t initID = 0, const DataFile&initData = DataFile( DataFile::JournalData ) ) : + CheckPoint( jo_id_t initID = 0, const DataFile& initData = DataFile( DataFile::JournalData ) ) : joID( initID ), data( initData ) { diff --git a/src/core/ProjectJournal.cpp b/src/core/ProjectJournal.cpp index 2c5c0d912..08ae8d6e7 100644 --- a/src/core/ProjectJournal.cpp +++ b/src/core/ProjectJournal.cpp @@ -29,6 +29,7 @@ #include "JournallingObject.h" #include "song.h" +const int ProjectJournal::MAX_UNDO_STATES = 100; // TODO: make this configurable in settings ProjectJournal::ProjectJournal() : m_joIDs(), @@ -109,6 +110,10 @@ void ProjectJournal::addJournalCheckPoint( JournallingObject *jo ) jo->saveState( dataFile, dataFile.content() ); m_undoCheckPoints.push( CheckPoint( jo->id(), dataFile ) ); + if( m_undoCheckPoints.size() > MAX_UNDO_STATES ) + { + m_undoCheckPoints.remove( 0, m_undoCheckPoints.size() - MAX_UNDO_STATES ); + } } } @@ -120,7 +125,7 @@ jo_id_t ProjectJournal::allocID( JournallingObject * _obj ) const jo_id_t EO_ID_MAX = (1 << 23)-1; jo_id_t id; while( m_joIDs.contains( id = - static_cast( (jo_id_t)rand()*(jo_id_t)rand() % + static_cast( (jo_id_t)rand()*(jo_id_t)rand() % EO_ID_MAX ) ) ) { } From e06c281132dd72176d4fd22e47104bf6f7177f3b Mon Sep 17 00:00:00 2001 From: Vesa Date: Sun, 13 Jul 2014 22:11:17 +0300 Subject: [PATCH 3/3] Sanitize master output Replace any inf/nan in master output with zero, to prevent corrupted files/audio. --- include/MixHelpers.h | 2 ++ src/core/FxMixer.cpp | 2 +- src/core/MixHelpers.cpp | 23 +++++++++++++++++++++-- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/include/MixHelpers.h b/include/MixHelpers.h index a1ddd3307..8d6b6da8b 100644 --- a/include/MixHelpers.h +++ b/include/MixHelpers.h @@ -39,6 +39,8 @@ void add( sampleFrame* dst, const sampleFrame* src, int frames ); /*! \brief Add samples from src multiplied by coeffSrc to dst */ void addMultiplied( sampleFrame* dst, const sampleFrame* src, float coeffSrc, int frames ); +/*! \brief Same as addMultiplied, but sanitize output (strip out infs/nans) */ +void addSanitizedMultiplied( sampleFrame* dst, const sampleFrame* src, float coeffSrc, int frames ); /*! \brief Add samples from src multiplied by coeffSrcLeft/coeffSrcRight to dst */ void addMultipliedStereo( sampleFrame* dst, const sampleFrame* src, float coeffSrcLeft, float coeffSrcRight, int frames ); diff --git a/src/core/FxMixer.cpp b/src/core/FxMixer.cpp index 34985d9de..98aea9811 100644 --- a/src/core/FxMixer.cpp +++ b/src/core/FxMixer.cpp @@ -506,7 +506,7 @@ void FxMixer::masterMix( sampleFrame * _buf ) //m_sendsMutex.unlock(); const float v = m_fxChannels[0]->m_volumeModel.value(); - MixHelpers::addMultiplied( _buf, m_fxChannels[0]->m_buffer, v, fpp ); + MixHelpers::addSanitizedMultiplied( _buf, m_fxChannels[0]->m_buffer, v, fpp ); m_fxChannels[0]->m_peakLeft *= engine::mixer()->masterGain(); m_fxChannels[0]->m_peakRight *= engine::mixer()->masterGain(); diff --git a/src/core/MixHelpers.cpp b/src/core/MixHelpers.cpp index 76e00cae3..22a781aaf 100644 --- a/src/core/MixHelpers.cpp +++ b/src/core/MixHelpers.cpp @@ -22,8 +22,7 @@ * */ -#include - +#include "lmms_math.h" #include "MixHelpers.h" @@ -106,6 +105,26 @@ void addMultiplied( sampleFrame* dst, const sampleFrame* src, float coeffSrc, in +struct AddSanitizedMultipliedOp +{ + AddSanitizedMultipliedOp( float coeff ) : m_coeff( coeff ) { } + + void operator()( sampleFrame& dst, const sampleFrame& src ) const + { + dst[0] += ( isinff( src[0] ) || isnanf( src[0] ) ) ? 0.0f : src[0] * m_coeff; + dst[1] += ( isinff( src[1] ) || isnanf( src[1] ) ) ? 0.0f : src[1] * m_coeff; + } + + const float m_coeff; +}; + +void addSanitizedMultiplied( sampleFrame* dst, const sampleFrame* src, float coeffSrc, int frames ) +{ + run<>( dst, src, frames, AddSanitizedMultipliedOp(coeffSrc) ); +} + + + struct AddMultipliedStereoOp { AddMultipliedStereoOp( float coeffLeft, float coeffRight )