Harping 🎸
Changing parameters might take a while until you hear it.
Reverb from Karplus synth with reverb by @srtuss
Log in to post a comment.
// // RTFM You can find the DittyToy API Reference here: https://dittytoy.net/syntax // // reverb from https://dittytoy.net/ditty/827b1b3e63 class Delayline { constructor(n) { this.n = ~~n; this.p = 0; this.lastOut = 0; this.data = new Float32Array(n); } clock(input) { this.lastOut = this.data[this.p]; this.data[this.p] = input; if(++this.p >= this.n) { this.p = 0; } } tap(offset) { var x = this.p - offset - 1; x %= this.n; if(x < 0) { x += this.n; } return this.data[x]; } } function allpass(delayline, x, k) { var delayin = x - delayline.lastOut * k; var y = delayline.lastOut + k * delayin; delayline.clock(delayin); return y; } // Simple allpass reverberator, based on this article: // http://www.spinsemi.com/knowledge_base/effects.html const reverb = filter.def(class { constructor(options) { this.lastReturn = 0; this.krt = .7; this.delaylines = []; // Create several delay lines with random lengths for(var i = 0; i < 12; ++i) { this.delaylines.push(new Delayline(10 + Math.floor(Math.random() * 5000))); } } process(input, options) { var inv = input[0] + input[1]; var v = this.lastReturn; // Let the signal pass through the loop of delay lines. Inject input signal at multiple locations. v = allpass(this.delaylines[0], v + inv, .5); v = allpass(this.delaylines[1], v, .5); this.delaylines[2].clock(v); v = this.delaylines[2].lastOut * this.krt; v = allpass(this.delaylines[3], v + inv, .5); v = allpass(this.delaylines[4], v, .5); this.delaylines[5].clock(v); v = this.delaylines[5].lastOut * this.krt; v = allpass(this.delaylines[6], v + inv, .5); v = allpass(this.delaylines[7], v, .5); this.delaylines[8].clock(v); v = this.delaylines[8].lastOut * this.krt; v = allpass(this.delaylines[9], v + inv, .5); v = allpass(this.delaylines[10], v, .5); this.delaylines[11].clock(v); v = this.delaylines[11].lastOut * this.krt; this.lastReturn = v; // Tap the delay lines at randomized locations and accumulate the output signal. var ret = [0, 0]; ret[0] += this.delaylines[2].tap(111); ret[1] += this.delaylines[2].tap(2250); ret[0] += this.delaylines[5].tap(311); ret[1] += this.delaylines[5].tap(1150); ret[0] += this.delaylines[8].tap(511); ret[1] += this.delaylines[8].tap(50); ret[0] += this.delaylines[11].tap(4411); ret[1] += this.delaylines[11].tap(540); // Mix wet + dry signal. ret[0] = ret[0] * .1 + input[0]; ret[1] = ret[1] * .1 + input[1]; // Slight stereo widening: var m = (ret[0] + ret[1]) * .5; var s = (ret[1] - ret[0]) * .5; ret[0] = m + s * 1.5; ret[1] = m - s * 1.5; return ret; } }); // source: https://dittytoy.net/ditty/6f30b0885d function tri(t) { return -1 + 4*Math.abs(t%1 - 0.5); } const varsaw = synth.def( (phase, env, tick) => { let x = (phase%1); return (x-0.5) * clamp01(15*x*(1-x)*(1 + 0.1*tri(tick))) * env.value; }, {attack:0.02, release:0.25, decay:0.5, sustain:0.15, duration: 1.5} ); input.type = 1; // min=0, max=1, step=1 (Linear, Mirror) input.sequenceLength = 16; // min=4, max=16, step=4 input.sequence = 1; // min=0, max=4, step=1 (+1, +2 -1, +3 -1 -1, +2 0 +2 -1 -2 0, custom) input.stepSize = 2; // min=1, max=2, step=1 const scaleNotesMinor = scale(f2, scales['minor'], 64); const scaleNotesHarmonic = scale(f2, scales['harmonic_minor'], 64); const scaleNotesMajor = scale(f2, scales['major'], 64); const scalesToChoose = new Array(12).fill(scaleNotesMajor); scalesToChoose.push(scaleNotesHarmonic); scalesToChoose.push(scaleNotesMinor); const ease = t => t * t * (3.0 - 2.0 * t); let stepSequence1 = [2,-1]; let stepSequence2 = [3,-1,-1]; let stepSequence3 = [2,0,2,-1,-2,0]; let stepSequenceCustom = [3,-2,-1,1]; // write your own custom arpeggio here let stepSequences=[stepSequence1,stepSequence2,stepSequence3,stepSequenceCustom]; let step = 0; loop( () => { let scaleNotes = scalesToChoose.choose(); let size = input.sequenceLength; let sequence = new Array(size).fill(0).map((_,idx) => idx*input.stepSize); if (input.sequence >= 1) { let stepSequence = stepSequences[input.sequence-1]; let tmp = []; let acc=0; for(let i=0;i<sequence.length;i++) { acc+=stepSequence[i%stepSequence.length]; tmp.push(sequence[acc]); } sequence = tmp; } if (input.type == 1) { sequence = sequence.mirror() } let stage = [0,0,0,1,2,3,4,5,6,7].choose(); for (let i=0; i<sequence.length; i++) { if (scaleNotes[stage + (sequence[i]-1)]) varsaw.play( scaleNotes[stage + (sequence[i]-1)] , {amp: 0.5 + 0.5*ease(1-i/sequence.length), pan: Math.sin(1-i/sequence.length*3) * 0.5 }); sleep( 0.25 ); } }, { name: 'arpeggio' }).connect(reverb.create());