trigger = param('trigger',0)
count = counter()
 
// only pass envelope signal through if its greater than 0
envelope = gtp( 
  sub( .5, div( count, mstosamps( 250) ) ),
  0
)
 
play( mul( envelope, cycle(440) ) )

// trigger envelope
count.value = 0


/********* using history *************/
envPhase = ssd(1)
env = mul( envPhase.out, t60( 10000 ) )
envPhase.in( env )

b = cycle( 330 )
play( mul( b, env ) )

// trigger envelope with amp (no attack)
envPhase.value = .5

/******* AD envelope via slide *******/
gain = .5
phase = counter()
attack = mstosamps( 200 )
decay  = mstosamps( 50 )
 
// only pass envelope signal through if its greater than 0
envelope = lt(
  div( phase, attack ),
  1
)

envelope = slide( envelope, attack, decay )
envelope = mul( envelope, gain )

play( mul( envelope, cycle(440) ), true )

// trigger envelope
phase.value = 0

/************** try for sustain ***************/
gain = 1
phase = counter()

attack = mstosamps( 1 )
decay  = mstosamps( 500 )
sustainLevel = .15
 
// only pass envelope signal through if its greater than 0
env = lt(
  div( phase, attack ),
  1
)

env = slide( env, attack, decay )
env = mul( env, gain )
env = ternary( lt( phase, add( attack, decay ) ), env, sustainLevel )

play( mul( env, cycle(440) ), true )

// trigger envelope
phase.value = 0

// attack = regular slide
// decay  = switch( gt( phase, add( attack, decay ) ), env, sustainLevel )

/********** simple sequencer **************/
speed = param('speed', 22050 )

trigger = counter( 1, 0, speed )

gain = .5
phase = counter( 1,0,Infinity, trigger.wrap )
attack = mstosamps( 1 )
decay  = mstosamps( param( 'decay',50 ) )
 
// only pass envelope signal through if its greater than 0
envelope = lt(
  div( phase, attack ),
  1
)

envelope = slide( envelope, attack, decay )
envelope = mul( envelope, gain )

cb = play( mul( envelope, cycle(440) ), true )

phase.value = 0

gui = new dat.GUI()
gui.add( cb, 'speed', 128, 44100 )
gui.add( cb, 'decay', 1, 500 )

/********* complex sequencer ************/
timeFeedback = ssd(5510) // needed to avoid feedback loop during gen

envelopeLengths = data([ 5510,5510,11025,11025,22050,22050,Infinity ])

envelopeAdvance = counter( 1, 0, timeFeedback.out )

lengthsPhase = accum( envelopeAdvance.wrap, 0, { max:envelopeLengths.buffer.length })

envelopeStageLength = peek( envelopeLengths, lengthsPhase, { mode:'samples', interp:'none' })

timeFeedback.in( envelopeStageLength )

gain = .5
phase2 = counter( 1,0,envelopeStageLength )
attack = mstosamps( 1 )
decay  = mstosamps( param( 'decay',50 ) )
 
// only pass envelope signal through if its greater than 0
envelope = lt(
  div( phase2, attack ),
  1
)

envelope = slide( envelope, attack, decay )
envelope = mul( envelope, gain )

cb = play( mul( envelope, cycle(440) ), true )

// re-trigger envelope: 
envelopeAdvance.value = cb.memory[ timeFeedback.memory.value.idx ] = 0;

gui = new dat.GUI()
gui.add( cb, 'decay', 1, 500 )

