diff --git a/include/BandLimitedWave.h b/include/BandLimitedWave.h index f8467b1bb..b4ef306f1 100644 --- a/include/BandLimitedWave.h +++ b/include/BandLimitedWave.h @@ -32,23 +32,41 @@ #include "engine.h" #include "Mixer.h" -#define MAXLEN 12 -#define MIPMAPSIZE 1 << ( MAXLEN + 1 ) +#define MAXLEN 11 +#define MIPMAPSIZE 2 << ( MAXLEN + 1 ) +#define MIPMAPSIZE3 3 << ( MAXLEN + 1 ) +#define MAXTBL 23 +#define MINTLEN 2 << 0 +#define MAXTLEN 3 << MAXLEN +// table for table sizes +const int TLENS[MAXTBL+1] = { 2 << 0, 3 << 0, 2 << 1, 3 << 1, + 2 << 2, 3 << 2, 2 << 3, 3 << 3, + 2 << 4, 3 << 4, 2 << 5, 3 << 5, + 2 << 6, 3 << 6, 2 << 7, 3 << 7, + 2 << 8, 3 << 8, 2 << 9, 3 << 9, + 2 << 10, 3 << 10, 2 << 11, 3 << 11 }; typedef struct { public: inline sample_t sampleAt( int _table, int _ph ) { - return m_data[ ( 1 << _table ) + _ph ]; + if( _table % 2 == 0 ) + { return m_data[ TLENS[ _table ] + _ph ]; } + else + { return m_data3[ TLENS[ _table ] + _ph ]; } } inline void setSampleAt( int _table, int _ph, sample_t _sample ) { - m_data[ ( 1 << _table ) + _ph ] = _sample; + if( _table % 2 == 0 ) + { m_data[ TLENS[ _table ] + _ph ] = _sample; } + else + { m_data3[ TLENS[ _table ] + _ph ] = _sample; } } private: sample_t m_data [ MIPMAPSIZE ]; + sample_t m_data3 [ MIPMAPSIZE3 ]; } WaveMipMap; @@ -96,10 +114,10 @@ public: static inline sample_t oscillate( float _ph, float _wavelen, Waveforms _wave ) { // high wavelen/ low freq - if( _wavelen >= 1 << MAXLEN ) + if( _wavelen > TLENS[ MAXTBL -1 ] ) { - const int t = MAXLEN; - const int tlen = 1 << t; + const int t = MAXTBL; + const int tlen = TLENS[t]; const float ph = fraction( _ph ); const float lookupf = ph * static_cast( tlen ); const int lookup = static_cast( lookupf ); @@ -110,8 +128,8 @@ public: // low wavelen/ high freq if( _wavelen <= 2.0f ) { - const int t = 1; - const int tlen = 2; + const int t = 0; + const int tlen = TLENS[t]; const float ph = fraction( _ph ); const float lookupf = ph * static_cast( tlen ); const int lookup = static_cast( lookupf ); @@ -121,33 +139,37 @@ public: } // get the next higher tlen - int t = 2; - while( ( 1 << t ) < _wavelen ) { t++; } + int t = 1; + while( TLENS[t] < _wavelen ) { t++; } - const int tlen = 1 << t; + int tlen = TLENS[t]; const float ph = fraction( _ph ); const float lookupf = ph * static_cast( tlen ); - const int lookup = static_cast( lookupf ); + int lookup = static_cast( 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 ); - const sample_t s12 = linearInterpolate( s1, s2, ip ); + //const sample_t sr = linearInterpolate( s1, s2, ip ); - return s12; - /*if( _wavelen > 0.75 * tlen ) return s12; + 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 ); - lookup = lookup >> 1; - tlen = tlen >> 1; - t -= 1; + return sr; + +/* lookup = lookup << 1; + tlen = tlen << 1; + t += 1; const sample_t s3 = s_waveforms[ _wave ].sampleAt( t, lookup ); const sample_t s4 = s_waveforms[ _wave ].sampleAt( t, ( lookup + 1 ) % tlen ); const sample_t s34 = linearInterpolate( s3, s4, ip ); - const float ip2 = ( ( _wavelen - tlen ) / tlen - 0.5 ) * 2.0; - - return linearInterpolate( s34, s12, ip2 );*/ + const float ip2 = ( ( tlen - _wavelen ) / tlen - 0.5 ) * 2.0; + return linearInterpolate( s12, s34, ip2 ); + */ }; diff --git a/src/core/BandLimitedWave.cpp b/src/core/BandLimitedWave.cpp index c820eea0e..92b438a01 100644 --- a/src/core/BandLimitedWave.cpp +++ b/src/core/BandLimitedWave.cpp @@ -34,9 +34,9 @@ void BandLimitedWave::generateWaves() int i; // saw wave - BLSaw - for( i = 1; i <= MAXLEN; i++ ) + for( i = 0; i <= MAXTBL; i++ ) { - const int len = 1 << i; + const int len = TLENS[i]; //const double om = 1.0 / len; double max = 0.0; @@ -65,9 +65,9 @@ void BandLimitedWave::generateWaves() } // square wave - BLSquare - for( i = 1; i <= MAXLEN; i++ ) + for( i = 0; i <= MAXTBL; i++ ) { - const int len = 1 << i; + const int len = TLENS[i]; //const double om = 1.0 / len; double max = 0.0; @@ -97,9 +97,9 @@ void BandLimitedWave::generateWaves() // triangle wave - BLTriangle - for( i = 1; i <= MAXLEN; i++ ) + for( i = 0; i <= MAXTBL; i++ ) { - const int len = 1 << i; + const int len = TLENS[i]; //const double om = 1.0 / len; double max = 0.0; @@ -131,9 +131,9 @@ void BandLimitedWave::generateWaves() // moog saw wave - BLMoog // basically, just add in triangle + 270-phase saw - for( i = 1; i <= MAXLEN; i++ ) + for( i = 0; i <= MAXTBL; i++ ) { - const int len = 1 << i; + const int len = TLENS[i]; for( int ph = 0; ph < len; ph++ ) {