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) } ) );