Implemented from youtube.com/watch?v=y7teskmse74&t=456s
Basic waveforms (variation)
Basic waveforms (variation)
Basic waveforms (variation)
Log in to post a comment.
input.waveForm = 2; //min=1 max=5 step=1 (Sine, Square, Triangle, Saw, Semi-circle) input.overdriveLevel = 1 //min=1, max=100 step=.1 // // RTFM You can find the DittyToy API Reference here: https://dittytoy.net/syntax // const WAVEFORM = {SINE: 1, SQUARE: 2, TRIANGLE: 3, SAW: 4, SEMICIRCLE: 5 }; const basicSynth = synth.def(class { process(note, env, tick, options) { switch(options.waveForm) { case WAVEFORM.SQUARE: return Array.from({length: options.k }, (v, i) => Math.sin(tick * midi_to_hz(note) * (2 * (i + 1) - 1) * 2 * Math.PI) / (2 * (i + 1) - 1) ).reduce((p, c) => p+c, 0) * 4 / Math.PI * env.value; case WAVEFORM.TRIANGLE: return Array.from({length: options.k }, (v, i) => (Math.sin(tick * midi_to_hz(note) * (2 * (i + 1) - 1) * 2 * Math.PI) / (2 * (i + 1) - 1)**2) * (-1)**(i+1) ).reduce((p, c) => p+c, 0) * 8 / Math.PI**2 * env.value; case WAVEFORM.SAW: return Array.from({length: options.k }, (v, i) => Math.sin(tick * midi_to_hz(note) * (i + 1) * 2 * Math.PI) / (i + 1) * (-1)**(i+1) ).reduce((p, c) => p+c, 0) * 2 / Math.PI * env.value; case WAVEFORM.SEMICIRCLE: // I modified the second answer from https://math.stackexchange.com/questions/44329/function-for-concatenated-semicircles // with a reference to https://www.desmos.com/calculator/e5xncapcnp const f = midi_to_hz(note) * Math.PI * tick * 2; return Math.sqrt(1 - ((2 * Math.asin(Math.sin(f))) / Math.PI)**2) * (Math.cos(f)/Math.abs(Math.cos(f))) * env.value; case WAVEFORM.SINE: default: return Math.sin(tick * midi_to_hz(note) * 2 * Math.PI) * env.value; } } }, { name: 'basicSynth', k: 15, waveForm: WAVEFORM.SQUARE }); const overdrive = filter.def( (input, options) => [...input.map(i => clamp(i * options.level, -1, 1))], { level: 1 }); ditty.bpm = 70; // Adapted from Bach's Cello Suite No. 1 in G Major BWV 1007, copied from https://dittytoy.net/ditty/0c920dd635 let melody = [d3,a3,fs4,e4,fs4,a3,fs4,a3, d3,a3,fs4,e4,fs4,a3,fs4,a3, d3,b3,g4,fs4,g4,b3,g4,b3, d3,b3,g4,fs4,g4,b3,g4,b3, d3,cs4,g4,fs4,g4,cs4,g4,cs4, d3,cs4,g4,fs4,g4,cs4,g4,cs4, d3,b3,fs4,e4,fs4,d4,cs4,d4, b3,d4,cs4,d4,fs3,a3,gs3,fs3, gs3,d4,e4,d4,e4,d4,e4,d4, gs3,d4,e4,d4,e4,d4,e4,d4, cs4,e4,a4,gs4,a4,e4,d4,e4, cs4,e4,d4,e4,a3,cs4,b3,a3, b2,fs3,d4,cs4,d4,fs3,d4,fs3, b2,fs3,d4,cs4,d4,fs3,d4,fs3, b2,gs3,a3,b3,a3,gs3,fs3,e3, d4,cs4,b3,a4,gs4,fs4,e4,d4, a2,b3,cs4,a4,e4,a4,cs4,e4, g4,b3,cs4,e4,g4,e4,cs4,a3, ]; loop( (count, options) => { melody.forEach(note => { [note].forEach((n, i) => { basicSynth.play(n, {amp:(Math.random() + 0.5 + (i%8==0?0.8:0)) * .5, pan:0.5 * (2*((n*0.618)%1)-1), release: .25, waveForm: () => input.waveForm }); sleep(0.25); }); }) }, { name: 'example' } ).connect(overdrive.create({level: () => input.overdriveLevel}));