Merge pull request #599 from diizy/master
Add some more interpolation algorithms
This commit is contained in:
@@ -114,33 +114,47 @@ public:
|
||||
static inline sample_t oscillate( float _ph, float _wavelen, Waveforms _wave )
|
||||
{
|
||||
// high wavelen/ low freq
|
||||
if( _wavelen > TLENS[ MAXTBL -1 ] )
|
||||
if( _wavelen > TLENS[ MAXTBL ] )
|
||||
{
|
||||
const int t = MAXTBL;
|
||||
const int tlen = TLENS[t];
|
||||
const float ph = fraction( _ph );
|
||||
const float lookupf = ph * static_cast<float>( tlen );
|
||||
const int lookup = static_cast<int>( lookupf );
|
||||
const float ip = fraction( lookupf );
|
||||
|
||||
const sample_t s1 = s_waveforms[ _wave ].sampleAt( t, lookup );
|
||||
const sample_t s2 = s_waveforms[ _wave ].sampleAt( t, ( lookup + 1 ) % tlen );
|
||||
return linearInterpolate( s1, s2, fraction( lookupf ) );
|
||||
const int lm = lookup == 0 ? tlen - 1 : lookup - 1;
|
||||
const sample_t s0 = s_waveforms[ _wave ].sampleAt( t, lm );
|
||||
const sample_t s3 = s_waveforms[ _wave ].sampleAt( t, ( lookup + 2 ) % tlen );
|
||||
const sample_t sr = optimal4pInterpolate( s0, s1, s2, s3, ip );
|
||||
|
||||
return sr;
|
||||
}
|
||||
// low wavelen/ high freq
|
||||
if( _wavelen <= 2.0f )
|
||||
if( _wavelen < 3.0f )
|
||||
{
|
||||
const int t = 0;
|
||||
const int tlen = TLENS[t];
|
||||
const float ph = fraction( _ph );
|
||||
const float lookupf = ph * static_cast<float>( tlen );
|
||||
const int lookup = static_cast<int>( lookupf );
|
||||
const float ip = fraction( lookupf );
|
||||
|
||||
const sample_t s1 = s_waveforms[ _wave ].sampleAt( t, lookup );
|
||||
const sample_t s2 = s_waveforms[ _wave ].sampleAt( t, ( lookup + 1 ) % tlen );
|
||||
return linearInterpolate( s1, s2, fraction( lookupf ) );
|
||||
const int lm = lookup == 0 ? tlen - 1 : lookup - 1;
|
||||
const sample_t s0 = s_waveforms[ _wave ].sampleAt( t, lm );
|
||||
const sample_t s3 = s_waveforms[ _wave ].sampleAt( t, ( lookup + 2 ) % tlen );
|
||||
const sample_t sr = optimal4pInterpolate( s0, s1, s2, s3, ip );
|
||||
|
||||
return sr;
|
||||
}
|
||||
|
||||
// get the next higher tlen
|
||||
int t = 1;
|
||||
while( TLENS[t] < _wavelen ) { t++; }
|
||||
int t = MAXTBL - 1;
|
||||
while( _wavelen < TLENS[t] ) { t--; }
|
||||
|
||||
int tlen = TLENS[t];
|
||||
const float ph = fraction( _ph );
|
||||
@@ -150,12 +164,11 @@ public:
|
||||
|
||||
const sample_t s1 = s_waveforms[ _wave ].sampleAt( t, lookup );
|
||||
const sample_t s2 = s_waveforms[ _wave ].sampleAt( t, ( lookup + 1 ) % tlen );
|
||||
//const sample_t sr = linearInterpolate( s1, s2, ip );
|
||||
|
||||
|
||||
const int lm = lookup == 0 ? tlen - 1 : lookup - 1;
|
||||
const sample_t s0 = s_waveforms[ _wave ].sampleAt( t, lm );
|
||||
const sample_t s3 = s_waveforms[ _wave ].sampleAt( t, ( lookup + 2 ) % tlen );
|
||||
const sample_t sr = cubicInterpolate( s0, s1, s2, s3, ip );
|
||||
const sample_t sr = optimal4pInterpolate( s0, s1, s2, s3, ip );
|
||||
|
||||
return sr;
|
||||
|
||||
|
||||
@@ -101,4 +101,50 @@ inline float linearInterpolate( float v0, float v1, float x )
|
||||
}
|
||||
|
||||
|
||||
inline float optimalInterpolate( float v0, float v1, float x )
|
||||
{
|
||||
const float z = x - 0.5f;
|
||||
const float even = v1 + v0;
|
||||
const float odd = v1 - v0;
|
||||
|
||||
const float c0 = even * 0.50037842517188658;
|
||||
const float c1 = odd * 1.00621089801788210;
|
||||
const float c2 = even * -0.004541102062639801;
|
||||
const float c3 = odd * -1.57015627178718420;
|
||||
|
||||
return ( ( c3*z + c2 ) * z + c1 ) * z + c0;
|
||||
}
|
||||
|
||||
|
||||
inline float optimal4pInterpolate( float v0, float v1, float v2, float v3, float x )
|
||||
{
|
||||
const float z = x - 0.5f;
|
||||
const float even1 = v2 + v1;
|
||||
const float odd1 = v2 - v1;
|
||||
const float even2 = v3 + v0;
|
||||
const float odd2 = v3 - v0;
|
||||
|
||||
const float c0 = even1 * 0.45868970870461956 + even2 * 0.04131401926395584;
|
||||
const float c1 = odd1 * 0.48068024766578432 + odd2 * 0.17577925564495955;
|
||||
const float c2 = even1 * -0.246185007019907091 + even2 * 0.24614027139700284;
|
||||
const float c3 = odd1 * -0.36030925263849456 + odd2 * 0.10174985775982505;
|
||||
|
||||
return ( ( c3*z + c2 ) * z + c1 ) * z + c0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline float lagrangeInterpolate( float v0, float v1, float v2, float v3, float x )
|
||||
{
|
||||
const float c0 = v1;
|
||||
const float c1 = v2 - v0 * ( 1.0f / 3.0f ) - v1 * 0.5f - v3 * ( 1.0f / 6.0f );
|
||||
const float c2 = 0.5f * (v0 + v2) - v1;
|
||||
const float c3 = ( 1.0f/6.0f ) * ( v3 - v0 ) + 0.5f * ( v1 - v2 );
|
||||
return ( ( c3*x + c2 ) * x + c1 ) * x + c0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -172,7 +172,7 @@ const float MAX_FREQ = 48000.0f;
|
||||
|
||||
// constants for amp delta capping - these will be divided by samplerate by the synth
|
||||
const float ADCAP1 = 44100 / 2;
|
||||
const float ADCAP2 = 44100 / 3;
|
||||
const float ADCAP2 = 44100 / 2.25;
|
||||
|
||||
|
||||
class MonstroInstrument;
|
||||
|
||||
@@ -55,7 +55,7 @@ void BandLimitedWave::generateWaves()
|
||||
//const double a2 = cos( om * harm * F_2PI );
|
||||
s += amp * /*a2 **/sin( static_cast<double>( ph * harm ) / static_cast<double>( len ) * F_2PI );
|
||||
harm++;
|
||||
} while( hlen >= 4.0 );
|
||||
} while( hlen > 2.0 );
|
||||
s_waveforms[ BandLimitedWave::BLSaw ].setSampleAt( i, ph, s );
|
||||
max = qMax( max, qAbs( s ) );
|
||||
}
|
||||
@@ -86,7 +86,7 @@ void BandLimitedWave::generateWaves()
|
||||
//const double a2 = cos( om * harm * F_2PI );
|
||||
s += amp * /*a2 **/ sin( static_cast<double>( ph * harm ) / static_cast<double>( len ) * F_2PI );
|
||||
harm += 2;
|
||||
} while( hlen >= 4.0 );
|
||||
} while( hlen > 2.0 );
|
||||
s_waveforms[ BandLimitedWave::BLSquare ].setSampleAt( i, ph, s );
|
||||
max = qMax( max, qAbs( s ) );
|
||||
}
|
||||
@@ -119,7 +119,7 @@ void BandLimitedWave::generateWaves()
|
||||
s += amp * /*a2 **/ sin( ( static_cast<double>( ph * harm ) / static_cast<double>( len ) +
|
||||
( ( harm + 1 ) % 4 == 0 ? 0.5 : 0.0 ) ) * F_2PI );
|
||||
harm += 2;
|
||||
} while( hlen >= 4.0 );
|
||||
} while( hlen > 2.0 );
|
||||
s_waveforms[ BandLimitedWave::BLTriangle ].setSampleAt( i, ph, s );
|
||||
max = qMax( max, qAbs( s ) );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user