One possible solution to create a portamento:
Create an additional property in the options object. When setting an options property value, it tracks the time of the setter within the loop. The actual assignment of the value is then, like the play calls, put on a timeline and executed later at the appropriate time.
dittytoy.net/syntax#portamento
dittytoy.net/syntax#options
#dittytoy #tutorial
Log in to post a comment.
// #17 Portamento. DittyToy 2022. // The MIT License. // // https://dittytoy.net/ditty/220e9dcde7 // // Forked from "How do I create a mono synth?" by athibaul - https://dittytoy.net/ditty/662d460791 // // Every time Dittytoy starts a new iteration of a loop, the entire body of the loop is evaluated instantaneously. // All play-calls are collected and sorted based on the intervening sleep times and put on a timeline before playback starts. // // A side effect of having the body of a loop evaluated in its entirety is that if you assign a value to a variable within // a loop at different times, it thus has the last assigned value after the evaluation. // // One possible solution to this problem is not to use a separate variable but to create an additional property in the // options object. When setting an options property value, it tracks the time of the setter within the loop. The actual // assignment of the value is then, like the play calls, put on a timeline and executed later at the appropriate time. // // https://dittytoy.net/syntax#portamento // https://dittytoy.net/syntax#options // ditty.bpm = 60; // To create a mono synth with portamento, we need to glide between notes, so I'm creating // a "pitch smoother" to do that class Smoother { // We feed values to this object, and it smoothes them out constructor(v, dur) { this.v = v; this.a0 = clamp01(ditty.dt / dur); } update(target) { // should be called once per sample return this.v += this.a0 * (target - this.v); } } // Melody const melody = [c4,d4,e4,b3,e4,a3,a4,e4]; loop( () => { const note_smoother = new Smoother(c4, 0.1); // Use the smoothed values as the note number const s = sine.play( (tick, options) => note_smoother.update(options.target), { duration: melody.length, target: c4 } ); melody.forEach( note => { // We now communicate notes via the option object s.options.target = note; sleep(1); }); });