/**********************************************
****** Bamd-limited Saw via FM feedback *******
***********************************************

ported from gibberish by thecharlie 5/15/2016
based on research from : http://scp.web.elte.hu/papers/synthesis1.pdf

In the paper linked above, the author describes how a sine oscillator whose
output is used to modulate itself produces harmonics similar to a saw wave.
With additional filtering, this waveform can create a reasonable version
of a band-limited sawtooth wave.

A scaling factor is applied to the amount of feedback used for modulation.
The scaling factor can in turn be scaled in a range of {0,1} to create a 
low-pass filter effect; here that effect is controlled via GUI.
*/

frequencies = peek( data([220,330,440,660,880]), phasor(.5), {interp:'none'})
slideFreqs = slide( frequencies, 1000 )
 
pseudoFilter = param( 'filter', 1)
lastSample = ssd()
 
w = memo( div( slideFreqs, gen.samplerate ) )
n = sub( -.5, w )
scaling = mul( mul(13,pseudoFilter), pow( n, 5 ) )
DC = sub( .376, mul( w, .752 ) )
norm = sub( 1, mul( 2, w ) )
phase = accum( w, 0, { min:-1 })
thisSample = memo(
  mul( 
    add( 
      lastSample.out, 
      sin( 
        mul( 
          Math.PI * 2, 
          add( phase, mul(lastSample.out,scaling) )
        )
      )
    ), .5 
  )
)
lastSample.in( thisSample )
 
out = add( mul( 2.5, thisSample), mul(-1.5, osc.out) )
out = add( out, DC )
out = mul( out, norm )
cb  = play( out )
 
gui = new dat.GUI()
gui.add( cb, 'filter', 0, 1 )