diff --git a/include/SampleBuffer.h b/include/SampleBuffer.h index eeda62991..b9e147978 100644 --- a/include/SampleBuffer.h +++ b/include/SampleBuffer.h @@ -222,23 +222,13 @@ public: inline sample_t userWaveSample( const float _sample ) const { - // Precise implementation -// const float frame = fraction( _sample ) * m_frames; -// const f_cnt_t f1 = static_cast( frame ); -// const f_cnt_t f2 = ( f1 + 1 ) % m_frames; -// sample_t waveSample = linearInterpolate( m_data[f1][0], -// m_data[f2][0], -// fraction( frame ) ); -// return waveSample; - - // Fast implementation const float frame = _sample * m_frames; f_cnt_t f1 = static_cast( frame ) % m_frames; if( f1 < 0 ) { f1 += m_frames; } - return m_data[f1][0]; + return linearInterpolate( m_data[f1][0], m_data[ (f1 + 1) % m_frames ][0], fraction( frame ) ); } static QString tryToMakeRelative( const QString & _file ); diff --git a/include/interpolation.h b/include/interpolation.h index 8b8fe91ea..43c50e102 100644 --- a/include/interpolation.h +++ b/include/interpolation.h @@ -80,7 +80,8 @@ inline float cubicInterpolate( float v0, float v1, float v2, float v3, float x ) inline float cosinusInterpolate( float v0, float v1, float x ) { float f = cosf( x * ( F_PI_2 ) ); - return( v0*f + v1*( 1.0f-f ) ); + return( v1 - f * (v1-v0) ); +// return( v0*f + v1*( 1.0f-f ) ); } diff --git a/plugins/bit_invader/bit_invader.cpp b/plugins/bit_invader/bit_invader.cpp index 852115afb..682f470a6 100644 --- a/plugins/bit_invader/bit_invader.cpp +++ b/plugins/bit_invader/bit_invader.cpp @@ -37,6 +37,7 @@ #include "templates.h" #include "tooltip.h" #include "song.h" +#include "interpolation.h" #include "embed.cpp" @@ -108,9 +109,9 @@ sample_t bSynth::nextStringSample() } // Nachkommaanteil - float frac = sample_realindex - static_cast(sample_realindex); + const float frac = fraction( sample_realindex ); - sample = sample_shape[a]*(1-frac) + sample_shape[b]*(frac); + sample = linearInterpolate( sample_shape[a], sample_shape[b], frac ); } else { // No interpolation diff --git a/plugins/dynamics_processor/dynamics_processor.cpp b/plugins/dynamics_processor/dynamics_processor.cpp index e5bea78d8..c3eb4eb35 100644 --- a/plugins/dynamics_processor/dynamics_processor.cpp +++ b/plugins/dynamics_processor/dynamics_processor.cpp @@ -25,7 +25,9 @@ #include "dynamics_processor.h" -#include +#include "lmms_math.h" +#include "interpolation.h" + #include "embed.cpp" #ifdef LMMS_BUILD_WIN32 @@ -107,8 +109,7 @@ bool dynProcEffect::processAudioBuffer( sampleFrame * _buf, // variables for effect int i = 0; - float lookup; - float frac; + float sm_peak[2] = { 0.0f, 0.0f }; float gain; @@ -182,22 +183,20 @@ bool dynProcEffect::processAudioBuffer( sampleFrame * _buf, for ( i=0; i <= 1; i++ ) { - if( sm_peak[i] != 0 ) + const int lookup = static_cast( sm_peak[i] * 200.0f ); + const float frac = fraction( sm_peak[i] * 200.0f ); + + if( sm_peak[i] > 0 ) { - lookup = sm_peak[i] * 200.0f; - if ( lookup < 1 ) { - frac = lookup - truncf(lookup); gain = frac * m_dpControls.m_wavegraphModel.samples()[0]; } else if ( lookup < 200 ) { - frac = lookup - truncf(lookup); - gain = - (( (1.0f-frac) * m_dpControls.m_wavegraphModel.samples()[ (int)truncf(lookup) - 1 ] ) + - ( frac * m_dpControls.m_wavegraphModel.samples()[ (int)truncf(lookup) ] )); + gain = linearInterpolate( m_dpControls.m_wavegraphModel.samples()[ lookup - 1 ], + m_dpControls.m_wavegraphModel.samples()[ lookup ], frac ); } else { @@ -206,8 +205,6 @@ bool dynProcEffect::processAudioBuffer( sampleFrame * _buf, s[i] *= ( gain / sm_peak[i] ); } - else { s[i] = 0.0f; } - } // apply output gain diff --git a/plugins/monstro/Monstro.cpp b/plugins/monstro/Monstro.cpp index 900fb4b5d..0de0e5c2a 100644 --- a/plugins/monstro/Monstro.cpp +++ b/plugins/monstro/Monstro.cpp @@ -33,6 +33,7 @@ #include "tooltip.h" #include "song.h" #include "lmms_math.h" +#include "interpolation.h" #include "embed.cpp" @@ -417,8 +418,8 @@ void MonstroSynth::renderOutput( fpp_t _frames, sampleFrame * _buf ) float sub = o3sub; modulateabs( sub, o3s ) - sample_t O3L = interpolate( O3AL, O3BL, sub ); - sample_t O3R = interpolate( O3AR, O3BR, sub ); + sample_t O3L = linearInterpolate( O3AL, O3BL, sub ); + sample_t O3R = linearInterpolate( O3AR, O3BR, sub ); // modulate volume O3L *= o3lv; diff --git a/plugins/monstro/Monstro.h b/plugins/monstro/Monstro.h index b86525ad0..7b4fe61a2 100644 --- a/plugins/monstro/Monstro.h +++ b/plugins/monstro/Monstro.h @@ -196,11 +196,10 @@ private: void renderModulators( fpp_t _frames ); // linear interpolation - inline sample_t interpolate( sample_t s1, sample_t s2, float x ) +/* inline sample_t interpolate( sample_t s1, sample_t s2, float x ) { return s1 + ( s2 - s1 ) * x; - } - + }*/ // using interpolation.h from now on inline sample_t calcSlope( sample_t _s, float _slope ) { diff --git a/plugins/watsyn/Watsyn.cpp b/plugins/watsyn/Watsyn.cpp index 3b7c93265..ab1393aeb 100644 --- a/plugins/watsyn/Watsyn.cpp +++ b/plugins/watsyn/Watsyn.cpp @@ -31,6 +31,7 @@ #include "tooltip.h" #include "song.h" #include "lmms_math.h" +#include "interpolation.h" #include "embed.cpp" @@ -132,10 +133,10 @@ void WatsynObject::renderOutput( fpp_t _frames ) if( A1_rphase < 0 ) A1_rphase += WAVELEN; } // A1 - sample_t A1_L = interpolate( m_A1wave[ static_cast( A1_lphase ) ], + sample_t A1_L = linearInterpolate( m_A1wave[ static_cast( A1_lphase ) ], m_A1wave[ static_cast( A1_lphase + 1 ) % WAVELEN ], fraction( A1_lphase ) ) * m_parent->m_lvol[A1_OSC]; - sample_t A1_R = interpolate( m_A1wave[ static_cast( A1_rphase ) ], + sample_t A1_R = linearInterpolate( m_A1wave[ static_cast( A1_rphase ) ], m_A1wave[ static_cast( A1_rphase + 1 ) % WAVELEN ], fraction( A1_rphase ) ) * m_parent->m_rvol[A1_OSC]; @@ -168,10 +169,10 @@ void WatsynObject::renderOutput( fpp_t _frames ) if( B1_rphase < 0 ) B1_rphase += WAVELEN; } // B1 - sample_t B1_L = interpolate( m_B1wave[ static_cast( B1_lphase ) % WAVELEN ], + sample_t B1_L = linearInterpolate( m_B1wave[ static_cast( B1_lphase ) % WAVELEN ], m_B1wave[ static_cast( B1_lphase + 1 ) % WAVELEN ], fraction( B1_lphase ) ) * m_parent->m_lvol[B1_OSC]; - sample_t B1_R = interpolate( m_B1wave[ static_cast( B1_rphase ) % WAVELEN ], + sample_t B1_R = linearInterpolate( m_B1wave[ static_cast( B1_rphase ) % WAVELEN ], m_B1wave[ static_cast( B1_rphase + 1 ) % WAVELEN ], fraction( B1_rphase ) ) * m_parent->m_rvol[B1_OSC]; diff --git a/plugins/watsyn/Watsyn.h b/plugins/watsyn/Watsyn.h index 66a2b4757..37c607d0f 100644 --- a/plugins/watsyn/Watsyn.h +++ b/plugins/watsyn/Watsyn.h @@ -103,10 +103,10 @@ public: private: // linear interpolation - inline sample_t interpolate( sample_t s1, sample_t s2, float x ) +/* inline sample_t interpolate( sample_t s1, sample_t s2, float x ) { return s1 + ( s2 - s1 ) * x; - } + }*/ // we use the one in interpolation.h now int m_amod; int m_bmod; diff --git a/plugins/waveshaper/waveshaper.cpp b/plugins/waveshaper/waveshaper.cpp index 905e37af5..293d97d29 100644 --- a/plugins/waveshaper/waveshaper.cpp +++ b/plugins/waveshaper/waveshaper.cpp @@ -25,8 +25,9 @@ #include "waveshaper.h" -#include +#include "lmms_math.h" #include "embed.cpp" +#include "interpolation.h" extern "C" @@ -77,9 +78,6 @@ bool waveShaperEffect::processAudioBuffer( sampleFrame * _buf, // variables for effect int i = 0; - float lookup; - float frac; - float posneg; double out_sum = 0.0; const float d = dryLevel(); @@ -101,23 +99,20 @@ bool waveShaperEffect::processAudioBuffer( sampleFrame * _buf, // start effect - for ( i=0; i <= 1; ++i ) + for( i=0; i <= 1; ++i ) { - lookup = fabsf( s[i] ) * 200.0f; - posneg = s[i] < 0 ? -1.0f : 1.0f; + const int lookup = static_cast( fabsf( s[i] ) * 200.0f ); + const float frac = fraction( fabsf( s[i] ) * 200.0f ); + const float posneg = s[i] < 0 ? -1.0f : 1.0f; - if ( lookup < 1 ) + if( lookup < 1 ) { - frac = lookup - truncf(lookup); s[i] = frac * m_wsControls.m_wavegraphModel.samples()[0] * posneg; } - else - if ( lookup < 200 ) - { - frac = lookup - truncf(lookup); - s[i] = - (( (1.0f-frac) * m_wsControls.m_wavegraphModel.samples()[ (int)truncf(lookup) - 1 ] ) + - ( frac * m_wsControls.m_wavegraphModel.samples()[ (int)truncf(lookup) ] )) + else if( lookup < 200 ) + { + s[i] = linearInterpolate( m_wsControls.m_wavegraphModel.samples()[ lookup - 1 ], + m_wsControls.m_wavegraphModel.samples()[ lookup ], frac ) * posneg; } else