Permalink
Browse files

[50m30n3] Added better emulation of original TB-303 envelopes

  • Loading branch information...
1 parent 3b8fbcb commit ed6bfe4158e333dbbd38f7ed20684acb71064e0e @jeremysalwen committed Jun 6, 2011
Showing with 32 additions and 17 deletions.
  1. +5 −4 README
  2. +25 −13 so-404.c
  3. +2 −0 so-404.h
View
9 README
@@ -1,4 +1,4 @@
-LV2 ports by Jeremy Salwen 2010
+LV2 ports by Jeremy Salwen 2010-20011
This is a package of three LV2 plugin synthesizers. To use them, you need an
LV2 host which works with MIDI synthesizers. The different parameters (listed
@@ -47,7 +47,7 @@ CC#74 - Filter Cutoff
Sustain can be controlled by CC#1 (Mod Wheel) and CC#64 (Sustain) to make
control easier for people without a sustain pedal.
-*******SO-404 v.1.0 by 50m30n3 2009*******
+*******SO-404 v.1.2 by 50m30n3 2009-2011*******
SO-404 is a simple bass synthesizer using 1 oscillator and 1 filter.
The oscillator is a simple saw wave oscillator and the filter is a simple
@@ -63,5 +63,6 @@ CC#74 - Filter Cutoff
CC#79 - Filter Envelope
If two notes are played together the pitch will slide according to the
-portamento time. Filter cutoff and note volume are influenced by the MIDI
-note velocity.
+portamento time. Filter cutoff is influenced by the MIDI note velocity.
+A note velocity above 100 generates an accented note where the amp EG is
+replaced by the filter EG.
View
@@ -58,13 +58,18 @@ void runSO_404( LV2_Handle arg, uint32_t nframes ) {
if( so->noteson == 0 )
{
so->freq = so->tfreq;
- so->amp = ((float)evt[2])/127.0;
+ so->amp=1.0;
+ so->vel = ((float)evt[2]);
+ so->env=so->vel/127.0;
so->cdelay = 0;
}
so->noteson += 1;
}
else if((evt[0]&MIDI_COMMANDMASK)==MIDI_NOTEOFF ) {
so->noteson -= 1;
+ if(so->noteson<0) {
+ so->noteson=0;
+ }
}
else if((*so->controlmode_p<=0) && (evt[0]&MIDI_COMMANDMASK)==MIDI_CONTROL ) {
unsigned int command_val=evt[2];
@@ -97,27 +102,32 @@ void runSO_404( LV2_Handle arg, uint32_t nframes ) {
if( so->cdelay <= 0 )
{
so->freq = ((so->portamento/127.0)*0.9)*so->freq + (1.0-((so->portamento/127.0)*0.9))*so->tfreq;
- if( so->noteson > 0 )
- so->amp *= 0.8+(so->release/127.0)/5.1;
- else
+ if( so->noteson > 0 ) {
+ so->amp *= 0.99;
+ } else {
so->amp *= 0.5;
- so->fcutoff = powf(so->cutoff/127.0,5.0)+so->amp*so->amp*powf(so->envmod/128.0,2.0);
- if( so->fcutoff > 1.0 ) {
- so->fcutoff = 1.0;
}
- so->fcutoff = sin(so->fcutoff*M_PI/2.0);
- so->freso = powf(so->resonance/127.0,0.25);
+ so->env*=0.8+powf(so->release/127.0,0.25)/5.1;
+
+ so->fcutoff = powf(so->cutoff/127.0,2.0)+powf(so->env,2.0)*powf(so->envmod/127.0,2.0);
+ so->fcutoff = tanh(so->fcutoff);
+ so->freso = powf(so->resonance/130.0,0.25);
so->cdelay = so->samplerate/100;
}
so->cdelay--;
float max = so->samplerate / so->freq;
float sample = (so->phase/max)*(so->phase/max)-0.25;
so->phase++;
- if( so->phase >= max )
- so->phase -= max;
+ if( so->phase >= max ) {
+ so->phase -= max;
+ }
- sample *= so->amp;
+ if(so->vel>100) {
+ sample*=so->env;
+ } else {
+ sample*=so->amp;
+ }
so->fpos += so->fspeed;
so->fspeed *= so->freso;
@@ -147,12 +157,14 @@ LV2_Handle instantiateSO_404(const LV2_Descriptor *descriptor,double s_rate, con
}
}
- puts( "SO-404 v.1.0 by 50m30n3 2009" );
+ puts( "SO-404 v.1.2 by 50m30n3 2009-2011" );
so->phase = 0.0;
so->freq = 440.0;
so->tfreq = 440.0;
so->amp = 0.0;
+ so->env=0.0;
+ so->vel=0;
so->fcutoff = 0.0;
so->fspeed = 0.0;
so->fpos = 0.0;
View
@@ -96,10 +96,12 @@ typedef struct so_404_t {
unsigned int portamento;
unsigned int release;
unsigned int envmod;
+ unsigned int vel;
float phase;
float amp;
float lastsample;
+ float env;
float fcutoff;
float fspeed;

0 comments on commit ed6bfe4

Please sign in to comment.