Further improvements to bandlimited waves

This commit is contained in:
Vesa
2014-04-09 13:03:34 +03:00
parent 7b0d829cc4
commit d5fa2568ed
2 changed files with 52 additions and 30 deletions

View File

@@ -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<float>( tlen );
const int lookup = static_cast<int>( 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<float>( tlen );
const int lookup = static_cast<int>( 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<float>( tlen );
const int lookup = static_cast<int>( lookupf );
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 );
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 );
*/
};

View File

@@ -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++ )
{