A filter is a function that modifies a signal.
Similar to synths, you can define a filter using a simple lambda function (input, options) => output [l, r]
If you want to keep a state (for example, when creating a delay effect), you can also define a filter using a class that implements a process method.
Note: the input of a filter will always be a stereo signal, and you always have to return a stereo signal.
dittytoy.net/syntax#filters
#dittytoy #tutorial
Log in to post a comment.
// #08 Filters. DittyToy 2022. // The MIT License. // // https://dittytoy.net/ditty/4a37b66afe // // A filter is a function that modifies a signal. // // Similar to synths, you can define a filter using a simple lambda function // (input, options) => output [l, r] // // https://dittytoy.net/syntax#filters // // Define a filter using a lambda function: const flipChannels = filter.def( (input, options) => [input[1], -input[0]], {}); // Note: the input of a filter will always be a stereo signal, and you always have to return a stereo signal. // If you want to keep a state (for example, when creating a delay effect), you // can also define a filter using a class that implements a process method. const lowpass = filter.def(class { constructor(options) { this.hist0 = [0, 0]; this.hist1 = [0, 0]; } process(input, options) { const alpha = options.cutoff; if (input) { for (let i = 0; i < 2; i++) { this.hist0[i] += alpha * (input[i] - this.hist0[i]); this.hist1[i] += alpha * (this.hist0[i] - this.hist1[i]); } return this.hist1; } } }, { cutoff: 1 }); // You can apply multiply filters on an input signal by chaining. const kick = synth.def( (phase, env, tick, options) => Math.sin(phase * 2 * Math.PI * (1.5 - tick * 4)) * env.value); const tri = synth.def( (phase, env, tick, options) => { const v = (phase % 1) * 4; return (v < 2 ? v - 1 : 3 - v) * env.value }, { attack: 0.0125, release: 0.25, amp: 0.8 }); ditty.bpm = 140; loop( (loopCount) => { kick.play(c3, { attack: 0.025, release: 0.05 }); }, { sync: 1, name: 'kick' }) .connect( flipChannels.create() ); // connect a filter to the loop loop( (loopCount) => { scale(c3, scales.minor_pentatonic, 1).forEach( note => { tri.play(note, { pan: Math.random() * 2 - 1 }); sleep(0.25); }); }, { name: 'melody' }) .connect( flipChannels.create() ) // connect two filters to this loop .connect( lowpass.create( { cutoff: () => 0.4 + 0.3 * Math.sin(ditty.time) } ) );