[sdiy] Soft ADSR ways?

Noah Vawter nvawter at media.mit.edu
Mon Feb 14 04:55:21 CET 2011


On Feb 13, 2011, at 5:06 AM, karl dalen wrote:

> How many ways could one do an ADSR in? Which one are
> fastest and which one are fast and code efficient??

I've lately been using this for an AR env gen:
A 16-bit word stores state and level.
MSB 0 = attack, MSB 1 = release
envOutput = 15 LSBs
I compute it every 16 samples at 22 kHz, so ~1.388kHz
I accumulate 8-bit attack/release values to that envelope state
Then I pass the 8 MSB values to my exp function (which yes uses a LUT,  
but a small one):

unsigned char powRef[16] PROGMEM ={
   0x80,0x85,0x8b,0x91,
   0x98,0x9e,0xa5,0xad,
   0xb5,0xbd,0xc5,0xce,
   0xe7,0xe0,0xea,0xf5
};

// input range 0-255
// output: 1+2^(t1/16), nominal range: 1 <=> 65535, actual range: 1  
<=> 0xf501(62721)
unsigned int my_exp(u08 input)
{
   u16 op = pgm_read_byte ( &powRef[input&0x0f] )<<8;
   return( 1 + (op>>(15-(input>>4))));
}

I guess disadvantages are slow-ish attack times (takes 2^(15-8)*.72ms  
~= 91ms) to reach max level, but
release times can be wonderfully slow (23 seconds?).  Also, you can  
enable/disable the exp function to get alternate shapes.

in hindsight I think that could be optimized further by combining the  
shifts...


T-bone`his was another, single phase one I did a while back for  
11.111kHz decay:

// update volume envelope .   these shift values will make approx 1  
second long sound max
   d->onTime++;
   t = (d->onTime>>4);    // 1 second = 11.1Ksamples = ~13.5 bits.  2  
seconds=22.2K=14.5 bits
   k = (decay^0x3ff);   // 8 bits
   val = my_exp(  (k*t)>>8 );
   if(val>0xf500){   // envelope complete.  time to turn it off  
(my_exp doesn't reach all the way to 0xff!)
     d->onTime=0;
     return(0);
   }






>
> 1.Impulse + low pass something, tight code? conceptually tricky?
>
> 2.Divide 1.0 with (time*samplerate), add/subtract value
> from envelope level for the appropriate number of samples
> does that need a LUT, no?
>
> 3.As 2 but use change state based on the envelope level +LUT?
>
> 4.Counter + level state machine + large/medium LUT?
>
> 5.Same as 4 but interpolate small LUT?
>
> 6.cube muls something?
>
> 7.......more ways?
>
> Why do i constantly end up with a LUT?!!?
> I still need to interpolate i.....hmmm..
>
> Reg
> KD (dont talk math with me im crap at it)
>
>
>
> _______________________________________________
> Synth-diy mailing list
> Synth-diy at dropmix.xs4all.nl
> http://dropmix.xs4all.nl/mailman/listinfo/synth-diy




More information about the Synth-diy mailing list