input.baseFrequency = 40; // min=20, max=100, step=1 input.loopEveryNTicks = 180; // min=20, max=300, step=1 input.shepardType = 2; // min=0, max=2, step=1 (Up, Down, Both) const octaves = 6; for(let i = 0; i < octaves; i++) { const getFp = (t) => (octaves * (t % input.loopEveryNTicks)) / input.loopEveryNTicks; synth.def( class { constructor (options) { this.phaseUp = 0; this.phaseDown = 0; } process(note, env, tick, options) { let fp = (getFp(tick) + i) % octaves; let frequencyUp = input.baseFrequency * 2**fp; let frequencyDown = input.baseFrequency * 2**(octaves - fp); this.phaseUp += ditty.dt * frequencyUp; this.phaseDown += ditty.dt * frequencyDown; const waveUp = Math.sin( this.phaseUp * Math.PI * 2 ); const waveDown = Math.sin( this.phaseDown * Math.PI * 2 ); switch(input.shepardType) { case 0: return [waveUp, waveUp]; case 1: return [waveDown, waveDown]; } return [waveUp, waveDown]; } }).play(0, { env: one, amp: () => Math.sin( getFp(ditty.tick + (i * (input.loopEveryNTicks / octaves)))/octaves * Math.PI )**6 }) };