// An implementation of the KSSYnth class in the ipython notebook in ../pynb/KarplusStrong.ipynb #include #include #include #include class KSSynth { public: typedef enum InitPacket { RANDOM, SQUARE, SAW, NOISYSAW, SIN, SINCHIRP // if you add remember to fix the count below... } InitPacket; std::string initPacketName( InitPacket p ) { switch(p) { case RANDOM: return "random"; case SQUARE: return "square"; case SAW: return "saw"; case NOISYSAW: return "noisysaw"; case SIN: return "sin"; case SINCHIRP: return "sinchirp"; } return ""; } int numInitPackets() { return (int)SINCHIRP + 1; } typedef enum FilterType { WEIGHTED_ONE_SAMPLE } FilterType; std::string filterTypeName( FilterType p ) { switch(p) { case WEIGHTED_ONE_SAMPLE: return "wgt 1samp"; } return ""; } int numFilterTypes() { return WEIGHTED_ONE_SAMPLE + 1; } public: // here's my interior state InitPacket packet; FilterType filter; float filtParamA, filtParamB, filtParamC, filtAtten; float sumDelaySquared; // This is updated about 100 times a second, not per sample bool active; //private: float freq; int burstLen; float wfMin, wfMax; int sampleRate, sampleRateBy100; float filtAttenScaled; long pos; std::vector< float > delay; public: KSSynth( float minv, float maxv, int sampleRateIn ) : packet( RANDOM ), filter( WEIGHTED_ONE_SAMPLE ), filtParamA( 0.5f ), filtParamB( 0.0f ), filtParamC( 0.0f ), filtAtten( 3.0f ), active( false ), wfMin( minv ), wfMax( maxv ), sampleRate( sampleRateIn ), sampleRateBy100( (int)( sampleRate / 100 ) ), pos( 0 ) { setFreq( 220 ); } void setFreq( float f ) { freq = f; burstLen = (int)( ( 1.0f * sampleRate / freq + 0.5 ) * 2 ); filtAttenScaled = filtAtten / 100 / ( freq / 440 ); delay.resize( burstLen ); } void trigger( float f ) { // remember: Interally we work on the range [-1.0f, 1.0f] to match the python (but different from // the ChipSym which works on [ 0 1.0f ] active = true; setFreq( f ); pos = 1; switch( packet ) { case RANDOM: { for( int i=0; i