From 483843bd0a776ff0690712b5495499a0535c2c1f Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 1 Jun 2025 18:06:36 +0200 Subject: [PATCH 001/335] begin supradough --- packages/superdough/dough.mjs | 445 +++++++++++++++++++++++++++++++ packages/superdough/synth.mjs | 4 +- packages/superdough/worklets.mjs | 53 ++++ packages/webaudio/supradough.mjs | 39 +++ 4 files changed, 539 insertions(+), 2 deletions(-) create mode 100644 packages/superdough/dough.mjs create mode 100644 packages/webaudio/supradough.mjs diff --git a/packages/superdough/dough.mjs b/packages/superdough/dough.mjs new file mode 100644 index 000000000..f3365b06c --- /dev/null +++ b/packages/superdough/dough.mjs @@ -0,0 +1,445 @@ +// this is dough, the superdough without dependencies + +const ISR = 1 / sampleRate; +// https://garten.salat.dev/audio-DSP/oscillators.html +export class SineOsc { + phase = 0; + update(freq) { + const value = Math.sin(this.phase * 2 * Math.PI); + this.phase = (this.phase + freq / sampleRate) % 1; + return value; + } +} + +export class ZawOsc { + phase = 0; + update(freq) { + this.phase += ISR * freq; + return (this.phase % 1) * 2 - 1; + } +} + +function polyBlep(t, dt) { + // 0 <= t < 1 + if (t < dt) { + t /= dt; + // 2 * (t - t^2/2 - 0.5) + return t + t - t * t - 1; + } + // -1 < t < 0 + if (t > 1 - dt) { + t = (t - 1) / dt; + // 2 * (t^2/2 + t + 0.5) + return t * t + t + t + 1; + } + // 0 otherwise + return 0; +} +export class SawOsc { + //phase = Math.random(); + phase = 0; + update(freq) { + const dt = freq / sampleRate; + let p = polyBlep(this.phase, dt); + let s = 2 * this.phase - 1 - p; + this.phase += dt; + if (this.phase > 1) { + this.phase -= 1; + } + return s; + } +} + +export class TriOsc { + phase = 0; + update(freq) { + this.phase += ISR * freq; + let phase = this.phase % 1; + let value = phase < 0.5 ? 2 * phase : 1 - 2 * (phase - 0.5); + return value * 2 - 1; + } +} + +export class Lpf { + s0 = 0; + s1 = 0; + update(s, cutoff, resonance = 0) { + // Out of bound values can produce NaNs + cutoff = Math.min(cutoff, 1); + resonance = Math.max(resonance, 0); + var c = Math.pow(0.5, (1 - cutoff) / 0.125); + var r = Math.pow(0.5, (resonance + 0.125) / 0.125); + var mrc = 1 - r * c; + var v0 = this.s0; + var v1 = this.s1; + // Apply the filter to the sample + v0 = mrc * v0 - c * v1 + c * s; + v1 = mrc * v1 + c * v0; + s = v1; + this.s0 = v0; + this.s1 = v1; + return s; + } +} + +export class PulseOsc { + phase = 0; + update(freq, duty = 0.5) { + this.phase += ISR * freq; + let cyclePos = this.phase % 1; + return cyclePos < duty ? 1 : -1; + } +} + +export class Dust { + update = (density) => (Math.random() < density * ISR ? Math.random() : 0); +} + +export class Impulse { + phase = 1; + update(freq) { + this.phase += ISR * freq; + let v = this.phase >= 1 ? 1 : 0; + this.phase = this.phase % 1; + return v; + } +} + +export class ClockDiv { + inSgn = true; + outSgn = true; + clockCnt = 0; + update(clock, factor) { + let curSgn = clock > 0; + if (this.inSgn != curSgn) { + this.clockCnt++; + if (this.clockCnt >= factor) { + this.clockCnt = 0; + this.outSgn = !this.outSgn; + } + } + + this.inSgn = curSgn; + return this.outSgn ? 1 : -1; + } +} + +export class Hold { + value = 0; + trigSgn = false; + update(input, trig) { + if (!this.trigSgn && trig > 0) this.value = input; + this.trigSgn = trig > 0; + return this.value; + } +} + +function lerp(x, y0, y1) { + if (x >= 1) return y1; + + return y0 + x * (y1 - y0); +} + +export class ADSR { + state = 'off'; + startTime = 0; + startVal = 0; + + update(curTime, gate, attack, decay, susVal, release) { + switch (this.state) { + case 'off': { + if (gate > 0) { + this.state = 'attack'; + this.startTime = curTime; + this.startVal = 0; + } + return 0; + } + case 'attack': { + let time = curTime - this.startTime; + if (time > attack) { + this.state = 'decay'; + this.startTime = curTime; + return 1; + } + return lerp(time / attack, this.startVal, 1); + } + case 'decay': { + let time = curTime - this.startTime; + let curVal = lerp(time / decay, 1, susVal); + if (gate <= 0) { + this.state = 'release'; + this.startTime = curTime; + this.startVal = curVal; + return curVal; + } + if (time > decay) { + this.state = 'sustain'; + this.startTime = curTime; + return susVal; + } + return curVal; + } + case 'sustain': { + if (gate <= 0) { + this.state = 'release'; + this.startTime = curTime; + this.startVal = susVal; + } + return susVal; + } + case 'release': { + let time = curTime - this.startTime; + if (time > release) { + this.state = 'off'; + return 0; + } + let curVal = lerp(time / release, this.startVal, 0); + if (gate > 0) { + this.state = 'attack'; + this.startTime = curTime; + this.startVal = curVal; + } + return curVal; + } + } + throw 'invalid envelope state'; + } +} + +/* + impulse(1).ad(.1).mul(sine(200)) +.add(x=>x.delay(.1).mul(.8)) +.out()*/ +const MAX_DELAY_TIME = 10; +export class Delay { + writeIdx = 0; + readIdx = 0; + buffer = new Float32Array(MAX_DELAY_TIME * sampleRate); // .fill(0) + write(s, delayTime) { + this.writeIdx = (this.writeIdx + 1) % this.buffer.length; + this.buffer[this.writeIdx] = s; + // Calculate how far in the past to read + let numSamples = Math.min(Math.floor(sampleRate * delayTime), this.buffer.length - 1); + this.readIdx = this.writeIdx - numSamples; + // If past the start of the buffer, wrap around + if (this.readIdx < 0) this.readIdx += this.buffer.length; + } + update(input, delayTime) { + this.write(input, delayTime); + return this.buffer[this.readIdx]; + } +} + +export class Fold { + update(input = 0, rate = 0) { + if (rate < 0) rate = 0; + rate = rate + 1; + input = input * rate; + return 4 * (Math.abs(0.25 * input + 0.25 - Math.round(0.25 * input + 0.25)) - 0.25); + } +} + +export class Lag { + lagUnit = 4410; + s = 0; + update(input, rate) { + // Remap so the useful range is around [0, 1] + rate = rate * this.lagUnit; + if (rate < 1) rate = 1; + this.s += (1 / rate) * (input - this.s); + return this.s; + } +} + +export class Slew { + last = 0; + update(input, up, dn) { + const upStep = up * ISR; + const downStep = dn * ISR; + let delta = input - this.last; + if (delta > upStep) { + delta = upStep; + } else if (delta < -downStep) { + delta = -downStep; + } + this.last += delta; + return this.last; + } +} + +export function applyDistortion(x, amount) { + amount = Math.min(Math.max(amount, 0), 1); + amount -= 0.01; + var k = (2 * amount) / (1 - amount); + var y = ((1 + k) * x) / (1 + k * Math.abs(x)); + return y; +} + +export class Sequence { + clockSgn = true; + step = 0; + first = true; + update(clock, ...ins) { + if (!this.clockSgn && clock > 0) { + this.step = (this.step + 1) % ins.length; + this.clockSgn = clock > 0; + return 0; // set first sample to zero to retrigger gates on step change... + } + this.clockSgn = clock > 0; + return ins[this.step]; + } +} + +export function _rangex(sig, min, max) { + let logmin = Math.log(min); + let range = Math.log(max) - logmin; + const unipolar = (sig + 1) / 2; + return Math.exp(unipolar * range + logmin); +} + +// duplicate +export const getADSRValues = (params, curve = 'linear', defaultValues) => { + const envmin = curve === 'exponential' ? 0.001 : 0.001; + const releaseMin = 0.01; + const envmax = 1; + const [a, d, s, r] = params; + if (a == null && d == null && s == null && r == null) { + return defaultValues ?? [envmin, envmin, envmax, releaseMin]; + } + const sustain = s != null ? s : (a != null && d == null) || (a == null && d == null) ? envmax : envmin; + return [Math.max(a ?? 0, envmin), Math.max(d ?? 0, envmin), Math.min(sustain, envmax), Math.max(r ?? 0, releaseMin)]; +}; +let oscillators = { + sine: SineOsc, + saw: SawOsc, + zaw: ZawOsc, + sawtooth: SawOsc, + zawtooth: ZawOsc, + tri: TriOsc, + triangle: TriOsc, + pulse: PulseOsc, + dust: Dust, + impulse: Impulse, +}; + +const defaultDefaultValues = { + s: 'triangle', + gain: 0.8, + postgain: 1, + density: '.03', + ftype: '12db', + fanchor: 0, + resonance: 1, + hresonance: 1, + bandq: 1, + channels: [1, 2], + phaserdepth: 0.75, + shapevol: 1, + distortvol: 1, + delay: 0, + byteBeatExpression: '0', + delayfeedback: 0.5, + delaytime: 0.25, + orbit: 1, + i: 1, + velocity: 1, + fft: 8, + z: 'triangle', +}; + +let getDefaultValue = (key) => defaultDefaultValues[key]; + +export class Dough { + init(value) { + // params without defaults: + /* + bank, + source, + cutoff, + lpenv, + lpattack, + lpdecay, + lpsustain, + lprelease, + hpenv, + hcutoff, + hpattack, + hpdecay, + hpsustain, + hprelease, + bpenv, + bandf, + bpattack, + bpdecay, + bpsustain, + bprelease, + phaserrate, + phasersweep, + phasercenter, + coarse, + crush, + shape, + distort, + pan, + vowel, + room, + roomfade, + roomlp, + roomdim, + roomsize, + ir, + analyze, + */ + Object.assign(this, value); + // params with defaults: + this.s = this.s ?? getDefaultValue('s'); + this.gain = this.gain ?? getDefaultValue('gain'); + this.postgain = this.postgain ?? getDefaultValue('postgain'); + this.density = this.density ?? getDefaultValue('density'); + this.fanchor = this.fanchor ?? getDefaultValue('fanchor'); + this.drive = this.drive ?? 0.69; + this.resonance = this.resonance ?? getDefaultValue('resonance'); + this.hresonance = this.hresonance ?? getDefaultValue('hresonance'); + this.bandq = this.bandq ?? getDefaultValue('bandq'); + this.phaserdepth = this.phaserdepth ?? getDefaultValue('phaserdepth'); + this.shapevol = this.shapevol ?? getDefaultValue('shapevol'); + this.distortvol = this.distortvol ?? getDefaultValue('distortvol'); + this.delay = this.delay ?? getDefaultValue('delay'); + this.delayfeedback = this.delayfeedback ?? getDefaultValue('delayfeedback'); + this.delaytime = this.delaytime ?? getDefaultValue('delaytime'); + this.orbit = this.orbit ?? getDefaultValue('orbit'); + this.i = this.i ?? getDefaultValue('i'); + this.velocity = this.velocity ?? getDefaultValue('velocity'); + this.fft = this.fft ?? getDefaultValue('fft'); + + [this.attack, this.decay, this.sustain, this.release] = getADSRValues([ + this.attack, + this.decay, + this.sustain, + this.release, + ]); + + const SourceClass = oscillators[this.s] ?? TriOsc; + this._sound = new SourceClass(); + this._lpf = this.cutoff ? new Lpf() : null; + this._adsr = new ADSR(); + } + update(t) { + if (!this._sound) { + return 0; + } + // sound source + let s = this._sound.update(this.freq); + // lpf + s = this._lpf ? this._lpf.update(s, this.cutoff, this.resonance) : s; + // not sure if gain is applied here + s = s * this.gain; + // envelope + let gate = Number(t >= this._begin && t <= this._end); + const env = this._adsr.update(t, gate, this.attack, this.decay, this.sustain, this.release); + s = s * env; + s = s * this.postgain; + return s; + } +} diff --git a/packages/superdough/synth.mjs b/packages/superdough/synth.mjs index 834e54c6d..7d175d6c4 100644 --- a/packages/superdough/synth.mjs +++ b/packages/superdough/synth.mjs @@ -12,7 +12,7 @@ import { } from './helpers.mjs'; import { getNoiseMix, getNoiseOscillator } from './noise.mjs'; -const getFrequencyFromValue = (value) => { +export const getFrequencyFromValue = (value) => { let { note, freq } = value; note = note || 36; if (typeof note === 'string') { @@ -25,7 +25,7 @@ const getFrequencyFromValue = (value) => { return Number(freq); }; -function destroyAudioWorkletNode(node) { +export function destroyAudioWorkletNode(node) { if (node == null) { return; } diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 24f7434a9..43a21477b 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -4,6 +4,7 @@ import OLAProcessor from './ola-processor'; import FFT from './fft.js'; +import { Dough } from './dough.mjs'; const clamp = (num, min, max) => Math.min(Math.max(num, min), max); const _mod = (n, m) => ((n % m) + m) % m; @@ -895,3 +896,55 @@ class ByteBeatProcessor extends AudioWorkletProcessor { } registerProcessor('byte-beat-processor', ByteBeatProcessor); + +class DoughProcessor extends AudioWorkletProcessor { + constructor() { + super(); + this.dough = new Dough(); + this.port.onmessage = (event) => this.dough.init(event.data); + } + static get parameterDescriptors() { + return [ + { + name: 'begin', + defaultValue: 0, + max: Number.POSITIVE_INFINITY, + min: 0, + }, + { + name: 'end', + defaultValue: 0, + max: Number.POSITIVE_INFINITY, + min: 0, + }, + ]; + } + + process(inputs, outputs, params) { + if (this.disconnected) { + return false; + } + if (currentTime <= params.begin[0]) { + return true; + } + if (currentTime >= params.end[0]) { + return false; + } + if (this.t == null) { + this.t = params.begin[0] * sampleRate; + } + const output = outputs[0]; + for (let i = 0; i < output[0].length; i++) { + const out = this.dough.update(currentTime); + + for (let c = 0; c < output.length; c++) { + //prevent speaker blowout via clipping if threshold exceeds + output[c][i] = clamp(out, -1, 1); + } + this.t = this.t + 1; + } + return true; // keep the audio processing going + } +} + +registerProcessor('dough-processor', DoughProcessor); diff --git a/packages/webaudio/supradough.mjs b/packages/webaudio/supradough.mjs new file mode 100644 index 000000000..514d5e606 --- /dev/null +++ b/packages/webaudio/supradough.mjs @@ -0,0 +1,39 @@ +import { Pattern } from '@strudel/core'; +import { connectToDestination, destroyAudioWorkletNode, getAudioContext } from 'superdough'; + +Pattern.prototype.supradough = function () { + return this.onTrigger((_, hap, __, cps, begin) => { + const { value } = hap; + value.freq = getFrequencyFromValue(hap.value); + const ac = getAudioContext(); + + const release = getADSRValues( + [value.attack, value.decay, value.sustain, value.release], + 'linear', + [0.001, 0.05, 0.6, 0.01], + )[3]; + + const duration = hap.duration / cps; + const holdend = begin + duration; + const end = holdend + release + 0.01; + value._begin = begin; // these are needed for the gate signal + value._end = end; + + let o = getWorklet( + ac, + 'dough-processor', + { + begin, // we might not need these, as we could send them via postMessage below + end, + }, + { + outputChannelCount: [2], + }, + ); + + o.port.postMessage(value); // send value to worklet + let timeoutNode = webAudioTimeout(ac, () => destroyAudioWorkletNode(o), begin, end); + timeoutNode.stop(end + 0.125); + connectToDestination(o); // channels? + }, 1); +}; From 5336569c25dfa0440396a61cc919d7b2cd29af70 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 1 Jun 2025 21:20:28 +0200 Subject: [PATCH 002/335] proper lpf mapping + remove redundant worklet params, --- packages/superdough/dough.mjs | 19 ++++++++++++++--- packages/superdough/worklets.mjs | 36 +++++++++++--------------------- packages/webaudio/supradough.mjs | 5 +---- packages/webaudio/webaudio.mjs | 1 + 4 files changed, 30 insertions(+), 31 deletions(-) diff --git a/packages/superdough/dough.mjs b/packages/superdough/dough.mjs index f3365b06c..876cfdf11 100644 --- a/packages/superdough/dough.mjs +++ b/packages/superdough/dough.mjs @@ -351,7 +351,7 @@ const defaultDefaultValues = { let getDefaultValue = (key) => defaultDefaultValues[key]; export class Dough { - init(value) { + init(value, sampleRate) { // params without defaults: /* bank, @@ -424,6 +424,14 @@ export class Dough { this._sound = new SourceClass(); this._lpf = this.cutoff ? new Lpf() : null; this._adsr = new ADSR(); + + this.piOverSr = Math.PI / sampleRate; + this.eighthOverLogHalf = 0.125 / Math.log(0.5); + } + // credits to pulu: https://github.com/felixroos/kabelsalat/issues/35 + freq2cutoff(freq) { + const c = 2 * Math.sin(freq * this.piOverSr); + return 1 - Math.log(c) * this.eighthOverLogHalf; } update(t) { if (!this._sound) { @@ -432,14 +440,19 @@ export class Dough { // sound source let s = this._sound.update(this.freq); // lpf - s = this._lpf ? this._lpf.update(s, this.cutoff, this.resonance) : s; + if (this._lpf) { + const cutoff = this.freq2cutoff(this.cutoff); + s = this._lpf ? this._lpf.update(s, cutoff, this.resonance) : s; + } // not sure if gain is applied here s = s * this.gain; // envelope let gate = Number(t >= this._begin && t <= this._end); + /* Math.random() > 0.99 && console.log('gate', gate); */ const env = this._adsr.update(t, gate, this.attack, this.decay, this.sustain, this.release); s = s * env; - s = s * this.postgain; + + s = s * this.postgain * 0.3; return s; } } diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 43a21477b..7633c6441 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -901,42 +901,30 @@ class DoughProcessor extends AudioWorkletProcessor { constructor() { super(); this.dough = new Dough(); - this.port.onmessage = (event) => this.dough.init(event.data); - } - static get parameterDescriptors() { - return [ - { - name: 'begin', - defaultValue: 0, - max: Number.POSITIVE_INFINITY, - min: 0, - }, - { - name: 'end', - defaultValue: 0, - max: Number.POSITIVE_INFINITY, - min: 0, - }, - ]; + this.port.onmessage = (event) => this.dough.init(event.data, sampleRate); } process(inputs, outputs, params) { if (this.disconnected) { return false; } - if (currentTime <= params.begin[0]) { + if (this.dough._begin === undefined) { return true; } - if (currentTime >= params.end[0]) { - return false; + if (currentTime <= this.dough._begin) { + return true; } - if (this.t == null) { - this.t = params.begin[0] * sampleRate; + if (currentTime >= this.dough._end + 1) { + return false; // this causes cracks for some reason (seems to kick in too early for some reason) + // it works with + 1 but not sure why this is needed + } + if (this.t === undefined) { + this.t = Math.floor(this.dough._begin * sampleRate); } const output = outputs[0]; for (let i = 0; i < output[0].length; i++) { - const out = this.dough.update(currentTime); - + // const out = this.dough.update(currentTime); + const out = this.dough.update(this.t / sampleRate); for (let c = 0; c < output.length; c++) { //prevent speaker blowout via clipping if threshold exceeds output[c][i] = clamp(out, -1, 1); diff --git a/packages/webaudio/supradough.mjs b/packages/webaudio/supradough.mjs index 514d5e606..8887a4132 100644 --- a/packages/webaudio/supradough.mjs +++ b/packages/webaudio/supradough.mjs @@ -22,10 +22,7 @@ Pattern.prototype.supradough = function () { let o = getWorklet( ac, 'dough-processor', - { - begin, // we might not need these, as we could send them via postMessage below - end, - }, + {}, { outputChannelCount: [2], }, diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 44a683480..8f7d041a9 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -6,6 +6,7 @@ This program is free software: you can redistribute it and/or modify it under th import * as strudel from '@strudel/core'; import { superdough, getAudioContext, setLogger, doughTrigger } from 'superdough'; +import './supradough.mjs'; const { Pattern, logger, repl } = strudel; setLogger(logger); From 5129fa667791abb0498f189a0ea3c7c506eac61c Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Wed, 4 Jun 2025 00:48:32 +0100 Subject: [PATCH 003/335] fix click --- packages/superdough/dough.mjs | 7 +++++-- packages/webaudio/supradough.mjs | 11 +++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/superdough/dough.mjs b/packages/superdough/dough.mjs index 876cfdf11..bff024150 100644 --- a/packages/superdough/dough.mjs +++ b/packages/superdough/dough.mjs @@ -146,6 +146,7 @@ export class ADSR { startVal = 0; update(curTime, gate, attack, decay, susVal, release) { + console.info('here') switch (this.state) { case 'off': { if (gate > 0) { @@ -352,6 +353,7 @@ let getDefaultValue = (key) => defaultDefaultValues[key]; export class Dough { init(value, sampleRate) { + // params without defaults: /* bank, @@ -447,12 +449,13 @@ export class Dough { // not sure if gain is applied here s = s * this.gain; // envelope - let gate = Number(t >= this._begin && t <= this._end); + let gate = Number(t >= this._begin && t <= this._holdEnd); + /* Math.random() > 0.99 && console.log('gate', gate); */ const env = this._adsr.update(t, gate, this.attack, this.decay, this.sustain, this.release); s = s * env; - s = s * this.postgain * 0.3; + s = s * this.postgain * .3 return s; } } diff --git a/packages/webaudio/supradough.mjs b/packages/webaudio/supradough.mjs index 8887a4132..dcf2cf4c0 100644 --- a/packages/webaudio/supradough.mjs +++ b/packages/webaudio/supradough.mjs @@ -1,6 +1,5 @@ import { Pattern } from '@strudel/core'; -import { connectToDestination, destroyAudioWorkletNode, getAudioContext } from 'superdough'; - +import { connectToDestination, destroyAudioWorkletNode, getAudioContext, webAudioTimeout } from 'superdough'; Pattern.prototype.supradough = function () { return this.onTrigger((_, hap, __, cps, begin) => { const { value } = hap; @@ -14,10 +13,11 @@ Pattern.prototype.supradough = function () { )[3]; const duration = hap.duration / cps; - const holdend = begin + duration; - const end = holdend + release + 0.01; + const holdEnd = begin + duration; + const end = holdEnd + release + 0.01; value._begin = begin; // these are needed for the gate signal value._end = end; + value._holdEnd = holdEnd let o = getWorklet( ac, @@ -29,8 +29,7 @@ Pattern.prototype.supradough = function () { ); o.port.postMessage(value); // send value to worklet - let timeoutNode = webAudioTimeout(ac, () => destroyAudioWorkletNode(o), begin, end); - timeoutNode.stop(end + 0.125); + webAudioTimeout(ac, () => destroyAudioWorkletNode(o), begin, end); connectToDestination(o); // channels? }, 1); }; From ff4b7ca1718fc7ffd409f6bd62b3e1234d7acd38 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Wed, 4 Jun 2025 01:08:36 +0100 Subject: [PATCH 004/335] fix volume --- packages/superdough/dough.mjs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/superdough/dough.mjs b/packages/superdough/dough.mjs index bff024150..32ca86ef7 100644 --- a/packages/superdough/dough.mjs +++ b/packages/superdough/dough.mjs @@ -146,7 +146,6 @@ export class ADSR { startVal = 0; update(curTime, gate, attack, decay, susVal, release) { - console.info('here') switch (this.state) { case 'off': { if (gate > 0) { @@ -191,6 +190,7 @@ export class ADSR { } case 'release': { let time = curTime - this.startTime; + if (time > release) { this.state = 'off'; return 0; @@ -353,7 +353,7 @@ let getDefaultValue = (key) => defaultDefaultValues[key]; export class Dough { init(value, sampleRate) { - + // params without defaults: /* bank, @@ -455,7 +455,7 @@ export class Dough { const env = this._adsr.update(t, gate, this.attack, this.decay, this.sustain, this.release); s = s * env; - s = s * this.postgain * .3 + s = s * this.postgain * .2 return s; } } From 930dabe4d6e4952445b952cb88c04a0bef49ee1d Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 5 Jun 2025 09:54:44 +0200 Subject: [PATCH 005/335] dough as a singleton worklet with voice allocation --- packages/superdough/dough.mjs | 78 ++++++++++++++++++++++++++++++-- packages/superdough/worklets.mjs | 25 +++------- packages/webaudio/supradough.mjs | 40 ++++++++++------ 3 files changed, 104 insertions(+), 39 deletions(-) diff --git a/packages/superdough/dough.mjs b/packages/superdough/dough.mjs index 32ca86ef7..65cc3793f 100644 --- a/packages/superdough/dough.mjs +++ b/packages/superdough/dough.mjs @@ -351,9 +351,8 @@ const defaultDefaultValues = { let getDefaultValue = (key) => defaultDefaultValues[key]; -export class Dough { - init(value, sampleRate) { - +export class DoughVoice { + constructor(value) { // params without defaults: /* bank, @@ -427,7 +426,7 @@ export class Dough { this._lpf = this.cutoff ? new Lpf() : null; this._adsr = new ADSR(); - this.piOverSr = Math.PI / sampleRate; + this.piOverSr = Math.PI / value.sampleRate; this.eighthOverLogHalf = 0.125 / Math.log(0.5); } // credits to pulu: https://github.com/felixroos/kabelsalat/issues/35 @@ -455,7 +454,76 @@ export class Dough { const env = this._adsr.update(t, gate, this.attack, this.decay, this.sustain, this.release); s = s * env; - s = s * this.postgain * .2 + s = s * this.postgain * 0.2; return s; } } + +// this class is the interface to the "outer world" +// it handles spawning and despawning of DoughVoice's +export class Dough { + voices = []; // DoughVoice[] + vid = 0; + q = []; + l = 0; // tbd + r = 0; // tbd + t = 0; + // sampleRate: number, currentTime: number (seconds) + constructor(sampleRate, currentTime) { + this.sampleRate = sampleRate; + this.t = Math.floor(currentTime * sampleRate); // samples + // console.log('init dough', this.sampleRate, this.t); + } + scheduleSpawn(value) { + const time = value._begin; // set from supradough.mjs + this.schedule({ time, type: 'spawn', arg: value }); + } + spawn(value) { + value.id = this.vid++; + const voice = new DoughVoice(value); + this.voices.push(voice); + console.log('spawn', voice.id, value._holdDuration, 'voices:', this.voices.length); + // schedule removal + const endTime = Math.ceil(value._end * this.sampleRate); + this.schedule({ time: endTime /* + 48000 */, type: 'despawn', arg: voice.id }); + } + despawn(vid) { + this.voices = this.voices.filter((v) => v.id !== vid); + console.log('despawn', vid, 'voices:', this.voices.length); + } + // schedules a function call with a single argument + // msg = {time:number,type:string, arg: any} + // the Dough method "type" will be called with "arg" at "time" + schedule(msg) { + if (!this.q.length) { + // if empty, just push + this.q.push(msg); + return; + } + // not empty + // find index where msg.time fits in + let i = 0; + while (i < this.q.length && this.q[i].time < msg.time) { + i++; + } + // this ensures q stays sorted by time, so we only need to check q[0] + this.q.splice(i, 0, msg); + } + // maybe update should be called once per block instead for perf reasons? + update() { + // go over q + while (this.q.length > 0 && this.q[0].time <= this.t) { + // console.log('schedule', this.q[0]); + // trigger due messages. q is sorted, so we only need to check q[0] + this[this.q[0].type](this.q[0].arg); // type is expected to be a Dough method + this.q.shift(); + } + // add active voices + let sum = 0; + for (let v = 0; v < this.voices.length; v++) { + sum += this.voices[v].update(this.t / this.sampleRate); + } + this.t++; + return sum; + } +} diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 7633c6441..5e5494255 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -900,36 +900,23 @@ registerProcessor('byte-beat-processor', ByteBeatProcessor); class DoughProcessor extends AudioWorkletProcessor { constructor() { super(); - this.dough = new Dough(); - this.port.onmessage = (event) => this.dough.init(event.data, sampleRate); + this.dough = new Dough(sampleRate, currentTime); + this.port.onmessage = (event) => { + event.data.sampleRate = sampleRate; + this.dough.scheduleSpawn(event.data); + }; } - process(inputs, outputs, params) { if (this.disconnected) { return false; } - if (this.dough._begin === undefined) { - return true; - } - if (currentTime <= this.dough._begin) { - return true; - } - if (currentTime >= this.dough._end + 1) { - return false; // this causes cracks for some reason (seems to kick in too early for some reason) - // it works with + 1 but not sure why this is needed - } - if (this.t === undefined) { - this.t = Math.floor(this.dough._begin * sampleRate); - } const output = outputs[0]; for (let i = 0; i < output[0].length; i++) { - // const out = this.dough.update(currentTime); - const out = this.dough.update(this.t / sampleRate); + const out = this.dough.update(); for (let c = 0; c < output.length; c++) { //prevent speaker blowout via clipping if threshold exceeds output[c][i] = clamp(out, -1, 1); } - this.t = this.t + 1; } return true; // keep the audio processing going } diff --git a/packages/webaudio/supradough.mjs b/packages/webaudio/supradough.mjs index dcf2cf4c0..f774b7180 100644 --- a/packages/webaudio/supradough.mjs +++ b/packages/webaudio/supradough.mjs @@ -1,10 +1,27 @@ import { Pattern } from '@strudel/core'; -import { connectToDestination, destroyAudioWorkletNode, getAudioContext, webAudioTimeout } from 'superdough'; +import { connectToDestination, getAudioContext, getWorklet } from 'superdough'; + +let doughWorklet; + +function initDoughWorklet() { + const ac = getAudioContext(); + doughWorklet = getWorklet( + ac, + 'dough-processor', + {}, + { + outputChannelCount: [2], + }, + ); + /* webAudioTimeout(ac, () => destroyAudioWorkletNode(doughWorklet), begin, end); */ + connectToDestination(doughWorklet); // channels? +} + Pattern.prototype.supradough = function () { return this.onTrigger((_, hap, __, cps, begin) => { const { value } = hap; + // todo: could these calculations be made inside dough as well? value.freq = getFrequencyFromValue(hap.value); - const ac = getAudioContext(); const release = getADSRValues( [value.attack, value.decay, value.sustain, value.release], @@ -17,19 +34,12 @@ Pattern.prototype.supradough = function () { const end = holdEnd + release + 0.01; value._begin = begin; // these are needed for the gate signal value._end = end; - value._holdEnd = holdEnd + value._holdEnd = holdEnd; + value._holdDuration = duration + release; - let o = getWorklet( - ac, - 'dough-processor', - {}, - { - outputChannelCount: [2], - }, - ); - - o.port.postMessage(value); // send value to worklet - webAudioTimeout(ac, () => destroyAudioWorkletNode(o), begin, end); - connectToDestination(o); // channels? + if (!doughWorklet) { + initDoughWorklet(); + } + doughWorklet.port.postMessage(value); }, 1); }; From 2cbd35f6d2a964331b199530ea2be80c1b6e5491 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 5 Jun 2025 10:26:14 +0200 Subject: [PATCH 006/335] refactor: make webaudio glue as minimal as possible --- packages/superdough/dough.mjs | 36 ++++++++++++++++++++++++++++++-- packages/webaudio/supradough.mjs | 22 +++---------------- 2 files changed, 37 insertions(+), 21 deletions(-) diff --git a/packages/superdough/dough.mjs b/packages/superdough/dough.mjs index 65cc3793f..032bb5a69 100644 --- a/packages/superdough/dough.mjs +++ b/packages/superdough/dough.mjs @@ -311,6 +311,7 @@ export const getADSRValues = (params, curve = 'linear', defaultValues) => { const sustain = s != null ? s : (a != null && d == null) || (a == null && d == null) ? envmax : envmin; return [Math.max(a ?? 0, envmin), Math.max(d ?? 0, envmin), Math.min(sustain, envmax), Math.max(r ?? 0, releaseMin)]; }; + let oscillators = { sine: SineOsc, saw: SawOsc, @@ -351,6 +352,33 @@ const defaultDefaultValues = { let getDefaultValue = (key) => defaultDefaultValues[key]; +const chromas = { c: 0, d: 2, e: 4, f: 5, g: 7, a: 9, b: 11 }; +const accs = { '#': 1, b: -1, s: 1, f: -1 }; +const note2midi = (note, defaultOctave = 3) => { + const [pc, acc = '', oct = defaultOctave] = + String(note) + .match(/^([a-gA-G])([#bsf]*)([0-9]*)$/) + ?.slice(1) || []; + if (!pc) { + throw new Error('not a note: "' + note + '"'); + } + const chroma = chromas[pc.toLowerCase()]; + const offset = acc?.split('').reduce((o, char) => o + accs[char], 0) || 0; + return (Number(oct) + 1) * 12 + chroma + offset; +}; +const getFrequency = (value) => { + let { note, freq } = value; + note = note || 36; + if (typeof note === 'string') { + note = note2midi(note); // e.g. c3 => 48 + } + if (!freq && typeof note === 'number') { + freq = Math.pow(2, (note - 69) / 12) * 440; + } + + return Number(freq); +}; + export class DoughVoice { constructor(value) { // params without defaults: @@ -392,6 +420,7 @@ export class DoughVoice { ir, analyze, */ + value.freq = getFrequency(value); Object.assign(this, value); // params with defaults: this.s = this.s ?? getDefaultValue('s'); @@ -421,6 +450,9 @@ export class DoughVoice { this.release, ]); + this._holdEnd = this._begin + this._duration; // needed for gate + this._end = this._holdEnd + this.release + 0.01; // needed for despawn + const SourceClass = oscillators[this.s] ?? TriOsc; this._sound = new SourceClass(); this._lpf = this.cutoff ? new Lpf() : null; @@ -482,9 +514,9 @@ export class Dough { value.id = this.vid++; const voice = new DoughVoice(value); this.voices.push(voice); - console.log('spawn', voice.id, value._holdDuration, 'voices:', this.voices.length); + console.log('spawn', voice.id, 'voices:', this.voices.length); // schedule removal - const endTime = Math.ceil(value._end * this.sampleRate); + const endTime = Math.ceil(voice._end * this.sampleRate); this.schedule({ time: endTime /* + 48000 */, type: 'despawn', arg: voice.id }); } despawn(vid) { diff --git a/packages/webaudio/supradough.mjs b/packages/webaudio/supradough.mjs index f774b7180..8df18bed6 100644 --- a/packages/webaudio/supradough.mjs +++ b/packages/webaudio/supradough.mjs @@ -13,33 +13,17 @@ function initDoughWorklet() { outputChannelCount: [2], }, ); - /* webAudioTimeout(ac, () => destroyAudioWorkletNode(doughWorklet), begin, end); */ connectToDestination(doughWorklet); // channels? } Pattern.prototype.supradough = function () { return this.onTrigger((_, hap, __, cps, begin) => { - const { value } = hap; - // todo: could these calculations be made inside dough as well? - value.freq = getFrequencyFromValue(hap.value); - - const release = getADSRValues( - [value.attack, value.decay, value.sustain, value.release], - 'linear', - [0.001, 0.05, 0.6, 0.01], - )[3]; - - const duration = hap.duration / cps; - const holdEnd = begin + duration; - const end = holdEnd + release + 0.01; - value._begin = begin; // these are needed for the gate signal - value._end = end; - value._holdEnd = holdEnd; - value._holdDuration = duration + release; + hap.value._begin = begin; + hap.value._duration = hap.duration / cps; if (!doughWorklet) { initDoughWorklet(); } - doughWorklet.port.postMessage(value); + doughWorklet.port.postMessage(hap.value); }, 1); }; From f0e6c5483c012de6d4c5de79fa2ac301a0c9ae94 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 5 Jun 2025 10:30:53 +0200 Subject: [PATCH 007/335] handle invalid spawns + remove logs --- packages/superdough/dough.mjs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/superdough/dough.mjs b/packages/superdough/dough.mjs index 032bb5a69..7261c4a5a 100644 --- a/packages/superdough/dough.mjs +++ b/packages/superdough/dough.mjs @@ -507,6 +507,12 @@ export class Dough { // console.log('init dough', this.sampleRate, this.t); } scheduleSpawn(value) { + if (value._begin === undefined) { + throw new Error('[dough]: scheduleSpawn expected _begin to be set'); + } + if (value._duration === undefined) { + throw new Error('[dough]: scheduleSpawn expected _duration to be set'); + } const time = value._begin; // set from supradough.mjs this.schedule({ time, type: 'spawn', arg: value }); } @@ -514,14 +520,14 @@ export class Dough { value.id = this.vid++; const voice = new DoughVoice(value); this.voices.push(voice); - console.log('spawn', voice.id, 'voices:', this.voices.length); + // console.log('spawn', voice.id, 'voices:', this.voices.length); // schedule removal const endTime = Math.ceil(voice._end * this.sampleRate); this.schedule({ time: endTime /* + 48000 */, type: 'despawn', arg: voice.id }); } despawn(vid) { this.voices = this.voices.filter((v) => v.id !== vid); - console.log('despawn', vid, 'voices:', this.voices.length); + // console.log('despawn', vid, 'voices:', this.voices.length); } // schedules a function call with a single argument // msg = {time:number,type:string, arg: any} From ccec7e725ab6344d8a4e58828f6b1cba1c85f776 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 5 Jun 2025 11:04:55 +0200 Subject: [PATCH 008/335] poc: render pattern audio with node script --- packages/superdough/.gitignore | 1 + packages/superdough/dough-export.mjs | 61 ++++++++++++++++++++++++++++ packages/superdough/dough.mjs | 15 +++---- packages/superdough/package.json | 3 +- packages/superdough/worklets.mjs | 5 +-- pnpm-lock.yaml | 8 ++++ 6 files changed, 81 insertions(+), 12 deletions(-) create mode 100644 packages/superdough/.gitignore create mode 100644 packages/superdough/dough-export.mjs diff --git a/packages/superdough/.gitignore b/packages/superdough/.gitignore new file mode 100644 index 000000000..d21cbdf3e --- /dev/null +++ b/packages/superdough/.gitignore @@ -0,0 +1 @@ +pattern.wav diff --git a/packages/superdough/dough-export.mjs b/packages/superdough/dough-export.mjs new file mode 100644 index 000000000..5f8b9a8ee --- /dev/null +++ b/packages/superdough/dough-export.mjs @@ -0,0 +1,61 @@ +// this is a poc of how a pattern can be rendered as a wav file using node +// run via: node dough-export.mjs +import fs from 'node:fs'; +import WavEncoder from 'wav-encoder'; +import { evalScope } from '@strudel/core'; +import { miniAllStrings } from '@strudel/mini'; +import { Dough } from './dough.mjs'; + +await evalScope( + import('@strudel/core'), + import('@strudel/mini'), + import('@strudel/tonal'), + // import('@strudel/tonal'), +); + +miniAllStrings(); // allows using single quotes for mini notation / skip transpilation + +let sampleRate = 48000, + cps = 0.5; + +let pat = note('[c e g b]*3') + .add(note(7)) + .lpf(sine.rangex(200, 4000).slow(2)) + .lpq(0.3) + .s('*2') + .att(0.01) + .rel(0.2) + .clip(2) + .delay(0.5) + .jux(rev) + .sometimes(add(note(12))) + .gain(0.25) + .slow(1 / cps); + +let cycles = 4; +let seconds = cycles + 1; // 1s release tail +const haps = pat.queryArc(0, cycles); + +const dough = new Dough(sampleRate); + +console.log('spawn voices...'); +haps.forEach((hap) => { + hap.value._begin = Number(hap.whole.begin); + hap.value._duration = hap.duration / cps; + dough.scheduleSpawn(hap.value); +}); +console.log(`render ${seconds}s long buffer...`); +const buffer = new Float32Array(seconds * sampleRate); +while (dough.t <= buffer.length) { + buffer[dough.t] = dough.update(); +} +console.log('done!'); + +const patternAudio = { + sampleRate, + channelData: [buffer], +}; + +WavEncoder.encode(patternAudio).then((buffer) => { + fs.writeFileSync('pattern.wav', new Float32Array(buffer)); +}); diff --git a/packages/superdough/dough.mjs b/packages/superdough/dough.mjs index 7261c4a5a..21918f95b 100644 --- a/packages/superdough/dough.mjs +++ b/packages/superdough/dough.mjs @@ -1,12 +1,12 @@ // this is dough, the superdough without dependencies - -const ISR = 1 / sampleRate; +const SAMPLE_RATE = typeof sampleRate !== 'undefined' ? sampleRate : 48000; +const ISR = 1 / SAMPLE_RATE; // https://garten.salat.dev/audio-DSP/oscillators.html export class SineOsc { phase = 0; update(freq) { const value = Math.sin(this.phase * 2 * Math.PI); - this.phase = (this.phase + freq / sampleRate) % 1; + this.phase = (this.phase + freq / SAMPLE_RATE) % 1; return value; } } @@ -39,7 +39,7 @@ export class SawOsc { //phase = Math.random(); phase = 0; update(freq) { - const dt = freq / sampleRate; + const dt = freq / SAMPLE_RATE; let p = polyBlep(this.phase, dt); let s = 2 * this.phase - 1 - p; this.phase += dt; @@ -216,12 +216,12 @@ const MAX_DELAY_TIME = 10; export class Delay { writeIdx = 0; readIdx = 0; - buffer = new Float32Array(MAX_DELAY_TIME * sampleRate); // .fill(0) + buffer = new Float32Array(MAX_DELAY_TIME * SAMPLE_RATE); // .fill(0) write(s, delayTime) { this.writeIdx = (this.writeIdx + 1) % this.buffer.length; this.buffer[this.writeIdx] = s; // Calculate how far in the past to read - let numSamples = Math.min(Math.floor(sampleRate * delayTime), this.buffer.length - 1); + let numSamples = Math.min(Math.floor(SAMPLE_RATE * delayTime), this.buffer.length - 1); this.readIdx = this.writeIdx - numSamples; // If past the start of the buffer, wrap around if (this.readIdx < 0) this.readIdx += this.buffer.length; @@ -501,7 +501,7 @@ export class Dough { r = 0; // tbd t = 0; // sampleRate: number, currentTime: number (seconds) - constructor(sampleRate, currentTime) { + constructor(sampleRate = 48000, currentTime = 0) { this.sampleRate = sampleRate; this.t = Math.floor(currentTime * sampleRate); // samples // console.log('init dough', this.sampleRate, this.t); @@ -513,6 +513,7 @@ export class Dough { if (value._duration === undefined) { throw new Error('[dough]: scheduleSpawn expected _duration to be set'); } + value.sampleRate = this.sampleRate; const time = value._begin; // set from supradough.mjs this.schedule({ time, type: 'spawn', arg: value }); } diff --git a/packages/superdough/package.json b/packages/superdough/package.json index a835f252d..6b45144e4 100644 --- a/packages/superdough/package.json +++ b/packages/superdough/package.json @@ -33,7 +33,8 @@ "homepage": "https://github.com/tidalcycles/strudel#readme", "devDependencies": { "vite": "^6.0.11", - "vite-plugin-bundle-audioworklet": "workspace:*" + "vite-plugin-bundle-audioworklet": "workspace:*", + "wav-encoder": "^1.3.0" }, "dependencies": { "nanostores": "^0.11.3" diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 5e5494255..2edcc6f53 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -901,10 +901,7 @@ class DoughProcessor extends AudioWorkletProcessor { constructor() { super(); this.dough = new Dough(sampleRate, currentTime); - this.port.onmessage = (event) => { - event.data.sampleRate = sampleRate; - this.dough.scheduleSpawn(event.data); - }; + this.port.onmessage = (event) => this.dough.scheduleSpawn(event.data); } process(inputs, outputs, params) { if (this.disconnected) { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a23c80924..ed8a7c014 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -485,6 +485,9 @@ importers: vite-plugin-bundle-audioworklet: specifier: workspace:* version: link:../vite-plugin-bundle-audioworklet + wav-encoder: + specifier: ^1.3.0 + version: 1.3.0 packages/tidal: dependencies: @@ -7464,6 +7467,9 @@ packages: walk-up-path@3.0.1: resolution: {integrity: sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==} + wav-encoder@1.3.0: + resolution: {integrity: sha512-FXJdEu2qDOI+wbVYZpu21CS1vPEg5NaxNskBr4SaULpOJMrLE6xkH8dECa7PiS+ZoeyvP7GllWUAxPN3AvFSEw==} + wav@1.0.2: resolution: {integrity: sha512-viHtz3cDd/Tcr/HbNqzQCofKdF6kWUymH9LGDdskfWFoIy/HJ+RTihgjEcHfnsy1PO4e9B+y4HwgTwMrByquhg==} @@ -15839,6 +15845,8 @@ snapshots: walk-up-path@3.0.1: {} + wav-encoder@1.3.0: {} + wav@1.0.2: dependencies: buffer-alloc: 1.2.0 From 87598e10d1c1af739cfc26f9efebe6e0039f6be1 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 6 Jun 2025 08:17:20 +0200 Subject: [PATCH 009/335] coarse --- packages/superdough/dough.mjs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/packages/superdough/dough.mjs b/packages/superdough/dough.mjs index 21918f95b..b6ded0d15 100644 --- a/packages/superdough/dough.mjs +++ b/packages/superdough/dough.mjs @@ -292,6 +292,19 @@ export class Sequence { } } +// sample rate bit crusher +export class Coarse { + hold = 0; + t = 0; + update(input, coarse) { + if (this.t++ % coarse === 0) { + this.t = 0; + this.hold = input; + } + return this.hold; + } +} + export function _rangex(sig, min, max) { let logmin = Math.log(min); let range = Math.log(max) - logmin; @@ -457,6 +470,7 @@ export class DoughVoice { this._sound = new SourceClass(); this._lpf = this.cutoff ? new Lpf() : null; this._adsr = new ADSR(); + this._coarse = this.coarse ? new Coarse() : null; this.piOverSr = Math.PI / value.sampleRate; this.eighthOverLogHalf = 0.125 / Math.log(0.5); @@ -475,7 +489,10 @@ export class DoughVoice { // lpf if (this._lpf) { const cutoff = this.freq2cutoff(this.cutoff); - s = this._lpf ? this._lpf.update(s, cutoff, this.resonance) : s; + s = this._lpf.update(s, cutoff, this.resonance); + } + if (this._coarse) { + s = this._coarse.update(s, this.coarse); } // not sure if gain is applied here s = s * this.gain; From 0cc18a64682c7f984f549e0e0240694e0721811e Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 6 Jun 2025 08:27:47 +0200 Subject: [PATCH 010/335] crush (might be wrong) --- packages/superdough/dough.mjs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/superdough/dough.mjs b/packages/superdough/dough.mjs index b6ded0d15..bd226cc72 100644 --- a/packages/superdough/dough.mjs +++ b/packages/superdough/dough.mjs @@ -305,6 +305,15 @@ export class Coarse { } } +// amplitude bit crusher +export class Crush { + update(input, crush) { + crush = Math.max(1, crush); + const x = Math.pow(2, crush - 1); + return Math.round(input * x) / x; + } +} + export function _rangex(sig, min, max) { let logmin = Math.log(min); let range = Math.log(max) - logmin; @@ -471,6 +480,7 @@ export class DoughVoice { this._lpf = this.cutoff ? new Lpf() : null; this._adsr = new ADSR(); this._coarse = this.coarse ? new Coarse() : null; + this._crush = this.crush ? new Crush() : null; this.piOverSr = Math.PI / value.sampleRate; this.eighthOverLogHalf = 0.125 / Math.log(0.5); @@ -494,6 +504,9 @@ export class DoughVoice { if (this._coarse) { s = this._coarse.update(s, this.coarse); } + if (this._crush) { + s = this._crush.update(s, this.crush); + } // not sure if gain is applied here s = s * this.gain; // envelope From 623bf9336865de8ff68bc8d2387a67e2ee412e6e Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 6 Jun 2025 08:50:02 +0200 Subject: [PATCH 011/335] panning --- packages/superdough/dough.mjs | 25 +++++++++++++++++++------ packages/superdough/worklets.mjs | 4 ++-- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/packages/superdough/dough.mjs b/packages/superdough/dough.mjs index bd226cc72..e6190f140 100644 --- a/packages/superdough/dough.mjs +++ b/packages/superdough/dough.mjs @@ -370,6 +370,7 @@ const defaultDefaultValues = { velocity: 1, fft: 8, z: 'triangle', + pan: 0.5, }; let getDefaultValue = (key) => defaultDefaultValues[key]; @@ -402,6 +403,8 @@ const getFrequency = (value) => { }; export class DoughVoice { + l = 0; + r = 0; constructor(value) { // params without defaults: /* @@ -464,6 +467,7 @@ export class DoughVoice { this.i = this.i ?? getDefaultValue('i'); this.velocity = this.velocity ?? getDefaultValue('velocity'); this.fft = this.fft ?? getDefaultValue('fft'); + this.pan = this.pan ?? getDefaultValue('pan'); [this.attack, this.decay, this.sustain, this.release] = getADSRValues([ this.attack, @@ -517,7 +521,15 @@ export class DoughVoice { s = s * env; s = s * this.postgain * 0.2; - return s; + + if (this.pan === 0.5) { + this.l = this.r = s; // mono + } else { + // stereo + const pos = (this.pan * Math.PI) / 2; + this.l = s * Math.cos(pos); + this.r = s * Math.sin(pos); + } } } @@ -527,8 +539,7 @@ export class Dough { voices = []; // DoughVoice[] vid = 0; q = []; - l = 0; // tbd - r = 0; // tbd + channels = [0, 0]; t = 0; // sampleRate: number, currentTime: number (seconds) constructor(sampleRate = 48000, currentTime = 0) { @@ -588,11 +599,13 @@ export class Dough { this.q.shift(); } // add active voices - let sum = 0; + this.channels[0] = 0; + this.channels[1] = 0; for (let v = 0; v < this.voices.length; v++) { - sum += this.voices[v].update(this.t / this.sampleRate); + this.voices[v].update(this.t / this.sampleRate); + this.channels[0] += this.voices[v].l; + this.channels[1] += this.voices[v].r; } this.t++; - return sum; } } diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 2edcc6f53..d8f189779 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -909,10 +909,10 @@ class DoughProcessor extends AudioWorkletProcessor { } const output = outputs[0]; for (let i = 0; i < output[0].length; i++) { - const out = this.dough.update(); + this.dough.update(); for (let c = 0; c < output.length; c++) { //prevent speaker blowout via clipping if threshold exceeds - output[c][i] = clamp(out, -1, 1); + output[c][i] = clamp(this.dough.channels[c], -1, 1); } } return true; // keep the audio processing going From 9ed690ce4551a471beb7784208f2fc275f7a808e Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 6 Jun 2025 09:37:40 +0200 Subject: [PATCH 012/335] pulse osc + velocity --- packages/superdough/dough.mjs | 38 ++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/packages/superdough/dough.mjs b/packages/superdough/dough.mjs index e6190f140..323e78d5c 100644 --- a/packages/superdough/dough.mjs +++ b/packages/superdough/dough.mjs @@ -82,7 +82,25 @@ export class Lpf { } } -export class PulseOsc { +class PulseOsc { + constructor(phase = 0) { + this.phase = phase; + } + saw(offset, dt) { + let phase = (this.phase + offset) % 1; + let p = polyBlep(phase, dt); + return 2 * phase - 1 - p; + } + update(freq, pw = 0.5) { + const dt = freq / sampleRate; + let pulse = this.saw(0, dt) - this.saw(pw, dt); + this.phase = (this.phase + dt) % 1; + return pulse + pw * 2 - 1; + } +} + +// non bandlimited (has aliasing) +export class PulzeOsc { phase = 0; update(freq, duty = 0.5) { this.phase += ISR * freq; @@ -343,14 +361,16 @@ let oscillators = { tri: TriOsc, triangle: TriOsc, pulse: PulseOsc, + pulze: PulzeOsc, dust: Dust, impulse: Impulse, }; const defaultDefaultValues = { s: 'triangle', - gain: 0.8, + gain: 1, postgain: 1, + velocity: 1, density: '.03', ftype: '12db', fanchor: 0, @@ -367,7 +387,6 @@ const defaultDefaultValues = { delaytime: 0.25, orbit: 1, i: 1, - velocity: 1, fft: 8, z: 'triangle', pan: 0.5, @@ -450,6 +469,7 @@ export class DoughVoice { // params with defaults: this.s = this.s ?? getDefaultValue('s'); this.gain = this.gain ?? getDefaultValue('gain'); + this.velocity = this.velocity ?? getDefaultValue('velocity'); this.postgain = this.postgain ?? getDefaultValue('postgain'); this.density = this.density ?? getDefaultValue('density'); this.fanchor = this.fanchor ?? getDefaultValue('fanchor'); @@ -465,7 +485,6 @@ export class DoughVoice { this.delaytime = this.delaytime ?? getDefaultValue('delaytime'); this.orbit = this.orbit ?? getDefaultValue('orbit'); this.i = this.i ?? getDefaultValue('i'); - this.velocity = this.velocity ?? getDefaultValue('velocity'); this.fft = this.fft ?? getDefaultValue('fft'); this.pan = this.pan ?? getDefaultValue('pan'); @@ -498,8 +517,13 @@ export class DoughVoice { if (!this._sound) { return 0; } + let s = 0; // sound source - let s = this._sound.update(this.freq); + if (this.s === 'pulse') { + s = this._sound.update(this.freq, this.pw ?? 0.5); + } else { + s = this._sound.update(this.freq); + } // lpf if (this._lpf) { const cutoff = this.freq2cutoff(this.cutoff); @@ -511,8 +535,8 @@ export class DoughVoice { if (this._crush) { s = this._crush.update(s, this.crush); } - // not sure if gain is applied here - s = s * this.gain; + // not sure if gain/velocity is applied here + s = s * this.gain * this.velocity; // envelope let gate = Number(t >= this._begin && t <= this._holdEnd); From 794bf86904fe89e9213e75258a06f33a6b7e87f0 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 6 Jun 2025 09:56:41 +0200 Subject: [PATCH 013/335] distort --- packages/superdough/dough.mjs | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/packages/superdough/dough.mjs b/packages/superdough/dough.mjs index 323e78d5c..d687bb63c 100644 --- a/packages/superdough/dough.mjs +++ b/packages/superdough/dough.mjs @@ -332,6 +332,26 @@ export class Crush { } } +// (unused) overdrive-style distortion (adapted from noisecraft) +export class Overdrive { + update(input, amount = 0, postgain = 1) { + amount = Math.min(Math.max(amount, 0), 1); + amount -= 0.01; + const shape = (2 * amount) / (1 - amount); + return (((1 + shape) * input) / (1 + shape * Math.abs(input))) * postgain; + } +} + +// this is the distort from superdough +export class Distort { + update(input, distort = 0, postgain = 1) { + postgain = Math.max(0.001, Math.min(1, postgain)); + const shape = Math.expm1(distort); + return (((1 + shape) * input) / (1 + shape * Math.abs(input))) * postgain; + } +} +// distortion could be expressed as a function, because it's stateless + export function _rangex(sig, min, max) { let logmin = Math.log(min); let range = Math.log(max) - logmin; @@ -504,6 +524,7 @@ export class DoughVoice { this._adsr = new ADSR(); this._coarse = this.coarse ? new Coarse() : null; this._crush = this.crush ? new Crush() : null; + this._distort = this.distort ? new Distort() : null; this.piOverSr = Math.PI / value.sampleRate; this.eighthOverLogHalf = 0.125 / Math.log(0.5); @@ -529,12 +550,11 @@ export class DoughVoice { const cutoff = this.freq2cutoff(this.cutoff); s = this._lpf.update(s, cutoff, this.resonance); } - if (this._coarse) { - s = this._coarse.update(s, this.coarse); - } - if (this._crush) { - s = this._crush.update(s, this.crush); - } + + this._coarse && (s = this._coarse.update(s, this.coarse)); + this._crush && (s = this._crush.update(s, this.crush)); + this._distort && (s = this._distort.update(s, this.distort, this.distortvol)); + // not sure if gain/velocity is applied here s = s * this.gain * this.velocity; // envelope From 6cf0b6f6515910da199a939740296a694100e5bf Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 6 Jun 2025 10:12:49 +0200 Subject: [PATCH 014/335] hpf + bpf --- packages/superdough/dough.mjs | 58 +++++++++++++++++------------------ 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/packages/superdough/dough.mjs b/packages/superdough/dough.mjs index d687bb63c..dce26ab3b 100644 --- a/packages/superdough/dough.mjs +++ b/packages/superdough/dough.mjs @@ -60,7 +60,7 @@ export class TriOsc { } } -export class Lpf { +export class TwoPoleFilter { s0 = 0; s1 = 0; update(s, cutoff, resonance = 0) { @@ -70,15 +70,10 @@ export class Lpf { var c = Math.pow(0.5, (1 - cutoff) / 0.125); var r = Math.pow(0.5, (resonance + 0.125) / 0.125); var mrc = 1 - r * c; - var v0 = this.s0; - var v1 = this.s1; - // Apply the filter to the sample - v0 = mrc * v0 - c * v1 + c * s; - v1 = mrc * v1 + c * v0; - s = v1; - this.s0 = v0; - this.s1 = v1; - return s; + + this.s0 = mrc * this.s0 - c * this.s1 + c * s; // bpf + this.s1 = mrc * this.s1 + c * this.s0; // lpf + return this.s1; // return lpf by default } } @@ -287,6 +282,7 @@ export class Slew { } } +// overdrive style distortion (adapted from noisecraft) currently unused export function applyDistortion(x, amount) { amount = Math.min(Math.max(amount, 0), 1); amount -= 0.01; @@ -332,16 +328,6 @@ export class Crush { } } -// (unused) overdrive-style distortion (adapted from noisecraft) -export class Overdrive { - update(input, amount = 0, postgain = 1) { - amount = Math.min(Math.max(amount, 0), 1); - amount -= 0.01; - const shape = (2 * amount) / (1 - amount); - return (((1 + shape) * input) / (1 + shape * Math.abs(input))) * postgain; - } -} - // this is the distort from superdough export class Distort { update(input, distort = 0, postgain = 1) { @@ -394,9 +380,12 @@ const defaultDefaultValues = { density: '.03', ftype: '12db', fanchor: 0, - resonance: 1, - hresonance: 1, - bandq: 1, + //resonance: 1, // superdough resonance is scaled differently + resonance: 0, + //hresonance: 1, // superdough resonance is scaled differently + hresonance: 0, + // bandq: 1, // superdough resonance is scaled differently + bandq: 0, channels: [1, 2], phaserdepth: 0.75, shapevol: 1, @@ -470,11 +459,7 @@ export class DoughVoice { phaserrate, phasersweep, phasercenter, - coarse, - crush, shape, - distort, - pan, vowel, room, roomfade, @@ -520,7 +505,9 @@ export class DoughVoice { const SourceClass = oscillators[this.s] ?? TriOsc; this._sound = new SourceClass(); - this._lpf = this.cutoff ? new Lpf() : null; + this._lpf = this.cutoff ? new TwoPoleFilter() : null; + this._hpf = this.hcutoff ? new TwoPoleFilter() : null; + this._bpf = this.bandf ? new TwoPoleFilter() : null; this._adsr = new ADSR(); this._coarse = this.coarse ? new Coarse() : null; this._crush = this.crush ? new Crush() : null; @@ -548,7 +535,20 @@ export class DoughVoice { // lpf if (this._lpf) { const cutoff = this.freq2cutoff(this.cutoff); - s = this._lpf.update(s, cutoff, this.resonance); + this._lpf.update(s, cutoff, this.resonance); + s = this._lpf.s1; + } + // hpf + if (this._hpf) { + const cutoff = this.freq2cutoff(this.hcutoff); + this._hpf.update(s, cutoff, this.hresonance); + s = s - this._hpf.s1; + } + // bpf + if (this._bpf) { + const cutoff = this.freq2cutoff(this.bandf); + this._bpf.update(s, cutoff, this.bandq); + s = this._bpf.s0; } this._coarse && (s = this._coarse.update(s, this.coarse)); From e4cd5dc552bcd3038b25b2914d475626d2277423 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 6 Jun 2025 10:55:38 +0200 Subject: [PATCH 015/335] rough filter envelope implementation --- packages/superdough/dough.mjs | 60 ++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 8 deletions(-) diff --git a/packages/superdough/dough.mjs b/packages/superdough/dough.mjs index dce26ab3b..09f85e153 100644 --- a/packages/superdough/dough.mjs +++ b/packages/superdough/dough.mjs @@ -505,10 +505,44 @@ export class DoughVoice { const SourceClass = oscillators[this.s] ?? TriOsc; this._sound = new SourceClass(); + + // filter setup this._lpf = this.cutoff ? new TwoPoleFilter() : null; + if (this.lpenv) { + this._lpenv = new ADSR(); + [this.lpattack, this.lpdecay, this.lpsustain, this.lprelease] = getADSRValues([ + this.lpattack, + this.lpdecay, + this.lpsustain, + this.lprelease, + ]); + } + this._hpf = this.hcutoff ? new TwoPoleFilter() : null; + if (this.hpenv) { + this._hpenv = new ADSR(); + [this.hpattack, this.hpdecay, this.hpsustain, this.hprelease] = getADSRValues([ + this.hpattack, + this.hpdecay, + this.hpsustain, + this.hprelease, + ]); + } this._bpf = this.bandf ? new TwoPoleFilter() : null; + if (this.bpenv) { + this._bpenv = new ADSR(); + [this.bpattack, this.bpdecay, this.bpsustain, this.bprelease] = getADSRValues([ + this.bpattack, + this.bpdecay, + this.bpsustain, + this.bprelease, + ]); + } + + // gain envelope this._adsr = new ADSR(); + + // fx setup this._coarse = this.coarse ? new Coarse() : null; this._crush = this.crush ? new Crush() : null; this._distort = this.distort ? new Distort() : null; @@ -532,21 +566,36 @@ export class DoughVoice { } else { s = this._sound.update(this.freq); } + let gate = Number(t >= this._begin && t <= this._holdEnd); + s = s * this.gain * this.velocity; + // lpf if (this._lpf) { - const cutoff = this.freq2cutoff(this.cutoff); + let cutoff = this.freq2cutoff(this.cutoff); + if (this._lpenv) { + const env = this._lpenv.update(t, gate, this.lpattack, this.lpdecay, this.lpsustain, this.lprelease) ** 2; + cutoff = cutoff + env * this.lpenv * cutoff; // todo proper scaling + } this._lpf.update(s, cutoff, this.resonance); s = this._lpf.s1; } // hpf if (this._hpf) { - const cutoff = this.freq2cutoff(this.hcutoff); + let cutoff = this.freq2cutoff(this.hcutoff); + if (this._hpenv) { + const env = this._hpenv.update(t, gate, this.hpattack, this.hpdecay, this.hpsustain, this.hprelease) ** 2; + cutoff = cutoff + env * this.hpenv * cutoff; // todo proper scaling + } this._hpf.update(s, cutoff, this.hresonance); s = s - this._hpf.s1; } // bpf if (this._bpf) { - const cutoff = this.freq2cutoff(this.bandf); + let cutoff = this.freq2cutoff(this.bandf); + if (this._bpenv) { + const env = this._bpenv.update(t, gate, this.bpattack, this.bpdecay, this.bpsustain, this.bprelease) ** 2; + cutoff = cutoff + env * this.bpenv * cutoff; // todo proper scaling + } this._bpf.update(s, cutoff, this.bandq); s = this._bpf.s0; } @@ -555,11 +604,6 @@ export class DoughVoice { this._crush && (s = this._crush.update(s, this.crush)); this._distort && (s = this._distort.update(s, this.distort, this.distortvol)); - // not sure if gain/velocity is applied here - s = s * this.gain * this.velocity; - // envelope - let gate = Number(t >= this._begin && t <= this._holdEnd); - /* Math.random() > 0.99 && console.log('gate', gate); */ const env = this._adsr.update(t, gate, this.attack, this.decay, this.sustain, this.release); s = s * env; From 998a0102471f63eec033f3bc52e330e1fcfc7b6e Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 6 Jun 2025 11:21:01 +0200 Subject: [PATCH 016/335] better filter envelopes --- packages/superdough/dough.mjs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/superdough/dough.mjs b/packages/superdough/dough.mjs index 09f85e153..a292b0c8b 100644 --- a/packages/superdough/dough.mjs +++ b/packages/superdough/dough.mjs @@ -571,31 +571,34 @@ export class DoughVoice { // lpf if (this._lpf) { - let cutoff = this.freq2cutoff(this.cutoff); + let cutoff = this.cutoff; if (this._lpenv) { const env = this._lpenv.update(t, gate, this.lpattack, this.lpdecay, this.lpsustain, this.lprelease) ** 2; - cutoff = cutoff + env * this.lpenv * cutoff; // todo proper scaling + cutoff = 2 ** this.lpenv * env * cutoff + cutoff; } + cutoff = this.freq2cutoff(cutoff); this._lpf.update(s, cutoff, this.resonance); s = this._lpf.s1; } // hpf if (this._hpf) { - let cutoff = this.freq2cutoff(this.hcutoff); + let cutoff = this.hcutoff; if (this._hpenv) { const env = this._hpenv.update(t, gate, this.hpattack, this.hpdecay, this.hpsustain, this.hprelease) ** 2; - cutoff = cutoff + env * this.hpenv * cutoff; // todo proper scaling + cutoff = 2 ** this.hpenv * env * cutoff + cutoff; } + cutoff = this.freq2cutoff(cutoff); this._hpf.update(s, cutoff, this.hresonance); s = s - this._hpf.s1; } // bpf if (this._bpf) { - let cutoff = this.freq2cutoff(this.bandf); + let cutoff = this.bandf; if (this._bpenv) { const env = this._bpenv.update(t, gate, this.bpattack, this.bpdecay, this.bpsustain, this.bprelease) ** 2; - cutoff = cutoff + env * this.bpenv * cutoff; // todo proper scaling + cutoff = 2 ** this.bpenv * env * cutoff + cutoff; } + cutoff = this.freq2cutoff(cutoff); this._bpf.update(s, cutoff, this.bandq); s = this._bpf.s0; } From ccc90d547cf85ec06b0433b6c02eb18c52112f1c Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 6 Jun 2025 15:47:19 +0200 Subject: [PATCH 017/335] ignore dough-export to fix checks --- eslint.config.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/eslint.config.mjs b/eslint.config.mjs index 19d9bb390..0ba44da07 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -42,6 +42,7 @@ export default [ '**/hydra.mjs', '**/jsdoc-synonyms.js', 'packages/hs2js/src/hs2js.mjs', + 'packages/superdough/dough-export.mjs', '**/samples', ], }, From 43c05cb5041e18431dd297be5fb5a9b3044aaf0d Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 6 Jun 2025 16:17:05 +0200 Subject: [PATCH 018/335] move supradough to separate package --- eslint.config.mjs | 2 +- packages/superdough/package.json | 3 +- packages/superdough/superdough.mjs | 9 ++++- packages/superdough/synth.mjs | 4 +- packages/superdough/worklets.mjs | 25 ------------- .../{superdough => supradough}/.gitignore | 0 packages/supradough/README.md | 3 ++ .../dough-export.mjs | 0 packages/supradough/dough-worklet.mjs | 27 ++++++++++++++ packages/{superdough => supradough}/dough.mjs | 0 packages/supradough/index.mjs | 4 ++ packages/supradough/package.json | 37 +++++++++++++++++++ packages/webaudio/package.json | 3 +- packages/webaudio/webaudio.mjs | 6 ++- pnpm-lock.yaml | 12 ++++++ 15 files changed, 102 insertions(+), 33 deletions(-) rename packages/{superdough => supradough}/.gitignore (100%) create mode 100644 packages/supradough/README.md rename packages/{superdough => supradough}/dough-export.mjs (100%) create mode 100644 packages/supradough/dough-worklet.mjs rename packages/{superdough => supradough}/dough.mjs (100%) create mode 100644 packages/supradough/index.mjs create mode 100644 packages/supradough/package.json diff --git a/eslint.config.mjs b/eslint.config.mjs index 0ba44da07..f2cf86307 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -42,7 +42,7 @@ export default [ '**/hydra.mjs', '**/jsdoc-synonyms.js', 'packages/hs2js/src/hs2js.mjs', - 'packages/superdough/dough-export.mjs', + 'packages/supradough/dough-export.mjs', '**/samples', ], }, diff --git a/packages/superdough/package.json b/packages/superdough/package.json index 6b45144e4..a835f252d 100644 --- a/packages/superdough/package.json +++ b/packages/superdough/package.json @@ -33,8 +33,7 @@ "homepage": "https://github.com/tidalcycles/strudel#readme", "devDependencies": { "vite": "^6.0.11", - "vite-plugin-bundle-audioworklet": "workspace:*", - "wav-encoder": "^1.3.0" + "vite-plugin-bundle-audioworklet": "workspace:*" }, "dependencies": { "nanostores": "^0.11.3" diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 1069d4e84..a6e54435c 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -190,11 +190,18 @@ export function getAudioContextCurrentTime() { return getAudioContext().currentTime; } +let externalWorklets = []; +export function registerWorklet(url) { + externalWorklets.push(url); +} + let workletsLoading; function loadWorklets() { if (!workletsLoading) { const audioCtx = getAudioContext(); - workletsLoading = audioCtx.audioWorklet.addModule(workletsUrl); + const allWorkletURLs = externalWorklets.concat([workletsUrl]); + console.log('allWorkletURLs', allWorkletURLs); + workletsLoading = Promise.all(allWorkletURLs.map((workletURL) => audioCtx.audioWorklet.addModule(workletURL))); } return workletsLoading; diff --git a/packages/superdough/synth.mjs b/packages/superdough/synth.mjs index 7d175d6c4..834e54c6d 100644 --- a/packages/superdough/synth.mjs +++ b/packages/superdough/synth.mjs @@ -12,7 +12,7 @@ import { } from './helpers.mjs'; import { getNoiseMix, getNoiseOscillator } from './noise.mjs'; -export const getFrequencyFromValue = (value) => { +const getFrequencyFromValue = (value) => { let { note, freq } = value; note = note || 36; if (typeof note === 'string') { @@ -25,7 +25,7 @@ export const getFrequencyFromValue = (value) => { return Number(freq); }; -export function destroyAudioWorkletNode(node) { +function destroyAudioWorkletNode(node) { if (node == null) { return; } diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index d8f189779..24f7434a9 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -4,7 +4,6 @@ import OLAProcessor from './ola-processor'; import FFT from './fft.js'; -import { Dough } from './dough.mjs'; const clamp = (num, min, max) => Math.min(Math.max(num, min), max); const _mod = (n, m) => ((n % m) + m) % m; @@ -896,27 +895,3 @@ class ByteBeatProcessor extends AudioWorkletProcessor { } registerProcessor('byte-beat-processor', ByteBeatProcessor); - -class DoughProcessor extends AudioWorkletProcessor { - constructor() { - super(); - this.dough = new Dough(sampleRate, currentTime); - this.port.onmessage = (event) => this.dough.scheduleSpawn(event.data); - } - process(inputs, outputs, params) { - if (this.disconnected) { - return false; - } - const output = outputs[0]; - for (let i = 0; i < output[0].length; i++) { - this.dough.update(); - for (let c = 0; c < output.length; c++) { - //prevent speaker blowout via clipping if threshold exceeds - output[c][i] = clamp(this.dough.channels[c], -1, 1); - } - } - return true; // keep the audio processing going - } -} - -registerProcessor('dough-processor', DoughProcessor); diff --git a/packages/superdough/.gitignore b/packages/supradough/.gitignore similarity index 100% rename from packages/superdough/.gitignore rename to packages/supradough/.gitignore diff --git a/packages/supradough/README.md b/packages/supradough/README.md new file mode 100644 index 000000000..a8cfa84b3 --- /dev/null +++ b/packages/supradough/README.md @@ -0,0 +1,3 @@ +# supradough + +platform agnostic synth and sampler intended for live coding. a reimplementation of superdough. \ No newline at end of file diff --git a/packages/superdough/dough-export.mjs b/packages/supradough/dough-export.mjs similarity index 100% rename from packages/superdough/dough-export.mjs rename to packages/supradough/dough-export.mjs diff --git a/packages/supradough/dough-worklet.mjs b/packages/supradough/dough-worklet.mjs new file mode 100644 index 000000000..0361afa0d --- /dev/null +++ b/packages/supradough/dough-worklet.mjs @@ -0,0 +1,27 @@ +import { Dough } from './dough.mjs'; + +const clamp = (num, min, max) => Math.min(Math.max(num, min), max); + +class DoughProcessor extends AudioWorkletProcessor { + constructor() { + super(); + this.dough = new Dough(sampleRate, currentTime); + this.port.onmessage = (event) => this.dough.scheduleSpawn(event.data); + } + process(inputs, outputs, params) { + if (this.disconnected) { + return false; + } + const output = outputs[0]; + for (let i = 0; i < output[0].length; i++) { + this.dough.update(); + for (let c = 0; c < output.length; c++) { + //prevent speaker blowout via clipping if threshold exceeds + output[c][i] = clamp(this.dough.channels[c], -1, 1); + } + } + return true; // keep the audio processing going + } +} + +registerProcessor('dough-processor', DoughProcessor); diff --git a/packages/superdough/dough.mjs b/packages/supradough/dough.mjs similarity index 100% rename from packages/superdough/dough.mjs rename to packages/supradough/dough.mjs diff --git a/packages/supradough/index.mjs b/packages/supradough/index.mjs new file mode 100644 index 000000000..1bce17f6d --- /dev/null +++ b/packages/supradough/index.mjs @@ -0,0 +1,4 @@ +import _workletUrl from './dough-worklet.mjs?audioworklet'; + +export * from './dough.mjs'; +export const workletUrl = _workletUrl; diff --git a/packages/supradough/package.json b/packages/supradough/package.json new file mode 100644 index 000000000..7e465c0a9 --- /dev/null +++ b/packages/supradough/package.json @@ -0,0 +1,37 @@ +{ + "name": "supradough", + "version": "1.2.3", + "description": "platform agnostic synth and sampler intended for live coding. a reimplementation of superdough.", + "main": "index.mjs", + "type": "module", + "publishConfig": { + "main": "dist/index.mjs" + }, + "scripts": { + "build": "vite build", + "prepublishOnly": "npm run build" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/tidalcycles/strudel.git" + }, + "keywords": [ + "tidalcycles", + "strudel", + "pattern", + "livecoding", + "algorave" + ], + "author": "Felix Roos ", + "license": "AGPL-3.0-or-later", + "bugs": { + "url": "https://github.com/tidalcycles/strudel/issues" + }, + "homepage": "https://github.com/tidalcycles/strudel#readme", + "devDependencies": { + "vite": "^6.0.11", + "vite-plugin-bundle-audioworklet": "workspace:*", + "wav-encoder": "^1.3.0" + }, + "dependencies": {} +} diff --git a/packages/webaudio/package.json b/packages/webaudio/package.json index 5714fddf3..2617c2872 100644 --- a/packages/webaudio/package.json +++ b/packages/webaudio/package.json @@ -35,7 +35,8 @@ "dependencies": { "@strudel/core": "workspace:*", "@strudel/draw": "workspace:*", - "superdough": "workspace:*" + "superdough": "workspace:*", + "supradough": "workspace:*" }, "devDependencies": { "vite": "^6.0.11" diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 8f7d041a9..de53bb5cd 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -5,8 +5,12 @@ This program is free software: you can redistribute it and/or modify it under th */ import * as strudel from '@strudel/core'; -import { superdough, getAudioContext, setLogger, doughTrigger } from 'superdough'; +import { superdough, getAudioContext, setLogger, doughTrigger, registerWorklet } from 'superdough'; import './supradough.mjs'; +import { workletUrl } from 'supradough'; + +registerWorklet(workletUrl); + const { Pattern, logger, repl } = strudel; setLogger(logger); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ed8a7c014..805412ede 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -485,6 +485,15 @@ importers: vite-plugin-bundle-audioworklet: specifier: workspace:* version: link:../vite-plugin-bundle-audioworklet + + packages/supradough: + devDependencies: + vite: + specifier: ^6.0.11 + version: 6.0.11(@types/node@22.10.10)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.37.0)(yaml@2.7.0) + vite-plugin-bundle-audioworklet: + specifier: workspace:* + version: link:../vite-plugin-bundle-audioworklet wav-encoder: specifier: ^1.3.0 version: 1.3.0 @@ -597,6 +606,9 @@ importers: superdough: specifier: workspace:* version: link:../superdough + supradough: + specifier: workspace:* + version: link:../supradough devDependencies: vite: specifier: ^6.0.11 From 49f38aeddbf7ce2815805b7c9640df0ba848a0bb Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 6 Jun 2025 16:26:17 +0200 Subject: [PATCH 019/335] remove log --- packages/superdough/superdough.mjs | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index a6e54435c..2629790df 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -200,7 +200,6 @@ function loadWorklets() { if (!workletsLoading) { const audioCtx = getAudioContext(); const allWorkletURLs = externalWorklets.concat([workletsUrl]); - console.log('allWorkletURLs', allWorkletURLs); workletsLoading = Promise.all(allWorkletURLs.map((workletURL) => audioCtx.audioWorklet.addModule(workletURL))); } From 1dac69635db5bf39324d2febdfc9aae45dc84706 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sat, 7 Jun 2025 10:40:34 +0200 Subject: [PATCH 020/335] feedback delay (still hard coded feedback / time values) --- packages/supradough/dough.mjs | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index a292b0c8b..ba00d672f 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -229,7 +229,7 @@ const MAX_DELAY_TIME = 10; export class Delay { writeIdx = 0; readIdx = 0; - buffer = new Float32Array(MAX_DELAY_TIME * SAMPLE_RATE); // .fill(0) + buffer = new Float32Array(MAX_DELAY_TIME * SAMPLE_RATE); //.fill(0) write(s, delayTime) { this.writeIdx = (this.writeIdx + 1) % this.buffer.length; this.buffer[this.writeIdx] = s; @@ -479,19 +479,13 @@ export class DoughVoice { this.density = this.density ?? getDefaultValue('density'); this.fanchor = this.fanchor ?? getDefaultValue('fanchor'); this.drive = this.drive ?? 0.69; - this.resonance = this.resonance ?? getDefaultValue('resonance'); - this.hresonance = this.hresonance ?? getDefaultValue('hresonance'); - this.bandq = this.bandq ?? getDefaultValue('bandq'); this.phaserdepth = this.phaserdepth ?? getDefaultValue('phaserdepth'); this.shapevol = this.shapevol ?? getDefaultValue('shapevol'); this.distortvol = this.distortvol ?? getDefaultValue('distortvol'); - this.delay = this.delay ?? getDefaultValue('delay'); - this.delayfeedback = this.delayfeedback ?? getDefaultValue('delayfeedback'); - this.delaytime = this.delaytime ?? getDefaultValue('delaytime'); - this.orbit = this.orbit ?? getDefaultValue('orbit'); this.i = this.i ?? getDefaultValue('i'); this.fft = this.fft ?? getDefaultValue('fft'); this.pan = this.pan ?? getDefaultValue('pan'); + this.orbit = this.orbit ?? getDefaultValue('orbit'); [this.attack, this.decay, this.sustain, this.release] = getADSRValues([ this.attack, @@ -508,6 +502,7 @@ export class DoughVoice { // filter setup this._lpf = this.cutoff ? new TwoPoleFilter() : null; + this.resonance = this.resonance ?? getDefaultValue('resonance'); if (this.lpenv) { this._lpenv = new ADSR(); [this.lpattack, this.lpdecay, this.lpsustain, this.lprelease] = getADSRValues([ @@ -519,6 +514,7 @@ export class DoughVoice { } this._hpf = this.hcutoff ? new TwoPoleFilter() : null; + this.hresonance = this.hresonance ?? getDefaultValue('hresonance'); if (this.hpenv) { this._hpenv = new ADSR(); [this.hpattack, this.hpdecay, this.hpsustain, this.hprelease] = getADSRValues([ @@ -529,6 +525,7 @@ export class DoughVoice { ]); } this._bpf = this.bandf ? new TwoPoleFilter() : null; + this.bandq = this.bandq ?? getDefaultValue('bandq'); if (this.bpenv) { this._bpenv = new ADSR(); [this.bpattack, this.bpdecay, this.bpsustain, this.bprelease] = getADSRValues([ @@ -547,6 +544,12 @@ export class DoughVoice { this._crush = this.crush ? new Crush() : null; this._distort = this.distort ? new Distort() : null; + // delay + this.delay = this.delay ?? getDefaultValue('delay'); + this.delayfeedback = this.delayfeedback ?? getDefaultValue('delayfeedback'); + this.delaytime = this.delaytime ?? getDefaultValue('delaytime'); + + // precalculated values this.piOverSr = Math.PI / value.sampleRate; this.eighthOverLogHalf = 0.125 / Math.log(0.5); } @@ -631,12 +634,17 @@ export class Dough { vid = 0; q = []; channels = [0, 0]; + delaysend = [0, 0]; + delaytime = getDefaultValue('delaytime'); + delayfeedback = getDefaultValue('delayfeedback'); t = 0; // sampleRate: number, currentTime: number (seconds) constructor(sampleRate = 48000, currentTime = 0) { this.sampleRate = sampleRate; this.t = Math.floor(currentTime * sampleRate); // samples // console.log('init dough', this.sampleRate, this.t); + this._delayL = new Delay(); + this._delayR = new Delay(); } scheduleSpawn(value) { if (value._begin === undefined) { @@ -696,7 +704,18 @@ export class Dough { this.voices[v].update(this.t / this.sampleRate); this.channels[0] += this.voices[v].l; this.channels[1] += this.voices[v].r; + if (this.voices[v].delay) { + this.delaysend[0] += this.voices[v].l * this.voices[v].delay; + this.delaysend[1] += this.voices[v].r * this.voices[v].delay; + } } + // todo: how to change delaytime / delayfeedback from a voice? + const delayL = this._delayL.update(this.delaysend[0], this.delaytime); + const delayR = this._delayR.update(this.delaysend[1], this.delaytime); + this.delaysend[0] = delayL * this.delayfeedback; + this.delaysend[1] = delayR * this.delayfeedback; + this.channels[0] += delayL; + this.channels[1] += delayR; this.t++; } } From d743570546d3659cd949441180e4a79df2fd023f Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sat, 7 Jun 2025 13:12:35 +0200 Subject: [PATCH 021/335] set delay time and feedback from voice --- packages/supradough/dough.mjs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index ba00d672f..14bab22fe 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -707,6 +707,8 @@ export class Dough { if (this.voices[v].delay) { this.delaysend[0] += this.voices[v].l * this.voices[v].delay; this.delaysend[1] += this.voices[v].r * this.voices[v].delay; + this.delaytime = this.voices[v].delaytime; // we trust that these are initialized in the voice + this.delayfeedback = this.voices[v].delayfeedback; } } // todo: how to change delaytime / delayfeedback from a voice? From e54449f5f73cf0d41ff14f460bdd4ca9ccfa59eb Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sat, 7 Jun 2025 13:24:06 +0200 Subject: [PATCH 022/335] white brown pink noise + crackle alias for dust --- packages/supradough/dough.mjs | 49 +++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index 14bab22fe..2050054ec 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -108,6 +108,51 @@ export class Dust { update = (density) => (Math.random() < density * ISR ? Math.random() : 0); } +export class WhiteNoise { + update() { + return Math.random() * 2 - 1; + } +} + +export class BrownNoise { + constructor() { + this.out = 0; + } + update() { + let white = Math.random() * 2 - 1; + this.out = (this.out + 0.02 * white) / 1.02; + return this.out; + } +} + +export class PinkNoise { + constructor() { + this.b0 = 0; + this.b1 = 0; + this.b2 = 0; + this.b3 = 0; + this.b4 = 0; + this.b5 = 0; + this.b6 = 0; + } + + update() { + const white = Math.random() * 2 - 1; + + this.b0 = 0.99886 * this.b0 + white * 0.0555179; + this.b1 = 0.99332 * this.b1 + white * 0.0750759; + this.b2 = 0.969 * this.b2 + white * 0.153852; + this.b3 = 0.8665 * this.b3 + white * 0.3104856; + this.b4 = 0.55 * this.b4 + white * 0.5329522; + this.b5 = -0.7616 * this.b5 - white * 0.016898; + + const pink = this.b0 + this.b1 + this.b2 + this.b3 + this.b4 + this.b5 + this.b6 + white * 0.5362; + this.b6 = white * 0.115926; + + return pink * 0.11; + } +} + export class Impulse { phase = 1; update(freq) { @@ -369,7 +414,11 @@ let oscillators = { pulse: PulseOsc, pulze: PulzeOsc, dust: Dust, + crackle: Dust, impulse: Impulse, + white: WhiteNoise, + brown: BrownNoise, + pink: PinkNoise, }; const defaultDefaultValues = { From 77463a199aaf68d2d32b4653b2c49443958be9f7 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sat, 7 Jun 2025 13:26:43 +0200 Subject: [PATCH 023/335] add square alias for pulse --- packages/supradough/dough.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index 2050054ec..0c0e667d9 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -412,6 +412,7 @@ let oscillators = { tri: TriOsc, triangle: TriOsc, pulse: PulseOsc, + square: PulseOsc, pulze: PulzeOsc, dust: Dust, crackle: Dust, From b000f2297d23ddc4b46b8fa5ad4848d504652ea8 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sat, 7 Jun 2025 20:31:47 +0200 Subject: [PATCH 024/335] fm --- packages/supradough/dough.mjs | 36 ++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index 0c0e667d9..08469e634 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -449,6 +449,7 @@ const defaultDefaultValues = { fft: 8, z: 'triangle', pan: 0.5, + fmh: 1, }; let getDefaultValue = (key) => defaultDefaultValues[key]; @@ -518,6 +519,8 @@ export class DoughVoice { roomsize, ir, analyze, + fmh, + fmi */ value.freq = getFrequency(value); Object.assign(this, value); @@ -550,6 +553,20 @@ export class DoughVoice { const SourceClass = oscillators[this.s] ?? TriOsc; this._sound = new SourceClass(); + if (this.fmi) { + this._fm = new SineOsc(); + this.fmh = this.fmh ?? getDefaultValue('fmh'); + if (this.fmenv) { + this._fmenv = new ADSR(); + [this.fmattack, this.fmdecay, this.fmsustain, this.fmrelease] = getADSRValues([ + this.fmattack, + this.fmdecay, + this.fmsustain, + this.fmrelease, + ]); + } + } + // filter setup this._lpf = this.cutoff ? new TwoPoleFilter() : null; this.resonance = this.resonance ?? getDefaultValue('resonance'); @@ -613,13 +630,26 @@ export class DoughVoice { return 0; } let s = 0; + let gate = Number(t >= this._begin && t <= this._holdEnd); + + let freq = this.freq; + if (this._fm) { + let fmi = this.fmi; + if (this._fmenv) { + const env = this._fmenv.update(t, gate, this.fmattack, this.fmdecay, this.fmsustain, this.fmrelease) ** 2; + fmi = /* 2 ** */ this.fmenv * env * fmi; // todo: find good scaling + } + const modfreq = freq * this.fmh; + const modgain = modfreq * fmi; + freq = freq + this._fm.update(modfreq) * modgain; + } + // sound source if (this.s === 'pulse') { - s = this._sound.update(this.freq, this.pw ?? 0.5); + s = this._sound.update(freq, this.pw ?? 0.5); } else { - s = this._sound.update(this.freq); + s = this._sound.update(freq); } - let gate = Number(t >= this._begin && t <= this._holdEnd); s = s * this.gain * this.velocity; // lpf From 2f2bf5bf29541ea1c4edee5e70302b109f54ce0b Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sat, 7 Jun 2025 22:36:54 +0200 Subject: [PATCH 025/335] fix: note2midi for notes without octave --- packages/supradough/dough.mjs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index 08469e634..2853f3971 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -457,7 +457,7 @@ let getDefaultValue = (key) => defaultDefaultValues[key]; const chromas = { c: 0, d: 2, e: 4, f: 5, g: 7, a: 9, b: 11 }; const accs = { '#': 1, b: -1, s: 1, f: -1 }; const note2midi = (note, defaultOctave = 3) => { - const [pc, acc = '', oct = defaultOctave] = + let [pc, acc = '', oct = ''] = String(note) .match(/^([a-gA-G])([#bsf]*)([0-9]*)$/) ?.slice(1) || []; @@ -466,13 +466,14 @@ const note2midi = (note, defaultOctave = 3) => { } const chroma = chromas[pc.toLowerCase()]; const offset = acc?.split('').reduce((o, char) => o + accs[char], 0) || 0; - return (Number(oct) + 1) * 12 + chroma + offset; + oct = Number(oct || defaultOctave); + return (oct + 1) * 12 + chroma + offset; }; const getFrequency = (value) => { let { note, freq } = value; note = note || 36; if (typeof note === 'string') { - note = note2midi(note); // e.g. c3 => 48 + note = note2midi(note, 3); // e.g. c3 => 48 } if (!freq && typeof note === 'number') { freq = Math.pow(2, (note - 69) / 12) * 440; From 5988e3d3b48541444440f6c165ea1b37ed22ff02 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sat, 7 Jun 2025 22:42:48 +0200 Subject: [PATCH 026/335] fix: hot reloading for dough.mjs (see comment) --- packages/supradough/index.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/supradough/index.mjs b/packages/supradough/index.mjs index 1bce17f6d..54a835495 100644 --- a/packages/supradough/index.mjs +++ b/packages/supradough/index.mjs @@ -1,4 +1,4 @@ -import _workletUrl from './dough-worklet.mjs?audioworklet'; +import _workletUrl from './dough-worklet.mjs?url'; // todo: change ?url to ?audioworklet before build (?audioworklet doesn't hot reload) export * from './dough.mjs'; export const workletUrl = _workletUrl; From ab052ce1ac6fe4232edd65e877dc2cb041df0d48 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sat, 7 Jun 2025 23:15:09 +0200 Subject: [PATCH 027/335] fix: polyblepped sawtooth + fm = death --- packages/supradough/dough.mjs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index 2853f3971..826172a2f 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -450,6 +450,7 @@ const defaultDefaultValues = { z: 'triangle', pan: 0.5, fmh: 1, + fmenv: 0, // differs from superdough }; let getDefaultValue = (key) => defaultDefaultValues[key]; @@ -540,6 +541,7 @@ export class DoughVoice { this.fft = this.fft ?? getDefaultValue('fft'); this.pan = this.pan ?? getDefaultValue('pan'); this.orbit = this.orbit ?? getDefaultValue('orbit'); + this.fmenv = this.fmenv ?? getDefaultValue('fmenv'); [this.attack, this.decay, this.sustain, this.release] = getADSRValues([ this.attack, @@ -551,6 +553,9 @@ export class DoughVoice { this._holdEnd = this._begin + this._duration; // needed for gate this._end = this._holdEnd + this.release + 0.01; // needed for despawn + if (this.s === 'saw' || this.s === 'sawtooth') { + this.s = 'zaw'; // polyblepped saw when fm is applied + } const SourceClass = oscillators[this.s] ?? TriOsc; this._sound = new SourceClass(); @@ -638,7 +643,7 @@ export class DoughVoice { let fmi = this.fmi; if (this._fmenv) { const env = this._fmenv.update(t, gate, this.fmattack, this.fmdecay, this.fmsustain, this.fmrelease) ** 2; - fmi = /* 2 ** */ this.fmenv * env * fmi; // todo: find good scaling + fmi = this.fmenv * env * fmi; } const modfreq = freq * this.fmh; const modgain = modfreq * fmi; From ac7ee376e5a0ed121526096baa3839a2e117aebe Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 8 Jun 2025 00:43:58 +0200 Subject: [PATCH 028/335] pitch envelope --- packages/supradough/dough.mjs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index 826172a2f..809b8d52b 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -559,6 +559,16 @@ export class DoughVoice { const SourceClass = oscillators[this.s] ?? TriOsc; this._sound = new SourceClass(); + if (this.penv) { + this._penv = new ADSR(); + [this.pattack, this.pdecay, this.psustain, this.prelease] = getADSRValues([ + this.pattack, + this.pdecay, + this.psustain, + this.prelease, + ]); + } + if (this.fmi) { this._fm = new SineOsc(); this.fmh = this.fmh ?? getDefaultValue('fmh'); @@ -650,6 +660,11 @@ export class DoughVoice { freq = freq + this._fm.update(modfreq) * modgain; } + if (this._penv) { + const env = this._penv.update(t, gate, this.pattack, this.pdecay, this.psustain, this.prelease) ** 2; + freq = freq + env * this.penv; + } + // sound source if (this.s === 'pulse') { s = this._sound.update(freq, this.pw ?? 0.5); From 0f2aa9569b9cabc3c1144e01c5586e4099baab0d Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 8 Jun 2025 02:04:49 +0200 Subject: [PATCH 029/335] half working samples --- packages/supradough/dough-worklet.mjs | 14 ++- packages/supradough/dough.mjs | 41 ++++++-- packages/webaudio/index.mjs | 1 + packages/webaudio/supradough.mjs | 138 +++++++++++++++++++++++++- 4 files changed, 182 insertions(+), 12 deletions(-) diff --git a/packages/supradough/dough-worklet.mjs b/packages/supradough/dough-worklet.mjs index 0361afa0d..97a35c487 100644 --- a/packages/supradough/dough-worklet.mjs +++ b/packages/supradough/dough-worklet.mjs @@ -6,7 +6,19 @@ class DoughProcessor extends AudioWorkletProcessor { constructor() { super(); this.dough = new Dough(sampleRate, currentTime); - this.port.onmessage = (event) => this.dough.scheduleSpawn(event.data); + this.port.onmessage = (event) => { + if (event.data.spawn) { + this.dough.scheduleSpawn(event.data.spawn); + } else if (event.data.sample) { + this.dough.loadSample(event.data.sample, event.data.channels); + } else if (event.data.samples) { + event.data.samples.forEach(([name, channels]) => { + this.dough.loadSample(name, channels); + }); + } else { + console.log('unrecognized event type', event.data); + } + }; } process(inputs, outputs, params) { if (this.disconnected) { diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index 809b8d52b..e42b4f8e8 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -383,6 +383,19 @@ export class Distort { } // distortion could be expressed as a function, because it's stateless +export class BufferPlayer { + channels = []; + pos = 0; + update(freq, channel = 0) { + if (this.pos >= this.channels[channel].length) { + return 0; + } + let s = this.channels[channel][this.pos]; + this.pos++; + return s; + } +} + export function _rangex(sig, min, max) { let logmin = Math.log(min); let range = Math.log(max) - logmin; @@ -403,7 +416,7 @@ export const getADSRValues = (params, curve = 'linear', defaultValues) => { return [Math.max(a ?? 0, envmin), Math.max(d ?? 0, envmin), Math.min(sustain, envmax), Math.max(r ?? 0, releaseMin)]; }; -let oscillators = { +let shapes = { sine: SineOsc, saw: SawOsc, zaw: ZawOsc, @@ -553,11 +566,20 @@ export class DoughVoice { this._holdEnd = this._begin + this._duration; // needed for gate this._end = this._holdEnd + this.release + 0.01; // needed for despawn + this.s ??= 'triangle'; if (this.s === 'saw' || this.s === 'sawtooth') { this.s = 'zaw'; // polyblepped saw when fm is applied } - const SourceClass = oscillators[this.s] ?? TriOsc; - this._sound = new SourceClass(); + if (shapes[this.s]) { + const SourceClass = shapes[this.s]; + this._sound = new SourceClass(); + } else if (value.samples.has(this.s)) { + this._sample = new BufferPlayer(); + this._sample.channels = value.samples.get(this.s); + this._sample.pos = 0; + } else { + console.warn('sound not found', this.s); + } if (this.penv) { this._penv = new ADSR(); @@ -642,7 +664,7 @@ export class DoughVoice { return 1 - Math.log(c) * this.eighthOverLogHalf; } update(t) { - if (!this._sound) { + if (!this._sound && !this._sample) { return 0; } let s = 0; @@ -666,10 +688,12 @@ export class DoughVoice { } // sound source - if (this.s === 'pulse') { + if (this._sound && this.s === 'pulse') { s = this._sound.update(freq, this.pw ?? 0.5); - } else { + } else if (this._sound) { s = this._sound.update(freq); + } else if (this._sample) { + s = this._sample.update(freq, 0); // tbd: stereo samples... } s = s * this.gain * this.velocity; @@ -738,6 +762,7 @@ export class Dough { delaysend = [0, 0]; delaytime = getDefaultValue('delaytime'); delayfeedback = getDefaultValue('delayfeedback'); + samples = new Map(); t = 0; // sampleRate: number, currentTime: number (seconds) constructor(sampleRate = 48000, currentTime = 0) { @@ -747,6 +772,9 @@ export class Dough { this._delayL = new Delay(); this._delayR = new Delay(); } + loadSample(name, channels) { + this.samples.set(name, channels); + } scheduleSpawn(value) { if (value._begin === undefined) { throw new Error('[dough]: scheduleSpawn expected _begin to be set'); @@ -760,6 +788,7 @@ export class Dough { } spawn(value) { value.id = this.vid++; + value.samples = this.samples; const voice = new DoughVoice(value); this.voices.push(voice); // console.log('spawn', voice.id, 'voices:', this.voices.length); diff --git a/packages/webaudio/index.mjs b/packages/webaudio/index.mjs index 59672b617..f89e12696 100644 --- a/packages/webaudio/index.mjs +++ b/packages/webaudio/index.mjs @@ -7,4 +7,5 @@ This program is free software: you can redistribute it and/or modify it under th export * from './webaudio.mjs'; export * from './scope.mjs'; export * from './spectrum.mjs'; +export * from './supradough.mjs'; export * from 'superdough'; diff --git a/packages/webaudio/supradough.mjs b/packages/webaudio/supradough.mjs index 8df18bed6..38b2330c3 100644 --- a/packages/webaudio/supradough.mjs +++ b/packages/webaudio/supradough.mjs @@ -20,10 +20,138 @@ Pattern.prototype.supradough = function () { return this.onTrigger((_, hap, __, cps, begin) => { hap.value._begin = begin; hap.value._duration = hap.duration / cps; - - if (!doughWorklet) { - initDoughWorklet(); - } - doughWorklet.port.postMessage(hap.value); + !doughWorklet && initDoughWorklet(); + doughWorklet.port.postMessage({ spawn: hap.value }); }, 1); }; + +async function loadSampleChannels(url) { + const buffer = await fetch(url) + .then((res) => res.arrayBuffer()) + .then((buf) => getAudioContext().decodeAudioData(buf)); + // console.log('buffer', buffer, buffer.numberOfChannels); + let channels = []; + for (let i = 0; i < buffer.numberOfChannels; i++) { + channels.push(buffer.getChannelData(i)); + } + return channels; +} + +let samples = { + casio: [ + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/casio/high.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/casio/low.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/casio/noise.wav', + ], + crow: [ + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/crow/000_crow.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/crow/001_crow2.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/crow/002_crow3.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/crow/003_crow4.wav', + ], + insect: [ + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/insect/000_everglades_conehead.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/insect/001_robust_shieldback.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/insect/002_seashore_meadow_katydid.wav', + ], + wind: [ + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/wind/000_wind1.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/wind/001_wind10.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/wind/002_wind2.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/wind/003_wind3.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/wind/004_wind4.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/wind/005_wind5.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/wind/006_wind6.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/wind/007_wind7.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/wind/008_wind8.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/wind/009_wind9.wav', + ], + jazz: [ + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/jazz/000_BD.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/jazz/001_CB.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/jazz/002_FX.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/jazz/003_HH.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/jazz/004_OH.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/jazz/005_P1.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/jazz/006_P2.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/jazz/007_SN.wav', + ], + metal: [ + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/metal/000_0.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/metal/001_1.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/metal/002_2.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/metal/003_3.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/metal/004_4.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/metal/005_5.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/metal/006_6.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/metal/007_7.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/metal/008_8.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/metal/009_9.wav', + ], + east: [ + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/east/000_nipon_wood_block.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/east/001_ohkawa_mute.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/east/002_ohkawa_open.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/east/003_shime_hi.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/east/004_shime_hi_2.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/east/005_shime_mute.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/east/006_taiko_1.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/east/007_taiko_2.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/east/008_taiko_3.wav', + ], + space: [ + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/000_0.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/001_1.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/002_11.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/003_12.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/004_13.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/005_14.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/006_15.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/007_16.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/008_17.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/009_18.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/010_2.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/011_3.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/012_4.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/013_5.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/014_6.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/015_7.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/016_8.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/017_9.wav', + ], + numbers: [ + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/numbers/0.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/numbers/1.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/numbers/2.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/numbers/3.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/numbers/4.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/numbers/5.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/numbers/6.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/numbers/7.wav', + 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/numbers/8.wav', + ], + piano: ['https://raw.githubusercontent.com/felixroos/dough-samples/refs/heads/main/piano/A3v8.mp3'], + flute: ['https://raw.githubusercontent.com/felixroos/samples/refs/heads/main/flute/c4.mp3'], + bd: [ + 'https://raw.githubusercontent.com/geikha/tidal-drum-machines/15eac73c5e878550f91d864a4863e014799403f1/machines/RolandTR909/rolandtr909-bd/Bassdrum-01.wav', + ], +}; +// for some reason, only piano and flute work.. is it because mp3?? + +let loaded = false; +export async function doughsample() { + !doughWorklet && initDoughWorklet(); + if (loaded) { + return; + } + loaded = true; + const sampleMap = await Promise.all( + Object.entries(samples).map(async ([key, url]) => { + url = url[0]; + console.log(key, 'url', url); + return [key, await loadSampleChannels(url)]; + }), + ); + console.log('sampleMap', sampleMap); + doughWorklet.port.postMessage({ samples: sampleMap }); +} From 356d4360ecbbe09a21b697de7c563a4387b572cd Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 8 Jun 2025 09:05:14 +0200 Subject: [PATCH 030/335] fix: scheduling + sample playback --- packages/supradough/dough.mjs | 14 ++++++-------- packages/webaudio/supradough.mjs | 28 ++++++++++++++-------------- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index e42b4f8e8..dc083bac7 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -384,6 +384,7 @@ export class Distort { // distortion could be expressed as a function, because it's stateless export class BufferPlayer { + static samples = new Map(); channels = []; pos = 0; update(freq, channel = 0) { @@ -573,10 +574,9 @@ export class DoughVoice { if (shapes[this.s]) { const SourceClass = shapes[this.s]; this._sound = new SourceClass(); - } else if (value.samples.has(this.s)) { + } else if (BufferPlayer.samples.has(this.s)) { this._sample = new BufferPlayer(); - this._sample.channels = value.samples.get(this.s); - this._sample.pos = 0; + this._sample.channels = BufferPlayer.samples.get(this.s); } else { console.warn('sound not found', this.s); } @@ -735,7 +735,6 @@ export class DoughVoice { this._crush && (s = this._crush.update(s, this.crush)); this._distort && (s = this._distort.update(s, this.distort, this.distortvol)); - /* Math.random() > 0.99 && console.log('gate', gate); */ const env = this._adsr.update(t, gate, this.attack, this.decay, this.sustain, this.release); s = s * env; @@ -762,7 +761,6 @@ export class Dough { delaysend = [0, 0]; delaytime = getDefaultValue('delaytime'); delayfeedback = getDefaultValue('delayfeedback'); - samples = new Map(); t = 0; // sampleRate: number, currentTime: number (seconds) constructor(sampleRate = 48000, currentTime = 0) { @@ -773,7 +771,7 @@ export class Dough { this._delayR = new Delay(); } loadSample(name, channels) { - this.samples.set(name, channels); + BufferPlayer.samples.set(name, channels); } scheduleSpawn(value) { if (value._begin === undefined) { @@ -783,12 +781,12 @@ export class Dough { throw new Error('[dough]: scheduleSpawn expected _duration to be set'); } value.sampleRate = this.sampleRate; - const time = value._begin; // set from supradough.mjs + // convert seconds to samples + const time = Math.floor(value._begin * this.sampleRate); // set from supradough.mjs this.schedule({ time, type: 'spawn', arg: value }); } spawn(value) { value.id = this.vid++; - value.samples = this.samples; const voice = new DoughVoice(value); this.voices.push(voice); // console.log('spawn', voice.id, 'voices:', this.voices.length); diff --git a/packages/webaudio/supradough.mjs b/packages/webaudio/supradough.mjs index 38b2330c3..317f3aa31 100644 --- a/packages/webaudio/supradough.mjs +++ b/packages/webaudio/supradough.mjs @@ -25,18 +25,6 @@ Pattern.prototype.supradough = function () { }, 1); }; -async function loadSampleChannels(url) { - const buffer = await fetch(url) - .then((res) => res.arrayBuffer()) - .then((buf) => getAudioContext().decodeAudioData(buf)); - // console.log('buffer', buffer, buffer.numberOfChannels); - let channels = []; - for (let i = 0; i < buffer.numberOfChannels; i++) { - channels.push(buffer.getChannelData(i)); - } - return channels; -} - let samples = { casio: [ 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/casio/high.wav', @@ -138,6 +126,17 @@ let samples = { }; // for some reason, only piano and flute work.. is it because mp3?? +async function loadSampleChannels(url) { + const buffer = await fetch(url) + .then((res) => res.arrayBuffer()) + .then((buf) => getAudioContext().decodeAudioData(buf)); + let channels = []; + for (let i = 0; i < buffer.numberOfChannels; i++) { + channels.push(buffer.getChannelData(i)); + } + return channels; +} + let loaded = false; export async function doughsample() { !doughWorklet && initDoughWorklet(); @@ -148,8 +147,9 @@ export async function doughsample() { const sampleMap = await Promise.all( Object.entries(samples).map(async ([key, url]) => { url = url[0]; - console.log(key, 'url', url); - return [key, await loadSampleChannels(url)]; + const channels = await loadSampleChannels(url); + // console.log(key, 'url', url, channels); + return [key, channels]; }), ); console.log('sampleMap', sampleMap); From 55aef1885117a94c4a153368f3b29f762a698db8 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 8 Jun 2025 14:43:23 +0200 Subject: [PATCH 031/335] buffers can now be repitched (still with aliasing) --- packages/supradough/dough-worklet.mjs | 6 +++--- packages/supradough/dough.mjs | 22 ++++++++++++++-------- packages/webaudio/supradough.mjs | 10 ++++------ 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/packages/supradough/dough-worklet.mjs b/packages/supradough/dough-worklet.mjs index 97a35c487..dd2315628 100644 --- a/packages/supradough/dough-worklet.mjs +++ b/packages/supradough/dough-worklet.mjs @@ -10,10 +10,10 @@ class DoughProcessor extends AudioWorkletProcessor { if (event.data.spawn) { this.dough.scheduleSpawn(event.data.spawn); } else if (event.data.sample) { - this.dough.loadSample(event.data.sample, event.data.channels); + this.dough.loadSample(event.data.sample, event.data.channels, event.data.sampleRate); } else if (event.data.samples) { - event.data.samples.forEach(([name, channels]) => { - this.dough.loadSample(name, channels); + event.data.samples.forEach(([name, channels, sampleRate]) => { + this.dough.loadSample(name, channels, sampleRate); }); } else { console.log('unrecognized event type', event.data); diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index dc083bac7..b378ee70e 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -385,14 +385,16 @@ export class Distort { export class BufferPlayer { static samples = new Map(); - channels = []; + buffer; // { channels: Float32Array, sampleRate: number } pos = 0; + sampleFreq = 261.626; // middle c update(freq, channel = 0) { - if (this.pos >= this.channels[channel].length) { + if (this.pos >= this.buffer.channels[channel].length) { return 0; } - let s = this.channels[channel][this.pos]; - this.pos++; + const speed = ((freq / this.sampleFreq) * this.buffer.sampleRate) / SAMPLE_RATE; + let s = this.buffer.channels[channel][Math.floor(this.pos)]; + this.pos = this.pos + speed; return s; } } @@ -576,7 +578,8 @@ export class DoughVoice { this._sound = new SourceClass(); } else if (BufferPlayer.samples.has(this.s)) { this._sample = new BufferPlayer(); - this._sample.channels = BufferPlayer.samples.get(this.s); + const buffer = BufferPlayer.samples.get(this.s); + this._sample.buffer = buffer; } else { console.warn('sound not found', this.s); } @@ -738,7 +741,10 @@ export class DoughVoice { const env = this._adsr.update(t, gate, this.attack, this.decay, this.sustain, this.release); s = s * env; - s = s * this.postgain * 0.2; + s = s * this.postgain; + if (!this._sample) { + s = s * 0.2; // turn down waveforms + } if (this.pan === 0.5) { this.l = this.r = s; // mono @@ -770,8 +776,8 @@ export class Dough { this._delayL = new Delay(); this._delayR = new Delay(); } - loadSample(name, channels) { - BufferPlayer.samples.set(name, channels); + loadSample(name, channels, sampleRate) { + BufferPlayer.samples.set(name, { channels, sampleRate }); } scheduleSpawn(value) { if (value._begin === undefined) { diff --git a/packages/webaudio/supradough.mjs b/packages/webaudio/supradough.mjs index 317f3aa31..269dcda95 100644 --- a/packages/webaudio/supradough.mjs +++ b/packages/webaudio/supradough.mjs @@ -118,7 +118,7 @@ let samples = { 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/numbers/7.wav', 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/numbers/8.wav', ], - piano: ['https://raw.githubusercontent.com/felixroos/dough-samples/refs/heads/main/piano/A3v8.mp3'], + piano: ['https://raw.githubusercontent.com/felixroos/dough-samples/refs/heads/main/piano/C3v8.mp3'], flute: ['https://raw.githubusercontent.com/felixroos/samples/refs/heads/main/flute/c4.mp3'], bd: [ 'https://raw.githubusercontent.com/geikha/tidal-drum-machines/15eac73c5e878550f91d864a4863e014799403f1/machines/RolandTR909/rolandtr909-bd/Bassdrum-01.wav', @@ -126,7 +126,7 @@ let samples = { }; // for some reason, only piano and flute work.. is it because mp3?? -async function loadSampleChannels(url) { +async function loadSampleChannels(key, url) { const buffer = await fetch(url) .then((res) => res.arrayBuffer()) .then((buf) => getAudioContext().decodeAudioData(buf)); @@ -134,7 +134,7 @@ async function loadSampleChannels(url) { for (let i = 0; i < buffer.numberOfChannels; i++) { channels.push(buffer.getChannelData(i)); } - return channels; + return [key, channels, buffer.sampleRate]; } let loaded = false; @@ -147,9 +147,7 @@ export async function doughsample() { const sampleMap = await Promise.all( Object.entries(samples).map(async ([key, url]) => { url = url[0]; - const channels = await loadSampleChannels(url); - // console.log(key, 'url', url, channels); - return [key, channels]; + return loadSampleChannels(key, url); }), ); console.log('sampleMap', sampleMap); From ec9109dd892386c65e3a374da48ed8eb0df53b59 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sun, 8 Jun 2025 19:24:55 +0200 Subject: [PATCH 032/335] exponential lerp --- packages/supradough/dough.mjs | 38 ++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index 08469e634..7ee353277 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -192,16 +192,30 @@ export class Hold { } } -function lerp(x, y0, y1) { +function lerp(x, y0, y1, exponent = 1) { + if (x <= 0) return y0; if (x >= 1) return y1; - return y0 + x * (y1 - y0); + let curvedX; + + if (exponent === 0) { + curvedX = x; // linear + } else if (exponent > 0) { + curvedX = Math.pow(x, exponent); // ease-in + } else { + curvedX = 1 - Math.pow(1 - x, -exponent); // ease-out + } + + return y0 + (y1 - y0) * curvedX; } export class ADSR { - state = 'off'; - startTime = 0; - startVal = 0; + constructor(props = {}) { + this.state = 'off' + this.startTime = 0; + this.startVal = 0; + this.curve = props.curve ?? 1; + } update(curTime, gate, attack, decay, susVal, release) { switch (this.state) { @@ -220,11 +234,11 @@ export class ADSR { this.startTime = curTime; return 1; } - return lerp(time / attack, this.startVal, 1); + return lerp(time / attack, this.startVal, 1, this.curve); } case 'decay': { let time = curTime - this.startTime; - let curVal = lerp(time / decay, 1, susVal); + let curVal = lerp(time / decay, 1, susVal, -this.curve); if (gate <= 0) { this.state = 'release'; this.startTime = curTime; @@ -253,7 +267,7 @@ export class ADSR { this.state = 'off'; return 0; } - let curVal = lerp(time / release, this.startVal, 0); + let curVal = lerp(time / release, this.startVal, 0, -this.curve); if (gate > 0) { this.state = 'attack'; this.startTime = curTime; @@ -564,6 +578,7 @@ export class DoughVoice { this.fmsustain, this.fmrelease, ]); + } } @@ -571,7 +586,9 @@ export class DoughVoice { this._lpf = this.cutoff ? new TwoPoleFilter() : null; this.resonance = this.resonance ?? getDefaultValue('resonance'); if (this.lpenv) { - this._lpenv = new ADSR(); + + this._lpenv = new ADSR({curve: 4}); + [this.lpattack, this.lpdecay, this.lpsustain, this.lprelease] = getADSRValues([ this.lpattack, this.lpdecay, @@ -584,6 +601,7 @@ export class DoughVoice { this.hresonance = this.hresonance ?? getDefaultValue('hresonance'); if (this.hpenv) { this._hpenv = new ADSR(); + [this.hpattack, this.hpdecay, this.hpsustain, this.hprelease] = getADSRValues([ this.hpattack, this.hpdecay, @@ -604,7 +622,7 @@ export class DoughVoice { } // gain envelope - this._adsr = new ADSR(); + this._adsr = new ADSR({curve: 2}); // fx setup this._coarse = this.coarse ? new Coarse() : null; From 181e51ef0e1421031187231c8b131aca9e3570cc Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sun, 8 Jun 2025 20:26:20 +0200 Subject: [PATCH 033/335] adjustable envelope curves --- packages/supradough/dough.mjs | 38 +++++++++++++++++------------------ 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index e16d11f8a..1b1be3e1d 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -214,7 +214,7 @@ export class ADSR { this.state = 'off' this.startTime = 0; this.startVal = 0; - this.curve = props.curve ?? 1; + this.decayCurve = props.decayCurve ?? 1; } update(curTime, gate, attack, decay, susVal, release) { @@ -234,11 +234,11 @@ export class ADSR { this.startTime = curTime; return 1; } - return lerp(time / attack, this.startVal, 1, this.curve); + return lerp(time / attack, this.startVal, 1, 1); } case 'decay': { let time = curTime - this.startTime; - let curVal = lerp(time / decay, 1, susVal, -this.curve); + let curVal = lerp(time / decay, 1, susVal, -this.decayCurve); if (gate <= 0) { this.state = 'release'; this.startTime = curTime; @@ -267,7 +267,7 @@ export class ADSR { this.state = 'off'; return 0; } - let curVal = lerp(time / release, this.startVal, 0, -this.curve); + let curVal = lerp(time / release, this.startVal, 0, -this.decayCurve); if (gate > 0) { this.state = 'attack'; this.startTime = curTime; @@ -599,7 +599,7 @@ export class DoughVoice { } if (this.penv) { - this._penv = new ADSR(); + this._penv = new ADSR({ decayCurve: 4 }); [this.pattack, this.pdecay, this.psustain, this.prelease] = getADSRValues([ this.pattack, this.pdecay, @@ -612,14 +612,14 @@ export class DoughVoice { this._fm = new SineOsc(); this.fmh = this.fmh ?? getDefaultValue('fmh'); if (this.fmenv) { - this._fmenv = new ADSR(); + this._fmenv = new ADSR({ decayCurve: 2 }); [this.fmattack, this.fmdecay, this.fmsustain, this.fmrelease] = getADSRValues([ this.fmattack, this.fmdecay, this.fmsustain, this.fmrelease, ]); - + } } @@ -628,8 +628,8 @@ export class DoughVoice { this.resonance = this.resonance ?? getDefaultValue('resonance'); if (this.lpenv) { - this._lpenv = new ADSR({curve: 4}); - + this._lpenv = new ADSR({ decayCurve: 4 }); + [this.lpattack, this.lpdecay, this.lpsustain, this.lprelease] = getADSRValues([ this.lpattack, this.lpdecay, @@ -641,8 +641,8 @@ export class DoughVoice { this._hpf = this.hcutoff ? new TwoPoleFilter() : null; this.hresonance = this.hresonance ?? getDefaultValue('hresonance'); if (this.hpenv) { - this._hpenv = new ADSR(); - + this._hpenv = new ADSR({ decayCurve: 4 }); + [this.hpattack, this.hpdecay, this.hpsustain, this.hprelease] = getADSRValues([ this.hpattack, this.hpdecay, @@ -653,7 +653,7 @@ export class DoughVoice { this._bpf = this.bandf ? new TwoPoleFilter() : null; this.bandq = this.bandq ?? getDefaultValue('bandq'); if (this.bpenv) { - this._bpenv = new ADSR(); + this._bpenv = new ADSR({ decayCurve: 4 }); [this.bpattack, this.bpdecay, this.bpsustain, this.bprelease] = getADSRValues([ this.bpattack, this.bpdecay, @@ -663,7 +663,7 @@ export class DoughVoice { } // gain envelope - this._adsr = new ADSR({curve: 2}); + this._adsr = new ADSR({ decayCurve: 2 }); // fx setup this._coarse = this.coarse ? new Coarse() : null; @@ -695,7 +695,7 @@ export class DoughVoice { if (this._fm) { let fmi = this.fmi; if (this._fmenv) { - const env = this._fmenv.update(t, gate, this.fmattack, this.fmdecay, this.fmsustain, this.fmrelease) ** 2; + const env = this._fmenv.update(t, gate, this.fmattack, this.fmdecay, this.fmsustain, this.fmrelease); fmi = this.fmenv * env * fmi; } const modfreq = freq * this.fmh; @@ -704,7 +704,7 @@ export class DoughVoice { } if (this._penv) { - const env = this._penv.update(t, gate, this.pattack, this.pdecay, this.psustain, this.prelease) ** 2; + const env = this._penv.update(t, gate, this.pattack, this.pdecay, this.psustain, this.prelease); freq = freq + env * this.penv; } @@ -722,8 +722,8 @@ export class DoughVoice { if (this._lpf) { let cutoff = this.cutoff; if (this._lpenv) { - const env = this._lpenv.update(t, gate, this.lpattack, this.lpdecay, this.lpsustain, this.lprelease) ** 2; - cutoff = 2 ** this.lpenv * env * cutoff + cutoff; + const env = this._lpenv.update(t, gate, this.lpattack, this.lpdecay, this.lpsustain, this.lprelease); + cutoff = this.lpenv * env * cutoff + cutoff; } cutoff = this.freq2cutoff(cutoff); this._lpf.update(s, cutoff, this.resonance); @@ -733,7 +733,7 @@ export class DoughVoice { if (this._hpf) { let cutoff = this.hcutoff; if (this._hpenv) { - const env = this._hpenv.update(t, gate, this.hpattack, this.hpdecay, this.hpsustain, this.hprelease) ** 2; + const env = this._hpenv.update(t, gate, this.hpattack, this.hpdecay, this.hpsustain, this.hprelease); cutoff = 2 ** this.hpenv * env * cutoff + cutoff; } cutoff = this.freq2cutoff(cutoff); @@ -744,7 +744,7 @@ export class DoughVoice { if (this._bpf) { let cutoff = this.bandf; if (this._bpenv) { - const env = this._bpenv.update(t, gate, this.bpattack, this.bpdecay, this.bpsustain, this.bprelease) ** 2; + const env = this._bpenv.update(t, gate, this.bpattack, this.bpdecay, this.bpsustain, this.bprelease); cutoff = 2 ** this.bpenv * env * cutoff + cutoff; } cutoff = this.freq2cutoff(cutoff); From 73ef43dd2c85db8493c7a0d41fda2ec0cd824f58 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 8 Jun 2025 22:56:55 +0200 Subject: [PATCH 034/335] move things around in init + shorten things --- packages/supradough/dough.mjs | 226 ++++++++++++---------------------- 1 file changed, 79 insertions(+), 147 deletions(-) diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index 1b1be3e1d..f0665b779 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -211,7 +211,7 @@ function lerp(x, y0, y1, exponent = 1) { export class ADSR { constructor(props = {}) { - this.state = 'off' + this.state = 'off'; this.startTime = 0; this.startVal = 0; this.decayCurve = props.decayCurve ?? 1; @@ -398,7 +398,7 @@ export class Distort { // distortion could be expressed as a function, because it's stateless export class BufferPlayer { - static samples = new Map(); + static samples = new Map(); // string -> { channels, sampleRate } buffer; // { channels: Float32Array, sampleRate: number } pos = 0; sampleFreq = 261.626; // middle c @@ -421,7 +421,7 @@ export function _rangex(sig, min, max) { } // duplicate -export const getADSRValues = (params, curve = 'linear', defaultValues) => { +export const getADSR = (params, curve = 'linear', defaultValues) => { const envmin = curve === 'exponential' ? 0.001 : 0.001; const releaseMin = 0.01; const envmax = 1; @@ -517,167 +517,99 @@ export class DoughVoice { l = 0; r = 0; constructor(value) { - // params without defaults: - /* - bank, - source, - cutoff, - lpenv, - lpattack, - lpdecay, - lpsustain, - lprelease, - hpenv, - hcutoff, - hpattack, - hpdecay, - hpsustain, - hprelease, - bpenv, - bandf, - bpattack, - bpdecay, - bpsustain, - bprelease, - phaserrate, - phasersweep, - phasercenter, - shape, - vowel, - room, - roomfade, - roomlp, - roomdim, - roomsize, - ir, - analyze, - fmh, - fmi - */ value.freq = getFrequency(value); - Object.assign(this, value); - // params with defaults: - this.s = this.s ?? getDefaultValue('s'); - this.gain = this.gain ?? getDefaultValue('gain'); - this.velocity = this.velocity ?? getDefaultValue('velocity'); - this.postgain = this.postgain ?? getDefaultValue('postgain'); - this.density = this.density ?? getDefaultValue('density'); - this.fanchor = this.fanchor ?? getDefaultValue('fanchor'); - this.drive = this.drive ?? 0.69; - this.phaserdepth = this.phaserdepth ?? getDefaultValue('phaserdepth'); - this.shapevol = this.shapevol ?? getDefaultValue('shapevol'); - this.distortvol = this.distortvol ?? getDefaultValue('distortvol'); - this.i = this.i ?? getDefaultValue('i'); - this.fft = this.fft ?? getDefaultValue('fft'); - this.pan = this.pan ?? getDefaultValue('pan'); - this.orbit = this.orbit ?? getDefaultValue('orbit'); - this.fmenv = this.fmenv ?? getDefaultValue('fmenv'); + let $ = this; + Object.assign($, value); + $.s = $.s ?? getDefaultValue('s'); + $.gain = $.gain ?? getDefaultValue('gain'); + $.velocity = $.velocity ?? getDefaultValue('velocity'); + $.postgain = $.postgain ?? getDefaultValue('postgain'); + $.density = $.density ?? getDefaultValue('density'); + $.fanchor = $.fanchor ?? getDefaultValue('fanchor'); + $.drive = $.drive ?? 0.69; + $.phaserdepth = $.phaserdepth ?? getDefaultValue('phaserdepth'); + $.shapevol = $.shapevol ?? getDefaultValue('shapevol'); + $.distortvol = $.distortvol ?? getDefaultValue('distortvol'); + $.i = $.i ?? getDefaultValue('i'); + $.fft = $.fft ?? getDefaultValue('fft'); + $.pan = $.pan ?? getDefaultValue('pan'); + $.orbit = $.orbit ?? getDefaultValue('orbit'); + $.fmenv = $.fmenv ?? getDefaultValue('fmenv'); + $.resonance = $.resonance ?? getDefaultValue('resonance'); + $.hresonance = $.hresonance ?? getDefaultValue('hresonance'); + $.bandq = $.bandq ?? getDefaultValue('bandq'); - [this.attack, this.decay, this.sustain, this.release] = getADSRValues([ - this.attack, - this.decay, - this.sustain, - this.release, - ]); + [$.attack, $.decay, $.sustain, $.release] = getADSR([$.attack, $.decay, $.sustain, $.release]); - this._holdEnd = this._begin + this._duration; // needed for gate - this._end = this._holdEnd + this.release + 0.01; // needed for despawn + $._holdEnd = $._begin + $._duration; // needed for gate + $._end = $._holdEnd + $.release + 0.01; // needed for despawn - this.s ??= 'triangle'; - if (this.s === 'saw' || this.s === 'sawtooth') { - this.s = 'zaw'; // polyblepped saw when fm is applied + $.s ??= 'triangle'; + if ($.s === 'saw' || $.s === 'sawtooth') { + $.s = 'zaw'; // polyblepped saw when fm is applied } - if (shapes[this.s]) { - const SourceClass = shapes[this.s]; - this._sound = new SourceClass(); - } else if (BufferPlayer.samples.has(this.s)) { - this._sample = new BufferPlayer(); - const buffer = BufferPlayer.samples.get(this.s); - this._sample.buffer = buffer; + + if (shapes[$.s]) { + const SourceClass = shapes[$.s]; + $._sound = new SourceClass(); + $._channels = 1; + } else if (BufferPlayer.samples.has($.s)) { + $._sample = new BufferPlayer(); + const buffer = BufferPlayer.samples.get($.s); + $._sample.buffer = buffer; // {channels,sampleRate} + $._channels = $._sample.buffer.channels.length; } else { - console.warn('sound not found', this.s); + console.warn('sound not found', $.s); } - if (this.penv) { - this._penv = new ADSR({ decayCurve: 4 }); - [this.pattack, this.pdecay, this.psustain, this.prelease] = getADSRValues([ - this.pattack, - this.pdecay, - this.psustain, - this.prelease, - ]); + if ($.penv) { + $._penv = new ADSR({ decayCurve: 4 }); + [$.pattack, $.pdecay, $.psustain, $.prelease] = getADSR([$.pattack, $.pdecay, $.psustain, $.prelease]); } - if (this.fmi) { - this._fm = new SineOsc(); - this.fmh = this.fmh ?? getDefaultValue('fmh'); - if (this.fmenv) { - this._fmenv = new ADSR({ decayCurve: 2 }); - [this.fmattack, this.fmdecay, this.fmsustain, this.fmrelease] = getADSRValues([ - this.fmattack, - this.fmdecay, - this.fmsustain, - this.fmrelease, - ]); - + if ($.fmi) { + $._fm = new SineOsc(); + $.fmh = $.fmh ?? getDefaultValue('fmh'); + if ($.fmenv) { + $._fmenv = new ADSR({ decayCurve: 2 }); + [$.fmattack, $.fmdecay, $.fmsustain, $.fmrelease] = getADSR([$.fmattack, $.fmdecay, $.fmsustain, $.fmrelease]); } } - // filter setup - this._lpf = this.cutoff ? new TwoPoleFilter() : null; - this.resonance = this.resonance ?? getDefaultValue('resonance'); - if (this.lpenv) { - - this._lpenv = new ADSR({ decayCurve: 4 }); - - [this.lpattack, this.lpdecay, this.lpsustain, this.lprelease] = getADSRValues([ - this.lpattack, - this.lpdecay, - this.lpsustain, - this.lprelease, - ]); - } - - this._hpf = this.hcutoff ? new TwoPoleFilter() : null; - this.hresonance = this.hresonance ?? getDefaultValue('hresonance'); - if (this.hpenv) { - this._hpenv = new ADSR({ decayCurve: 4 }); - - [this.hpattack, this.hpdecay, this.hpsustain, this.hprelease] = getADSRValues([ - this.hpattack, - this.hpdecay, - this.hpsustain, - this.hprelease, - ]); - } - this._bpf = this.bandf ? new TwoPoleFilter() : null; - this.bandq = this.bandq ?? getDefaultValue('bandq'); - if (this.bpenv) { - this._bpenv = new ADSR({ decayCurve: 4 }); - [this.bpattack, this.bpdecay, this.bpsustain, this.bprelease] = getADSRValues([ - this.bpattack, - this.bpdecay, - this.bpsustain, - this.bprelease, - ]); - } - // gain envelope - this._adsr = new ADSR({ decayCurve: 2 }); - - // fx setup - this._coarse = this.coarse ? new Coarse() : null; - this._crush = this.crush ? new Crush() : null; - this._distort = this.distort ? new Distort() : null; - + $._adsr = new ADSR({ decayCurve: 2 }); // delay - this.delay = this.delay ?? getDefaultValue('delay'); - this.delayfeedback = this.delayfeedback ?? getDefaultValue('delayfeedback'); - this.delaytime = this.delaytime ?? getDefaultValue('delaytime'); + $.delay = $.delay ?? getDefaultValue('delay'); + $.delayfeedback = $.delayfeedback ?? getDefaultValue('delayfeedback'); + $.delaytime = $.delaytime ?? getDefaultValue('delaytime'); // precalculated values - this.piOverSr = Math.PI / value.sampleRate; - this.eighthOverLogHalf = 0.125 / Math.log(0.5); + $.piOverSr = Math.PI / value.sampleRate; + $.eighthOverLogHalf = 0.125 / Math.log(0.5); + + // filter setup + if ($.lpenv) { + $._lpenv = new ADSR({ decayCurve: 4 }); + [$.lpattack, $.lpdecay, $.lpsustain, $.lprelease] = getADSR([$.lpattack, $.lpdecay, $.lpsustain, $.lprelease]); + } + if ($.hpenv) { + $._hpenv = new ADSR({ decayCurve: 4 }); + [$.hpattack, $.hpdecay, $.hpsustain, $.hprelease] = getADSR([$.hpattack, $.hpdecay, $.hpsustain, $.hprelease]); + } + if ($.bpenv) { + $._bpenv = new ADSR({ decayCurve: 4 }); + [$.bpattack, $.bpdecay, $.bpsustain, $.bprelease] = getADSR([$.bpattack, $.bpdecay, $.bpsustain, $.bprelease]); + } + + // 1 per channel:: + $._lpf = $.cutoff ? new TwoPoleFilter() : null; + $._hpf = $.hcutoff ? new TwoPoleFilter() : null; + $._bpf = $.bandf ? new TwoPoleFilter() : null; + + // fx setup + $._coarse = $.coarse ? new Coarse() : null; + $._crush = $.crush ? new Crush() : null; + $._distort = $.distort ? new Distort() : null; } // credits to pulu: https://github.com/felixroos/kabelsalat/issues/35 freq2cutoff(freq) { From 1081fc69e9130bed6c28a516d8a17d6003be7e13 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 9 Jun 2025 09:52:29 +0200 Subject: [PATCH 035/335] refactor: stereo sample support + channelwise fx --- packages/supradough/dough-worklet.mjs | 2 +- packages/supradough/dough.mjs | 176 +++++++++++++++----------- 2 files changed, 101 insertions(+), 77 deletions(-) diff --git a/packages/supradough/dough-worklet.mjs b/packages/supradough/dough-worklet.mjs index dd2315628..18c316b2d 100644 --- a/packages/supradough/dough-worklet.mjs +++ b/packages/supradough/dough-worklet.mjs @@ -29,7 +29,7 @@ class DoughProcessor extends AudioWorkletProcessor { this.dough.update(); for (let c = 0; c < output.length; c++) { //prevent speaker blowout via clipping if threshold exceeds - output[c][i] = clamp(this.dough.channels[c], -1, 1); + output[c][i] = clamp(this.dough.out[c], -1, 1); } } return true; // keep the audio processing going diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index f0665b779..963bd9bdc 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -399,15 +399,20 @@ export class Distort { export class BufferPlayer { static samples = new Map(); // string -> { channels, sampleRate } - buffer; // { channels: Float32Array, sampleRate: number } + buffer; // Float32Array + sampleRate; pos = 0; sampleFreq = 261.626; // middle c - update(freq, channel = 0) { - if (this.pos >= this.buffer.channels[channel].length) { + constructor(buffer, sampleRate) { + this.buffer = buffer; + this.sampleRate = sampleRate; + } + update(freq) { + if (this.pos >= this.buffer.length) { return 0; } - const speed = ((freq / this.sampleFreq) * this.buffer.sampleRate) / SAMPLE_RATE; - let s = this.buffer.channels[channel][Math.floor(this.pos)]; + const speed = ((freq / this.sampleFreq) * this.sampleRate) / SAMPLE_RATE; + let s = this.buffer[Math.floor(this.pos)]; this.pos = this.pos + speed; return s; } @@ -514,8 +519,7 @@ const getFrequency = (value) => { }; export class DoughVoice { - l = 0; - r = 0; + out = [0, 0]; constructor(value) { value.freq = getFrequency(value); let $ = this; @@ -554,10 +558,12 @@ export class DoughVoice { $._sound = new SourceClass(); $._channels = 1; } else if (BufferPlayer.samples.has($.s)) { - $._sample = new BufferPlayer(); - const buffer = BufferPlayer.samples.get($.s); - $._sample.buffer = buffer; // {channels,sampleRate} - $._channels = $._sample.buffer.channels.length; + const sample = BufferPlayer.samples.get($.s); + $._buffers = []; + $._channels = sample.channels.length; + for (let i = 0; i < $._channels; i++) { + $._buffers.push(new BufferPlayer(sample.channels[i], sample.sampleRate)); + } } else { console.warn('sound not found', $.s); } @@ -601,15 +607,21 @@ export class DoughVoice { [$.bpattack, $.bpdecay, $.bpsustain, $.bprelease] = getADSR([$.bpattack, $.bpdecay, $.bpsustain, $.bprelease]); } - // 1 per channel:: - $._lpf = $.cutoff ? new TwoPoleFilter() : null; - $._hpf = $.hcutoff ? new TwoPoleFilter() : null; - $._bpf = $.bandf ? new TwoPoleFilter() : null; - - // fx setup - $._coarse = $.coarse ? new Coarse() : null; - $._crush = $.crush ? new Crush() : null; - $._distort = $.distort ? new Distort() : null; + // channelwise effects setup + $._lpf = $.cutoff ? [] : null; + $._hpf = $.hcutoff ? [] : null; + $._bpf = $.bandf ? [] : null; + $._coarse = $.coarse ? [] : null; + $._crush = $.crush ? [] : null; + $._distort = $.distort ? [] : null; + for (let i = 0; i < this._channels; i++) { + $._lpf?.push(new TwoPoleFilter()); + $._hpf?.push(new TwoPoleFilter()); + $._bpf?.push(new TwoPoleFilter()); + $._coarse?.push(new Coarse()); + $._crush?.push(new Crush()); + $._distort?.push(new Distort()); + } } // credits to pulu: https://github.com/felixroos/kabelsalat/issues/35 freq2cutoff(freq) { @@ -617,13 +629,13 @@ export class DoughVoice { return 1 - Math.log(c) * this.eighthOverLogHalf; } update(t) { - if (!this._sound && !this._sample) { + if (!this._sound && !this._buffers) { return 0; } - let s = 0; let gate = Number(t >= this._begin && t <= this._holdEnd); let freq = this.freq; + // frequency modulation if (this._fm) { let fmi = this.fmi; if (this._fmenv) { @@ -635,74 +647,86 @@ export class DoughVoice { freq = freq + this._fm.update(modfreq) * modgain; } + // pitch envelope if (this._penv) { const env = this._penv.update(t, gate, this.pattack, this.pdecay, this.psustain, this.prelease); freq = freq + env * this.penv; } - // sound source - if (this._sound && this.s === 'pulse') { - s = this._sound.update(freq, this.pw ?? 0.5); - } else if (this._sound) { - s = this._sound.update(freq); - } else if (this._sample) { - s = this._sample.update(freq, 0); // tbd: stereo samples... - } - s = s * this.gain * this.velocity; - - // lpf + // filters + let lpf = this.cutoff; if (this._lpf) { - let cutoff = this.cutoff; if (this._lpenv) { const env = this._lpenv.update(t, gate, this.lpattack, this.lpdecay, this.lpsustain, this.lprelease); - cutoff = this.lpenv * env * cutoff + cutoff; + lpf = this.lpenv * env * lpf + lpf; } - cutoff = this.freq2cutoff(cutoff); - this._lpf.update(s, cutoff, this.resonance); - s = this._lpf.s1; + lpf = this.freq2cutoff(lpf); } - // hpf + let hpf = this.hcutoff; if (this._hpf) { - let cutoff = this.hcutoff; if (this._hpenv) { const env = this._hpenv.update(t, gate, this.hpattack, this.hpdecay, this.hpsustain, this.hprelease); - cutoff = 2 ** this.hpenv * env * cutoff + cutoff; + hpf = 2 ** this.hpenv * env * hpf + hpf; } - cutoff = this.freq2cutoff(cutoff); - this._hpf.update(s, cutoff, this.hresonance); - s = s - this._hpf.s1; + hpf = this.freq2cutoff(hpf); } - // bpf + let bpf = this.bandf; if (this._bpf) { - let cutoff = this.bandf; if (this._bpenv) { const env = this._bpenv.update(t, gate, this.bpattack, this.bpdecay, this.bpsustain, this.bprelease); - cutoff = 2 ** this.bpenv * env * cutoff + cutoff; + bpf = 2 ** this.bpenv * env * bpf + bpf; } - cutoff = this.freq2cutoff(cutoff); - this._bpf.update(s, cutoff, this.bandq); - s = this._bpf.s0; + bpf = this.freq2cutoff(bpf); } - - this._coarse && (s = this._coarse.update(s, this.coarse)); - this._crush && (s = this._crush.update(s, this.crush)); - this._distort && (s = this._distort.update(s, this.distort, this.distortvol)); - + // gain envelope const env = this._adsr.update(t, gate, this.attack, this.decay, this.sustain, this.release); - s = s * env; - s = s * this.postgain; - if (!this._sample) { - s = s * 0.2; // turn down waveforms + // channelwise dsp + for (let i = 0; i < this._channels; i++) { + // sound source + if (this._sound && this.s === 'pulse') { + this.out[i] = this._sound.update(freq, this.pw ?? 0.5); + } else if (this._sound) { + this.out[i] = this._sound.update(freq); + } else if (this._buffers) { + this.out[i] = this._buffers[i].update(freq); + } + this.out[i] = this.out[i] * this.gain * this.velocity; + + if (this._lpf) { + this._lpf[i].update(this.out[i], lpf, this.resonance); + this.out[i] = this._lpf[i].s1; + } + if (this._hpf) { + this._hpf[i].update(this.out[i], hcutoff, this.hresonance); + this.out[i] = this.out[i] - this._hpf[i].s1; + } + if (this._bpf) { + this._bpf[i].update(this.out[i], bpf, this.bandq); + this.out[i] = this._bpf[i].s0; + } + if (this._coarse) { + this.out[i] = this._coarse[i].update(this.out[i], this.coarse); + } + if (this._crush) { + this.out[i] = this._crush[i].update(this.out[i], this.crush); + } + if (this._distort) { + this.out[i] = this._distort[i].update(this.out[i], this.distort, this.distortvol); + } + this.out[i] = this.out[i] * env; + this.out[i] = this.out[i] * this.postgain; + if (!this._buffers) { + this.out[i] = this.out[i] * 0.2; // turn down waveform + } } - - if (this.pan === 0.5) { - this.l = this.r = s; // mono - } else { - // stereo - const pos = (this.pan * Math.PI) / 2; - this.l = s * Math.cos(pos); - this.r = s * Math.sin(pos); + if (this._channels === 1) { + this.out[1] = this.out[0]; + } + if (this.pan !== 0.5) { + const panpos = (this.pan * Math.PI) / 2; + this.out[0] = this.out[0] * Math.cos(panpos); + this.out[1] = this.out[1] * Math.sin(panpos); } } } @@ -713,7 +737,7 @@ export class Dough { voices = []; // DoughVoice[] vid = 0; q = []; - channels = [0, 0]; + out = [0, 0]; delaysend = [0, 0]; delaytime = getDefaultValue('delaytime'); delayfeedback = getDefaultValue('delayfeedback'); @@ -782,15 +806,15 @@ export class Dough { this.q.shift(); } // add active voices - this.channels[0] = 0; - this.channels[1] = 0; + this.out[0] = 0; + this.out[1] = 0; for (let v = 0; v < this.voices.length; v++) { this.voices[v].update(this.t / this.sampleRate); - this.channels[0] += this.voices[v].l; - this.channels[1] += this.voices[v].r; + this.out[0] += this.voices[v].out[0]; + this.out[1] += this.voices[v].out[1]; if (this.voices[v].delay) { - this.delaysend[0] += this.voices[v].l * this.voices[v].delay; - this.delaysend[1] += this.voices[v].r * this.voices[v].delay; + this.delaysend[0] += this.voices[v].out[0] * this.voices[v].delay; + this.delaysend[1] += this.voices[v].out[1] * this.voices[v].delay; this.delaytime = this.voices[v].delaytime; // we trust that these are initialized in the voice this.delayfeedback = this.voices[v].delayfeedback; } @@ -800,8 +824,8 @@ export class Dough { const delayR = this._delayR.update(this.delaysend[1], this.delaytime); this.delaysend[0] = delayL * this.delayfeedback; this.delaysend[1] = delayR * this.delayfeedback; - this.channels[0] += delayL; - this.channels[1] += delayR; + this.out[0] += delayL; + this.out[1] += delayR; this.t++; } } From d1b6b6be8541b833410f147672aa68071dda3f5f Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 9 Jun 2025 09:54:24 +0200 Subject: [PATCH 036/335] fix: hpf --- packages/supradough/dough.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index 963bd9bdc..975840cb3 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -698,7 +698,7 @@ export class DoughVoice { this.out[i] = this._lpf[i].s1; } if (this._hpf) { - this._hpf[i].update(this.out[i], hcutoff, this.hresonance); + this._hpf[i].update(this.out[i], hpf, this.hresonance); this.out[i] = this.out[i] - this._hpf[i].s1; } if (this._bpf) { From 3ac0fdf619d824757aa9f2f6b0da8366b7b42463 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 9 Jun 2025 11:07:57 +0200 Subject: [PATCH 037/335] rudimentary sample map loading (doughsamples) --- packages/superdough/sampler.mjs | 91 ++++++++-------- packages/supradough/dough.mjs | 19 ++-- packages/webaudio/supradough.mjs | 178 ++++++++++++------------------- 3 files changed, 126 insertions(+), 162 deletions(-) diff --git a/packages/superdough/sampler.mjs b/packages/superdough/sampler.mjs index 18d1b7797..9188c17c3 100644 --- a/packages/superdough/sampler.mjs +++ b/packages/superdough/sampler.mjs @@ -196,6 +196,52 @@ function getSamplesPrefixHandler(url) { return; } +export async function fetchSampleMap(url) { + // check if custom prefix handler + const handler = getSamplesPrefixHandler(url); + if (handler) { + return handler(url); + } + url = resolveSpecialPaths(url); + if (url.startsWith('github:')) { + url = githubPath(url, 'strudel.json'); + } + if (url.startsWith('local:')) { + url = `http://localhost:5432`; + } + if (url.startsWith('shabda:')) { + let [_, path] = url.split('shabda:'); + url = `https://shabda.ndre.gr/${path}.json?strudel=1`; + } + if (url.startsWith('shabda/speech')) { + let [_, path] = url.split('shabda/speech'); + path = path.startsWith('/') ? path.substring(1) : path; + let [params, words] = path.split(':'); + let gender = 'f'; + let language = 'en-GB'; + if (params) { + [language, gender] = params.split('/'); + } + url = `https://shabda.ndre.gr/speech/${words}.json?gender=${gender}&language=${language}&strudel=1'`; + } + if (typeof fetch !== 'function') { + // not a browser + return; + } + const base = url.split('/').slice(0, -1).join('/'); + if (typeof fetch === 'undefined') { + // skip fetch when in node / testing + return; + } + const json = await fetch(url) + .then((res) => res.json()) + .catch((error) => { + console.error(error); + throw new Error(`error loading "${url}"`); + }); + return [json, json._base || base]; +} + /** * Loads a collection of samples to use with `s` * @example @@ -217,49 +263,8 @@ function getSamplesPrefixHandler(url) { export const samples = async (sampleMap, baseUrl = sampleMap._base || '', options = {}) => { if (typeof sampleMap === 'string') { - // check if custom prefix handler - const handler = getSamplesPrefixHandler(sampleMap); - if (handler) { - return handler(sampleMap); - } - sampleMap = resolveSpecialPaths(sampleMap); - if (sampleMap.startsWith('github:')) { - sampleMap = githubPath(sampleMap, 'strudel.json'); - } - if (sampleMap.startsWith('local:')) { - sampleMap = `http://localhost:5432`; - } - if (sampleMap.startsWith('shabda:')) { - let [_, path] = sampleMap.split('shabda:'); - sampleMap = `https://shabda.ndre.gr/${path}.json?strudel=1`; - } - if (sampleMap.startsWith('shabda/speech')) { - let [_, path] = sampleMap.split('shabda/speech'); - path = path.startsWith('/') ? path.substring(1) : path; - let [params, words] = path.split(':'); - let gender = 'f'; - let language = 'en-GB'; - if (params) { - [language, gender] = params.split('/'); - } - sampleMap = `https://shabda.ndre.gr/speech/${words}.json?gender=${gender}&language=${language}&strudel=1'`; - } - if (typeof fetch !== 'function') { - // not a browser - return; - } - const base = sampleMap.split('/').slice(0, -1).join('/'); - if (typeof fetch === 'undefined') { - // skip fetch when in node / testing - return; - } - return fetch(sampleMap) - .then((res) => res.json()) - .then((json) => samples(json, baseUrl || json._base || base, options)) - .catch((error) => { - console.error(error); - throw new Error(`error loading "${sampleMap}"`); - }); + const [json, base] = await fetchSampleMap(sampleMap); + return samples(json, baseUrl || base, options); } const { prebake, tag } = options; processSampleMap( diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index 975840cb3..207638737 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -402,7 +402,7 @@ export class BufferPlayer { buffer; // Float32Array sampleRate; pos = 0; - sampleFreq = 261.626; // middle c + sampleFreq = note2freq(); constructor(buffer, sampleRate) { this.buffer = buffer; this.sampleRate = sampleRate; @@ -411,7 +411,7 @@ export class BufferPlayer { if (this.pos >= this.buffer.length) { return 0; } - const speed = ((freq / this.sampleFreq) * this.sampleRate) / SAMPLE_RATE; + const speed = ((freq / this.sampleFreq) * SAMPLE_RATE) / this.sampleRate; let s = this.buffer[Math.floor(this.pos)]; this.pos = this.pos + speed; return s; @@ -458,6 +458,7 @@ let shapes = { }; const defaultDefaultValues = { + note: 48, s: 'triangle', gain: 1, postgain: 1, @@ -505,23 +506,19 @@ const note2midi = (note, defaultOctave = 3) => { oct = Number(oct || defaultOctave); return (oct + 1) * 12 + chroma + offset; }; -const getFrequency = (value) => { - let { note, freq } = value; - note = note || 36; +const midi2freq = (midi) => Math.pow(2, (midi - 69) / 12) * 440; +const note2freq = (note) => { + note = note || getDefaultValue('note'); if (typeof note === 'string') { note = note2midi(note, 3); // e.g. c3 => 48 } - if (!freq && typeof note === 'number') { - freq = Math.pow(2, (note - 69) / 12) * 440; - } - - return Number(freq); + return midi2freq(note); }; export class DoughVoice { out = [0, 0]; constructor(value) { - value.freq = getFrequency(value); + value.freq ??= note2freq(value.note); let $ = this; Object.assign($, value); $.s = $.s ?? getDefaultValue('s'); diff --git a/packages/webaudio/supradough.mjs b/packages/webaudio/supradough.mjs index 269dcda95..3b45415df 100644 --- a/packages/webaudio/supradough.mjs +++ b/packages/webaudio/supradough.mjs @@ -25,105 +25,58 @@ Pattern.prototype.supradough = function () { }, 1); }; -let samples = { - casio: [ - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/casio/high.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/casio/low.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/casio/noise.wav', - ], - crow: [ - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/crow/000_crow.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/crow/001_crow2.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/crow/002_crow3.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/crow/003_crow4.wav', - ], - insect: [ - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/insect/000_everglades_conehead.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/insect/001_robust_shieldback.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/insect/002_seashore_meadow_katydid.wav', - ], - wind: [ - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/wind/000_wind1.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/wind/001_wind10.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/wind/002_wind2.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/wind/003_wind3.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/wind/004_wind4.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/wind/005_wind5.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/wind/006_wind6.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/wind/007_wind7.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/wind/008_wind8.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/wind/009_wind9.wav', - ], - jazz: [ - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/jazz/000_BD.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/jazz/001_CB.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/jazz/002_FX.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/jazz/003_HH.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/jazz/004_OH.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/jazz/005_P1.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/jazz/006_P2.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/jazz/007_SN.wav', - ], - metal: [ - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/metal/000_0.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/metal/001_1.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/metal/002_2.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/metal/003_3.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/metal/004_4.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/metal/005_5.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/metal/006_6.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/metal/007_7.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/metal/008_8.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/metal/009_9.wav', - ], - east: [ - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/east/000_nipon_wood_block.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/east/001_ohkawa_mute.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/east/002_ohkawa_open.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/east/003_shime_hi.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/east/004_shime_hi_2.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/east/005_shime_mute.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/east/006_taiko_1.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/east/007_taiko_2.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/east/008_taiko_3.wav', - ], - space: [ - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/000_0.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/001_1.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/002_11.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/003_12.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/004_13.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/005_14.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/006_15.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/007_16.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/008_17.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/009_18.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/010_2.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/011_3.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/012_4.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/013_5.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/014_6.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/015_7.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/016_8.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/space/017_9.wav', - ], - numbers: [ - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/numbers/0.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/numbers/1.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/numbers/2.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/numbers/3.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/numbers/4.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/numbers/5.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/numbers/6.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/numbers/7.wav', - 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/numbers/8.wav', - ], - piano: ['https://raw.githubusercontent.com/felixroos/dough-samples/refs/heads/main/piano/C3v8.mp3'], - flute: ['https://raw.githubusercontent.com/felixroos/samples/refs/heads/main/flute/c4.mp3'], - bd: [ - 'https://raw.githubusercontent.com/geikha/tidal-drum-machines/15eac73c5e878550f91d864a4863e014799403f1/machines/RolandTR909/rolandtr909-bd/Bassdrum-01.wav', - ], -}; +function githubPath(base, subpath = '') { + if (!base.startsWith('github:')) { + throw new Error('expected "github:" at the start of pseudoUrl'); + } + let [_, path] = base.split('github:'); + path = path.endsWith('/') ? path.slice(0, -1) : path; + if (path.split('/').length === 2) { + // assume main as default branch if none set + path += '/main'; + } + return `https://raw.githubusercontent.com/${path}/${subpath}`; +} +export async function fetchSampleMap(url) { + if (url.startsWith('github:')) { + url = githubPath(url, 'strudel.json'); + } + if (url.startsWith('local:')) { + url = `http://localhost:5432`; + } + if (url.startsWith('shabda:')) { + let [_, path] = url.split('shabda:'); + url = `https://shabda.ndre.gr/${path}.json?strudel=1`; + } + if (url.startsWith('shabda/speech')) { + let [_, path] = url.split('shabda/speech'); + path = path.startsWith('/') ? path.substring(1) : path; + let [params, words] = path.split(':'); + let gender = 'f'; + let language = 'en-GB'; + if (params) { + [language, gender] = params.split('/'); + } + url = `https://shabda.ndre.gr/speech/${words}.json?gender=${gender}&language=${language}&strudel=1'`; + } + if (typeof fetch !== 'function') { + // not a browser + return; + } + const base = url.split('/').slice(0, -1).join('/'); + if (typeof fetch === 'undefined') { + // skip fetch when in node / testing + return; + } + const json = await fetch(url) + .then((res) => res.json()) + .catch((error) => { + console.error(error); + throw new Error(`error loading "${url}"`); + }); + return [json, json._base || base]; +} + // for some reason, only piano and flute work.. is it because mp3?? async function loadSampleChannels(key, url) { @@ -138,18 +91,27 @@ async function loadSampleChannels(key, url) { } let loaded = false; -export async function doughsample() { +export async function doughsamples(sampleMap, baseUrl) { + if (typeof sampleMap === 'string') { + const [json, base] = await fetchSampleMap(sampleMap); + // console.log('json', json, 'base', base); + return doughsamples(json, base); + } !doughWorklet && initDoughWorklet(); if (loaded) { return; } loaded = true; - const sampleMap = await Promise.all( - Object.entries(samples).map(async ([key, url]) => { - url = url[0]; - return loadSampleChannels(key, url); - }), - ); - console.log('sampleMap', sampleMap); - doughWorklet.port.postMessage({ samples: sampleMap }); + const json = ( + await Promise.all( + Object.entries(sampleMap).map(async ([key, url]) => { + if (key !== '_base') { + url = baseUrl + url[0]; + return loadSampleChannels(key, url); + } + }), + ) + ).filter(Boolean); + // console.log('sampleMap', json); + doughWorklet.port.postMessage({ samples: json }); } From aeaed50446e6f31e0a722ed3f19b8bd99e25efbb Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Mon, 9 Jun 2025 15:18:47 +0200 Subject: [PATCH 038/335] gaincurve --- packages/supradough/dough.mjs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index 207638737..fe3786a05 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -1,6 +1,15 @@ // this is dough, the superdough without dependencies const SAMPLE_RATE = typeof sampleRate !== 'undefined' ? sampleRate : 48000; const ISR = 1 / SAMPLE_RATE; + +let gainCurveFunc = (val) => Math.pow(val, 2); + +function applyGainCurve(val) { + return gainCurveFunc(val); +} +// function setGainCurve(newGainCurveFunc) { +// gainCurveFunc = newGainCurveFunc; +// } // https://garten.salat.dev/audio-DSP/oscillators.html export class SineOsc { phase = 0; @@ -522,15 +531,15 @@ export class DoughVoice { let $ = this; Object.assign($, value); $.s = $.s ?? getDefaultValue('s'); - $.gain = $.gain ?? getDefaultValue('gain'); - $.velocity = $.velocity ?? getDefaultValue('velocity'); - $.postgain = $.postgain ?? getDefaultValue('postgain'); + $.gain = applyGainCurve($.gain ?? getDefaultValue('gain')); + $.velocity = applyGainCurve($.velocity ?? getDefaultValue('velocity')); + $.postgain = applyGainCurve($.postgain ?? getDefaultValue('postgain')); $.density = $.density ?? getDefaultValue('density'); $.fanchor = $.fanchor ?? getDefaultValue('fanchor'); $.drive = $.drive ?? 0.69; $.phaserdepth = $.phaserdepth ?? getDefaultValue('phaserdepth'); - $.shapevol = $.shapevol ?? getDefaultValue('shapevol'); - $.distortvol = $.distortvol ?? getDefaultValue('distortvol'); + $.shapevol = applyGainCurve($.shapevol ?? getDefaultValue('shapevol')); + $.distortvol = applyGainCurve($.distortvol ?? getDefaultValue('distortvol')); $.i = $.i ?? getDefaultValue('i'); $.fft = $.fft ?? getDefaultValue('fft'); $.pan = $.pan ?? getDefaultValue('pan'); @@ -582,7 +591,7 @@ export class DoughVoice { // gain envelope $._adsr = new ADSR({ decayCurve: 2 }); // delay - $.delay = $.delay ?? getDefaultValue('delay'); + $.delay = applyGainCurve($.delay ?? getDefaultValue('delay')); $.delayfeedback = $.delayfeedback ?? getDefaultValue('delayfeedback'); $.delaytime = $.delaytime ?? getDefaultValue('delaytime'); From 3d300077563dd4f978b8315f6beeb5b9abfe3a8c Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Mon, 9 Jun 2025 15:55:44 +0200 Subject: [PATCH 039/335] supersaw --- packages/supradough/dough.mjs | 59 +++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index fe3786a05..4af3b7118 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -45,8 +45,9 @@ function polyBlep(t, dt) { return 0; } export class SawOsc { - //phase = Math.random(); - phase = 0; + constructor(props = {}) { + this.phase = props.phase ?? 0 + } update(freq) { const dt = freq / SAMPLE_RATE; let p = polyBlep(this.phase, dt); @@ -59,6 +60,59 @@ export class SawOsc { } } +function getUnisonDetune(unison, detune, voiceIndex) { + if (unison < 2) { + return 0; + } + const lerp = (a, b, n) => { + return n * (b - a) + a; + } + return lerp(-detune * 0.5, detune * 0.5, voiceIndex / (unison - 1)); +} +function applySemitoneDetuneToFrequency(frequency, detune) { + return frequency * Math.pow(2, detune / 12); +} +export class SupersawOsc { + constructor(props = {}) { + //TODO: figure out a good way to pass in these params + this.voices = props.voices ?? 5; + this.freqspread = props.freqspread ?? .2 + this.panspread = props.panspread ?? 0.4; + this.phase = new Float32Array(this.voices).map(() => Math.random()); + } + update(freq) { + const gain1 = Math.sqrt(1 - this.panspread); + const gain2 = Math.sqrt(this.panspread); + let sl = 0 + let sr = 0 + for (let n = 0; n < this.voices; n++) { + const freqAdjusted = applySemitoneDetuneToFrequency(freq, getUnisonDetune(this.voices, this.freqspread, n)) + const dt = freqAdjusted / SAMPLE_RATE; + const isOdd = (n & 1) == 1; + let gainL = gain1; + let gainR = gain2; + // invert right and left gain + if (isOdd) { + gainL = gain2; + gainR = gain1; + } + let p = polyBlep(this.phase[n], dt); + let s = 2 * this.phase[n] - 1 - p; + sl = sl + s * gainL + sr = sr + s * gainL + + this.phase[n] += dt; + if (this.phase[n] > 1) { + this.phase[n] -= 1; + } + } + + return sl + sr + //TODO: make stereo + // return [sl, sr]; + } +} + export class TriOsc { phase = 0; update(freq) { @@ -453,6 +507,7 @@ let shapes = { zaw: ZawOsc, sawtooth: SawOsc, zawtooth: ZawOsc, + supersaw: SupersawOsc, tri: TriOsc, triangle: TriOsc, pulse: PulseOsc, From e8254735bb3ad281bbaa4c0838cbe9a2fac7d2d7 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 9 Jun 2025 19:35:50 +0200 Subject: [PATCH 040/335] apply speed to synths and samples + add normalize flag (for fit) --- packages/supradough/dough.mjs | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index 4af3b7118..b11de6c24 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -46,7 +46,7 @@ function polyBlep(t, dt) { } export class SawOsc { constructor(props = {}) { - this.phase = props.phase ?? 0 + this.phase = props.phase ?? 0; } update(freq) { const dt = freq / SAMPLE_RATE; @@ -66,7 +66,7 @@ function getUnisonDetune(unison, detune, voiceIndex) { } const lerp = (a, b, n) => { return n * (b - a) + a; - } + }; return lerp(-detune * 0.5, detune * 0.5, voiceIndex / (unison - 1)); } function applySemitoneDetuneToFrequency(frequency, detune) { @@ -76,17 +76,17 @@ export class SupersawOsc { constructor(props = {}) { //TODO: figure out a good way to pass in these params this.voices = props.voices ?? 5; - this.freqspread = props.freqspread ?? .2 + this.freqspread = props.freqspread ?? 0.2; this.panspread = props.panspread ?? 0.4; this.phase = new Float32Array(this.voices).map(() => Math.random()); } update(freq) { const gain1 = Math.sqrt(1 - this.panspread); const gain2 = Math.sqrt(this.panspread); - let sl = 0 - let sr = 0 + let sl = 0; + let sr = 0; for (let n = 0; n < this.voices; n++) { - const freqAdjusted = applySemitoneDetuneToFrequency(freq, getUnisonDetune(this.voices, this.freqspread, n)) + const freqAdjusted = applySemitoneDetuneToFrequency(freq, getUnisonDetune(this.voices, this.freqspread, n)); const dt = freqAdjusted / SAMPLE_RATE; const isOdd = (n & 1) == 1; let gainL = gain1; @@ -98,8 +98,8 @@ export class SupersawOsc { } let p = polyBlep(this.phase[n], dt); let s = 2 * this.phase[n] - 1 - p; - sl = sl + s * gainL - sr = sr + s * gainL + sl = sl + s * gainL; + sr = sr + s * gainL; this.phase[n] += dt; if (this.phase[n] > 1) { @@ -107,7 +107,7 @@ export class SupersawOsc { } } - return sl + sr + return sl + sr; //TODO: make stereo // return [sl, sr]; } @@ -466,15 +466,22 @@ export class BufferPlayer { sampleRate; pos = 0; sampleFreq = note2freq(); - constructor(buffer, sampleRate) { + constructor(buffer, sampleRate, normalize) { this.buffer = buffer; this.sampleRate = sampleRate; + this.duration = this.buffer.length / this.sampleRate; + this.speed = SAMPLE_RATE / this.sampleRate; + if (normalize) { + // this will make the buffer last 1s if freq = sampleFreq + // it's useful to loop samples (e.g. fit function) + this.speed *= this.duration; + } } update(freq) { if (this.pos >= this.buffer.length) { return 0; } - const speed = ((freq / this.sampleFreq) * SAMPLE_RATE) / this.sampleRate; + const speed = (freq / this.sampleFreq) * this.speed; let s = this.buffer[Math.floor(this.pos)]; this.pos = this.pos + speed; return s; @@ -551,6 +558,7 @@ const defaultDefaultValues = { pan: 0.5, fmh: 1, fmenv: 0, // differs from superdough + speed: 1, }; let getDefaultValue = (key) => defaultDefaultValues[key]; @@ -603,6 +611,7 @@ export class DoughVoice { $.resonance = $.resonance ?? getDefaultValue('resonance'); $.hresonance = $.hresonance ?? getDefaultValue('hresonance'); $.bandq = $.bandq ?? getDefaultValue('bandq'); + $.speed = $.speed ?? getDefaultValue('speed'); [$.attack, $.decay, $.sustain, $.release] = getADSR([$.attack, $.decay, $.sustain, $.release]); @@ -623,7 +632,7 @@ export class DoughVoice { $._buffers = []; $._channels = sample.channels.length; for (let i = 0; i < $._channels; i++) { - $._buffers.push(new BufferPlayer(sample.channels[i], sample.sampleRate)); + $._buffers.push(new BufferPlayer(sample.channels[i], sample.sampleRate, $.unit === 'c')); // tbd unit === 'c' } } else { console.warn('sound not found', $.s); @@ -695,7 +704,7 @@ export class DoughVoice { } let gate = Number(t >= this._begin && t <= this._holdEnd); - let freq = this.freq; + let freq = this.freq * this.speed; // frequency modulation if (this._fm) { let fmi = this.fmi; From c9f494d8657e5990ded89a02dbaf8ab80caa1e40 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 9 Jun 2025 22:10:09 +0200 Subject: [PATCH 041/335] fix: node export --- packages/supradough/dough-export.mjs | 3 ++- packages/supradough/dough.mjs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/supradough/dough-export.mjs b/packages/supradough/dough-export.mjs index 5f8b9a8ee..a9f5614b0 100644 --- a/packages/supradough/dough-export.mjs +++ b/packages/supradough/dough-export.mjs @@ -47,7 +47,8 @@ haps.forEach((hap) => { console.log(`render ${seconds}s long buffer...`); const buffer = new Float32Array(seconds * sampleRate); while (dough.t <= buffer.length) { - buffer[dough.t] = dough.update(); + dough.update(); + buffer[dough.t] = dough.out[0]; } console.log('done!'); diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index b11de6c24..aa2e1dfd5 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -150,7 +150,7 @@ class PulseOsc { return 2 * phase - 1 - p; } update(freq, pw = 0.5) { - const dt = freq / sampleRate; + const dt = freq / SAMPLE_RATE; let pulse = this.saw(0, dt) - this.saw(pw, dt); this.phase = (this.phase + dt) % 1; return pulse + pw * 2 - 1; From e99adffc562e6495b02d19d8d66fc684935a77ec Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 9 Jun 2025 22:29:35 +0200 Subject: [PATCH 042/335] vibrato --- packages/supradough/dough.mjs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index aa2e1dfd5..8a648a449 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -643,6 +643,11 @@ export class DoughVoice { [$.pattack, $.pdecay, $.psustain, $.prelease] = getADSR([$.pattack, $.pdecay, $.psustain, $.prelease]); } + if ($.vib) { + $._vib = new SineOsc(); + $.vibmod = $.vibmod ?? getDefaultValue('vibmod'); + } + if ($.fmi) { $._fm = new SineOsc(); $.fmh = $.fmh ?? getDefaultValue('fmh'); @@ -705,6 +710,7 @@ export class DoughVoice { let gate = Number(t >= this._begin && t <= this._holdEnd); let freq = this.freq * this.speed; + // frequency modulation if (this._fm) { let fmi = this.fmi; @@ -717,6 +723,11 @@ export class DoughVoice { freq = freq + this._fm.update(modfreq) * modgain; } + // vibrato + if (this._vib) { + freq = freq * 2 ** ((this._vib.update(this.vib) * this.vibmod) / 12); + } + // pitch envelope if (this._penv) { const env = this._penv.update(t, gate, this.pattack, this.pdecay, this.psustain, this.prelease); From 3963b807ebb35815890858e2d09bfadbc9e8a9f4 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 9 Jun 2025 22:32:41 +0200 Subject: [PATCH 043/335] fix: calling doughsamples multiple times --- packages/webaudio/supradough.mjs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/webaudio/supradough.mjs b/packages/webaudio/supradough.mjs index 3b45415df..d9775642e 100644 --- a/packages/webaudio/supradough.mjs +++ b/packages/webaudio/supradough.mjs @@ -90,18 +90,12 @@ async function loadSampleChannels(key, url) { return [key, channels, buffer.sampleRate]; } -let loaded = false; export async function doughsamples(sampleMap, baseUrl) { if (typeof sampleMap === 'string') { const [json, base] = await fetchSampleMap(sampleMap); // console.log('json', json, 'base', base); return doughsamples(json, base); } - !doughWorklet && initDoughWorklet(); - if (loaded) { - return; - } - loaded = true; const json = ( await Promise.all( Object.entries(sampleMap).map(async ([key, url]) => { @@ -113,5 +107,6 @@ export async function doughsamples(sampleMap, baseUrl) { ) ).filter(Boolean); // console.log('sampleMap', json); + !doughWorklet && initDoughWorklet(); doughWorklet.port.postMessage({ samples: json }); } From 7e8206dcbc67570c5001869e86251199c0fd5ad7 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Tue, 10 Jun 2025 12:31:21 +0200 Subject: [PATCH 044/335] pitched delay --- packages/core/controls.mjs | 19 ++++++++++++--- packages/supradough/dough.mjs | 45 +++++++++++++++++++++++------------ 2 files changed, 46 insertions(+), 18 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 21c183da9..9c9bdbc8c 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -964,14 +964,27 @@ export const { delay } = registerControl(['delay', 'delaytime', 'delayfeedback'] * */ export const { delayfeedback, delayfb, dfb } = registerControl('delayfeedback', 'delayfb', 'dfb'); + +/** + * Sets the level of the signal that is fed back into the delay. + * Caution: Values >= 1 will result in a signal that gets louder and louder! Don't do it + * + * @name delayfeedback + * @param {number | Pattern} feedback between 0 and 1 + * @synonyms delayfb, dfb + * @example + * s("bd").delay(.25).delayfeedback("<.25 .5 .75 1>") + * + */ +export const { delayspeed } = registerControl('delayspeed'); /** * Sets the time of the delay effect. * - * @name delaytime - * @param {number | Pattern} seconds between 0 and Infinity + * @name delayspeed + * @param {number | Pattern} delayspeed controls the pitch of the delay feedback * @synonyms delayt, dt * @example - * s("bd bd").delay(.25).delaytime("<.125 .25 .5 1>") + * note("d d a# a".fast(2)).s("sawtooth").delay(.8).delaytime(1/2).delayspeed("<2 .5 -1 -2>") * */ export const { delaytime, delayt, dt } = registerControl('delaytime', 'delayt', 'dt'); diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index 8a648a449..8e3544c9f 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -44,6 +44,7 @@ function polyBlep(t, dt) { // 0 otherwise return 0; } + export class SawOsc { constructor(props = {}) { this.phase = props.phase ?? 0; @@ -349,21 +350,31 @@ export class ADSR { .out()*/ const MAX_DELAY_TIME = 10; export class Delay { - writeIdx = 0; - readIdx = 0; - buffer = new Float32Array(MAX_DELAY_TIME * SAMPLE_RATE); //.fill(0) - write(s, delayTime) { - this.writeIdx = (this.writeIdx + 1) % this.buffer.length; - this.buffer[this.writeIdx] = s; - // Calculate how far in the past to read - let numSamples = Math.min(Math.floor(SAMPLE_RATE * delayTime), this.buffer.length - 1); - this.readIdx = this.writeIdx - numSamples; - // If past the start of the buffer, wrap around - if (this.readIdx < 0) this.readIdx += this.buffer.length; + constructor(_props = {}) { + this.buffer = new Float32Array(MAX_DELAY_TIME * SAMPLE_RATE); + this.writeIdx = 0; + this.readIdx = 0; + this.numSamples = 0; } - update(input, delayTime) { + write(s, delayTime) { + // Calculate how far in the past to read + this.numSamples = Math.min(Math.floor(SAMPLE_RATE * delayTime), this.buffer.length - 1); + this.writeIdx = (this.writeIdx + 1) % this.numSamples; + this.buffer[this.writeIdx] = s; + this.readIdx = this.writeIdx - this.numSamples + 1; + + // If past the start of the buffer, wrap around (Q: is this possible?) + if (this.readIdx < 0) this.readIdx += this.numSamples; + } + update(input, delayTime, speed = 1) { this.write(input, delayTime); - return this.buffer[this.readIdx]; + let index = this.readIdx; + if (speed < 0) { + index = this.numSamples - Math.floor(Math.abs(this.readIdx * speed) % this.numSamples); + } else { + index = Math.floor(this.readIdx * speed) % this.numSamples; + } + return this.buffer[index]; } } @@ -550,6 +561,7 @@ const defaultDefaultValues = { delay: 0, byteBeatExpression: '0', delayfeedback: 0.5, + delayspeed: 1, delaytime: 0.25, orbit: 1, i: 1, @@ -662,6 +674,7 @@ export class DoughVoice { // delay $.delay = applyGainCurve($.delay ?? getDefaultValue('delay')); $.delayfeedback = $.delayfeedback ?? getDefaultValue('delayfeedback'); + $.delayspeed = $.delayspeed ?? getDefaultValue('delayspeed'); $.delaytime = $.delaytime ?? getDefaultValue('delaytime'); // precalculated values @@ -822,6 +835,7 @@ export class Dough { delaysend = [0, 0]; delaytime = getDefaultValue('delaytime'); delayfeedback = getDefaultValue('delayfeedback'); + delayspeed = getDefaultValue('delayspeed'); t = 0; // sampleRate: number, currentTime: number (seconds) constructor(sampleRate = 48000, currentTime = 0) { @@ -897,12 +911,13 @@ export class Dough { this.delaysend[0] += this.voices[v].out[0] * this.voices[v].delay; this.delaysend[1] += this.voices[v].out[1] * this.voices[v].delay; this.delaytime = this.voices[v].delaytime; // we trust that these are initialized in the voice + this.delayspeed = this.voices[v].delayspeed; // we trust that these are initialized in the voice this.delayfeedback = this.voices[v].delayfeedback; } } // todo: how to change delaytime / delayfeedback from a voice? - const delayL = this._delayL.update(this.delaysend[0], this.delaytime); - const delayR = this._delayR.update(this.delaysend[1], this.delaytime); + const delayL = this._delayL.update(this.delaysend[0], this.delaytime, this.delayspeed); + const delayR = this._delayR.update(this.delaysend[1], this.delaytime, this.delayspeed); this.delaysend[0] = delayL * this.delayfeedback; this.delaysend[1] = delayR * this.delayfeedback; this.out[0] += delayL; From 43504d16b66e739590ec80c4fd18e10f54c31802 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Tue, 10 Jun 2025 16:03:42 +0200 Subject: [PATCH 045/335] add chorus --- packages/core/controls.mjs | 11 ++++++ packages/supradough/dough.mjs | 64 ++++++++++++++++++++++++++++++++--- 2 files changed, 71 insertions(+), 4 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 9c9bdbc8c..ed440b56d 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -285,6 +285,17 @@ export const { fmvelocity } = registerControl('fmvelocity'); */ export const { bank } = registerControl('bank'); +/** + * mix control for the chorus effect + * + * @name chorus + * @param {string | Pattern} chorus mix amount between 0 and 1 + * @example + * note("d d a# a").s("sawtooth").chorus(.5) + * + */ +export const { chorus } = registerControl('chorus'); + // analyser node send amount 0 - 1 (used by scope) export const { analyze } = registerControl('analyze'); // fftSize of analyser diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index 8e3544c9f..6be0af78c 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -7,6 +7,22 @@ let gainCurveFunc = (val) => Math.pow(val, 2); function applyGainCurve(val) { return gainCurveFunc(val); } + +/** + * Equal Power Crossfade function. + * Smoothly transitions between signals A and B, maintaining consistent perceived loudness. + * + * @param {number} a - Signal A (can be a single value or an array value in buffer processing). + * @param {number} b - Signal B (can be a single value or an array value in buffer processing). + * @param {number} m - Crossfade parameter (0.0 = all A, 1.0 = all B, 0.5 = equal mix). + * @returns {number} Crossfaded output value. + */ +function crossfade(a, b, m) { + const aGain = Math.sin((1 - m) * 0.5 * Math.PI); + const bGain = Math.sin(m * 0.5 * Math.PI); + return a * aGain + b * bGain; +} + // function setGainCurve(newGainCurveFunc) { // gainCurveFunc = newGainCurveFunc; // } @@ -349,7 +365,8 @@ export class ADSR { .add(x=>x.delay(.1).mul(.8)) .out()*/ const MAX_DELAY_TIME = 10; -export class Delay { +export class PitchDelay { + lpf = new TwoPoleFilter(); constructor(_props = {}) { this.buffer = new Float32Array(MAX_DELAY_TIME * SAMPLE_RATE); this.writeIdx = 0; @@ -374,7 +391,38 @@ export class Delay { } else { index = Math.floor(this.readIdx * speed) % this.numSamples; } - return this.buffer[index]; + const s = this.lpf.update(this.buffer[index], 0.9, 0); + + return s; + } +} + +export class Delay { + writeIdx = 0; + readIdx = 0; + buffer = new Float32Array(MAX_DELAY_TIME * SAMPLE_RATE); //.fill(0) + write(s, delayTime) { + this.writeIdx = (this.writeIdx + 1) % this.buffer.length; + this.buffer[this.writeIdx] = s; + // Calculate how far in the past to read + let numSamples = Math.min(Math.floor(SAMPLE_RATE * delayTime), this.buffer.length - 1); + this.readIdx = this.writeIdx - numSamples; + // If past the start of the buffer, wrap around + if (this.readIdx < 0) this.readIdx += this.buffer.length; + } + update(input, delayTime) { + this.write(input, delayTime); + return this.buffer[this.readIdx]; + } +} +//TODO: Figure out why clicking at the start off the buffer +export class Chorus { + delay = new Delay(); + modulator = new TriOsc(); + update(input, mix, delayTime, modulationFreq, modulationDepth) { + const m = this.modulator.update(modulationFreq) * modulationDepth; + const c = this.delay.update(input, delayTime * (1 + m)); + return crossfade(input, c, mix); } } @@ -540,6 +588,7 @@ let shapes = { }; const defaultDefaultValues = { + chorus: 0, note: 48, s: 'triangle', gain: 1, @@ -616,6 +665,7 @@ export class DoughVoice { $.shapevol = applyGainCurve($.shapevol ?? getDefaultValue('shapevol')); $.distortvol = applyGainCurve($.distortvol ?? getDefaultValue('distortvol')); $.i = $.i ?? getDefaultValue('i'); + $.chorus = $.chorus ?? getDefaultValue('chorus'); $.fft = $.fft ?? getDefaultValue('fft'); $.pan = $.pan ?? getDefaultValue('pan'); $.orbit = $.orbit ?? getDefaultValue('orbit'); @@ -696,6 +746,7 @@ export class DoughVoice { } // channelwise effects setup + $._chorus = $.chorus ? [] : null; $._lpf = $.cutoff ? [] : null; $._hpf = $.hcutoff ? [] : null; $._bpf = $.bandf ? [] : null; @@ -706,6 +757,7 @@ export class DoughVoice { $._lpf?.push(new TwoPoleFilter()); $._hpf?.push(new TwoPoleFilter()); $._bpf?.push(new TwoPoleFilter()); + $._chorus?.push(new Chorus()); $._coarse?.push(new Coarse()); $._crush?.push(new Crush()); $._distort?.push(new Distort()); @@ -786,6 +838,10 @@ export class DoughVoice { this.out[i] = this._buffers[i].update(freq); } this.out[i] = this.out[i] * this.gain * this.velocity; + if (this._chorus) { + const c = this._chorus[i].update(this.out[i], this.chorus, 0.03 + 0.05 * i, 1, 0.11); + this.out[i] = c + this.out[i]; + } if (this._lpf) { this._lpf[i].update(this.out[i], lpf, this.resonance); @@ -842,8 +898,8 @@ export class Dough { this.sampleRate = sampleRate; this.t = Math.floor(currentTime * sampleRate); // samples // console.log('init dough', this.sampleRate, this.t); - this._delayL = new Delay(); - this._delayR = new Delay(); + this._delayL = new PitchDelay(); + this._delayR = new PitchDelay(); } loadSample(name, channels, sampleRate) { BufferPlayer.samples.set(name, { channels, sampleRate }); From bbd7ed0f27f1b49eefb674afa70ea8fe1acbcbe8 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 12 Jun 2025 02:25:04 +0200 Subject: [PATCH 046/335] lazy sample loading --- packages/webaudio/supradough.mjs | 48 ++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/packages/webaudio/supradough.mjs b/packages/webaudio/supradough.mjs index d9775642e..10664aa89 100644 --- a/packages/webaudio/supradough.mjs +++ b/packages/webaudio/supradough.mjs @@ -16,11 +16,35 @@ function initDoughWorklet() { connectToDestination(doughWorklet); // channels? } +const soundMap = new Map(); +const loadedSounds = new Map(); + Pattern.prototype.supradough = function () { return this.onTrigger((_, hap, __, cps, begin) => { hap.value._begin = begin; hap.value._duration = hap.duration / cps; !doughWorklet && initDoughWorklet(); + const s = (hap.value.bank ? hap.value.bank + '_' : '') + hap.value.s; + const n = hap.value.n ?? 0; + const soundKey = `${s}:${n}`; + if (soundMap.has(s)) { + hap.value.s = soundKey; // dough.mjs is unaware of bank and n (only maps keys to buffers) + } + if (soundMap.has(s) && !loadedSounds.has(soundKey)) { + const urls = soundMap.get(s); + const url = urls[n % urls.length]; + console.log(`load ${soundKey} from ${url}`); + const loadSample = fetchSample(url); + loadedSounds.set(soundKey, loadSample); + loadSample.then(({ channels, sampleRate }) => + doughWorklet.port.postMessage({ + sample: soundKey, + channels, + sampleRate, + }), + ); + } + doughWorklet.port.postMessage({ spawn: hap.value }); }, 1); }; @@ -79,7 +103,7 @@ export async function fetchSampleMap(url) { // for some reason, only piano and flute work.. is it because mp3?? -async function loadSampleChannels(key, url) { +async function fetchSample(url) { const buffer = await fetch(url) .then((res) => res.arrayBuffer()) .then((buf) => getAudioContext().decodeAudioData(buf)); @@ -87,7 +111,7 @@ async function loadSampleChannels(key, url) { for (let i = 0; i < buffer.numberOfChannels; i++) { channels.push(buffer.getChannelData(i)); } - return [key, channels, buffer.sampleRate]; + return { channels, sampleRate: buffer.sampleRate }; } export async function doughsamples(sampleMap, baseUrl) { @@ -96,17 +120,11 @@ export async function doughsamples(sampleMap, baseUrl) { // console.log('json', json, 'base', base); return doughsamples(json, base); } - const json = ( - await Promise.all( - Object.entries(sampleMap).map(async ([key, url]) => { - if (key !== '_base') { - url = baseUrl + url[0]; - return loadSampleChannels(key, url); - } - }), - ) - ).filter(Boolean); - // console.log('sampleMap', json); - !doughWorklet && initDoughWorklet(); - doughWorklet.port.postMessage({ samples: json }); + Object.entries(sampleMap).map(async ([key, urls]) => { + if (key !== '_base') { + urls = urls.map((url) => baseUrl + url); + // console.log('set', key, urls); + soundMap.set(key, urls); + } + }); } From 5cbd38a3e83b0b29414675bee6a1a961a13c93fa Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 12 Jun 2025 02:25:46 +0200 Subject: [PATCH 047/335] improve filter performance making it accept hz directly --- packages/supradough/dough.mjs | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index 6be0af78c..711922b63 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -1,5 +1,6 @@ // this is dough, the superdough without dependencies const SAMPLE_RATE = typeof sampleRate !== 'undefined' ? sampleRate : 48000; +const PI_DIV_SR = Math.PI / SAMPLE_RATE; const ISR = 1 / SAMPLE_RATE; let gainCurveFunc = (val) => Math.pow(val, 2); @@ -145,11 +146,13 @@ export class TwoPoleFilter { s1 = 0; update(s, cutoff, resonance = 0) { // Out of bound values can produce NaNs - cutoff = Math.min(cutoff, 1); resonance = Math.max(resonance, 0); - var c = Math.pow(0.5, (1 - cutoff) / 0.125); - var r = Math.pow(0.5, (resonance + 0.125) / 0.125); - var mrc = 1 - r * c; + + cutoff = Math.min(cutoff, 20000); + const c = 2 * Math.sin(cutoff * PI_DIV_SR); + + const r = Math.pow(0.5, (resonance + 0.125) / 0.125); + const mrc = 1 - r * c; this.s0 = mrc * this.s0 - c * this.s1 + c * s; // bpf this.s1 = mrc * this.s1 + c * this.s0; // lpf @@ -591,6 +594,7 @@ const defaultDefaultValues = { chorus: 0, note: 48, s: 'triangle', + bank: '', gain: 1, postgain: 1, velocity: 1, @@ -620,6 +624,7 @@ const defaultDefaultValues = { fmh: 1, fmenv: 0, // differs from superdough speed: 1, + pw: 0.5, }; let getDefaultValue = (key) => defaultDefaultValues[key]; @@ -674,14 +679,14 @@ export class DoughVoice { $.hresonance = $.hresonance ?? getDefaultValue('hresonance'); $.bandq = $.bandq ?? getDefaultValue('bandq'); $.speed = $.speed ?? getDefaultValue('speed'); + $.pw = $.pw ?? getDefaultValue('pw'); [$.attack, $.decay, $.sustain, $.release] = getADSR([$.attack, $.decay, $.sustain, $.release]); $._holdEnd = $._begin + $._duration; // needed for gate $._end = $._holdEnd + $.release + 0.01; // needed for despawn - $.s ??= 'triangle'; - if ($.s === 'saw' || $.s === 'sawtooth') { + if ($.fmi && ($.s === 'saw' || $.s === 'sawtooth')) { $.s = 'zaw'; // polyblepped saw when fm is applied } @@ -697,7 +702,7 @@ export class DoughVoice { $._buffers.push(new BufferPlayer(sample.channels[i], sample.sampleRate, $.unit === 'c')); // tbd unit === 'c' } } else { - console.warn('sound not found', $.s); + console.warn('sound not loaded', $.s); } if ($.penv) { @@ -727,10 +732,6 @@ export class DoughVoice { $.delayspeed = $.delayspeed ?? getDefaultValue('delayspeed'); $.delaytime = $.delaytime ?? getDefaultValue('delaytime'); - // precalculated values - $.piOverSr = Math.PI / value.sampleRate; - $.eighthOverLogHalf = 0.125 / Math.log(0.5); - // filter setup if ($.lpenv) { $._lpenv = new ADSR({ decayCurve: 4 }); @@ -763,11 +764,6 @@ export class DoughVoice { $._distort?.push(new Distort()); } } - // credits to pulu: https://github.com/felixroos/kabelsalat/issues/35 - freq2cutoff(freq) { - const c = 2 * Math.sin(freq * this.piOverSr); - return 1 - Math.log(c) * this.eighthOverLogHalf; - } update(t) { if (!this._sound && !this._buffers) { return 0; @@ -806,7 +802,6 @@ export class DoughVoice { const env = this._lpenv.update(t, gate, this.lpattack, this.lpdecay, this.lpsustain, this.lprelease); lpf = this.lpenv * env * lpf + lpf; } - lpf = this.freq2cutoff(lpf); } let hpf = this.hcutoff; if (this._hpf) { @@ -814,7 +809,6 @@ export class DoughVoice { const env = this._hpenv.update(t, gate, this.hpattack, this.hpdecay, this.hpsustain, this.hprelease); hpf = 2 ** this.hpenv * env * hpf + hpf; } - hpf = this.freq2cutoff(hpf); } let bpf = this.bandf; if (this._bpf) { @@ -822,7 +816,6 @@ export class DoughVoice { const env = this._bpenv.update(t, gate, this.bpattack, this.bpdecay, this.bpsustain, this.bprelease); bpf = 2 ** this.bpenv * env * bpf + bpf; } - bpf = this.freq2cutoff(bpf); } // gain envelope const env = this._adsr.update(t, gate, this.attack, this.decay, this.sustain, this.release); @@ -831,7 +824,7 @@ export class DoughVoice { for (let i = 0; i < this._channels; i++) { // sound source if (this._sound && this.s === 'pulse') { - this.out[i] = this._sound.update(freq, this.pw ?? 0.5); + this.out[i] = this._sound.update(freq, this.pw); } else if (this._sound) { this.out[i] = this._sound.update(freq); } else if (this._buffers) { From 3caf08e199a7f210094cae213e934ead30750933 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 12 Jun 2025 02:26:08 +0200 Subject: [PATCH 048/335] up latency --- packages/superdough/superdough.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 2629790df..ef43d7906 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -174,7 +174,7 @@ export const resetLoadedSounds = () => soundMap.set({}); let audioContext; export const setDefaultAudioContext = () => { - audioContext = new AudioContext(); + audioContext = new AudioContext({ latencyHint: 'playback' }); return audioContext; }; From 14193abe0315dcd54d17ba2680f85bdf0373ca9b Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 12 Jun 2025 02:26:50 +0200 Subject: [PATCH 049/335] improve export: add stereo + measure performance + add bigger pattern for testing --- packages/supradough/dough-export.mjs | 103 +++++++++++++++++++++------ 1 file changed, 82 insertions(+), 21 deletions(-) diff --git a/packages/supradough/dough-export.mjs b/packages/supradough/dough-export.mjs index a9f5614b0..a6c55bf46 100644 --- a/packages/supradough/dough-export.mjs +++ b/packages/supradough/dough-export.mjs @@ -16,23 +16,72 @@ await evalScope( miniAllStrings(); // allows using single quotes for mini notation / skip transpilation let sampleRate = 48000, - cps = 0.5; + cps = 0.4; -let pat = note('[c e g b]*3') - .add(note(7)) - .lpf(sine.rangex(200, 4000).slow(2)) - .lpq(0.3) - .s('*2') - .att(0.01) - .rel(0.2) - .clip(2) - .delay(0.5) - .jux(rev) - .sometimes(add(note(12))) - .gain(0.25) +/* await doughsamples('github:eddyflux/crate'); +await doughsamples('github:eddyflux/wax'); */ + +let pat = note('c,eb,g,') + .s('sine') + .press() + .add(note(24)) + .fmi(3) + .fmh(5.01) + .dec(0.4) + .delay('.6:<.12 .22>:.8') + .jux(press) + .rarely(add(note('12'))) + .lpf(400) + .lpq(0.2) + .lpd(0.4) + .lpenv(3) + .fmdecay(0.4) + .fmenv(1) + .postgain(0.6) + .stack(s('*8').dec(0.07).rarely(ply('2')).delay(0.5).hpf(sine.range(200, 2000).slow(4)).hpq(0.2)) + .stack( + s('[- white@3]*2') + .dec(0.4) + .hpf('<2000!3 <4000 8000>>*4') + .hpq(0.6) + .ply('<1 2>*4') + .postgain(0.5) + .delay(0.5) + .jux(rev) + .lpf(5000), + ) + .stack( + note('*2') + .s('square') + .lpf(sine.range(100, 300).slow(4)) + .lpe(1) + .segment(8) + .lpd(0.3) + .lpq(0.2) + .dec(0.2) + .speed('<1 2>') + .ply('<1 2>') + .postgain(1), + ) + .stack( + chord('') + .voicing() + .s('') + .clip(1) + .rel(0.4) + .vib('4:.2') + .gain(0.7) + .hpf(1200) + .fm(0.5) + .att(1) + .lpa(0.5) + .lpf(200) + .lpenv(4) + .chorus(0.8), + ) .slow(1 / cps); -let cycles = 4; +let cycles = 30; let seconds = cycles + 1; // 1s release tail const haps = pat.queryArc(0, cycles); @@ -41,20 +90,32 @@ const dough = new Dough(sampleRate); console.log('spawn voices...'); haps.forEach((hap) => { hap.value._begin = Number(hap.whole.begin); - hap.value._duration = hap.duration / cps; + hap.value._duration = hap.duration/* / cps */; dough.scheduleSpawn(hap.value); }); -console.log(`render ${seconds}s long buffer...`); -const buffer = new Float32Array(seconds * sampleRate); -while (dough.t <= buffer.length) { +console.log(`render ${seconds}s long buffer, each dot is 1 second:`); +const buffers = [new Float32Array(seconds * sampleRate), new Float32Array(seconds * sampleRate)]; +let t = performance.now(); +while (dough.t <= buffers[0].length) { dough.update(); - buffer[dough.t] = dough.out[0]; + buffers[0][dough.t] = dough.out[0]; + buffers[1][dough.t] = dough.out[1]; + if (dough.t % sampleRate === 0) { + process.stdout.write('.'); + } } -console.log('done!'); +const took = (performance.now() - t) / 1000; +const load = (took / seconds) * 100; +const speed = (seconds / took).toFixed(2); +console.log(''); +console.log(`done! +rendered ${seconds}s in ${took.toFixed(2)}s +speed: ${speed}x +load: ${load.toFixed(2)}%`); const patternAudio = { sampleRate, - channelData: [buffer], + channelData: buffers, }; WavEncoder.encode(patternAudio).then((buffer) => { From 8363ba5a41ca3210d6cd4b436ead3692d7d29d3c Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 12 Jun 2025 10:22:35 +0200 Subject: [PATCH 050/335] format --- packages/supradough/dough-export.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/supradough/dough-export.mjs b/packages/supradough/dough-export.mjs index a6c55bf46..bd4b530b3 100644 --- a/packages/supradough/dough-export.mjs +++ b/packages/supradough/dough-export.mjs @@ -90,7 +90,7 @@ const dough = new Dough(sampleRate); console.log('spawn voices...'); haps.forEach((hap) => { hap.value._begin = Number(hap.whole.begin); - hap.value._duration = hap.duration/* / cps */; + hap.value._duration = hap.duration /* / cps */; dough.scheduleSpawn(hap.value); }); console.log(`render ${seconds}s long buffer, each dot is 1 second:`); From 239987af0b70169d6db451f277a3f24da59ca203 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 12 Jun 2025 10:23:06 +0200 Subject: [PATCH 051/335] snapshot --- test/__snapshots__/examples.test.mjs.snap | 67 +++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index 0eacfdfb0..e3df24d47 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -1847,6 +1847,27 @@ exports[`runs examples > example "chop" example index 0 1`] = ` ] `; +exports[`runs examples > example "chorus" example index 0 1`] = ` +[ + "[ 0/1 → 1/4 | note:d s:sawtooth chorus:0.5 ]", + "[ 1/4 → 1/2 | note:d s:sawtooth chorus:0.5 ]", + "[ 1/2 → 3/4 | note:a# s:sawtooth chorus:0.5 ]", + "[ 3/4 → 1/1 | note:a s:sawtooth chorus:0.5 ]", + "[ 1/1 → 5/4 | note:d s:sawtooth chorus:0.5 ]", + "[ 5/4 → 3/2 | note:d s:sawtooth chorus:0.5 ]", + "[ 3/2 → 7/4 | note:a# s:sawtooth chorus:0.5 ]", + "[ 7/4 → 2/1 | note:a s:sawtooth chorus:0.5 ]", + "[ 2/1 → 9/4 | note:d s:sawtooth chorus:0.5 ]", + "[ 9/4 → 5/2 | note:d s:sawtooth chorus:0.5 ]", + "[ 5/2 → 11/4 | note:a# s:sawtooth chorus:0.5 ]", + "[ 11/4 → 3/1 | note:a s:sawtooth chorus:0.5 ]", + "[ 3/1 → 13/4 | note:d s:sawtooth chorus:0.5 ]", + "[ 13/4 → 7/2 | note:d s:sawtooth chorus:0.5 ]", + "[ 7/2 → 15/4 | note:a# s:sawtooth chorus:0.5 ]", + "[ 15/4 → 4/1 | note:a s:sawtooth chorus:0.5 ]", +] +`; + exports[`runs examples > example "chunk" example index 0 1`] = ` [ "[ 0/1 → 1/4 | note:A4 ]", @@ -2505,6 +2526,52 @@ exports[`runs examples > example "delayfeedback" example index 0 1`] = ` ] `; +exports[`runs examples > example "delayfeedback" example index 0 2`] = ` +[ + "[ 0/1 → 1/1 | s:bd delay:0.25 delayfeedback:0.25 ]", + "[ 1/1 → 2/1 | s:bd delay:0.25 delayfeedback:0.5 ]", + "[ 2/1 → 3/1 | s:bd delay:0.25 delayfeedback:0.75 ]", + "[ 3/1 → 4/1 | s:bd delay:0.25 delayfeedback:1 ]", +] +`; + +exports[`runs examples > example "delayspeed" example index 0 1`] = ` +[ + "[ 0/1 → 1/8 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:2 ]", + "[ 1/8 → 1/4 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:2 ]", + "[ 1/4 → 3/8 | note:a# s:sawtooth delay:0.8 delaytime:0.5 delayspeed:2 ]", + "[ 3/8 → 1/2 | note:a s:sawtooth delay:0.8 delaytime:0.5 delayspeed:2 ]", + "[ 1/2 → 5/8 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:2 ]", + "[ 5/8 → 3/4 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:2 ]", + "[ 3/4 → 7/8 | note:a# s:sawtooth delay:0.8 delaytime:0.5 delayspeed:2 ]", + "[ 7/8 → 1/1 | note:a s:sawtooth delay:0.8 delaytime:0.5 delayspeed:2 ]", + "[ 1/1 → 9/8 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:0.5 ]", + "[ 9/8 → 5/4 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:0.5 ]", + "[ 5/4 → 11/8 | note:a# s:sawtooth delay:0.8 delaytime:0.5 delayspeed:0.5 ]", + "[ 11/8 → 3/2 | note:a s:sawtooth delay:0.8 delaytime:0.5 delayspeed:0.5 ]", + "[ 3/2 → 13/8 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:0.5 ]", + "[ 13/8 → 7/4 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:0.5 ]", + "[ 7/4 → 15/8 | note:a# s:sawtooth delay:0.8 delaytime:0.5 delayspeed:0.5 ]", + "[ 15/8 → 2/1 | note:a s:sawtooth delay:0.8 delaytime:0.5 delayspeed:0.5 ]", + "[ 2/1 → 17/8 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-1 ]", + "[ 17/8 → 9/4 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-1 ]", + "[ 9/4 → 19/8 | note:a# s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-1 ]", + "[ 19/8 → 5/2 | note:a s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-1 ]", + "[ 5/2 → 21/8 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-1 ]", + "[ 21/8 → 11/4 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-1 ]", + "[ 11/4 → 23/8 | note:a# s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-1 ]", + "[ 23/8 → 3/1 | note:a s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-1 ]", + "[ 3/1 → 25/8 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-2 ]", + "[ 25/8 → 13/4 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-2 ]", + "[ 13/4 → 27/8 | note:a# s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-2 ]", + "[ 27/8 → 7/2 | note:a s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-2 ]", + "[ 7/2 → 29/8 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-2 ]", + "[ 29/8 → 15/4 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-2 ]", + "[ 15/4 → 31/8 | note:a# s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-2 ]", + "[ 31/8 → 4/1 | note:a s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-2 ]", +] +`; + exports[`runs examples > example "delaytime" example index 0 1`] = ` [ "[ 0/1 → 1/2 | s:bd delay:0.25 delaytime:0.125 ]", From 5efcd14f4084295e287cf4a97364e7e932db994e Mon Sep 17 00:00:00 2001 From: anecondev Date: Wed, 18 Jun 2025 17:07:13 +0200 Subject: [PATCH 052/335] Update website/src/pages/learn/code.mdx Correct "appended" to "prepended" --- website/src/pages/learn/code.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/pages/learn/code.mdx b/website/src/pages/learn/code.mdx index ca2564dec..7057c4576 100644 --- a/website/src/pages/learn/code.mdx +++ b/website/src/pages/learn/code.mdx @@ -44,7 +44,7 @@ xxx("foo").yyy("bar") Generally, `xxx` and `yyy` are called [_functions_](), while `foo` and `bar` are called function [_arguments_ or _parameters_](). So far, we've used the functions to declare which aspect of the sound we want to control, and their arguments for the actual data. -The `yyy` function is called a [_chained_ function](https://en.wikipedia.org/wiki/Method_chaining), because it is appended with a dot (`.`). +The `yyy` function is called a [_chained_ function](https://en.wikipedia.org/wiki/Method_chaining), because it is prepended with a dot (`.`). Generally, the idea with chaining is that code such as `a("this").b("that").c("other")` allows `a`, `b` and `c` functions to happen in a specified order, without needing to write them as three separate lines of code. You can think of this as being similar to chaining audio effects together using guitar pedals or digital audio effects. From f5ae50c3cee2dd4b53476518b2765d8c58ddcaa6 Mon Sep 17 00:00:00 2001 From: JoStro Date: Tue, 1 Jul 2025 22:02:54 +0100 Subject: [PATCH 053/335] Modify `extend` to better match behavior of `!` operator --- packages/core/pattern.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index cbaf8a8a2..abe613d19 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -2928,7 +2928,7 @@ export const drop = stepRegister('drop', function (i, pat) { * ).pace(8) */ export const extend = stepRegister('extend', function (factor, pat) { - return pat.fast(factor).expand(factor); + return pat.repeatCycles(factor).fast(factor).expand(factor); }); /** From cbb4207bab08eb1a791d8e77f9508ddd37431324 Mon Sep 17 00:00:00 2001 From: dudymas Date: Fri, 4 Jul 2025 18:50:21 -0400 Subject: [PATCH 054/335] chore(docker): basic support added --- Dockerfile | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..b0c6618be --- /dev/null +++ b/Dockerfile @@ -0,0 +1,21 @@ +FROM node:24 + +WORKDIR /app + +RUN npm install pnpm --global + +COPY pnpm-workspace.yaml ./ +COPY package.json pnpm-lock.yaml ./ +COPY packages/ ./packages/ +COPY examples/ ./examples/ +RUN mkdir -p website/public +COPY website/package.json ./website/ + +RUN pnpm install + + +COPY . . + +EXPOSE 4321 + +CMD ["pnpm", "dev"] From 31c1450edc8eb606716fc5e35af52614bf67c8c3 Mon Sep 17 00:00:00 2001 From: dudymas Date: Fri, 4 Jul 2025 18:50:21 -0400 Subject: [PATCH 055/335] docs(website/learn/xen): add tune() examples --- website/src/pages/learn/xen.mdx | 64 +++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 website/src/pages/learn/xen.mdx diff --git a/website/src/pages/learn/xen.mdx b/website/src/pages/learn/xen.mdx new file mode 100644 index 000000000..21db10eb4 --- /dev/null +++ b/website/src/pages/learn/xen.mdx @@ -0,0 +1,64 @@ +--- +title: Xen Harmonic Functions +layout: ../../layouts/MainLayout.astro +--- + +import { MiniRepl } from '../../docs/MiniRepl'; +import { JsDoc } from '../../docs/JsDoc'; + +# Xen Harmonic Functions + +These functions allow the use of scales other than your typical chromatic 12 based ones. + +### tune(scale) + + + +Here's an example of how to configure a basic hexany scale: + + + +Try other scales like `hexany1`, `iraq`, `gumbeng`, `gunkali`, or `tranh3` + +For a full list of available scales from tunejs, see http://abbernie.github.io/tune/scales.html + +You can set your root to be a particular note with `getFreq` + + + +Some tunings become more pronounced with a longer reverb decay: + + -".tune("gumbeng") + .mul(getFreq('c3')) + .freq().clip(.8).room("3:10").rdim(10000).rfade(5)`} +/> + +Additionally, you can combo this with `fmap` so that the base note changes: + +".fmap(getFreq)) + .freq().legato("2 .7").room("1:15").rdim(8500).rlp(14000).rfade(8)`} +/> + +Combining this with various polyrhythm tricks can become very evocative: + + ~ ~,<-4 -5>" + .transpose(4) + .tune("iraq") + .mul("".fmap(getFreq)) + .freq().clip(.5).room(1).rfade(9)`} +/> From 37fde8f3e807a64289701ed67dd14d9d30713cc7 Mon Sep 17 00:00:00 2001 From: dudymas Date: Sat, 5 Jul 2025 13:43:09 -0400 Subject: [PATCH 056/335] docs(website/learn/xen): discussed strumming --- website/src/config.ts | 1 + website/src/pages/learn/xen.mdx | 36 +++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/website/src/config.ts b/website/src/config.ts index 2e2e264da..f335b272e 100644 --- a/website/src/config.ts +++ b/website/src/config.ts @@ -103,6 +103,7 @@ export const SIDEBAR: Sidebar = { Understand: [ { text: 'Coding syntax', link: 'learn/code' }, { text: 'Pitch', link: 'understand/pitch' }, + { text: 'Xen Harmonic Functions', link: 'learn/xen' }, { text: 'Cycles', link: 'understand/cycles' }, { text: 'Voicings', link: 'understand/voicings' }, { text: 'Pattern Alignment', link: 'technical-manual/alignment' }, diff --git a/website/src/pages/learn/xen.mdx b/website/src/pages/learn/xen.mdx index 21db10eb4..32e2c0b43 100644 --- a/website/src/pages/learn/xen.mdx +++ b/website/src/pages/learn/xen.mdx @@ -62,3 +62,39 @@ Combining this with various polyrhythm tricks can become very evocative: .mul("".fmap(getFreq)) .freq().clip(.5).room(1).rfade(9)`} /> + +Another helpful trick when exploring new tunings is to strum them. +Many have a much more enchanting sound that was chosen over many generations of musicians for being strummed. + +Take the `sanza` tuning: + + +Notes 7 and 9 will clash quite a bit if you arp them normally. Many tunings will have this sort of sound, and it can feel distracting on its own. +See how close they are on the pitch wheel? + + + +This quality is often due to how the tunings were formed with instruments that were played differently than a piano. +As such, some tunings are much better strummed, with the subtle clash of the detuned notes actually making the sound much more magical: + +") + .tune("sanza") + .mul(getFreq('c3')).freq() + .legato("3").room(1).rfade(5)`} +/> + +Note the legato and reverb effects make sure the sound of the strumming gets to wash together. Alternating the direction of the strum can make the +tones sound even more alive, too. + +The `tranh3` tuning has a similar set of notes, with two clashing. You might trying plugging that in above and see if you find a favorite strumming pattern. From 0722cf7ded81194dc91aef2690c30eb3c5cf4781 Mon Sep 17 00:00:00 2001 From: dudymas Date: Sat, 5 Jul 2025 13:43:42 -0400 Subject: [PATCH 057/335] feat(xen/tunejs): support sending a custom tuning --- packages/xen/tunejs.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/xen/tunejs.js b/packages/xen/tunejs.js index 6b5e7cb7c..5806cf596 100644 --- a/packages/xen/tunejs.js +++ b/packages/xen/tunejs.js @@ -139,10 +139,10 @@ Tune.prototype.MIDI = function(stepIn,octaveIn) { /* Load a new scale */ -Tune.prototype.loadScale = function(name){ +Tune.prototype.loadScale = function(scale){ /* load the scale */ - var freqs = TuningList[name].frequencies + var freqs = isArrayOfNumbers(scale) ? scale : TuningList[scale].frequencies this.scale = [] for (var i=0;i 0 && arg.every(item => typeof item === 'number' && !isNaN(item)); +} + +/* allow an array of values too */ +Tune.prototype.isValidScale = function(scale) { + return !!TuningList[scale] || isArrayOfNumbers(scale) ; } /* Return a collection of notes as an array */ From 5632d83afb124d679be292890a49ffd31b34e690 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Wed, 16 Jul 2025 02:21:39 +0200 Subject: [PATCH 058/335] fix: supradough onTrigger after breaking change --- packages/webaudio/supradough.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/webaudio/supradough.mjs b/packages/webaudio/supradough.mjs index 10664aa89..f97251a07 100644 --- a/packages/webaudio/supradough.mjs +++ b/packages/webaudio/supradough.mjs @@ -20,7 +20,7 @@ const soundMap = new Map(); const loadedSounds = new Map(); Pattern.prototype.supradough = function () { - return this.onTrigger((_, hap, __, cps, begin) => { + return this.onTrigger((hap, __, cps, begin) => { hap.value._begin = begin; hap.value._duration = hap.duration / cps; !doughWorklet && initDoughWorklet(); From 10156f00670462b0280351c549c92b4728a95bff Mon Sep 17 00:00:00 2001 From: Dsm0 Date: Tue, 15 Jul 2025 19:13:24 -0700 Subject: [PATCH 059/335] add basicSetup for keybindings --- packages/codemirror/basicSetup.mjs | 63 +++++++++++++++++++++++++++++ packages/codemirror/codemirror.mjs | 8 +++- packages/codemirror/keybindings.mjs | 5 ++- packages/codemirror/package.json | 2 +- pnpm-lock.yaml | 37 ++++++++++++----- 5 files changed, 101 insertions(+), 14 deletions(-) create mode 100644 packages/codemirror/basicSetup.mjs diff --git a/packages/codemirror/basicSetup.mjs b/packages/codemirror/basicSetup.mjs new file mode 100644 index 000000000..3faf7d7ab --- /dev/null +++ b/packages/codemirror/basicSetup.mjs @@ -0,0 +1,63 @@ +import { + keymap, + highlightSpecialChars, + drawSelection, + highlightActiveLine, + dropCursor, + rectangularSelection, + crosshairCursor, + lineNumbers, + highlightActiveLineGutter, +} from '@codemirror/view'; +import { + defaultHighlightStyle, + syntaxHighlighting, + bracketMatching, + foldGutter, + foldKeymap, +} from '@codemirror/language'; +import { defaultKeymap, history, historyKeymap } from '@codemirror/commands'; +import { searchKeymap, highlightSelectionMatches } from '@codemirror/search'; +import { completionKeymap, closeBracketsKeymap } from '@codemirror/autocomplete'; + +// Taken + slightly modified from https://github.com/codemirror/basic-setup/blob/main/src/codemirror.ts + +export const basicSetup = (() => [ + lineNumbers(), + highlightActiveLineGutter(), + highlightSpecialChars(), + history(), + foldGutter(), + drawSelection(), + dropCursor(), + // EditorState.allowMultipleSelections.of(true), + // indentOnInput(), + syntaxHighlighting(defaultHighlightStyle, { fallback: true }), + // autocompletion(), + rectangularSelection(), + crosshairCursor(), + highlightActiveLine(), + highlightSelectionMatches(), + keymap.of([ + ...closeBracketsKeymap, + ...defaultKeymap, + ...searchKeymap, + ...historyKeymap, + ...foldKeymap, + ...completionKeymap, + ]), +])(); + +/// A minimal set of extensions to create a functional editor. Only +/// includes [the default keymap](#commands.defaultKeymap), [undo +/// history](#commands.history), [special character +/// highlighting](#view.highlightSpecialChars), [custom selection +/// drawing](#view.drawSelection), and [default highlight +/// style](#language.defaultHighlightStyle). +export const minimalSetup = (() => [ + highlightSpecialChars(), + history(), + drawSelection(), + syntaxHighlighting(defaultHighlightStyle, { fallback: true }), + keymap.of([...defaultKeymap, ...historyKeymap]), +])(); diff --git a/packages/codemirror/codemirror.mjs b/packages/codemirror/codemirror.mjs index f47f6eba5..195971df9 100644 --- a/packages/codemirror/codemirror.mjs +++ b/packages/codemirror/codemirror.mjs @@ -2,7 +2,7 @@ import { closeBrackets } from '@codemirror/autocomplete'; export { toggleComment, toggleBlockComment, toggleLineComment, toggleBlockCommentByLine } from '@codemirror/commands'; // import { search, highlightSelectionMatches } from '@codemirror/search'; import { history, indentWithTab } from '@codemirror/commands'; -import { javascript } from '@codemirror/lang-javascript'; +import { javascript, javascriptLanguage } from '@codemirror/lang-javascript'; import { defaultHighlightStyle, syntaxHighlighting, bracketMatching } from '@codemirror/language'; import { Compartment, EditorState, Prec } from '@codemirror/state'; import { @@ -24,6 +24,7 @@ import { initTheme, activateTheme, theme } from './themes.mjs'; import { sliderPlugin, updateSliderWidgets } from './slider.mjs'; import { widgetPlugin, updateWidgets } from './widget.mjs'; import { persistentAtom } from '@nanostores/persistent'; +import { basicSetup } from './basicSetup.mjs'; const extensions = { isLineWrappingEnabled: (on) => (on ? EditorView.lineWrapping : []), @@ -85,7 +86,12 @@ export function initEditor({ initialCode = '', onChange, onEvaluate, onStop, roo /* search(), highlightSelectionMatches(), */ ...initialSettings, + basicSetup, mondo ? [] : javascript(), + javascriptLanguage.data.of({ + closeBrackets: { brackets: ['(', '[', '{', "'", '"', '<'] }, + bracketMatching: { brackets: ['(', '[', '{', "'", '"', '<'] }, + }), sliderPlugin, widgetPlugin, // indentOnInput(), // works without. already brought with javascript extension? diff --git a/packages/codemirror/keybindings.mjs b/packages/codemirror/keybindings.mjs index 1201959a2..a72b164eb 100644 --- a/packages/codemirror/keybindings.mjs +++ b/packages/codemirror/keybindings.mjs @@ -3,8 +3,9 @@ import { keymap, ViewPlugin } from '@codemirror/view'; // import { searchKeymap } from '@codemirror/search'; import { emacs } from '@replit/codemirror-emacs'; import { vim } from '@replit/codemirror-vim'; +// import { vim } from './vim_test.mjs'; import { vscodeKeymap } from '@replit/codemirror-vscode-keymap'; -import { defaultKeymap, historyKeymap } from '@codemirror/commands'; +import { defaultKeymap } from '@codemirror/commands'; const vscodePlugin = ViewPlugin.fromClass( class { @@ -27,5 +28,5 @@ const keymaps = { export function keybindings(name) { const active = keymaps[name]; - return [active ? active() : [], keymap.of(historyKeymap)]; + return [active ? active() : []]; } diff --git a/packages/codemirror/package.json b/packages/codemirror/package.json index 4f8508c90..a802be2ed 100644 --- a/packages/codemirror/package.json +++ b/packages/codemirror/package.json @@ -42,7 +42,7 @@ "@lezer/highlight": "^1.2.1", "@nanostores/persistent": "^0.10.2", "@replit/codemirror-emacs": "^6.1.0", - "@replit/codemirror-vim": "^6.2.1", + "@replit/codemirror-vim": "^6.3.0", "@replit/codemirror-vscode-keymap": "^6.0.2", "@strudel/core": "workspace:*", "@strudel/draw": "workspace:*", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7aecd35bd..810ffb9d5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -201,8 +201,8 @@ importers: specifier: ^6.1.0 version: 6.1.0(@codemirror/autocomplete@6.18.4)(@codemirror/commands@6.8.0)(@codemirror/search@6.5.8)(@codemirror/state@6.5.1)(@codemirror/view@6.36.2) '@replit/codemirror-vim': - specifier: ^6.2.1 - version: 6.2.1(@codemirror/commands@6.8.0)(@codemirror/language@6.10.8)(@codemirror/search@6.5.8)(@codemirror/state@6.5.1)(@codemirror/view@6.36.2) + specifier: ^6.3.0 + version: 6.3.0(@codemirror/commands@6.8.0)(@codemirror/language@6.10.8)(@codemirror/search@6.5.8)(@codemirror/state@6.5.1)(@codemirror/view@6.36.2) '@replit/codemirror-vscode-keymap': specifier: ^6.0.2 version: 6.0.2(@codemirror/autocomplete@6.18.4)(@codemirror/commands@6.8.0)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.8)(@codemirror/state@6.5.1)(@codemirror/view@6.36.2) @@ -215,6 +215,9 @@ importers: '@strudel/transpiler': specifier: workspace:* version: link:../transpiler + codemirror: + specifier: ^6.0.2 + version: 6.0.2 nanostores: specifier: ^0.11.3 version: 0.11.3 @@ -2232,14 +2235,14 @@ packages: '@codemirror/state': ^6.0.1 '@codemirror/view': ^6.3.0 - '@replit/codemirror-vim@6.2.1': - resolution: {integrity: sha512-qDAcGSHBYU5RrdO//qCmD8K9t6vbP327iCj/iqrkVnjbrpFhrjOt92weGXGHmTNRh16cUtkUZ7Xq7rZf+8HVow==} + '@replit/codemirror-vim@6.3.0': + resolution: {integrity: sha512-aTx931ULAMuJx6xLf7KQDOL7CxD+Sa05FktTDrtLaSy53uj01ll3Zf17JdKsriER248oS55GBzg0CfCTjEneAQ==} peerDependencies: - '@codemirror/commands': ^6.0.0 - '@codemirror/language': ^6.1.0 - '@codemirror/search': ^6.2.0 - '@codemirror/state': ^6.0.1 - '@codemirror/view': ^6.0.3 + '@codemirror/commands': 6.x.x + '@codemirror/language': 6.x.x + '@codemirror/search': 6.x.x + '@codemirror/state': 6.x.x + '@codemirror/view': 6.x.x '@replit/codemirror-vscode-keymap@6.0.2': resolution: {integrity: sha512-j45qTwGxzpsv82lMD/NreGDORFKSctMDVkGRopaP+OrzSzv+pXDQuU3LnFvKpasyjVT0lf+PKG1v2DSCn/vxxg==} @@ -3445,6 +3448,9 @@ packages: resolution: {integrity: sha512-FMabTRlc5t5zjdenF6mS0MBeFZm0XqHqeOkcskKFb/LYCcRQ5fVgLOHVc4Lq9CqABd9zhjwPjMBCJvMCziSVtA==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + codemirror@6.0.2: + resolution: {integrity: sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw==} + collapse-white-space@2.1.0: resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} @@ -7657,6 +7663,7 @@ packages: workbox-google-analytics@7.0.0: resolution: {integrity: sha512-MEYM1JTn/qiC3DbpvP2BVhyIH+dV/5BjHk756u9VbwuAhu0QHyKscTnisQuz21lfRpOwiS9z4XdqeVAKol0bzg==} + deprecated: It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained workbox-navigation-preload@7.0.0: resolution: {integrity: sha512-juWCSrxo/fiMz3RsvDspeSLGmbgC0U9tKqcUPZBCf35s64wlaLXyn2KdHHXVQrb2cqF7I0Hc9siQalainmnXJA==} @@ -9595,7 +9602,7 @@ snapshots: '@codemirror/state': 6.5.1 '@codemirror/view': 6.36.2 - '@replit/codemirror-vim@6.2.1(@codemirror/commands@6.8.0)(@codemirror/language@6.10.8)(@codemirror/search@6.5.8)(@codemirror/state@6.5.1)(@codemirror/view@6.36.2)': + '@replit/codemirror-vim@6.3.0(@codemirror/commands@6.8.0)(@codemirror/language@6.10.8)(@codemirror/search@6.5.8)(@codemirror/state@6.5.1)(@codemirror/view@6.36.2)': dependencies: '@codemirror/commands': 6.8.0 '@codemirror/language': 6.10.8 @@ -11043,6 +11050,16 @@ snapshots: cmd-shim@6.0.3: {} + codemirror@6.0.2: + dependencies: + '@codemirror/autocomplete': 6.18.4 + '@codemirror/commands': 6.8.0 + '@codemirror/language': 6.10.8 + '@codemirror/lint': 6.8.4 + '@codemirror/search': 6.5.8 + '@codemirror/state': 6.5.1 + '@codemirror/view': 6.36.2 + collapse-white-space@2.1.0: {} color-convert@2.0.1: From 06fafbd8ebfdda48c86848e00ae13a49641b2c5d Mon Sep 17 00:00:00 2001 From: Dsm0 Date: Wed, 16 Jul 2025 15:03:55 -0700 Subject: [PATCH 060/335] Ensure no default extensions conflict with extensions in defaultSettings --- packages/codemirror/basicSetup.mjs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/codemirror/basicSetup.mjs b/packages/codemirror/basicSetup.mjs index 3faf7d7ab..de5b30417 100644 --- a/packages/codemirror/basicSetup.mjs +++ b/packages/codemirror/basicSetup.mjs @@ -23,20 +23,20 @@ import { completionKeymap, closeBracketsKeymap } from '@codemirror/autocomplete' // Taken + slightly modified from https://github.com/codemirror/basic-setup/blob/main/src/codemirror.ts export const basicSetup = (() => [ - lineNumbers(), - highlightActiveLineGutter(), + // lineNumbers(), + // highlightActiveLineGutter(), highlightSpecialChars(), history(), - foldGutter(), + // foldGutter(), drawSelection(), dropCursor(), // EditorState.allowMultipleSelections.of(true), // indentOnInput(), - syntaxHighlighting(defaultHighlightStyle, { fallback: true }), + // syntaxHighlighting(defaultHighlightStyle, { fallback: true }), // autocompletion(), rectangularSelection(), crosshairCursor(), - highlightActiveLine(), + // highlightActiveLine(), highlightSelectionMatches(), keymap.of([ ...closeBracketsKeymap, From 5448fc607748bceec0002b92c93be4a7814d3b3b Mon Sep 17 00:00:00 2001 From: Dsm0 Date: Wed, 16 Jul 2025 15:17:34 -0700 Subject: [PATCH 061/335] removed duplication and unnecessary keymappings in codemirror config --- packages/codemirror/basicSetup.mjs | 16 ++++++++-------- packages/codemirror/codemirror.mjs | 3 +-- packages/codemirror/keybindings.mjs | 2 +- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/packages/codemirror/basicSetup.mjs b/packages/codemirror/basicSetup.mjs index de5b30417..02294b93a 100644 --- a/packages/codemirror/basicSetup.mjs +++ b/packages/codemirror/basicSetup.mjs @@ -27,24 +27,24 @@ export const basicSetup = (() => [ // highlightActiveLineGutter(), highlightSpecialChars(), history(), - // foldGutter(), - drawSelection(), + // foldGutter(), + // drawSelection(), dropCursor(), // EditorState.allowMultipleSelections.of(true), // indentOnInput(), - // syntaxHighlighting(defaultHighlightStyle, { fallback: true }), + // syntaxHighlighting(defaultHighlightStyle, { fallback: true }), // autocompletion(), rectangularSelection(), crosshairCursor(), - // highlightActiveLine(), - highlightSelectionMatches(), + // highlightActiveLine(), + // highlightSelectionMatches(), keymap.of([ ...closeBracketsKeymap, ...defaultKeymap, - ...searchKeymap, + // ...searchKeymap, ...historyKeymap, - ...foldKeymap, - ...completionKeymap, + // ...foldKeymap, + // ...completionKeymap, ]), ])(); diff --git a/packages/codemirror/codemirror.mjs b/packages/codemirror/codemirror.mjs index 195971df9..4dc23996f 100644 --- a/packages/codemirror/codemirror.mjs +++ b/packages/codemirror/codemirror.mjs @@ -1,7 +1,7 @@ import { closeBrackets } from '@codemirror/autocomplete'; export { toggleComment, toggleBlockComment, toggleLineComment, toggleBlockCommentByLine } from '@codemirror/commands'; // import { search, highlightSelectionMatches } from '@codemirror/search'; -import { history, indentWithTab } from '@codemirror/commands'; +import { indentWithTab } from '@codemirror/commands'; import { javascript, javascriptLanguage } from '@codemirror/lang-javascript'; import { defaultHighlightStyle, syntaxHighlighting, bracketMatching } from '@codemirror/language'; import { Compartment, EditorState, Prec } from '@codemirror/state'; @@ -97,7 +97,6 @@ export function initEditor({ initialCode = '', onChange, onEvaluate, onStop, roo // indentOnInput(), // works without. already brought with javascript extension? // bracketMatching(), // does not do anything syntaxHighlighting(defaultHighlightStyle), - history(), EditorView.updateListener.of((v) => onChange(v)), drawSelection({ cursorBlinkRate: 0 }), Prec.highest( diff --git a/packages/codemirror/keybindings.mjs b/packages/codemirror/keybindings.mjs index a72b164eb..ca5f34f4c 100644 --- a/packages/codemirror/keybindings.mjs +++ b/packages/codemirror/keybindings.mjs @@ -28,5 +28,5 @@ const keymaps = { export function keybindings(name) { const active = keymaps[name]; - return [active ? active() : []]; + return [active ? Prec.high(active()) : []]; } From a4ab8e1b06e80c9092b75fb5bd8107aa24f288a0 Mon Sep 17 00:00:00 2001 From: Aria Date: Wed, 6 Aug 2025 00:45:01 -0500 Subject: [PATCH 062/335] First pass at extending scale function to include notes --- packages/tonal/tonal.mjs | 113 ++++++++++++++++++++++------------- packages/tonal/tonleiter.mjs | 14 ++++- 2 files changed, 84 insertions(+), 43 deletions(-) diff --git a/packages/tonal/tonal.mjs b/packages/tonal/tonal.mjs index c4dd54880..2aca7e9cb 100644 --- a/packages/tonal/tonal.mjs +++ b/packages/tonal/tonal.mjs @@ -6,7 +6,8 @@ This program is free software: you can redistribute it and/or modify it under th import { Note, Interval, Scale } from '@tonaljs/tonal'; import { register, _mod, silence, logger, pure, isNote } from '@strudel/core'; -import { stepInNamedScale } from './tonleiter.mjs'; +import { stepInNamedScale, scaleToChromas } from './tonleiter.mjs'; +import { noteToMidi } from '../core/util.mjs' const octavesInterval = (octaves) => (octaves <= 0 ? -1 : 1) + octaves * 7 + 'P'; @@ -171,8 +172,52 @@ export const { scaleTranspose, scaleTrans, strans } = register( }, ); +// Converts a step value, which is a number optionally decorated with sharps and flats, +// to a number and an `offset` number of semitones +function _convertStepToNumberAndOffset(step) { + if (isNote(step)) { + // legacy.. + return pure(step); + } + let asNumber = Number(step); + let offset = 0; + if (isNaN(asNumber)) { + step = String(step); + // Check to see if the format correctly matches the expected one of + // Optionally starting with + or - + // A number + // Some number of sharps or flats (but not both) + const match = /^[-+]?(\d+)((#{1,})|(b{1,}))?$/.exec(step); + + if (!match) { + logger( + `[tonal] invalid scale step "${step}", expected number or integer with optional # b suffixes`, + 'error', + ); + return silence; + } + asNumber = Number(match[2]); + // The number of semitones will be given by either the total number of sharps (match 3) + // or the negative of the total number of flats (match 4) + offset = match[3].length > 0 ? match[3].length : -match[4].length; + } + return [asNumber, offset]; +} + +// Finds the nearest (named) scale note to `note` (a string which is then converted to a midi number) +function _getNearestScaleNote(scaleName, note) { + let midiNote = noteToMidi(note); + const octave = (midiNote / 12) >> 0; + const goal = midiNote % 12; + const chromas = scaleToChromas(scaleName); + return chromas.reduce((prev, curr) => { + return Math.abs(curr - goal) < Math.abs(prev - goal) ? curr : prev; + }) + octave * 12; +} + /** - * Turns numbers into notes in the scale (zero indexed). Also sets scale for other scale operations, like {@link Pattern#scaleTranspose}. + * Turns numbers into notes in the scale (zero indexed) or quantizes notes to a scale. + * Also sets scale for other scale operations, like {@link Pattern#scaleTranspose}. * * A scale consists of a root note (e.g. `c4`, `c`, `f#`, `bb4`) followed by semicolon (':') and then a [scale type](https://github.com/tonaljs/tonal/blob/main/packages/scale-type/data.ts). * @@ -200,58 +245,42 @@ export const scale = register( if (Array.isArray(scale)) { scale = scale.flat().join(' '); } - return ( + let output = ( pat .fmap((value) => { const isObject = typeof value === 'object'; - let step = isObject ? value.n : value; - if (isObject) { + // The case where the note has been defined via `n` + if ((isObject && 'n' in value) || !isObject) { + let step = isObject ? value.n : value; + debugger; delete value.n; // remove n so it won't cause trouble - } - if (isNote(step)) { - // legacy.. - return pure(step); - } - let asNumber = Number(step); - let semitones = 0; - if (isNaN(asNumber)) { - step = String(step); - if (!/^[-+]?\d+(#*|b*){1}$/.test(step)) { - logger( - `[tonal] invalid scale step "${step}", expected number or integer with optional # b suffixes`, - 'error', - ); - return silence; - } - const isharp = step.indexOf('#'); - if (isharp >= 0) { - asNumber = Number(step.substring(0, isharp)); - semitones = step.length - isharp; - } else { - const iflat = step.indexOf('b'); - asNumber = Number(step.substring(0, iflat)); - semitones = iflat - step.length; + let [number, offset] = _convertStepToNumberAndOffset(step); + try { + let note; + if (isObject && value.anchor) { + note = stepInNamedScale(number, scale, value.anchor); + } else { + note = scaleStep(number, scale); + } + if (offset != 0) note = Note.transpose(note, Interval.fromSemitones(offset)); + value = pure(isObject ? { ...value, note } : note); + } catch (err) { + logger(`[tonal] ${err.message}`, 'error'); + value = silence; } + return value; } - try { - let note; - if (isObject && value.anchor) { - note = stepInNamedScale(asNumber, scale, value.anchor); - } else { - note = scaleStep(asNumber, scale); - } - if (semitones != 0) note = Note.transpose(note, Interval.fromSemitones(semitones)); - value = pure(isObject ? { ...value, note } : note); - } catch (err) { - logger(`[tonal] ${err.message}`, 'error'); - value = silence; + // The case where the note has been defined via `note` + else { + let note = _getNearestScaleNote(scale, value.note); + return pure(isObject ? { ...value, note } : note); } - return value; }) .outerJoin() // legacy: .withHap((hap) => hap.setContext({ ...hap.context, scale })) ); + return output; }, true, true, // preserve step count diff --git a/packages/tonal/tonleiter.mjs b/packages/tonal/tonleiter.mjs index 3814394f6..63ae9c942 100644 --- a/packages/tonal/tonleiter.mjs +++ b/packages/tonal/tonleiter.mjs @@ -222,6 +222,7 @@ export const Note = { }; // TODO: support octave numbers +// Example: Note("Bb3").transpose("c3") export function transpose(note, step) { // example: E, 3 const stepNumber = Step.tokenize(step)[1]; // 3 @@ -236,4 +237,15 @@ export function transpose(note, step) { return [targetNote, offsetAccidentals].join(''); } -//Note("Bb3").transpose("c3") +// Converts a `scaleName` into a corresponding list of chromas between 0 and 12 +export function scaleToChromas (scaleName) { + if (Array.isArray(scaleName)) { + scaleName = scaleName.flat().join(' '); + } + const [tonic, name] = Scale.tokenize(scaleName); + const rootMidi = noteToMidi(tonic); + const chroma = rootMidi % 12; + const intervals = Scale.get(name).intervals; + const scaleSteps = intervals.map(Interval.semitones); + return scaleSteps.map(s => (s + chroma) % 12); +} From 7046c1f54669f26a93252349af28e6adca4b6310 Mon Sep 17 00:00:00 2001 From: Aria Date: Wed, 6 Aug 2025 10:17:48 -0500 Subject: [PATCH 063/335] Cleanup and simplification; improved docstrings --- packages/tonal/tonal.mjs | 43 +++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/packages/tonal/tonal.mjs b/packages/tonal/tonal.mjs index 2aca7e9cb..5b0c63b97 100644 --- a/packages/tonal/tonal.mjs +++ b/packages/tonal/tonal.mjs @@ -183,11 +183,10 @@ function _convertStepToNumberAndOffset(step) { let offset = 0; if (isNaN(asNumber)) { step = String(step); - // Check to see if the format correctly matches the expected one of - // Optionally starting with + or - - // A number - // Some number of sharps or flats (but not both) - const match = /^[-+]?(\d+)((#{1,})|(b{1,}))?$/.exec(step); + // Check to see if the step matches the expected format: + // - A number (possibly negative) + // - Some number of sharps or flats (but not both) + const match = /^(-?\d+)(#+|b+)?$/.exec(step); if (!match) { logger( @@ -196,27 +195,33 @@ function _convertStepToNumberAndOffset(step) { ); return silence; } - asNumber = Number(match[2]); - // The number of semitones will be given by either the total number of sharps (match 3) - // or the negative of the total number of flats (match 4) - offset = match[3].length > 0 ? match[3].length : -match[4].length; + asNumber = Number(match[1]); + // These decorations will determine the semitone offset based on the number of + // sharps or flats + const decorations = match[2] || ''; + offset = decorations[0] === '#' ? decorations.length : -decorations.length; } return [asNumber, offset]; } -// Finds the nearest (named) scale note to `note` (a string which is then converted to a midi number) +// Finds the nearest scale note to `note` function _getNearestScaleNote(scaleName, note) { - let midiNote = noteToMidi(note); + let midiNote = typeof note === 'string' ? noteToMidi(note) : note; const octave = (midiNote / 12) >> 0; - const goal = midiNote % 12; - const chromas = scaleToChromas(scaleName); - return chromas.reduce((prev, curr) => { - return Math.abs(curr - goal) < Math.abs(prev - goal) ? curr : prev; + const targetChroma = midiNote % 12; + const scaleChromas = scaleToChromas(scaleName); + return scaleChromas.reduce((prev, curr) => { + // Include equality so ties are broken upwards + return Math.abs(curr - targetChroma) <= Math.abs(prev - targetChroma) ? curr : prev; }) + octave * 12; } /** * Turns numbers into notes in the scale (zero indexed) or quantizes notes to a scale. + * + * When describing notes via numbers, note that negative numbers can be used to wrap backwards + * in the scale as well as sharps or flats (but not both) to produce notes outside of the scale. + * * Also sets scale for other scale operations, like {@link Pattern#scaleTranspose}. * * A scale consists of a root note (e.g. `c4`, `c`, `f#`, `bb4`) followed by semicolon (':') and then a [scale type](https://github.com/tonaljs/tonal/blob/main/packages/scale-type/data.ts). @@ -236,6 +241,10 @@ function _getNearestScaleNote(scaleName, note) { * n(rand.range(0,12).segment(8)) * .scale("C:ritusen") * .s("piano") + * @example + * n("<[0,7b] [-4# -4] [-2,7##] 4 [0,7] [-4# -4b] [-2,7###] 4b>*4") + * .scale("C:/2") + * .s("piano") */ export const scale = register( @@ -245,14 +254,13 @@ export const scale = register( if (Array.isArray(scale)) { scale = scale.flat().join(' '); } - let output = ( + return ( pat .fmap((value) => { const isObject = typeof value === 'object'; // The case where the note has been defined via `n` if ((isObject && 'n' in value) || !isObject) { let step = isObject ? value.n : value; - debugger; delete value.n; // remove n so it won't cause trouble let [number, offset] = _convertStepToNumberAndOffset(step); try { @@ -280,7 +288,6 @@ export const scale = register( // legacy: .withHap((hap) => hap.setContext({ ...hap.context, scale })) ); - return output; }, true, true, // preserve step count From a4c040e10134c8978fdeda318bddb93caf5fa267 Mon Sep 17 00:00:00 2001 From: Aria Date: Wed, 6 Aug 2025 12:37:55 -0500 Subject: [PATCH 064/335] Add new tests, organize old tests, fix issue with note --- packages/tonal/test/tonal.test.mjs | 171 +++++++++++++++++------------ packages/tonal/tonal.mjs | 32 +++--- packages/tonal/tonleiter.mjs | 4 +- 3 files changed, 120 insertions(+), 87 deletions(-) diff --git a/packages/tonal/test/tonal.test.mjs b/packages/tonal/test/tonal.test.mjs index cd8b3c88b..5486d5135 100644 --- a/packages/tonal/test/tonal.test.mjs +++ b/packages/tonal/test/tonal.test.mjs @@ -7,80 +7,113 @@ This program is free software: you can redistribute it and/or modify it under th // import { strict as assert } from 'assert'; import '../tonal.mjs'; // need to import this to add prototypes -import { pure, n, seq, note } from '@strudel/core'; +import { pure, n, seq, note, noteToMidi } from '@strudel/core'; import { describe, it, expect } from 'vitest'; import { mini } from '../../mini/mini.mjs'; describe('tonal', () => { - it('Should run tonal functions ', () => { - expect(pure('c3').scale('C major').scaleTranspose(1).firstCycleValues).toEqual(['D3']); + describe('scaleTranspose', () => { + it('transposes notes by scale degrees', () => { + expect(pure('c3').scale('C major').scaleTranspose(1).firstCycleValues).toEqual(['D3']); + }); }); - it('scale with plain values', () => { - expect( - seq(0, 1, 2) - .scale('C major') - .note() - .firstCycleValues.map((h) => h.note), - ).toEqual(['C3', 'D3', 'E3']); + describe('scale', () => { + it('converts plain values', () => { + expect( + seq(0, 1, 2) + .scale('C major') + .note() + .firstCycleValues.map((h) => h.note), + ).toEqual(['C3', 'D3', 'E3']); + }); + it('converts n values', () => { + expect( + n(seq(0, 1, 2)) + .scale('C major') + .firstCycleValues.map((h) => h.note), + ).toEqual(['C3', 'D3', 'E3']); + }); + it('converts n values (mini notation)', () => { + expect( + n(seq(0, 1, 2)) + .scale('C:major') + .firstCycleValues.map((h) => h.note), + ).toEqual(['C3', 'D3', 'E3']); + }); + it('converts n values (no tonic)', () => { + expect( + n(seq(0, 1, 2)) + .scale('major') + .firstCycleValues.map((h) => h.note), + ).toEqual(['C3', 'D3', 'E3']); + }); + it('converts n values (explicit mini notation)', () => { + expect( + n(seq(0, 1, 2)) + .scale(mini('C:major')) + .firstCycleValues.map((h) => h.note), + ).toEqual(['C3', 'D3', 'E3']); + }); + it('converts decorated n values', () => { + expect( + n(seq('0b', '1#', '-2', '3##', '4bb')) + .scale('C major') + .firstCycleValues.map((h) => h.note), + ).toEqual(['B2', 'Eb3', 'A2', 'G3', 'F3']); + }); + it('produces silence for mixed sharps and flats', () => { + expect( + n(seq('0b#', '1#b', '2#b#')) + .scale('C major') + .firstCycleValues.map((h) => h.note), + ).toEqual(['', '', '']); + }); + it('snaps notes (upwards) to scale', () => { + const inputNotes = ['Cb', 'Eb', 'G', 'A#', 'Bb']; + let expectedNotes = ['B2', 'E3', 'G3', 'B3', 'B3']; + + // Notes are converted to midi by scale + expectedNotes = expectedNotes.map((note) => noteToMidi(note)); + + expect( + note(seq(inputNotes)) + .scale('C major') + .firstCycleValues.map((h) => h.note), + ).toEqual(expectedNotes); + }); }); - it('scale with n values', () => { - expect( - n(seq(0, 1, 2)) - .scale('C major') - .firstCycleValues.map((h) => h.note), - ).toEqual(['C3', 'D3', 'E3']); - }); - it('scale with colon', () => { - expect( - n(seq(0, 1, 2)) - .scale('C:major') - .firstCycleValues.map((h) => h.note), - ).toEqual(['C3', 'D3', 'E3']); - }); - it('scale without tonic', () => { - expect( - n(seq(0, 1, 2)) - .scale('major') - .firstCycleValues.map((h) => h.note), - ).toEqual(['C3', 'D3', 'E3']); - }); - it('scale with mininotation colon', () => { - expect( - n(seq(0, 1, 2)) - .scale(mini('C:major')) - .firstCycleValues.map((h) => h.note), - ).toEqual(['C3', 'D3', 'E3']); - }); - it('transposes note numbers with interval numbers', () => { - expect( - note(seq(40, 40, 40)) - .transpose(0, 1, 2) - .firstCycleValues.map((h) => h.note), - ).toEqual([40, 41, 42]); - expect(seq(40, 40, 40).transpose(0, 1, 2).firstCycleValues).toEqual([40, 41, 42]); - }); - it('transposes note numbers with interval strings', () => { - expect( - note(seq(40, 40, 40)) - .transpose('1P', '2M', '3m') - .firstCycleValues.map((h) => h.note), - ).toEqual([40, 42, 43]); - expect(seq(40, 40, 40).transpose('1P', '2M', '3m').firstCycleValues).toEqual([40, 42, 43]); - }); - it('transposes note strings with interval numbers', () => { - expect( - note(seq('c', 'c', 'c')) - .transpose(0, 1, 2) - .firstCycleValues.map((h) => h.note), - ).toEqual(['C', 'Db', 'D']); - expect(seq('c', 'c', 'c').transpose(0, 1, 2).firstCycleValues).toEqual(['C', 'Db', 'D']); - }); - it('transposes note strings with interval strings', () => { - expect( - note(seq('c', 'c', 'c')) - .transpose('1P', '2M', '3m') - .firstCycleValues.map((h) => h.note), - ).toEqual(['C', 'D', 'Eb']); - expect(seq('c', 'c', 'c').transpose('1P', '2M', '3m').firstCycleValues).toEqual(['C', 'D', 'Eb']); + describe('transpose', () => { + it('transposes note numbers with interval numbers', () => { + expect( + note(seq(40, 40, 40)) + .transpose(0, 1, 2) + .firstCycleValues.map((h) => h.note), + ).toEqual([40, 41, 42]); + expect(seq(40, 40, 40).transpose(0, 1, 2).firstCycleValues).toEqual([40, 41, 42]); + }); + it('transposes note numbers with interval strings', () => { + expect( + note(seq(40, 40, 40)) + .transpose('1P', '2M', '3m') + .firstCycleValues.map((h) => h.note), + ).toEqual([40, 42, 43]); + expect(seq(40, 40, 40).transpose('1P', '2M', '3m').firstCycleValues).toEqual([40, 42, 43]); + }); + it('transposes note strings with interval numbers', () => { + expect( + note(seq('c', 'c', 'c')) + .transpose(0, 1, 2) + .firstCycleValues.map((h) => h.note), + ).toEqual(['C', 'Db', 'D']); + expect(seq('c', 'c', 'c').transpose(0, 1, 2).firstCycleValues).toEqual(['C', 'Db', 'D']); + }); + it('transposes note strings with interval strings', () => { + expect( + note(seq('c', 'c', 'c')) + .transpose('1P', '2M', '3m') + .firstCycleValues.map((h) => h.note), + ).toEqual(['C', 'D', 'Eb']); + expect(seq('c', 'c', 'c').transpose('1P', '2M', '3m').firstCycleValues).toEqual(['C', 'D', 'Eb']); + }); }); }); diff --git a/packages/tonal/tonal.mjs b/packages/tonal/tonal.mjs index 5b0c63b97..5e505c75a 100644 --- a/packages/tonal/tonal.mjs +++ b/packages/tonal/tonal.mjs @@ -7,7 +7,7 @@ This program is free software: you can redistribute it and/or modify it under th import { Note, Interval, Scale } from '@tonaljs/tonal'; import { register, _mod, silence, logger, pure, isNote } from '@strudel/core'; import { stepInNamedScale, scaleToChromas } from './tonleiter.mjs'; -import { noteToMidi } from '../core/util.mjs' +import { noteToMidi } from '../core/util.mjs'; const octavesInterval = (octaves) => (octaves <= 0 ? -1 : 1) + octaves * 7 + 'P'; @@ -175,25 +175,18 @@ export const { scaleTranspose, scaleTrans, strans } = register( // Converts a step value, which is a number optionally decorated with sharps and flats, // to a number and an `offset` number of semitones function _convertStepToNumberAndOffset(step) { - if (isNote(step)) { - // legacy.. - return pure(step); - } let asNumber = Number(step); let offset = 0; if (isNaN(asNumber)) { step = String(step); // Check to see if the step matches the expected format: - // - A number (possibly negative) - // - Some number of sharps or flats (but not both) + // - A number (possibly negative) + // - Some number of sharps or flats (but not both) const match = /^(-?\d+)(#+|b+)?$/.exec(step); if (!match) { - logger( - `[tonal] invalid scale step "${step}", expected number or integer with optional # b suffixes`, - 'error', - ); - return silence; + logger(`[tonal] invalid scale step "${step}", expected number or integer with optional # b suffixes`, 'error'); + return [silence, 0]; } asNumber = Number(match[1]); // These decorations will determine the semitone offset based on the number of @@ -210,10 +203,13 @@ function _getNearestScaleNote(scaleName, note) { const octave = (midiNote / 12) >> 0; const targetChroma = midiNote % 12; const scaleChromas = scaleToChromas(scaleName); - return scaleChromas.reduce((prev, curr) => { - // Include equality so ties are broken upwards - return Math.abs(curr - targetChroma) <= Math.abs(prev - targetChroma) ? curr : prev; - }) + octave * 12; + return ( + scaleChromas.reduce((prev, curr) => { + // Include equality so ties are broken upwards + return Math.abs(curr - targetChroma) <= Math.abs(prev - targetChroma) ? curr : prev; + }) + + octave * 12 + ); } /** @@ -262,6 +258,10 @@ export const scale = register( if ((isObject && 'n' in value) || !isObject) { let step = isObject ? value.n : value; delete value.n; // remove n so it won't cause trouble + if (isNote(step)) { + // legacy.. + return pure(step); + } let [number, offset] = _convertStepToNumberAndOffset(step); try { let note; diff --git a/packages/tonal/tonleiter.mjs b/packages/tonal/tonleiter.mjs index 63ae9c942..39c819cd7 100644 --- a/packages/tonal/tonleiter.mjs +++ b/packages/tonal/tonleiter.mjs @@ -238,7 +238,7 @@ export function transpose(note, step) { } // Converts a `scaleName` into a corresponding list of chromas between 0 and 12 -export function scaleToChromas (scaleName) { +export function scaleToChromas(scaleName) { if (Array.isArray(scaleName)) { scaleName = scaleName.flat().join(' '); } @@ -247,5 +247,5 @@ export function scaleToChromas (scaleName) { const chroma = rootMidi % 12; const intervals = Scale.get(name).intervals; const scaleSteps = intervals.map(Interval.semitones); - return scaleSteps.map(s => (s + chroma) % 12); + return scaleSteps.map((s) => (s + chroma) % 12); } From c8c6a2ce08e0fca7857323156ba2a8adf877cd5c Mon Sep 17 00:00:00 2001 From: Aria Date: Fri, 15 Aug 2025 13:34:43 -0500 Subject: [PATCH 065/335] Add example test and update fastChunk test (which was previously broken) --- test/__snapshots__/examples.test.mjs.snap | 37 +++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index eb6c238d5..1b5e73d34 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -3418,6 +3418,8 @@ exports[`runs examples > example "fast" example index 0 1`] = ` exports[`runs examples > example "fastChunk" example index 0 1`] = ` [ + "[ 0/1 → 1/4 | color:red note:0 ]", + "[ 1/4 → 1/2 | color:red note:1 ]", "[ 1/2 → 3/4 | note:E2 ]", "[ 3/4 → 1/1 | note:F2 ]", "[ 1/1 → 5/4 | note:G2 ]", @@ -3426,6 +3428,8 @@ exports[`runs examples > example "fastChunk" example index 0 1`] = ` "[ 7/4 → 2/1 | note:C3 ]", "[ 2/1 → 9/4 | note:D3 ]", "[ 9/4 → 5/2 | note:D2 ]", + "[ 5/2 → 11/4 | color:red note:2 ]", + "[ 11/4 → 3/1 | color:red note:3 ]", "[ 3/1 → 13/4 | note:G2 ]", "[ 13/4 → 7/2 | note:A2 ]", "[ 7/2 → 15/4 | note:B2 ]", @@ -8414,6 +8418,39 @@ exports[`runs examples > example "scale" example index 2 1`] = ` ] `; +exports[`runs examples > example "scale" example index 3 1`] = ` +[ + "[ 0/1 → 1/4 | note:C3 s:piano ]", + "[ 0/1 → 1/4 | note:B3 s:piano ]", + "[ 1/4 → 3/8 | note:Gb2 s:piano ]", + "[ 3/8 → 1/2 | note:F2 s:piano ]", + "[ 1/2 → 3/4 | note:A2 s:piano ]", + "[ 1/2 → 3/4 | note:D4 s:piano ]", + "[ 3/4 → 1/1 | note:G3 s:piano ]", + "[ 1/1 → 5/4 | note:C3 s:piano ]", + "[ 1/1 → 5/4 | note:C4 s:piano ]", + "[ 5/4 → 11/8 | note:Gb2 s:piano ]", + "[ 11/8 → 3/2 | note:E2 s:piano ]", + "[ 3/2 → 7/4 | note:A2 s:piano ]", + "[ 3/2 → 7/4 | note:Eb4 s:piano ]", + "[ 7/4 → 2/1 | note:F#3 s:piano ]", + "[ 2/1 → 9/4 | note:C3 s:piano ]", + "[ 2/1 → 9/4 | note:B3 s:piano ]", + "[ 9/4 → 19/8 | note:Gb2 s:piano ]", + "[ 19/8 → 5/2 | note:F2 s:piano ]", + "[ 5/2 → 11/4 | note:Ab2 s:piano ]", + "[ 5/2 → 11/4 | note:D4 s:piano ]", + "[ 11/4 → 3/1 | note:G3 s:piano ]", + "[ 3/1 → 13/4 | note:C3 s:piano ]", + "[ 3/1 → 13/4 | note:C4 s:piano ]", + "[ 13/4 → 27/8 | note:Gb2 s:piano ]", + "[ 27/8 → 7/2 | note:E2 s:piano ]", + "[ 7/2 → 15/4 | note:Ab2 s:piano ]", + "[ 7/2 → 15/4 | note:Eb4 s:piano ]", + "[ 15/4 → 4/1 | note:F#3 s:piano ]", +] +`; + exports[`runs examples > example "scaleTranspose" example index 0 1`] = ` [ "[ 0/1 → 1/2 | note:C3 ]", From e9aef9e4d49cb451e7e96fd989101949c72c9121 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sun, 17 Aug 2025 16:49:10 -0400 Subject: [PATCH 066/335] working --- packages/core/controls.mjs | 22 ++++++++++++++++++++++ packages/core/pattern.mjs | 2 +- packages/superdough/reverb.mjs | 20 ++++++++++++++------ packages/superdough/superdough.mjs | 17 +++++++++++------ 4 files changed, 48 insertions(+), 13 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index e6181d453..9f07f8c76 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -1516,6 +1516,28 @@ export const { roomfade, rfade } = registerControl('roomfade', 'rfade'); * */ export const { ir, iresponse } = registerControl(['ir', 'i'], 'iresponse'); + +/** + * Sets the sample to use as an impulse response for the reverb. + * @name iresponse + * @param {string | Pattern} sample to use as an impulse response + * @synonyms ir + * @example + * s("bd sd [~ bd] sd").room(.8).ir("") + * + */ +export const { irspeed } = registerControl('irspeed'); + +/** + * Sets the sample to use as an impulse response for the reverb. + * @name iresponse + * @param {string | Pattern} sample to use as an impulse response + * @synonyms ir + * @example + * s("bd sd [~ bd] sd").room(.8).ir("") + * + */ +export const { irbegin } = registerControl('irbegin'); /** * Sets the room size of the reverb, see `room`. * When this property is changed, the reverb will be recaculated, so only change this sparsely.. diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index dbf1b17f7..56f2c16e3 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -3276,7 +3276,7 @@ export const slice = register( * @memberof Pattern * @returns Pattern * @example - * s("bd!8").onTriggerTime((hap) => {console.info(hap)}) + * s("bd!8").onTriggerTime((hap) => {console.log(hap)}) */ Pattern.prototype.onTriggerTime = function (func) { return this.onTrigger((hap, currentTime, _cps, targetTime) => { diff --git a/packages/superdough/reverb.mjs b/packages/superdough/reverb.mjs index 0f638ca80..4d62aafdc 100644 --- a/packages/superdough/reverb.mjs +++ b/packages/superdough/reverb.mjs @@ -1,7 +1,8 @@ import reverbGen from './reverbGen.mjs'; if (typeof AudioContext !== 'undefined') { - AudioContext.prototype.adjustLength = function (duration, buffer) { + AudioContext.prototype.adjustLength = function (duration, buffer, speed = 1, offsetSeconds = 0) { + const offset = offsetSeconds * buffer.sampleRate; const newLength = buffer.sampleRate * duration; const newBuffer = this.createBuffer(buffer.numberOfChannels, buffer.length, buffer.sampleRate); for (let channel = 0; channel < buffer.numberOfChannels; channel++) { @@ -9,22 +10,29 @@ if (typeof AudioContext !== 'undefined') { let newData = newBuffer.getChannelData(channel); for (let i = 0; i < newLength; i++) { - newData[i] = oldData[i] || 0; + let position = (offset + i * Math.abs(speed)) % oldData.length; + if (speed < 1) { + position = position * -1; + } + + newData[i] = oldData.at(position) || 0; } } return newBuffer; }; - AudioContext.prototype.createReverb = function (duration, fade, lp, dim, ir) { + AudioContext.prototype.createReverb = function (duration, fade, lp, dim, ir, irspeed, irbegin) { const convolver = this.createConvolver(); - convolver.generate = (d = 2, fade = 0.1, lp = 15000, dim = 1000, ir) => { + convolver.generate = (d = 2, fade = 0.1, lp = 15000, dim = 1000, ir, irspeed, irbegin) => { convolver.duration = d; convolver.fade = fade; convolver.lp = lp; convolver.dim = dim; convolver.ir = ir; + convolver.irspeed = irspeed; + convolver.irbegin = irbegin; if (ir) { - convolver.buffer = this.adjustLength(d, ir); + convolver.buffer = this.adjustLength(d, ir, irspeed, irbegin); } else { reverbGen.generateReverb( { @@ -41,7 +49,7 @@ if (typeof AudioContext !== 'undefined') { ); } }; - convolver.generate(duration, fade, lp, dim, ir); + convolver.generate(duration, fade, lp, dim, ir, irspeed, irbegin); return convolver; }; } diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index eb1466d91..ccdb15abf 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -326,7 +326,7 @@ export const panic = () => { channelMerger == null; }; -function getDelay(orbit, delaytime, delayfeedback, t, channels) { +function getDelay(orbit, delaytime, delayfeedback, t) { if (delayfeedback > maxfeedback) { //logger(`delayfeedback was clamped to ${maxfeedback} to save your ears`); } @@ -442,19 +442,22 @@ function duckOrbit(audioContext, targetOrbit, t, attacktime = 0.1, duckdepth = 1 } let hasChanged = (now, before) => now !== undefined && now !== before; -function getReverb(orbit, duration, fade, lp, dim, ir) { +function getReverb(orbit, duration, fade, lp, dim, ir, irspeed, irbegin) { // If no reverb has been created for a given orbit, create one if (!orbits[orbit].reverbNode) { const ac = getAudioContext(); - const reverb = ac.createReverb(duration, fade, lp, dim, ir); + const reverb = ac.createReverb(duration, fade, lp, dim, ir, irspeed, irbegin); connectToOrbit(reverb, orbit); orbits[orbit].reverbNode = reverb; } + if ( hasChanged(duration, orbits[orbit].reverbNode.duration) || hasChanged(fade, orbits[orbit].reverbNode.fade) || hasChanged(lp, orbits[orbit].reverbNode.lp) || hasChanged(dim, orbits[orbit].reverbNode.dim) || + hasChanged(irspeed, orbits[orbit].reverbNode.irspeed) || + hasChanged(irbegin, orbits[orbit].reverbNode.irbegin) || orbits[orbit].reverbNode.ir !== ir ) { // only regenerate when something has changed @@ -462,7 +465,7 @@ function getReverb(orbit, duration, fade, lp, dim, ir) { // stack(s("a"), s("b").rsize(8)).room(.5) // this only works when args may stay undefined until here // setting default values breaks this - orbits[orbit].reverbNode.generate(duration, fade, lp, dim, ir); + orbits[orbit].reverbNode.generate(duration, fade, lp, dim, ir, irspeed, irbegin); } return orbits[orbit].reverbNode; } @@ -619,6 +622,8 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) roomdim, roomsize, ir, + irspeed, + irbegin, i = getDefaultValue('i'), velocity = getDefaultValue('velocity'), analyze, // analyser wet @@ -832,7 +837,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) // delay let delaySend; if (delay > 0 && delaytime > 0 && delayfeedback > 0) { - const delayNode = getDelay(orbit, delaytime, delayfeedback, t, orbitChannels); + const delayNode = getDelay(orbit, delaytime, delayfeedback, t); delaySend = effectSend(post, delayNode, delay); audioNodes.push(delaySend); } @@ -850,7 +855,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) } roomIR = await loadBuffer(url, ac, ir, 0); } - const reverbNode = getReverb(orbit, roomsize, roomfade, roomlp, roomdim, roomIR, orbitChannels); + const reverbNode = getReverb(orbit, roomsize, roomfade, roomlp, roomdim, roomIR, irspeed, irbegin); reverbSend = effectSend(post, reverbNode, room); audioNodes.push(reverbSend); } From e7e636886d8ca04dc35e5540cd3239f153a2105a Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sun, 17 Aug 2025 17:21:36 -0400 Subject: [PATCH 067/335] add tests --- packages/core/controls.mjs | 19 +++--- packages/core/logger.mjs | 2 +- packages/superdough/reverb.mjs | 8 ++- test/__snapshots__/examples.test.mjs.snap | 74 +++++++++++++++++++++++ 4 files changed, 90 insertions(+), 13 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 9f07f8c76..58a30652c 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -1518,23 +1518,24 @@ export const { roomfade, rfade } = registerControl('roomfade', 'rfade'); export const { ir, iresponse } = registerControl(['ir', 'i'], 'iresponse'); /** - * Sets the sample to use as an impulse response for the reverb. - * @name iresponse - * @param {string | Pattern} sample to use as an impulse response - * @synonyms ir + * Sets speed of the sample for the impulse response. + * @name irspeed + * @param {string | Pattern} speed * @example - * s("bd sd [~ bd] sd").room(.8).ir("") + * samples('github:switchangel/pad') + * $: s("brk/2").fit().scrub(irand(16).div(16).seg(8)).ir("swpad:4").room(.2).irspeed("<2 1 .5>/2").irbegin(.5).roomsize(.5) * */ export const { irspeed } = registerControl('irspeed'); /** - * Sets the sample to use as an impulse response for the reverb. - * @name iresponse - * @param {string | Pattern} sample to use as an impulse response + * Sets the beginning of the IR response sample + * @name irbegin + * @param {string | Pattern} begin between 0 and 1 * @synonyms ir * @example - * s("bd sd [~ bd] sd").room(.8).ir("") + * samples('github:switchangel/pad') + * $: s("brk/2").fit().scrub(irand(16).div(16).seg(8)).ir("swpad:4").room(.65).irspeed("-2").irbegin("<0 .5 .75>/2").roomsize(.6) * */ export const { irbegin } = registerControl('irbegin'); diff --git a/packages/core/logger.mjs b/packages/core/logger.mjs index 4f2002319..488bce5e8 100644 --- a/packages/core/logger.mjs +++ b/packages/core/logger.mjs @@ -6,7 +6,7 @@ let debounce = 1000, export function errorLogger(e, origin = 'cyclist') { //TODO: add some kind of debug flag that enables this while in dev mode - // console.error(e); + console.error(e); logger(`[${origin}] error: ${e.message}`); } diff --git a/packages/superdough/reverb.mjs b/packages/superdough/reverb.mjs index 4d62aafdc..2960b597c 100644 --- a/packages/superdough/reverb.mjs +++ b/packages/superdough/reverb.mjs @@ -1,8 +1,9 @@ import reverbGen from './reverbGen.mjs'; +import { clamp } from './util.mjs'; if (typeof AudioContext !== 'undefined') { - AudioContext.prototype.adjustLength = function (duration, buffer, speed = 1, offsetSeconds = 0) { - const offset = offsetSeconds * buffer.sampleRate; + AudioContext.prototype.adjustLength = function (duration, buffer, speed = 1, offsetAmount = 0) { + const sampleOffset = Math.floor(clamp(offsetAmount, 0, 1) * buffer.length); const newLength = buffer.sampleRate * duration; const newBuffer = this.createBuffer(buffer.numberOfChannels, buffer.length, buffer.sampleRate); for (let channel = 0; channel < buffer.numberOfChannels; channel++) { @@ -10,7 +11,8 @@ if (typeof AudioContext !== 'undefined') { let newData = newBuffer.getChannelData(channel); for (let i = 0; i < newLength; i++) { - let position = (offset + i * Math.abs(speed)) % oldData.length; + // loop the buffer around to prevent + let position = (sampleOffset + i * Math.abs(speed)) % oldData.length; if (speed < 1) { position = position * -1; } diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index bb0489a91..3409ce1b9 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -4842,6 +4842,43 @@ exports[`runs examples > example "irand" example index 0 1`] = ` ] `; +exports[`runs examples > example "irbegin" example index 0 1`] = ` +[ + "[ 0/1 → 1/8 | s:brk speed:0.5 unit:c begin:0 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 1/8 → 1/4 | s:brk speed:0.5 unit:c begin:0.625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 1/4 → 3/8 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 3/8 → 1/2 | s:brk speed:0.5 unit:c begin:0.375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 1/2 → 5/8 | s:brk speed:0.5 unit:c begin:0.25 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 5/8 → 3/4 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 3/4 → 7/8 | s:brk speed:0.5 unit:c begin:0.1875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 7/8 → 1/1 | s:brk speed:0.5 unit:c begin:0.375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 1/1 → 9/8 | s:brk speed:0.5 unit:c begin:0.5 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 9/8 → 5/4 | s:brk speed:0.5 unit:c begin:0.625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 5/4 → 11/8 | s:brk speed:0.5 unit:c begin:0.6875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 11/8 → 3/2 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 3/2 → 13/8 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 13/8 → 7/4 | s:brk speed:0.5 unit:c begin:0.4375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 7/4 → 15/8 | s:brk speed:0.5 unit:c begin:0.1875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 15/8 → 2/1 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 2/1 → 17/8 | s:brk speed:0.5 unit:c begin:0.9375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 17/8 → 9/4 | s:brk speed:0.5 unit:c begin:0.875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 9/4 → 19/8 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 19/8 → 5/2 | s:brk speed:0.5 unit:c begin:0.8125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 5/2 → 21/8 | s:brk speed:0.5 unit:c begin:0.4375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 21/8 → 11/4 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 11/4 → 23/8 | s:brk speed:0.5 unit:c begin:0.625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 23/8 → 3/1 | s:brk speed:0.5 unit:c begin:0 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 3/1 → 25/8 | s:brk speed:0.5 unit:c begin:0.1875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 25/8 → 13/4 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 13/4 → 27/8 | s:brk speed:0.5 unit:c begin:0.9375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 27/8 → 7/2 | s:brk speed:0.5 unit:c begin:0.375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 7/2 → 29/8 | s:brk speed:0.5 unit:c begin:0.375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 29/8 → 15/4 | s:brk speed:0.5 unit:c begin:0.9375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 15/4 → 31/8 | s:brk speed:0.5 unit:c begin:0.75 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 31/8 → 4/1 | s:brk speed:0.5 unit:c begin:0.6875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", +] +`; + exports[`runs examples > example "iresponse" example index 0 1`] = ` [ "[ 0/1 → 1/4 | s:bd room:0.8 ir:shaker_large i:0 ]", @@ -4863,6 +4900,43 @@ exports[`runs examples > example "iresponse" example index 0 1`] = ` ] `; +exports[`runs examples > example "irspeed" example index 0 1`] = ` +[ + "[ 0/1 → 1/8 | s:brk speed:0.5 unit:c begin:0 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 1/8 → 1/4 | s:brk speed:0.5 unit:c begin:0.625 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 1/4 → 3/8 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 3/8 → 1/2 | s:brk speed:0.5 unit:c begin:0.375 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 1/2 → 5/8 | s:brk speed:0.5 unit:c begin:0.25 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 5/8 → 3/4 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 3/4 → 7/8 | s:brk speed:0.5 unit:c begin:0.1875 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 7/8 → 1/1 | s:brk speed:0.5 unit:c begin:0.375 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 1/1 → 9/8 | s:brk speed:0.5 unit:c begin:0.5 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 9/8 → 5/4 | s:brk speed:0.5 unit:c begin:0.625 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 5/4 → 11/8 | s:brk speed:0.5 unit:c begin:0.6875 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 11/8 → 3/2 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 3/2 → 13/8 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 13/8 → 7/4 | s:brk speed:0.5 unit:c begin:0.4375 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 7/4 → 15/8 | s:brk speed:0.5 unit:c begin:0.1875 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 15/8 → 2/1 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 2/1 → 17/8 | s:brk speed:0.5 unit:c begin:0.9375 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 17/8 → 9/4 | s:brk speed:0.5 unit:c begin:0.875 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 9/4 → 19/8 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 19/8 → 5/2 | s:brk speed:0.5 unit:c begin:0.8125 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 5/2 → 21/8 | s:brk speed:0.5 unit:c begin:0.4375 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 21/8 → 11/4 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 11/4 → 23/8 | s:brk speed:0.5 unit:c begin:0.625 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 23/8 → 3/1 | s:brk speed:0.5 unit:c begin:0 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 3/1 → 25/8 | s:brk speed:0.5 unit:c begin:0.1875 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 25/8 → 13/4 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 13/4 → 27/8 | s:brk speed:0.5 unit:c begin:0.9375 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 27/8 → 7/2 | s:brk speed:0.5 unit:c begin:0.375 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 7/2 → 29/8 | s:brk speed:0.5 unit:c begin:0.375 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 29/8 → 15/4 | s:brk speed:0.5 unit:c begin:0.9375 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 15/4 → 31/8 | s:brk speed:0.5 unit:c begin:0.75 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 31/8 → 4/1 | s:brk speed:0.5 unit:c begin:0.6875 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", +] +`; + exports[`runs examples > example "isaw" example index 0 1`] = ` [ "[ 0/1 → 1/8 | note:c3 clip:1 ]", From cf55d4c8d19c47d4ae31c7d47a10e10ea001effb Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Mon, 18 Aug 2025 11:49:11 -0400 Subject: [PATCH 068/335] rm var --- packages/superdough/superdough.mjs | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index ccdb15abf..a518f49b6 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -282,7 +282,6 @@ export async function initAudioOnFirstClick(options) { return audioReady; } -let delays = {}; const maxfeedback = 0.98; let channelMerger, destinationGain; From 32fe73aba2949a4725f458844a558e275afd9591 Mon Sep 17 00:00:00 2001 From: Aria Date: Tue, 19 Aug 2025 11:10:34 -0500 Subject: [PATCH 069/335] Update effects documentation to include information on signal flow --- website/public/img/strudel-signal-flow.png | Bin 0 -> 37017 bytes website/src/pages/learn/effects.mdx | 118 +++++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 website/public/img/strudel-signal-flow.png diff --git a/website/public/img/strudel-signal-flow.png b/website/public/img/strudel-signal-flow.png new file mode 100644 index 0000000000000000000000000000000000000000..c5099c917c0e569dd8b5f78bb4eb36e0f7c77baf GIT binary patch literal 37017 zcmeFa1z45o{w@s5rGmK#K?S50q@+u_8$n3{X%H5R?o^PL5J4IdP^6@#Q30j9OHfKe zknZ!muyC9`bM~J9KG*e~+53DtW4!P4KKaZ0cRw@!it-X?PhCERfq`*WN>Wq_0|Q2Z zfr0rA>jZehJwG9HOmbXl#MMlt0*-Ki>{?5qk*Ze zv9&JJhS9>%7CZv)b&U-z&<*5J&Zg$(y3{PZ7FI4UZWcZ6Lzw`7WoChX0)c=I6sdbO z47w{D6I}z8!{NvWkN$W7N5^1|LV=n5a@vP4e*G2F4iQ6hNR*FG06h+nxc~XLKljo4 zrzZWMbZ4#ZWF+ixM~X#6?!LSz7ps#xD;onl*p>qw&^5P1pB6O>hdEfOun`LAFAIk; z^k)TYJxKEoUx3B@`tGm;8(XI%T{$=!L+Egr!KV%;rnZL4mb&^-_YOdk!7~$Eq&fOE zuq);wD09@IQn4E78gd!wgC;h%)+jT>U*2%&a~bLxfj7F~ydh=P2fG64qOiHHo}sxS z%Er|8P>X-Q0E%sE3ItB}9~$VPY;93U@a0hhA#|6vC}?)j;(i%e{NM+8j@~KIsUcbi z|Kx-Y9{qDMIg%)#*oMGF*;+dRfjR1tg_V&LZ6J>Hn)wDJC$M(VF**FEC~P-47|{() zeo+%nw20`UwbS_L5YYF3MGiq5v>5;MW&DY>|G9{<{fUS{llett3=M#3KuZwH+SUYR zjIz)*7yIq0@NYr|?5yx_ZDdiC7_wKcW>{iOazhldt1``_$? zoSm(yh4G<*Md~_&gS14MJ6W2bEPx#U$+;eA-|x@j4=VhRiik8dFo4X7u(hF$sk5%$ zfoXvb-Vy}@hXc`O7p7(x1y2sNU-+j>I8s~-lm+zt|5%sN-VQw^SP)vDEOmdg!hb3O z><6Oq&sFA6B>=7YAVA?_Wj)+MwB{ei1S~iHvW)zd(SMtRBD9y__>N4^@5e@4oFh?0 z85!9eg?9hiiX07cU`u{lxqm)ARuIMg+m`2#Hbzm`7PtqCKZxX?`J+Q;a}Ln8FAqsRXP-TBiEI1&x7>o(^zpwDX?6WX)p(EO(RN(&` zyZ@hT+K*K67fDpMwKlZXH~E8&`8yeR&Lb2DebUTF2+n_?c}E8bzns7yw*EgW4PZrU z;lEA;4sx=8L+AhQ=KYU}wYaG{NUUxCaI$}ArD9=YVPyFuhWa0pUbCSwsQ)6pLPHq; zTCe^~aaC6I2K;iQVn#-w%=RCqSKR;6dW8zD_VL;Li_LYrL1U~{w3lC#3@@~cm5Q#{X3`htpC|5{U3Ep6ykw_jO15d z)Zga-n2$gRG)&3H`X8P79RyatBP=KZny$6p-}nUBZlE!P|Be&*BLE@_sBnL06=2~+ zOU-}90UYtHe{lsufOF~O3^=uaUo*u1H#b8EB)0zzRUA!l`-RQ_Yk+a^_UQh=;S2N! z(AA4WYU$3hrZffy0z*nv=(Z!~T>Qzn+ufV%iRuKABgfN~#8R*yJb(pcBDzfU{Er7E zUzEd=rbp5H>&eQ}d$8+?DN^eB-+CdQn>Kya+&FRZSP*6%hJF%TonXMyNf^Qt15SqF1; zj)Nm8xcx29V`2$nfaikmvB*SmAH_T(!@$IXhhPwhd^Q0sBq&9Bz!wLNtSCJZ{zMwr zA7Q{BNMHn#V|cyC74*Z8ytqkz*Z@Jp48sb;6_FA{U|qqa2kpod?}8`exG6V}IuX0- ziJ)cSIduXW;$UDYJVCz*wp-sG3Swdh5pCz;l-DPDGF~MDA7g-zVS=ab6U;pp@UqgE z@U6vqCqq0gaNPtG_Kw06fgM?u%Ylu3hKQr-5zftbWZ1svwH|m*VUvj_Gk%4^QYAho zxGXRWTeH$svr1hNO@S8C z@(@Fq>iiASgSmnh2oKO=gEj3q)Z!hbXDxz;4AWZ@Qz-20(e8#{150#D>%zip#ho6h zDDx41Zer5)Dr|SN)uSk$*J0AEGtaPbE|_z~Z_;Udz8JYQUfaHnarYhtSh6VSp5noa zi|`%k&yRT*-q_9d^bZu8A)B5tuk}{#b!)rK7rHjbvl>4hcHf?Fzq#dAq@Hgi_Pyj_ z`h;LA+6I2Uf`Zt$)0Jw!b*1Zr4hj?aTn5AlwG8w>KDJ|{Vq~n`(90l_=lx#3Y~GO~ zRb)_)OT=UQ%Fw{zSqIxg3SH~vX3oL4R$t6VE8XN%*ia)w^8A}$U%leC{OlQT-9Wqc z{xp+XECm^&2#9! zhi`9u3CTi@R%T~6GF1)T?|yCgy=uQQ-ts-R{fD!hT zh0@u%lqd3eW#20Y83u1IRv)wPl;e#4wz0F^%D~GzXw>v?qm45a68YtWrrl>cQh9KI?j!;&+33oBcHAo& zw=KLOSu9Xicd!V#)}^eV9(Lzh(J^v zXLVe>$4QyzvTo5C%N)?kbUQ<(nYwCwp=_aVmVAS5|B}^OtJy6y9!UX41<@N#&C8+N&8Er3K2!$+0&l znE1am>&;&K(a2OLm!V;FYqOPqyJ_OffkhzKtD^yOc}g%zCW_I1p=3(q;fb@EuA4tB zNc~5$+ta!plkk>aUReudEGW4{q`o>x0Y1)@i|6TP_)ep>dWM)wvHvcX&$&b#t1xC? zMVkGUXPI|}F<@7yz$}wGr&-|RV)uT0txp@psn6O|q%qjv9^E(J{4rs%CW0!O_H9aV z{UMd1Q&pLzQP^PA5;qet;<3M*b}8aCQ+eA!F$(2e>o8L8RHRpXs`yr+d4FD-I$j0$ zi{PB=w{!Kx*00KSrpejOKIphJGHeOf;VS&uk`+PWyZrea48e5@6M3~eJTTAHD8+g8 zTdD1P3VQ|rk!SvM>!H(avz2FwIBcD`A=~PQ5cCt3w1mtd*p(VDj60JG806ssq)JD2 z(~lD9E%BHVJ7k6ko?uT%GDp$)k zGB`{SgB%y*n!a8;c1@Xqa}`~4h|tiENtAgw5{@O9^c8pp>BrRULP?77j_tEpfe4Qi zUW;XJd0}8V_=#Ym8)w{ZA4`MQ3U&!s1}si(q~OHS)X#Vco({Ws4m!94Bdd4{IF?k5 z_^ardV^W1?)MJI+%|&1zeL?{_BcW)H1J6U|2!Hcd5PWm|z3A0LZ-oIL7XouW|GEqM z1Zr>*CI%b=EiT8YBU`SB3qGM13gZELnnD#Cj>~d9@FVFrZw$D!H<+{N4JB;&DTU8< zv(EjbzAL$xyRTnS*(iEvT(3-{Nz^XDfQ?K8@M+|)VCcB107T(y1Q^~UMO$SFn(-1UfDowrLK-WeQ8>yL4-7<{YulrFU& z1ND?qT78Ln5=1@mC0Ma zW_&FNLkF{wl%nJpLU#3$lHT8Dx+=rWSc|tJzW4ET%hK0S={Y>TQAU*gZOkaag1D=( zG{IHzOhQMxKdtustMlJ9YfnwYoh>QM*un>X^;a+$9PnN;h(KA|Papj_AR zltEuzy??Ev>g8bN?#WE!;z-79%_t*|iN@Ns_Koi!kazOFaYsI+|43R$r@K74Us<#p zeR3|P=qz%`dy`{o`;I)E)}`tV8EvdaT>=qb?N#^OHu;&pnnJ$iSVIoW&w}fgsLt03 zaxq11dHMNws4n03NDVOMxZi}YS!Derosl}>$w(ass^9L-{x-|}(29M)<43`<4x+{n zq~lDifoPUQ;{Rfa5_Q)xtt2VP69@C(#fv( z4KJVCt1mwP-tq{&W|@0z`juvlxUTFl)5wXyXqmaP<7VcY zuba68zdG*^@30pcY>I2l7fK#J?1u zb4pK^7I%Z6{+tFIcil>}%jy8bSpUNzUS;Z=%V91JW4SILD8!g?>3Mqj(gF-?ndg2Bejt4c_r^`lCMp4MB`RI4#$p!gFRYvjiJGgAg9TB+-r-Y-35$^f_b0f~SRAQZ zWHE?z#$r-)-S}Xmy&>eGm*H$7VluIqCzf(jCTibAA+SntiU7)nV_x86JVeK-=}O zls%oTz!r!r`b@w3R=tRO4q8j*hHeXYq?3x z`vc^P_{v4oZsJ&+%$Y}sHRfwgPy&A_b}dwCB{>54oB)x}OH*}&9}`<`?%Z6?ky=|+ z{xVcp^Xb?J0sG#8s>PaDt@HI$*ZRItejF50a33FEMegSs3$P-ux{Y-+%>_FcM;o1^ zn233{pB24yWQ<6zojvESHtuCOa59m&FqZ(&p4}Wk@vr32KsUDOjYC{ zSBN_2!(Iy5b`rbOk-1%^;BFA{gg^#pI;aqg8vmt zuh?-WWNn%?(Px{tF~M0kxngZJdhB*Swld+sVpw9C83{0@{UeunHKUx0W^tjwXcPAn z6ApPeDM<%eC>(CTFkpO&yDYha>=gGGn-NrhX(LY&(xg|X`vc@Wz7Z?eBD-!^UhbwF zxP~`5n36slda5v8WkPScK?ND!+|1Ezf9A4fDW1}GB2D?;fJXJi zahuZ(FYSv+W3cNP6sQ(V=EZ+lfq?832*i{ejUqffUt*c;*LE_=7ogtDuxX@SVmEs2 zLL@HkdL_ZDEiW`1?-G@JPp$bQ29rUJZ$9gapdKLqWqzS}1-NkJUC@hMu2 z*@p!|gAJS6J@NK_T`&m}m#P#rUD^=B!Ie_I36d30L3$9O(x1%+{Zimbes`GAHKfcZ zk!Dj-+_f;r;X-bhFOt^Cg`hB zO}X8@oT>z3KPPPbBx49Bpg0W-%?;QLH~4UbFq6OJ5JrEsqlGQn$5tV`ty&<4y0Pl{S? z&%h9pS7FD$pB7H}ocRgcs~X`r74MKK7t5hiY@r3F6La?Bjp~EkOr!9%{teW~&DrjZ zs4{_x2xaqz2wFyMr@gJ-s#0Jx9LN2qWgC)&9^NIn{?gg^%q6{(=ZF0FXXLAkYlq1;{ zYZ_%=9`njl7y`tEQEvVzgJutv9{=u>}!|m^Ou=PM|!HCtLdnZ%-8V&Ap8;@-!x< zldm(f^Cp{Pd6#mnzK9bExR*=aE8p9i?Wu5a=wx~9vyU$-IOOuZ!ouEgy6t&SstloK zfk_y{-M4Mn@liVN{fs4Faf$d{9p7^7frI-^evVTmP2g5AKuP|Sw|ylxFDrgD&~YFK z*vj_zwvqjLhW6wB*E9gmk<4C%8Xf7$(j=@1xjQ#l%w#>&5=_KtZ%k4^ekY#}@0xtU zmk@!G`@Pv&Cdyh14@7YBlFSe^+(5p=^`+zxi^nmWl_aT5xW!M*G)F_Yjr(ebPDy_t z=(3FZA~r#)v9a-B9Jh_EiAOH8ENn7y*#?tYfd#;V zQq&teK~E7hH@u9RW7Ok$?1o}l02pF3QMte8QcPv@qyCy^vBmJ+p-*9y@s57wQk3M$ zm(Dj^(yQmyfG-ROR=%-J*|hz5Y^0jtGL#P&*xbse-n%&`foTz#8SyX#-&r364b3Bk~2<2bC`2KWcWaMN_$6i=-EazZXy0V;$WOm8qWx||GIP>J~ zKLSP~+vohWXYM4!A88-!DSTk0bUP%QTA0JU?=wfvH@VBrHE&c!4X_Z40s!LKcMI}C z(BNV=TNaqKzu!%elx_$kz0jSZS`09%QXQROq@WWKo5{WBiepA>1?qQDQ{KWpbcBN( zy$Dawbu8k|nQ=a%X=ZqUnCJV$9Q>y`9{@ElFQ7WuLx}2ohh|0a2f!?-LYStp4{=*E zOSmhOC~WH188nLF=m%0>k(T6)J?f6;l?G?5l6=I0WgL55%`-R2{-^z z1j!bF(Xx_|J$A5W@a0$FF~bQjjgup8!qm<{J&l1D*b?#&k6MTVhe<)jb@C@Xoesg% zrKhJ4(HlXsx8Q?!OMH=NG$R}UHB>Wqg?%CO4Q$Xm^3OWtxWuG-w1+!aoe$b4*pZO< z9(F)=-YaGYaczY;%)@FC}+%6&6g1NTCKr-w(Z?QBM{FE>9K@?QZ^m?XYegebcxFPPgHR)OiAR*)8F zY0aLHz>niXhMgtdEUDP3iz?FXJXe;a4k$X&nmDah`p)=f#}nEV4zGrp}JDCW)^rM|^!2ibVw(U+nGa_g?azjbFBU1*3Z z^w*)!yZ*E@)4A}JuX+(mCvAS9qE#hpSTCoX`vZ2Q_DfRKbHz^$Q3{34n)U;GO~)8_ zheM18-v^y-|Dk>|PfPu&PKA9&*5I4wjt-?4GbLJVDC?kD!xH3T|5~Gse1MS@UDSO5 zy{D%+HiyTxXQi@RsCAw=M{IJ3E~;2Z%Q8=EEwE)RKYu{9acAt&h`nr9gT3_2tM(u6 z@Xa|KYqiX0dzi!h;kpXf+la0l2coi7hnegV84s(xd^!!G$AOPlUze#T3hgQsLqHDl z^ThDnvw=IZ9&DX2oG*ANI~u)mdNL5eQM+38N~YlKs-_bPyZ91qM!xxLjns0w55N@p zod?q4`c{b!=y%d~dNXqSaRtYG26g1qr^uHMrU}MwG3@=N$dK+=D(%?e-zRf&<>!e8 zNwWnSw{%w)6YoPe|``=#Z@poU0f*?jZ9 z8`7|Gw?H68!m#PIM&v_bysnE_G(V7&D0!U>;HPZ=dF<3tc{V`g=Th1(K}dyMRK}J zt3%VY*$auQJna+RvaKT((Q6HwtjNwtE&H(&lK5A*_JB0T8hNW^_nXJ_UNN5KG%udJ zF{}ImCgoG+gY2)`_e2g>N)!W(giIdjffY=quwIs|WE)^vnNlw_ii}(NivojgEtt1wkKz0%P`BrOU7uh@O z_eP2+zxyIr7tMpNtbGrPM_y`lFOV8DB=3GK0B*gyfqe0j*Z=%_f@_Axwivh;Zgw&sIv2Kv&{pDuT0OiH^lvr^t9Di}_4kJe2$Jm-$ThggtU7RkTb z{K2&{zIb2)D#X-;RKN3ZTgpg`0r9pl?sQw4*Nj)RMo~~9|DM`l@psRsr=xF{!)(th9lF?D}7RrfDx@oPhk%5x>{Pv)1x zz982Zc6)M>lu?m`&&3_n#Fk>l+SE7gR3v5ShzN+)2~G)ozCb{)Z7dUsyseb|T-Ybi zx0VzDq+%3o`FN*BO{64P@m?$F&NKvbaNab-m2X)8?sZI^k&mIgiON03|CXo`m-gzb zJ*U&X1CQffE+BCoOGEEO% zigdr6BU^9%}O1&ak%g$7l?n$_wj$8gvk#7`E!Txwq zr-t~lxOYvZTXg%|zQ9$Y;@B%A0cPzh&lY9t-?`zJs;cF=zL+5&&DWISbg`Cx`2~Oe z0bIepsQ+YQlO5~nkDM9$-(s(98NMGEjb5ql&8RVKNKxyRKN)3#pQyTFv>>fKvNUEG z9rCf&CZEFY-27(fy>PdZr^w#Y%2e;cuDpnva3cve%6z_?gUc3 z`iV-LoT=EOFI#9>ut@t-HD>q(ppd1h*lvN}0rodIoi3LW&%~HZ;_UzVxnHS*IaYkIvSo@H8zQjRcm0lRJ{{wnUY?kXP{AhKR4iNnnlj2ZHE9CT|6?%2Wk9ZKW@0VemB-X8 zCO^OR<~yDO)9GxRD^ypy#OD{So3_7H+STK|Z)A(P1Av)S4^{^su^OKN>u9~Lr0srP zO=^=gk3!J{rEY<{(uj`B27Mz(NWivE>{l;_AlDq|&YOviPLn$Sz$1LQ(zp0^8Bf-Q z{;u9elBx@-+ZyY3Z`I3wfPfV4yWEeH<146H95>T>Cd{R|lC!4r$^!f8On&45Fm%bL zVSx(QT8dwOXuPSv$NFK9TdzFbE!Fhl6yA%geO20tMlb4Q3klz^((Qp7?wgPA-P$Hq z7<{MijN>rLJ&x1@NT(Fl^aZ^M)i$NDwdW=r6F#a{Z;bcY>+8xlQ|lu?SqB&y_aOVy zKHVkOKf(g$e2+if6sXAFNo1NIds7h@wKv^Sdka~$Hkvc%e=BhiU>;?T69CuQ|Jcy2 znY>1GE7KrxE6W82A_g5G2^&9B?Xe;*WBS9J>G9K!vA>t$3-h&Wv37P5%{e_4)Vo`{ z$nwZNQMC6`;G|l9d@sG8hX~rMf&n7c3UL0!9}khkMZBhRTla?UKKbl7|2f8P(EP4r z-BpgqAc3yt1xh)xbb${_iOG{ljbZ^N$Ve+HM8*hzRp1RGJ?V=y-9KwJmS71F@+q$U zEP&NSgSe{2GyMw8{aR9U`j@)OIS1C<^T65R0cRIit;7I-Ae^KgxE7gfQZ($YuhU2? zX`86&iktu348$Q1zyP>s;wH&HOF)sPtx+%$FAu%AxMtmZZeQcDm%zbGPhp$$9Xg=nEgJ6_G`JI);fw{8Vu3xq4V%P=Jgv2NeM}h^+QfJsWc3Th!fpYtw7~{Ag^^zYs>tW7%Y^pWjgL4y>nNuSQ8kpTt-6WHELM@ax#Ldz$ns%GW~JuQt%XB~ye z_yAx?!3g~XgVu6Tdh-XshSV8j4X?wG1jz`&w%koZ02u0kN&;aHAXeuYGQDsVtKR^_ zT!eW*f%v9o+|#FqGLiJm@yo61*6AR_zu^;}5f%d`zy$IT$9FO-I52FA(CBDW&QaHV zkoL5KLi}V)uZ~B>d|&Q|)q4X4rW}S1_zqgnM1&f4Czw2#3-3I0u0M^5q8ip)(x{UaY#$6Y|GJqPOJ1;wN8gW^FKbzew? z6rH@{Sgq|icDxK!+~)_(a)Mh7$~VRXd!CD&G#e=|*)CLTe)E<7CD(3>+iw z_xzYaA-xd56eCUG!yyV%puYQl;rm2B*xqIsN1)T5%z!U&X}*BG1@It7H403075Fz(+yGH! zZKYFzE(S=&#xucy5ab6ofRly7x7NRZH{yrr91g>FQFhYE<{w#tWjLQ_C`iDeE` zQ|ty$bI@P=7v6KCZKV?-Hmq-vjWI{fN^Pi1>C7Zd)@i zRVrPbI2*$>6{xtBl+L*a(W||wreYC(9_j-a6$beLMW765P81l`D7GL8t{Qtplxf_W zu)t4YX{%g#|IT2AOEDv;NP31~6Ys#6a=o5`v=u*25WrS*-Ksiv#{od~B~sU-Y@Q<) zuy6t!zbob&$!&ij-8bQNSg_RvQo-TAvq2dUXWJoVp?)oVu}2ft-xSR{jJ$vUHLnfG z@xo&S{q4_@Dw&knby zUThON-=F*O$}C6FebW^C`2i65URh5IIt6GY9~cHrNF{0T^FHMT`Ror_H!}3R(G^iu zK~fP#^?gDd%PJ=!J@PZ6a>#6h1gue?#q$--SIG%)_`^<0#Y{Ie7c3rC?eSbp38 z5C$QixwK*0qI z1Qr&s|ANFMH(7JJuE3R)gnM2Ioz1vQ%W$Pz83X|cK`;Xh9+D^Iiuf=A-i+X3jt%oN zP!QzUh+&;O&$&_rks{nZTDY=OhaI(YcJe}jmcjwarRLf(3|2Bw<#=g(Uyo#f?M>^; zoqOlc?Ds+Cr?t6ZR8-t3?Wj>zbXmvV`cm=cBsmT^dJZs~H@hLL2pWV}Cl6=-Jn!1T zin@%}o}8wAKhgK5Ja)5U@hDTqZ9`)yedkyko|+Fk`Q3U`gCj%V_>r-g?F;pYJwiJx zC$@ZR@#4sUs{pFNy!QDPIj&`nExA#RVo_eG+35Vrv2m*O+J1%kPk_m62y>GT7z=0H0?@d{9O>vTOO+4(oKd zz>s4WFoPLa2S^xE z#O)0Edou9bW9fT)=gqR@=NoP@E3H4fzLu|jO}sI_EiW5n>4VyCE@^VxKg{SfIoMB(CdNN)M1q$Nz#`F|Sn|krx%h7%iTh6_=QOG;sx_oOajdoWy0Bnbr6jRoyxBUpD zireDeAaXe}%YG}pSxaMX=%YfffL4htLgK`6bIL zvmGkgBjeh~>^X_06EXNa1!+P55frX5k34&^=0@^IBk4y?T-HfSPKs_z_GAuTW;bo@ z8E!XYgyN~603-%x6>c>n&^3PmIEH_^WPAKjgAr^%@{^p1T^=4N7AOfZgCoY}_02}d z$~yq{9CtW>vX%dUV2goy9@O6)KdIZIL#xl6!0P0n+(iSDf@F`tUY|G-bz~oEaQ*h#g{k&}On(}cn_!MVFhtl63Tz;Oz^A7yA^VI8 zvt?caYVB_}LJ^ z^rGUiaQ~W*lXA1NFoT*e#p?M4BmuXXd~k(4Imi^Zz$dBSk2zytwnBA6!>&g`KKb(* zGo&DVe<;HNuwl{8x1ejXP{8e^x`wj=Asl!n_MpIL{BGrBN^eqF}q zd*FEu`|DMnj_9*XDNHkLa9rRd!zBj_j(d6IN}B6)gD5=utW@SPle4fZpdh;R>dQ0- zJUmP=b3+ou`j@ms6Ujnt!K|dFaCvUuhG}1qdTLi4$(S%(7K$sKyLC2Jb1K`-%~-QW z=SO^0-DNi)!90K)QPlBefah?5II>8;%XY}dUbTuT2T)lE)9G^ zN<=kbmHPd~(_UBjoG+4ZUfM7$*F6aj4+g92zbWhilejlt<1a4he!`3B*~K$}zr7fQ zkV2e~`5AC~fw^IO%PFG|F$5v0#)(6LEg~m!bgW-N1+`wv+vPwEAZ9ZoJJ=f~5rq#& zEyzSK9suPBCOwo5TJ4upJW!MmU}x}!x8$PhW59Ptcr6Tbe!L9FH=c0UXv}C1csm zR0`ss(y0!#Jr{|;R{}z7tsPK~oChIMAqY4$KtMbv<01Cl0_-&QN~&c-UzwKJ8LCAj*yU2Qll{_0?ZXGzZnJJg@QF@J0Odhw}mjps+0V0W2cH zOcRjdph^$KMvnj7W?mn3iPgNu4<|Aq!2$&7Rd}?C?px_}Oz$Yh+A~y{H1iDnk$rF8 zb#!#Z`9-sthLdnvRv%DuH=t~2pTABR3qQIVg!*GfbZq+17eQQ4_=*vjZgGZLKsyE` zUn^D`Tw;PfN~`3zi>c|sr!HJqE3==^6bmF+Yvvq%7U>Zo4)kva)MUo_NIUhhsQA1< z22jF(Kk-vbJg=M(D;1%ZZCGFkpGnE&ix7Tm)UZineJHsIL>9|ce+%L)SI92uPw8C- zx+us>%xgbqnX__Vz;6JkKtXC++Q7!rmn=XVwonmW${kbi*m}YT_}?ly+I+L4RaG(r z`Nkm!!Ss#-*`^ODka_wb7OA`xY4GPAKuik}i(M)ygn_Bay zVZc9Cl6skUMFQ1iviy3a&9o!M-zD~{Qtxy6IAEhmf#PoTl{`D)HI8_8(!;m0I-?cXtTvOfs-igy_aA*7L{$}n98PSuLz6v*)++k_Nu(Oc z>oU??*v)$0sy_VCz5{R&X@9}wSTR4U7_NDt>W}b(Gs>ybPha_fGOabL6VT`>FGmfE zb-%uo1ya1Uosv|%lfTmGAuZ&(j>!@M1uLd5o@+<+S#YBQ`^_>l$$^s6KN8FX4uL9G zVj3U@z~cy#LDX4HYmPMG!&nX>X%CdkU>&i$%!j!w~YVK>z{~(1EIv;Z{#lK`;fbMB7<(kct37>Vs)JbFjKYo0kIFyl)pv(exQCh--l; z4+=hF&)fvG-Eka=b~!96IuprQ;N`QBg>!a~rJE2#(=+L#9y3$VUQgDs>ZpaAagJ>t;)MIX4o-~%%c_6Ntu z;QY#Y*cGzS*lFO&YK|qm2t?3mfthqnD9j=j&w9n>Q_M6y+NdkO2=j8pl@uq(Rd7is z0yrC`m)cTTi@7ARlrlSf2jDm3q&j;3zE}o^ByUm!r?wbVyp=NDKTP(NnCXo66D&o! zPCb7vu1XGW?WD#YCs!)nG384Fp?yOi>wbA{liW10kg>b>9?EA5%;gwO&Ha#L@=;vF#*T4O4q8sbx4=Bo$b z6-f1qA>eIZz!`lRY7tah{ay|embd6zStI%YUu1ruu+i=+xN%Zs-anoVaZM035SdBW zKa3Q{f2|GBIZpcsOL&uuJmPAU2)=Cik=Q1vV&_LAhufB|S$ne2E`T!ZOnvxdV>z1B zWTTb(^uB`l%N6Kbcvnk`4T6RQ<}hUC3$EZ06M!o!lRT7|*1cK|fSJ8awEgvoLMA|P zAgn4%rSF5s-ZH5RxO;L+GiV3GDZqZXewCF4JSLo1;2sP+a$x0+BJh~ofVg6j=&@H4 ze3AM6-pWgX{>8BmNN`=k9ztHybX=FjX4{@WWC!wbmH zdJ%-{kGO9mRa>XqU(9=*ymDirWF{>((_*-^CryqBP*>LPs-FY1sKQR6dg8PKqFBju zFjk|cH>x^rt8d-_)=L?1&hrpH*2q}a1QA+zr{Zj6Ww>!K{TUjyP_^%F+;*08=w2Wp zQxSwfK{sEDBRT;$=2vJdI?|PZUhROuqh(cl!G3RZDt0aT?I|vBHkD8Wmu1F$2JkNz z0nF78ys4`ia9~;Bjz!1tX~fgM8#5 z$M$;F{=5<2O5!$zCt6Ve+O9fq;%|<3Fl)wiCXX8?v^IXFd({ zzY0N5Pdxhp0f;v9Zb?U72r23#i9_6MfYEK+FaWA5++6Y&Te$EtN!3$eYnoEC$UOQi z2~SsZW>YMuf)pGp;tb|}DQRF0QfyDhKM3UhP1xJrE_(}H z$XiwrTvb;Ah1^?Zh!jft1i#|8a;x~HD5_fYeOB?vN`zq`+6T79WwltVR`4;0ihl+o){4pmUU@V05?>unA<(KpZ0t{5sD=*^T) z(LUhz?m_2}gUUSv!@dTH+?i6293n)@BF__z7gkW!C{2OT&sfMP>;*kavJYv<%% zJjfGWf%6=fDF*q&p`#-LJ6u0=&G`ZuY)jw{){~)qh9^zLFg7Y?Kz#%gm7=k@{IEI< z?z}c<>iyN&GG)pSY`D_K+hwz3j9HDcIpgQE2Snkh&PHIA+A~jJPwWWsWA_P;mn*9?tEzAXse%XCY`_(ukS?4E#`0uwbdLXG&q1Ik<0k z>nb?_FIK`qO@$j62r7e9Ig5_tRAxbD_4$h%N zujbx+3P?~9ig{M#8C{&fLkp^epO$2zlR9Y zd;a8tNqJ)ZA(O?`)l4rSA3bjJO7A*+91Mo*P{W4dwR7ao$vl|CPXYWK0##pqr8((^ zO96RvIz=*_bnENn4$6S|8wy>qJ&CYD>jFZO7@WztTBp(&7NjeX9HB3$feW$+5v@8n z#PC|ym1Boe@EckPy~Tjl3nvwLOXl?{2plwroV6IRaZ26_od_&kFX&3`kBP>I1}sIw z0DhrDsRG@ZC2~ID^%n7G_jL)N2gz6q3 z#Ug8E34^b$f|~|GL)K7+BMF38pQP+=knNngR+h+P|i50{`BSQYwd!`=0g`^qXU)Yxog>8JoknO ziE^C7UmFTcJL|yBS3W3TgxmrP3(Fix=2eP5ya)9K!fRA)$CSW5NablzQVPDpH?TH8 zNZ1Vd#o^n=P&s5W7WKF#GKiSF17c>ntj#g68iF*2G0{jZf*{NDG_d>-`>obit1g*a z+*9aQoglNXc5Z+Sd=A7@fS76lY6Wkg5Ci)W2sWUkJyY1{)Y`j~q;I*feOG6DV@0bU z96x<`=Yr~8T~Mp4ypy9neB$ioucFQI!0n1ArYR&^Tql+4s{%PNS=Cl|PTXh39k7>X zA$)7kVyT@#Tr+g08PrEIsABnCiqhx771mg0{YQKopC7JGzX;)ZZaZw(%k4GJa&=J= zU*}`hnf((L4P0I#oTjnDe)yg2lvk>n0hwLSQ|S4}!^xiqm(8!=dHvOhujS^lEYXd7 zp0Vv00kJm=_}>E8Wa_7&;@4WZJo7TKv_Aw~0#(z{h>^0D1p$IqF>H2OfD^-H7%#ilhc zaO+EHpspQb#NIUt?#&|nttrG|A`e9ES`!5XVj`D?iOen#&LkRH+9rNdR1?lrUJ#^JZ6C|2z=iD9&#$k13YYkS^Csz=J`Ig4qA1*D-QpiKnSX2~0%fHnw6DUfsC5nF}=!!jEco!RUcR|8jX6w#vzMa)NIrDNOS-tg`nzR{>8Gw?p z`4bFJopBBnr=Y~=;rd|J#QgD@sPy4&k3H~TnxM5y>^OuTJq0a+y?-$4LXU>5BY3>L zPlqWLKRbtxGsylCt)#JnN$HRSVy>3x$)gYp9j-M|!dEz% z0UsLfEsw1o1#WmlvwQ$Lz`fn7&xu|GHW*O)9X8w1)$wW}(7{7uE_47%1}>Z9LM^Vx zpcyTKKZ9BH1N>0Wk9p*xHz#kD0=@_&QNIf!p}3R}s<~L5>~KSetx;g(%IEmD5+b0O zF_-KlH?@BIoFMC`#(h2IIl<$I#YPG+D+!x1)sD!`zkgi5;0#4-l=ZejltI~*Pa9oQ%BCH&npConUic_VIs zWqNWG+o1QU9zqgiN3gVY(E9{~VzEU`&rP&6bO88Yipp&OAan;keug^uU}*_>P0*4( z1u3v2ULpDuN%ATLd<5?{ste^`a#<#w3i99Cgxl@Fk$0z^$YQY(T$jD{PKU*-(-u*u zmS;858<#cQ$(w7qbL;|~%Y;K8wWlA)943&M^f)mo_%z@7mAh@rLao^S3VxiJs2&{y z^1N%jweAH!R3@Hj*o*h#&8Qm^Z3ew<{35LZGrzOXw~%aNDODDAua9mKIf7H z0r&F6YqNQ-zOk7!RnuCUIGsS`>>hzn@NMa&m+)zvv&q&^Gt~AMn;=aA6`zg2Gh1LHepjk?hFo$*vox_JqmK!C&FR-cck?`6tjh zSHc^uGn=KLcC5Sxcm7us=N(Vw|G#moIJVdiWL}s>-y=jq* z>{*gB4*A$yWN+E>d*9Ue@$;YKIL>k3@B4nguIqVS*Apu=!}TAzSMieU1pdnm-uL-_RuL9HS&v;})|NTAIo zotRukjzZ&QA`v=4wHq zWam~=`&XY6_3WC~Y`o7UEn{?kp>D2r)HOmKi+lf5`WbRogk7*_yk@%MlY4g376Wx> za#sc9kZydccaZVt_NtGhbcm%MYVyXl0tM@XDqoo1`Jz)^7MJ z>vZZ6I~`p{u~O}2CV*_YFn+SpcdRXf5~kcE?SFk$`nrSv$19tBGZ6vc z_q3jvB%&Q+-QrKOlfZW;#)V_w-lm zYpr}gX>7`)-6hJ?eMZ8oCtSCo#N>F5n_E}~dS2y*{`-uzkqVA==f0Lc*tpM1i3?X( zhRDuhYHY$YOn5dHO5Wcpenl6UwWn*Y0Ts|7d~&!`5^(khLi@%%hD={N`ZJ%(<$2tE@kW@6{no&6_7P-Rbe6b|8rL>*LEUgM8BTo0dUf_Q62e zRbdyUSSFL z%OmqUC=?9K1uTQ}EURW3L%9bwP06?50EAg+qupC`EYjXpP^Q|iw_{>OB~1yb4?8mTkZ6FEx2UEKuUN($D-0NJVz^F zQ*&Fw4unb9zP}}TLNB#e*}s|>$x{y0crzI-7-6{o%m@F3dMMUGICmK z9P{E~Eocl=m%&hd1SNSS{WKzHCp!}_X$M}p74dzv?xc!*f;9CUv3@Vf%RtVouz3%} zdQGp92%0V$|G;PTo4%Zr?6QlU?{&@Y$&2UW4G6_ep+JKv#|RAp%cErA2e<%2p!7KB zn|?*F8G@qLMNy6L!p|jABK8(P;M)r<@eA8UGe4b<+e+ zb+z9P&{wXd9|!SUv|zo{d6PiNL`R)=?f7?Tz#8&lnZQ*be$-IjI6Bd^gpET{x7`wB zH^|G+gTa_{!cK0KGUl^9!@?pBfVu-4tbA%#R27>2PxC4a;(5e(x&(?wU=b8wxJ~Q+ zyQi(awpKmmDUb^_JqJPIEq4qW5ZB;`G~4G zCsk7d0b1R7hGtIM1Cg9??xVqC*V4M7$~wa3F%Qm14_EDK^^fl&N*^x2d9{on0dki6 z&{4+H=*M@?<28K~?n=bi5wMR1hS#|p?Lt*L?aO?Fftpdk(5;9sKnlFN4AYVd7r5|p|iQtchMRx+7Cgo3? zWbC7jkcXQ~OCee8T8u38NrJc1D~!RVQ<;O1yo~m*?Rq3Z+Ldls z20JRbLo;B&RhQ|ys@P4%7Y{z;;P>2p`n>A{#3w8vNJh00wW&a}8WSV0U0?{n8THNO zr86?qIsmejn(8%CMWdl|zd2F#pnpOL5p|l4A`o|Mq>e{0%*tVzw*-n7LbB*>v%HHS zR-w=_SuOjjNKeC=5iYNgA7 z;?hP)hnx%<&LKGcbCx{TuJy{TF25`FbUZUkTcXPv=*_})HX4vq@$dsT5bq!wNxvH7 zo_<`dDSur_Oc!e+C$=-qpjkE$TKjrLSGcGv@mS*D%%`2uy&zZ`udNtUEnrIm@<=b* zMNjvzW4qCeY_K?WcDF0O=HN5qpXoi8r3$5{A%F5hM=Esz)}w96Gpu%1*fJv~h|l*@ zj~S%P5Tb?h@N3w;bU8u{Z|yh{Xzlw{JBqkE)k7xk(PMG19fLqzx_iHR935$|mk)Rs zm;E|P&dS4^R`%drc_M8WT@9|SMW<{&1okBQ=_84;Wz2-%7-e%m+j6qr{Lisuh0&S8 zj^*vPLqK2;;pn)y$Ffc}nY62pT?SNVr_2Lfq3Zqlm*#a_`543#+8+jJT9LNQr#3R+ zQsC9U5a4tl4m0xX?^1FCM;Aeu+7>za;lJ`?o39^rN?+0ozAN<0?Uj*QskkGn>jv(i zxf(@=`53ZG+rC3|<3u%rA(Y!H;j^vv)9cRTOj?AEtd9 zegBAxfiOg^)QtzS#uN(4k|0_9#a+pzZ9YAQ&;rShmp-?|s$Ljn4=n`l5zh&e>f9k? znjfI&t<&$7Q~zlL*dM5BuOHE{N4OYR&|vgOOA=-}v0_}>9*6Wv^VX(A@c}C4)ks7} ziG6IWU;fax$6!kMTwkMKaVq87MBHX?lT5dhy`J1L(XIEpv=rC0fjnJpZWfQ-(X66^>2Ix5f{b!8l(4jpRTG&`w)>Jmko8r- zRnzt~(`7p^Ki@Eo3WV^VHO9Ul<_{>BwTKRG%E4e1j0vr*|F)z5^ItBuqnwsFl5a^- zvn;k&gcsXS;BmourC}oydq^RPtwUz{Bwi#YpE|M*}b9yPxMk+by6DMrt{4-22gGr zTb`HAq$!Q_=UKdk zgV=N$ggBQdnO*L%c2>DeWg;?*D9>Mg+8Jm953H>XQ#W_mq*Rr5qylkZ6qcN>hE)#_ zW9wMYr5@0wpfDY_xg(EBveK2cG$-e*A^$e%YK}2pBFg7Gw>Hsm0*%rpnAF|xVc9oY z%V<=0m^Cd>_jnSW=gY~4+e)bxbg8%gDogo5t&qo1O6bR=r4l!Bfafv8lPdN{Pog}8 z9`_kd0MHQ_fRR`s&lIIGWD<(kL$WzqE0B@yESj7sIN^{cw_~h&*2m$dtmf-}U(GN6 zanh{>i?z86VOcC8J_m?mAGCL(bnaK#kxjUI_lJa2pLKrU<9?AUm!F=oX&Tk2I6It5 z{6GuvPGm7e62iMDz3!|jtRF;$aYCq=-?HA~y7Sg{t!j;4Xe8jX)!YDCQ#o(5sY|53 zOXUE472KkQ2I@-2k-WSs-s>)d!I$9Jg_I`f-2$B3tb!3kz5HG7Zs*u>~>SW8y{coQ0q)G9QgaZwhbEhoRD3fmX11C53reLp_m1 z`y{f}s_Uus1b>^Eu^DlFkc+iB3vzRYt+Y6`6r7+9%lJ!c^38~u9i-GLP-hj&|s=>r&T13e@{ zsY9iq-ok4A{SQ*(y<`3!t>4a@4nT9J@mJ4ibjhz_QQfs)Q+rjF=r@W5*`V+7w0SCf zZI+(Fc*4g+YSI*nKrxX+MaN7&SJR0Um=J^`uJ2b}t^iT$aeGe{e)d6ImcLtGiD`59 zQO3yVXohC9=5KC;${xv+RbTxg!xy82wV&PAMK$rGAkyz42(-+R6KIfkL`uJm`D$3Z z+0`y~e_{CKLwH9|57-v%4|kp&{@7dVtjsbsHUJ@d7g9{}?#e{F%c*JIK&f%J?&B?t zSltNOmrOS!RqCM+W*#dPJpCX1Jyv|s+WMZGw`^+!0px^*7X$$fg0c5qb76umnxD(d z%bmA=kc1^AF&Q?xyt5yHAR*AcQ+ygh;xv%PU3H5~C$V;&PuF?0i>=D}E0RN$Rrb2B zio3Ot%cy;)o(ungfd4j*H3zgV2^azsTMVOG$vIgApU<$R;^LR1x!D5YgdutM70t%h zrA-q3pd@W&w#ct`m|es80VXJ}s0>O5s~T~49Qpo{V&;e2PE`a5t#Uk&Yv*Zin**ii_+MiZ>1?p$8FJSjo_vxzSmG`q_QqMR|3>2W%&B%rG*35> z%Z*d8QDPn;XpD7mcpHvFpkj}sJ<+~Uvw&ohnmI&2 z@z)e#+u>g&^?3shKkawf{j@54*tGqftp@0Y;es=Zi&F}!gY}N{Zqy(M0s=x&(la4S zEm)R3c=8r2RTFz4B5vZf|5;>jRrSRxXuSKF^iKH3NM-8pz!}D|gn9ajM*sWr`?1jn zU1mr7k9@8ETUZxXN<09CjO*1(j~YRAMjrzLBn8GGh7E2v05-wvnWr&fz!CFY{|I## zfb2ezN%UmY2!JHB4h6^_q%L<0;6jC`Ik1BXui)@0iKr)k7a}VJ$5<`&-hx(tE68QZ zfRzbL`&tGe>?BT!M;{T%@{@N)IK|ZKsM!e?lwLqHbUrqpe z`HL5YE)ReFl>Q;Jf6El;8{YmUjhHlV + +The signal chain in Strudel is as follows: + +- An sound-generating event is triggered by a pattern + - This has a start time and a duration, which is usually +controlled by the note length and ADSR parameters + - If we exceed the max polyphony, old sounds begin to die off + - Muted sounds (one whose `s` value is `-`, `~`, or `_`) are skipped +- A sound is produced (through, say, a sample or an oscillator) + - This is where detune-based effects (like `detune`, `penv`, etc. occur) +- The following will only occur if their respective parameters are turned on. Note that all of these are +_single use_ effects, meaning that multiple occurrences of them in a pattern will simply override the values +(i.e. you can't (currently) do `s("bd").lpf(100).distort(2).lpf(800)` to lowpass, distort, and then lowpass +again) + - Phase vocoder (`stretch`) + - Gain is applied (`gain`) + - This is where the main (volume) ADSR happens + - A lowpass filter (`lpf`) + - A highpass filter (`hpf`) + - A bandpass filter (`bandpass`) + - A vowel filter (`vowel`) + - Sample rate reduction (`coarse`) + - Bit crushing (`crush`) + - Waveshape distortion (`shape`) + - Normal distortion (`distort`) + - Tremolo (`tremolo`) + - Compressor (`compressor`) + - Panning (`pan`) + - Phaser (`phaser`) + - Postgain (`post`) +- The sound is then split into multiple destinations + - Main output (amount controlled by `dry` parameter) + - This is where the `duck` function will apply sidechain + - Analyzer (used for tooling like `scope` and `spectrum`) + - Per-orbit effects (see the section below) + - Delay send (amount controlled by `delay` parameter) + - Reverb send (amount controlled by `delay` parameter) + +## Orbits + +Orbits are the way in which outputs are handled in Strudel. If you are listening in +normal circumstances, you will just hear all of them mixed down to stereo at the output. However you can also +use routers like Blackhole 16 to retrieve and record all of the split channels in a DAW for later processing. +By default all orbits are mono, however with the "Multi Channel Orbits" setting (under settings at the right) +you can use them as 2 channel stereo outs. + +The default orbit is `1` and it is set with `orbit`. You may send a sound to multiple orbits via mininotation + + + +but please be careful as this will create three copies of the sound behind the scenes, meaning that if they are mixed +down to a single output, they will triple the volume. We've reduced the gain here to save your ears. + +⚠️ There is only one delay and reverb per orbit, so please be aware that if you attempt to change the parameters on two +patterns pointing to the same orbit, it can lead to unpredictable results. Compare, for example, this pretty pluck +with a large reverb: + + + +versus the same pluck with a muted kick drum coming in and overwriting the `roomsize` value (occasionally) + + +This is due to them sharing the same orbit (the default of `1`). It can be corrected simply by updating the orbits to be +distinct: + + + +## Continuous changes + +As all of the above is triggered by a _sound occurring_, it is often the case that parameters may not be +modified continuously in time. For example, + + + +Will not produce a continually LFO'd low-pass filter due to the `tri` only being sample every time the note hits +(in this case the default of once per cycle). You can fake it by introducing more sound-generating events, e.g.: + + + +Some parameters _do_ induce continuous variations in time, though: +* The ADSR curve (governed by `attack`, `sustain`, `decay`, `release`) +* The pitch envelope curve (governed by `penv` and its associated ADSR) +* The FM curve (`fmenv`) +* The filter envelopes (`lpenv`, `hpenv`, `bpenv`) +* Tremolo +* Phaser + # Filters Filters are an essential building block of [subtractive synthesis](https://en.wikipedia.org/wiki/Subtractive_synthesis). From ce7cff2c3b6a25994e595b96849cd289474fb472 Mon Sep 17 00:00:00 2001 From: Aria Date: Tue, 19 Aug 2025 11:26:25 -0500 Subject: [PATCH 070/335] Clean up wording on orbit routing --- website/src/pages/learn/effects.mdx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/website/src/pages/learn/effects.mdx b/website/src/pages/learn/effects.mdx index 5e41eb92d..70218b78f 100644 --- a/website/src/pages/learn/effects.mdx +++ b/website/src/pages/learn/effects.mdx @@ -54,11 +54,9 @@ again) ## Orbits -Orbits are the way in which outputs are handled in Strudel. If you are listening in -normal circumstances, you will just hear all of them mixed down to stereo at the output. However you can also -use routers like Blackhole 16 to retrieve and record all of the split channels in a DAW for later processing. -By default all orbits are mono, however with the "Multi Channel Orbits" setting (under settings at the right) -you can use them as 2 channel stereo outs. +Orbits are the way in which outputs are handled in Strudel. By default all orbits are mixed down to channels `1` and `2` in stereo, however with the "Multi Channel Orbits" setting +(under settings at the right) you can use them as individual 2 channel stereo outs (orbit `i` will be mapped to +to channels `2i` and `2i + 1`). You can then use routers like Blackhole 16 to retrieve and record all of the channels in a DAW for later processing. The default orbit is `1` and it is set with `orbit`. You may send a sound to multiple orbits via mininotation From 59c8d707149ceeddda26aaa69bbdf7f7a42a4f40 Mon Sep 17 00:00:00 2001 From: Aria Date: Tue, 19 Aug 2025 11:27:56 -0500 Subject: [PATCH 071/335] Code format --- website/src/pages/learn/effects.mdx | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/website/src/pages/learn/effects.mdx b/website/src/pages/learn/effects.mdx index 70218b78f..4194757ef 100644 --- a/website/src/pages/learn/effects.mdx +++ b/website/src/pages/learn/effects.mdx @@ -19,15 +19,15 @@ The signal chain in Strudel is as follows: - An sound-generating event is triggered by a pattern - This has a start time and a duration, which is usually -controlled by the note length and ADSR parameters + controlled by the note length and ADSR parameters - If we exceed the max polyphony, old sounds begin to die off - Muted sounds (one whose `s` value is `-`, `~`, or `_`) are skipped - A sound is produced (through, say, a sample or an oscillator) - This is where detune-based effects (like `detune`, `penv`, etc. occur) - The following will only occur if their respective parameters are turned on. Note that all of these are -_single use_ effects, meaning that multiple occurrences of them in a pattern will simply override the values -(i.e. you can't (currently) do `s("bd").lpf(100).distort(2).lpf(800)` to lowpass, distort, and then lowpass -again) + _single use_ effects, meaning that multiple occurrences of them in a pattern will simply override the values + (i.e. you can't (currently) do `s("bd").lpf(100).distort(2).lpf(800)` to lowpass, distort, and then lowpass + again) - Phase vocoder (`stretch`) - Gain is applied (`gain`) - This is where the main (volume) ADSR happens @@ -77,13 +77,14 @@ $: s("triangle*4").decay(0.5).n(irand(12)).scale('C minor') /> versus the same pluck with a muted kick drum coming in and overwriting the `roomsize` value (occasionally) + This is due to them sharing the same orbit (the default of `1`). It can be corrected simply by updating the orbits to be @@ -95,7 +96,7 @@ distinct: $: s("triangle*4").decay(0.5).n(irand(12)).scale('C minor') .room(1).roomsize(10).orbit(2) -$: s("bd*4").room(0.01).roomsize(0.01).postgain(0)`} +$: s("bd\*4").room(0.01).roomsize(0.01).postgain(0)`} /> ## Continuous changes @@ -115,17 +116,17 @@ Will not produce a continually LFO'd low-pass filter due to the `tri` only being Some parameters _do_ induce continuous variations in time, though: -* The ADSR curve (governed by `attack`, `sustain`, `decay`, `release`) -* The pitch envelope curve (governed by `penv` and its associated ADSR) -* The FM curve (`fmenv`) -* The filter envelopes (`lpenv`, `hpenv`, `bpenv`) -* Tremolo -* Phaser + +- The ADSR curve (governed by `attack`, `sustain`, `decay`, `release`) +- The pitch envelope curve (governed by `penv` and its associated ADSR) +- The FM curve (`fmenv`) +- The filter envelopes (`lpenv`, `hpenv`, `bpenv`) +- Tremolo +- Phaser # Filters From 34e8a574726fa01e036a8147ddc729d090003dfb Mon Sep 17 00:00:00 2001 From: Aria Date: Tue, 19 Aug 2025 11:32:07 -0500 Subject: [PATCH 072/335] Typos grammar etc --- website/src/pages/learn/effects.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/src/pages/learn/effects.mdx b/website/src/pages/learn/effects.mdx index 4194757ef..268d7071a 100644 --- a/website/src/pages/learn/effects.mdx +++ b/website/src/pages/learn/effects.mdx @@ -87,7 +87,7 @@ $: s("triangle*4").decay(0.5).n(irand(12)).scale('C minor') $: s("bd\*4").room(0.01).roomsize(0.01).postgain(0)`} /> -This is due to them sharing the same orbit (the default of `1`). It can be corrected simply by updating the orbits to be +This is due to them sharing the same orbit: the default of `1`. It can be corrected simply by updating the orbits to be distinct: -Will not produce a continually LFO'd low-pass filter due to the `tri` only being sample every time the note hits +Will not produce a continually LFO'd low-pass filter due to the `tri` only being sampled every time the note hits (in this case the default of once per cycle). You can fake it by introducing more sound-generating events, e.g.: Date: Tue, 19 Aug 2025 16:06:18 -0500 Subject: [PATCH 073/335] Mention order of effects --- website/src/pages/learn/effects.mdx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/website/src/pages/learn/effects.mdx b/website/src/pages/learn/effects.mdx index 268d7071a..7a57b898f 100644 --- a/website/src/pages/learn/effects.mdx +++ b/website/src/pages/learn/effects.mdx @@ -24,9 +24,9 @@ The signal chain in Strudel is as follows: - Muted sounds (one whose `s` value is `-`, `~`, or `_`) are skipped - A sound is produced (through, say, a sample or an oscillator) - This is where detune-based effects (like `detune`, `penv`, etc. occur) -- The following will only occur if their respective parameters are turned on. Note that all of these are - _single use_ effects, meaning that multiple occurrences of them in a pattern will simply override the values - (i.e. you can't (currently) do `s("bd").lpf(100).distort(2).lpf(800)` to lowpass, distort, and then lowpass +- The following will occur _in order_ and only if they've been called in the pattern. Note that all of these are + single use effects, meaning that multiple occurrences of them in a pattern will simply override the values + (e.g. you can't do `s("bd").lpf(100).distort(2).lpf(800)` to lowpass, distort, and then lowpass again) - Phase vocoder (`stretch`) - Gain is applied (`gain`) @@ -127,6 +127,7 @@ Some parameters _do_ induce continuous variations in time, though: - The filter envelopes (`lpenv`, `hpenv`, `bpenv`) - Tremolo - Phaser +- Ducking (`duckorbit`) # Filters From 4f15d681b0cdccf1410c1107567c1f194d08e130 Mon Sep 17 00:00:00 2001 From: Aria Date: Thu, 21 Aug 2025 13:12:36 -0500 Subject: [PATCH 074/335] Add release parameter, avoid clicks, some cleanup --- packages/core/controls.mjs | 56 ++++++++++++-------- packages/superdough/superdough.mjs | 84 ++++++++++++++++++------------ 2 files changed, 87 insertions(+), 53 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index e6181d453..4d6f8d8b7 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -141,8 +141,8 @@ export const { note } = registerControl(['note', 'n']); */ export const { accelerate } = registerControl('accelerate'); /** - * * Sets the velocity from 0 to 1. Is multiplied together with gain. + * * @name velocity * @example * s("hh*8") @@ -254,7 +254,7 @@ export const { fmenv } = registerControl('fmenv'); export const { fmattack } = registerControl('fmattack'); /** - * waveform of the fm modulator + * Waveform of the fm modulator * * @name fmwave * @param {number | Pattern} wave waveform @@ -377,7 +377,7 @@ export const { bandf, bpf, bp } = registerControl(['bandf', 'bandq', 'bpenv'], ' // ['bpq'], export const { bandq, bpq } = registerControl('bandq', 'bpq'); /** - * a pattern of numbers from 0 to 1. Skips the beginning of each sample, e.g. `0.25` to cut off the first quarter from each sample. + * A pattern of numbers from 0 to 1. Skips the beginning of each sample, e.g. `0.25` to cut off the first quarter from each sample. * * @memberof Pattern * @name begin @@ -438,7 +438,7 @@ export const { loopBegin, loopb } = registerControl('loopBegin', 'loopb'); */ export const { loopEnd, loope } = registerControl('loopEnd', 'loope'); /** - * bit crusher effect. + * Bit crusher effect. * * @name crush * @param {number | Pattern} depth between 1 (for drastic reduction in bit-depth) to 16 (for barely no reduction). @@ -449,7 +449,7 @@ export const { loopEnd, loope } = registerControl('loopEnd', 'loope'); // ['clhatdecay'], export const { crush } = registerControl('crush'); /** - * fake-resampling for lowering the sample rate. Caution: This effect seems to only work in chromium based browsers + * Fake-resampling for lowering the sample rate. Caution: This effect seems to only work in chromium based browsers * * @name coarse * @param {number | Pattern} factor 1 for original 2 for half, 3 for a third and so on. @@ -460,7 +460,7 @@ export const { crush } = registerControl('crush'); export const { coarse } = registerControl('coarse'); /** - * modulate the amplitude of a sound with a continuous waveform + * Modulate the amplitude of a sound with a continuous waveform * * @name tremolo * @synonyms trem @@ -472,7 +472,7 @@ export const { coarse } = registerControl('coarse'); export const { tremolo } = registerControl(['tremolo', 'tremolodepth', 'tremoloskew', 'tremolophase'], 'trem'); /** - * modulate the amplitude of a sound with a continuous waveform + * Modulate the amplitude of a sound with a continuous waveform * * @name tremolosync * @synonyms tremsync @@ -487,7 +487,7 @@ export const { tremolosync } = registerControl( ); /** - * depth of amplitude modulation + * Depth of amplitude modulation * * @name tremolodepth * @synonyms tremdepth @@ -498,7 +498,7 @@ export const { tremolosync } = registerControl( */ export const { tremolodepth } = registerControl('tremolodepth', 'tremdepth'); /** - * alter the shape of the modulation waveform + * Alter the shape of the modulation waveform * * @name tremoloskew * @synonyms tremskew @@ -510,7 +510,7 @@ export const { tremolodepth } = registerControl('tremolodepth', 'tremdepth'); export const { tremoloskew } = registerControl('tremoloskew', 'tremskew'); /** - * alter the phase of the modulation waveform + * Alter the phase of the modulation waveform * * @name tremolophase * @synonyms tremphase @@ -522,7 +522,7 @@ export const { tremoloskew } = registerControl('tremoloskew', 'tremskew'); export const { tremolophase } = registerControl('tremolophase', 'tremphase'); /** - * shape of amplitude modulation + * Shape of amplitude modulation * * @name tremoloshape * @param {number | Pattern} shape tri | square | sine | saw | ramp @@ -532,7 +532,7 @@ export const { tremolophase } = registerControl('tremolophase', 'tremphase'); */ export const { tremoloshape } = registerControl('tremoloshape', 'tremshape'); /** - * filter overdrive for supported filter types + * Filter overdrive for supported filter types * * @name drive * @param {number | Pattern} amount @@ -542,7 +542,7 @@ export const { tremoloshape } = registerControl('tremoloshape', 'tremshape'); */ /** - * modulate the amplitude of an orbit to create a "sidechain" like effect + * Modulate the amplitude of an orbit to create a "sidechain" like effect * * @name duckorbit * @param {number | Pattern} orbit target orbit @@ -554,7 +554,7 @@ export const { tremoloshape } = registerControl('tremoloshape', 'tremshape'); export const { duck } = registerControl('duckorbit', 'duck'); /** - * the amount of ducking applied to target orbit + * The amount of ducking applied to target orbit * * @name duckdepth * @param {number | Pattern} depth depth of modulation from 0 to 1 @@ -566,16 +566,30 @@ export const { duck } = registerControl('duckorbit', 'duck'); export const { duckdepth } = registerControl('duckdepth'); /** - * the attack time of the duck effect + * The attack time of the duck effect. Can be used to prevent clicking or for creative rhythmic effects * * @name duckattack * @param {number | Pattern} time * @example - * stack( n(run(8)).scale("c:minor").s("sawtooth").delay(.7).orbit(2), s("bd:4!4").beat("0,4,8,11,14",16).duckorbit(2).duckattack("<0.2 0 0.4>").duckdepth(1)) + * sound: n(run(8)).scale("c:minor").s("sawtooth").lpf(200).delay(.7).orbit(2) + * duckerWithClick: s("bd*4").duckorbit(2).duckattack(0).postgain(0) + * _duckerWithoutClick: s("bd*4").duckorbit(2).duckattack(0.003).postgain(0) * */ export const { duckattack } = registerControl('duckattack', 'duckatt'); +/** + * The release time of the duck effect + * + * @name duckrelease + * @param {number | Pattern} time + * @example + * sound: n(run(8)).scale("c:minor").s("sawtooth").delay(.7).orbit(2) + * ducker: s("bd:4!4").beat("0,4,8,11,14",16).duckorbit(2).duckrelease("<0.2 0 0.4>").duckdepth(1) + * + */ +export const { duckrelease } = registerControl('duckrelease', 'duckrelease'); + export const { drive } = registerControl('drive'); /** @@ -618,7 +632,7 @@ export const { byteBeatStartTime, bbst } = registerControl('byteBeatStartTime', export const { channels, ch } = registerControl('channels', 'ch'); /** - * controls the pulsewidth of the pulse oscillator + * Controls the pulsewidth of the pulse oscillator * * @name pw * @param {number | Pattern} pulsewidth @@ -630,7 +644,7 @@ export const { channels, ch } = registerControl('channels', 'ch'); export const { pw } = registerControl(['pw', 'pwrate', 'pwsweep']); /** - * controls the lfo rate for the pulsewidth of the pulse oscillator + * Controls the lfo rate for the pulsewidth of the pulse oscillator * * @name pwrate * @param {number | Pattern} rate @@ -642,7 +656,7 @@ export const { pw } = registerControl(['pw', 'pwrate', 'pwsweep']); export const { pwrate } = registerControl('pwrate'); /** - * controls the lfo sweep for the pulsewidth of the pulse oscillator + * Controls the lfo sweep for the pulsewidth of the pulse oscillator * * @name pwsweep * @param {number | Pattern} sweep @@ -683,7 +697,7 @@ export const { phaserrate, ph, phaser } = registerControl( export const { phasersweep, phs } = registerControl('phasersweep', 'phs'); /** - * The center frequency of the phaser in HZ. Defaults to 1000 + * The center frequency of the phaser in HZ. Defaults to 1000 * * @name phasercenter * @synonyms phc @@ -711,7 +725,7 @@ export const { phasercenter, phc } = registerControl('phasercenter', 'phc'); export const { phaserdepth, phd, phasdp } = registerControl('phaserdepth', 'phd', 'phasdp'); /** - * choose the channel the pattern is sent to in superdirt + * Choose the channel the pattern is sent to in superdirt * * @name channel * @param {number | Pattern} channel channel number diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index eb1466d91..a75727240 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -331,18 +331,19 @@ function getDelay(orbit, delaytime, delayfeedback, t, channels) { //logger(`delayfeedback was clamped to ${maxfeedback} to save your ears`); } delayfeedback = clamp(delayfeedback, 0, 0.98); - if (!orbits[orbit].delayNode) { + let delayNode = orbits[orbit].delayNode; + if (delayNode === undefined) { const ac = getAudioContext(); const dly = ac.createFeedbackDelay(1, delaytime, delayfeedback); dly.start?.(t); // for some reason, this throws when audion extension is installed.. connectToOrbit(dly, orbit); - orbits[orbit].delayNode = dly; + delayNode = dly; } - orbits[orbit].delayNode.delayTime.value !== delaytime && - orbits[orbit].delayNode.delayTime.setValueAtTime(delaytime, t); - orbits[orbit].delayNode.feedback.value !== delayfeedback && - orbits[orbit].delayNode.feedback.setValueAtTime(delayfeedback, t); - return orbits[orbit].delayNode; + delayNode.delayTime.value !== delaytime && + delayNode.delayTime.setValueAtTime(delaytime, t); + delayNode.feedback.value !== delayfeedback && + delayNode.feedback.setValueAtTime(delayfeedback, t); + return delayNode; } export function getLfo(audioContext, begin, end, properties = {}) { @@ -398,42 +399,59 @@ function getFilterType(ftype) { return typeof ftype === 'number' ? filterTypes[Math.floor(_mod(ftype, filterTypes.length))] : ftype; } -//type orbit { -// gain: number, -// reverbNode: reverbNode -// delayNode: delayNode -//} +// type orbit { +// output: GainNode, +// reverbNode: ConvolverNode +// delayNode: FeedbackDelayNode +// } let orbits = {}; function connectToOrbit(node, orbit) { if (orbits[orbit] == null) { errorLogger(new Error('target orbit does not exist'), 'superdough'); } - node.connect(orbits[orbit].gain); + node.connect(orbits[orbit].output); } function setOrbit(audioContext, orbit, channels) { if (orbits[orbit] == null) { orbits[orbit] = { - gain: new GainNode(audioContext, { gain: 1 }), + // Setup output node through which all audio filters prior to hitting + // the destination (and thus allows for global volume automation) + output: new GainNode(audioContext, { gain: 1 }), }; - connectToDestination(orbits[orbit].gain, channels); + connectToDestination(orbits[orbit].output, channels); } } -function duckOrbit(audioContext, targetOrbit, t, attacktime = 0.1, duckdepth = 1) { - const targetArr = [targetOrbit].flat(); - targetArr.forEach((target) => { +function duckOrbit(audioContext, targetOrbit, t, attacktime = 0.003, releasetime = 0.1, duckdepth = 1) { + const targetArr = [targetOrbit].flat(); + const attackArr = [attacktime].flat(); + const releaseArr = [releasetime].flat(); + const depthArr = [duckdepth].flat(); + + targetArr.forEach((target, idx) => { if (orbits[target] == null) { errorLogger(new Error(`duck target orbit ${target} does not exist`), 'superdough'); return; } + const attack = attackArr[idx] ?? attackArr[0]; + const release = Math.max(releaseArr[idx] ?? releaseArr[0], 0.002); + const depth = depthArr[idx] ?? depthArr[0]; + const gainParam = orbits[target].output.gain; webAudioTimeout( audioContext, () => { - orbits[target].gain.gain.cancelScheduledValues(t); - const currVal = orbits[target].gain.gain.value; - orbits[target].gain.gain.linearRampToValueAtTime(clamp(1 - Math.pow(duckdepth, 0.5), 0.01, currVal), t); - orbits[target].gain.gain.exponentialRampToValueAtTime(1, t + Math.max(0.002, attacktime)); + gainParam.cancelScheduledValues(t); + const currVal = gainParam.value; + const duckedVal = clamp(1 - Math.sqrt(depth), 0.01, currVal); + + // Guarantees the value is set to currVal at time t. This in conjunction with + // cancelScheduledValues above emulates cancelAndHoldAtTime on browsers which lack + // that method + gainParam.setValueAtTime(currVal, t); + + gainParam.exponentialRampToValueAtTime(duckedVal, t + attack); + gainParam.exponentialRampToValueAtTime(1, t + attack + release); }, 0, t - 0.01, @@ -444,27 +462,28 @@ function duckOrbit(audioContext, targetOrbit, t, attacktime = 0.1, duckdepth = 1 let hasChanged = (now, before) => now !== undefined && now !== before; function getReverb(orbit, duration, fade, lp, dim, ir) { // If no reverb has been created for a given orbit, create one - if (!orbits[orbit].reverbNode) { + let reverbNode = orbits[orbit].reverbNode; + if (reverbNode === undefined) { const ac = getAudioContext(); const reverb = ac.createReverb(duration, fade, lp, dim, ir); connectToOrbit(reverb, orbit); - orbits[orbit].reverbNode = reverb; + reverbNode = reverb; } if ( - hasChanged(duration, orbits[orbit].reverbNode.duration) || - hasChanged(fade, orbits[orbit].reverbNode.fade) || - hasChanged(lp, orbits[orbit].reverbNode.lp) || - hasChanged(dim, orbits[orbit].reverbNode.dim) || - orbits[orbit].reverbNode.ir !== ir + hasChanged(duration, reverbNode.duration) || + hasChanged(fade, reverbNode.fade) || + hasChanged(lp, reverbNode.lp) || + hasChanged(dim, reverbNode.dim) || + reverbNode.ir !== ir ) { // only regenerate when something has changed // avoids endless regeneration on things like // stack(s("a"), s("b").rsize(8)).room(.5) // this only works when args may stay undefined until here // setting default values breaks this - orbits[orbit].reverbNode.generate(duration, fade, lp, dim, ir); + reverbNode.generate(duration, fade, lp, dim, ir); } - return orbits[orbit].reverbNode; + return reverbNode; } export let analysers = {}, @@ -562,6 +581,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) density = getDefaultValue('density'), duckorbit, duckattack, + duckrelease, duckdepth, // filters fanchor = getDefaultValue('fanchor'), @@ -640,7 +660,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) setOrbit(ac, orbit, channels, t, cycle, cps); if (duckorbit != null) { - duckOrbit(ac, duckorbit, t, duckattack, duckdepth); + duckOrbit(ac, duckorbit, t, duckattack, duckrelease, duckdepth); } gain = applyGainCurve(nanFallback(gain, 1)); From bf5d9917ab8366e2d82289945405cc3721b448f6 Mon Sep 17 00:00:00 2001 From: Aria Date: Thu, 21 Aug 2025 13:20:12 -0500 Subject: [PATCH 075/335] Codeformat and examples --- packages/codemirror/autocomplete.mjs | 2 +- packages/superdough/superdough.mjs | 6 +-- test/__snapshots__/examples.test.mjs.snap | 57 ----------------------- website/src/pages/learn/samples.mdx | 2 +- website/src/repl/Repl.css | 1 - 5 files changed, 4 insertions(+), 64 deletions(-) diff --git a/packages/codemirror/autocomplete.mjs b/packages/codemirror/autocomplete.mjs index d3091d874..c0845895e 100644 --- a/packages/codemirror/autocomplete.mjs +++ b/packages/codemirror/autocomplete.mjs @@ -74,7 +74,7 @@ const hasExcludedTags = (doc) => const jsdocCompletions = jsdoc.docs .filter((doc) => isValidDoc(doc) && !hasExcludedTags(doc)) - // https://codemirror.net/docs/ref/#autocomplete.Completion + // https://codemirror.net/docs/ref/#autocomplete.Completion .map((doc) => ({ label: getDocLabel(doc), // detail: 'xxx', // An optional short piece of information to show (with a different style) after the label. diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index a75727240..b8975a852 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -339,10 +339,8 @@ function getDelay(orbit, delaytime, delayfeedback, t, channels) { connectToOrbit(dly, orbit); delayNode = dly; } - delayNode.delayTime.value !== delaytime && - delayNode.delayTime.setValueAtTime(delaytime, t); - delayNode.feedback.value !== delayfeedback && - delayNode.feedback.setValueAtTime(delayfeedback, t); + delayNode.delayTime.value !== delaytime && delayNode.delayTime.setValueAtTime(delaytime, t); + delayNode.feedback.value !== delayfeedback && delayNode.feedback.setValueAtTime(delayfeedback, t); return delayNode; } diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index 398749359..6002fa849 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -3036,63 +3036,6 @@ exports[`runs examples > example "dry" example index 0 1`] = ` ] `; -exports[`runs examples > example "duckattack" example index 0 1`] = ` -[ - "[ 0/1 → 1/16 | s:bd n:4 duckorbit:2 duckattack:0.2 duckdepth:1 ]", - "[ 0/1 → 1/8 | note:C3 s:sawtooth delay:0.7 orbit:2 ]", - "[ 1/8 → 1/4 | note:D3 s:sawtooth delay:0.7 orbit:2 ]", - "[ 1/4 → 5/16 | s:bd n:4 duckorbit:2 duckattack:0.2 duckdepth:1 ]", - "[ 1/4 → 3/8 | note:Eb3 s:sawtooth delay:0.7 orbit:2 ]", - "[ 3/8 → 1/2 | note:F3 s:sawtooth delay:0.7 orbit:2 ]", - "[ 1/2 → 9/16 | s:bd n:4 duckorbit:2 duckattack:0.2 duckdepth:1 ]", - "[ 1/2 → 5/8 | note:G3 s:sawtooth delay:0.7 orbit:2 ]", - "[ 5/8 → 3/4 | note:Ab3 s:sawtooth delay:0.7 orbit:2 ]", - "[ 11/16 → 3/4 | s:bd n:4 duckorbit:2 duckattack:0.2 duckdepth:1 ]", - "[ 3/4 → 7/8 | note:Bb3 s:sawtooth delay:0.7 orbit:2 ]", - "[ 7/8 → 15/16 | s:bd n:4 duckorbit:2 duckattack:0.2 duckdepth:1 ]", - "[ 7/8 → 1/1 | note:C4 s:sawtooth delay:0.7 orbit:2 ]", - "[ 1/1 → 17/16 | s:bd n:4 duckorbit:2 duckattack:0 duckdepth:1 ]", - "[ 1/1 → 9/8 | note:C3 s:sawtooth delay:0.7 orbit:2 ]", - "[ 9/8 → 5/4 | note:D3 s:sawtooth delay:0.7 orbit:2 ]", - "[ 5/4 → 21/16 | s:bd n:4 duckorbit:2 duckattack:0 duckdepth:1 ]", - "[ 5/4 → 11/8 | note:Eb3 s:sawtooth delay:0.7 orbit:2 ]", - "[ 11/8 → 3/2 | note:F3 s:sawtooth delay:0.7 orbit:2 ]", - "[ 3/2 → 25/16 | s:bd n:4 duckorbit:2 duckattack:0 duckdepth:1 ]", - "[ 3/2 → 13/8 | note:G3 s:sawtooth delay:0.7 orbit:2 ]", - "[ 13/8 → 7/4 | note:Ab3 s:sawtooth delay:0.7 orbit:2 ]", - "[ 27/16 → 7/4 | s:bd n:4 duckorbit:2 duckattack:0 duckdepth:1 ]", - "[ 7/4 → 15/8 | note:Bb3 s:sawtooth delay:0.7 orbit:2 ]", - "[ 15/8 → 31/16 | s:bd n:4 duckorbit:2 duckattack:0 duckdepth:1 ]", - "[ 15/8 → 2/1 | note:C4 s:sawtooth delay:0.7 orbit:2 ]", - "[ 2/1 → 33/16 | s:bd n:4 duckorbit:2 duckattack:0.4 duckdepth:1 ]", - "[ 2/1 → 17/8 | note:C3 s:sawtooth delay:0.7 orbit:2 ]", - "[ 17/8 → 9/4 | note:D3 s:sawtooth delay:0.7 orbit:2 ]", - "[ 9/4 → 37/16 | s:bd n:4 duckorbit:2 duckattack:0.4 duckdepth:1 ]", - "[ 9/4 → 19/8 | note:Eb3 s:sawtooth delay:0.7 orbit:2 ]", - "[ 19/8 → 5/2 | note:F3 s:sawtooth delay:0.7 orbit:2 ]", - "[ 5/2 → 41/16 | s:bd n:4 duckorbit:2 duckattack:0.4 duckdepth:1 ]", - "[ 5/2 → 21/8 | note:G3 s:sawtooth delay:0.7 orbit:2 ]", - "[ 21/8 → 11/4 | note:Ab3 s:sawtooth delay:0.7 orbit:2 ]", - "[ 43/16 → 11/4 | s:bd n:4 duckorbit:2 duckattack:0.4 duckdepth:1 ]", - "[ 11/4 → 23/8 | note:Bb3 s:sawtooth delay:0.7 orbit:2 ]", - "[ 23/8 → 47/16 | s:bd n:4 duckorbit:2 duckattack:0.4 duckdepth:1 ]", - "[ 23/8 → 3/1 | note:C4 s:sawtooth delay:0.7 orbit:2 ]", - "[ 3/1 → 49/16 | s:bd n:4 duckorbit:2 duckattack:0.2 duckdepth:1 ]", - "[ 3/1 → 25/8 | note:C3 s:sawtooth delay:0.7 orbit:2 ]", - "[ 25/8 → 13/4 | note:D3 s:sawtooth delay:0.7 orbit:2 ]", - "[ 13/4 → 53/16 | s:bd n:4 duckorbit:2 duckattack:0.2 duckdepth:1 ]", - "[ 13/4 → 27/8 | note:Eb3 s:sawtooth delay:0.7 orbit:2 ]", - "[ 27/8 → 7/2 | note:F3 s:sawtooth delay:0.7 orbit:2 ]", - "[ 7/2 → 57/16 | s:bd n:4 duckorbit:2 duckattack:0.2 duckdepth:1 ]", - "[ 7/2 → 29/8 | note:G3 s:sawtooth delay:0.7 orbit:2 ]", - "[ 29/8 → 15/4 | note:Ab3 s:sawtooth delay:0.7 orbit:2 ]", - "[ 59/16 → 15/4 | s:bd n:4 duckorbit:2 duckattack:0.2 duckdepth:1 ]", - "[ 15/4 → 31/8 | note:Bb3 s:sawtooth delay:0.7 orbit:2 ]", - "[ 31/8 → 63/16 | s:bd n:4 duckorbit:2 duckattack:0.2 duckdepth:1 ]", - "[ 31/8 → 4/1 | note:C4 s:sawtooth delay:0.7 orbit:2 ]", -] -`; - exports[`runs examples > example "duckdepth" example index 0 1`] = ` [ "[ 0/1 → 1/16 | s:bd n:4 duckorbit:2 duckattack:0.2 duckdepth:1 ]", diff --git a/website/src/pages/learn/samples.mdx b/website/src/pages/learn/samples.mdx index 475319748..0deb60704 100644 --- a/website/src/pages/learn/samples.mdx +++ b/website/src/pages/learn/samples.mdx @@ -363,7 +363,7 @@ Sampler effects are functions that can be used to change the behaviour of sample ### scrub - +{' '} ### speed diff --git a/website/src/repl/Repl.css b/website/src/repl/Repl.css index 62e7dcf24..b8443081f 100644 --- a/website/src/repl/Repl.css +++ b/website/src/repl/Repl.css @@ -198,5 +198,4 @@ } .autocomplete-info-tooltip::-webkit-scrollbar-thumb:hover { - } From 9a9fe83f9c341d5689475854c78de7ace8043d0a Mon Sep 17 00:00:00 2001 From: Aria Date: Thu, 21 Aug 2025 14:13:01 -0500 Subject: [PATCH 076/335] Example tests --- test/__snapshots__/examples.test.mjs.snap | 46 +++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index 6002fa849..85079269e 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -3036,6 +3036,27 @@ exports[`runs examples > example "dry" example index 0 1`] = ` ] `; +exports[`runs examples > example "duckattack" example index 0 1`] = ` +[ + "[ 0/1 → 1/4 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", + "[ 1/4 → 1/2 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", + "[ 1/2 → 3/4 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", + "[ 3/4 → 1/1 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", + "[ 1/1 → 5/4 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", + "[ 5/4 → 3/2 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", + "[ 3/2 → 7/4 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", + "[ 7/4 → 2/1 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", + "[ 2/1 → 9/4 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", + "[ 9/4 → 5/2 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", + "[ 5/2 → 11/4 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", + "[ 11/4 → 3/1 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", + "[ 3/1 → 13/4 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", + "[ 13/4 → 7/2 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", + "[ 7/2 → 15/4 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", + "[ 15/4 → 4/1 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", +] +`; + exports[`runs examples > example "duckdepth" example index 0 1`] = ` [ "[ 0/1 → 1/16 | s:bd n:4 duckorbit:2 duckattack:0.2 duckdepth:1 ]", @@ -3118,6 +3139,31 @@ exports[`runs examples > example "duckorbit" example index 0 1`] = ` ] `; +exports[`runs examples > example "duckrelease" example index 0 1`] = ` +[ + "[ 0/1 → 1/16 | s:bd n:4 duckorbit:2 duckrelease:0.2 duckdepth:1 ]", + "[ 1/4 → 5/16 | s:bd n:4 duckorbit:2 duckrelease:0.2 duckdepth:1 ]", + "[ 1/2 → 9/16 | s:bd n:4 duckorbit:2 duckrelease:0.2 duckdepth:1 ]", + "[ 11/16 → 3/4 | s:bd n:4 duckorbit:2 duckrelease:0.2 duckdepth:1 ]", + "[ 7/8 → 15/16 | s:bd n:4 duckorbit:2 duckrelease:0.2 duckdepth:1 ]", + "[ 1/1 → 17/16 | s:bd n:4 duckorbit:2 duckrelease:0 duckdepth:1 ]", + "[ 5/4 → 21/16 | s:bd n:4 duckorbit:2 duckrelease:0 duckdepth:1 ]", + "[ 3/2 → 25/16 | s:bd n:4 duckorbit:2 duckrelease:0 duckdepth:1 ]", + "[ 27/16 → 7/4 | s:bd n:4 duckorbit:2 duckrelease:0 duckdepth:1 ]", + "[ 15/8 → 31/16 | s:bd n:4 duckorbit:2 duckrelease:0 duckdepth:1 ]", + "[ 2/1 → 33/16 | s:bd n:4 duckorbit:2 duckrelease:0.4 duckdepth:1 ]", + "[ 9/4 → 37/16 | s:bd n:4 duckorbit:2 duckrelease:0.4 duckdepth:1 ]", + "[ 5/2 → 41/16 | s:bd n:4 duckorbit:2 duckrelease:0.4 duckdepth:1 ]", + "[ 43/16 → 11/4 | s:bd n:4 duckorbit:2 duckrelease:0.4 duckdepth:1 ]", + "[ 23/8 → 47/16 | s:bd n:4 duckorbit:2 duckrelease:0.4 duckdepth:1 ]", + "[ 3/1 → 49/16 | s:bd n:4 duckorbit:2 duckrelease:0.2 duckdepth:1 ]", + "[ 13/4 → 53/16 | s:bd n:4 duckorbit:2 duckrelease:0.2 duckdepth:1 ]", + "[ 7/2 → 57/16 | s:bd n:4 duckorbit:2 duckrelease:0.2 duckdepth:1 ]", + "[ 59/16 → 15/4 | s:bd n:4 duckorbit:2 duckrelease:0.2 duckdepth:1 ]", + "[ 31/8 → 63/16 | s:bd n:4 duckorbit:2 duckrelease:0.2 duckdepth:1 ]", +] +`; + exports[`runs examples > example "duration" example index 0 1`] = ` [ "[ 0/1 → 1/4 | note:c s:piano duration:0.5 ]", From a0fc52b1ec2d1d8786ae8f711fe777aadf15be8a Mon Sep 17 00:00:00 2001 From: Aria Date: Thu, 21 Aug 2025 14:42:52 -0500 Subject: [PATCH 077/335] Final tweaks --- website/src/pages/learn/effects.mdx | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/website/src/pages/learn/effects.mdx b/website/src/pages/learn/effects.mdx index 7a57b898f..d9efe8f8a 100644 --- a/website/src/pages/learn/effects.mdx +++ b/website/src/pages/learn/effects.mdx @@ -45,17 +45,21 @@ The signal chain in Strudel is as follows: - Phaser (`phaser`) - Postgain (`post`) - The sound is then split into multiple destinations - - Main output (amount controlled by `dry` parameter) - - This is where the `duck` function will apply sidechain - - Analyzer (used for tooling like `scope` and `spectrum`) - - Per-orbit effects (see the section below) - - Delay send (amount controlled by `delay` parameter) - - Reverb send (amount controlled by `delay` parameter) + - Dry output (amount controlled by `dry` parameter) + - The sends + - Analyzers + - These are used for tooling like `scope` and `spectrum` and their setup usually happens behind the scenes + - Delay (amount controlled by `delay` parameter) + - Reverb (amount controlled by `room` parameter) +- The dry output, delay, and reverb are joined into what is called the "orbit" of the pattern (see more in the section below) + - The `duck` effect affects the volume of all signals in the orbit + - The orbit is then sent to the mixer ## Orbits -Orbits are the way in which outputs are handled in Strudel. By default all orbits are mixed down to channels `1` and `2` in stereo, however with the "Multi Channel Orbits" setting -(under settings at the right) you can use them as individual 2 channel stereo outs (orbit `i` will be mapped to +Orbits are the way in which outputs are handled in Strudel. They also prescribe which delay and reverb to associate with the dry signal. +By default, all orbits are mixed down to channels `1` and `2` in stereo, however with the "Multi Channel Orbits" setting +(under Settings at the right) you can use them as individual 2 channel stereo outs (orbit `i` will be mapped to to channels `2i` and `2i + 1`). You can then use routers like Blackhole 16 to retrieve and record all of the channels in a DAW for later processing. The default orbit is `1` and it is set with `orbit`. You may send a sound to multiple orbits via mininotation @@ -76,7 +80,7 @@ $: s("triangle*4").decay(0.5).n(irand(12)).scale('C minor') .room(1).roomsize(10)`} /> -versus the same pluck with a muted kick drum coming in and overwriting the `roomsize` value (occasionally) +versus the same pluck with a muted kick drum coming in and overwriting the `roomsize` value: Date: Fri, 22 Aug 2025 11:25:13 -0500 Subject: [PATCH 078/335] Working version with note names --- packages/tonal/test/tonal.test.mjs | 25 ++++++++-- packages/tonal/tonal.mjs | 79 ++++++++++++++++++++---------- packages/tonal/tonleiter.mjs | 17 +------ 3 files changed, 75 insertions(+), 46 deletions(-) diff --git a/packages/tonal/test/tonal.test.mjs b/packages/tonal/test/tonal.test.mjs index 5486d5135..a64b455b9 100644 --- a/packages/tonal/test/tonal.test.mjs +++ b/packages/tonal/test/tonal.test.mjs @@ -70,10 +70,7 @@ describe('tonal', () => { }); it('snaps notes (upwards) to scale', () => { const inputNotes = ['Cb', 'Eb', 'G', 'A#', 'Bb']; - let expectedNotes = ['B2', 'E3', 'G3', 'B3', 'B3']; - - // Notes are converted to midi by scale - expectedNotes = expectedNotes.map((note) => noteToMidi(note)); + const expectedNotes = ['B2', 'E3', 'G3', 'B3', 'B3']; expect( note(seq(inputNotes)) @@ -81,6 +78,26 @@ describe('tonal', () => { .firstCycleValues.map((h) => h.note), ).toEqual(expectedNotes); }); + it('snaps notes to the correct octave', () => { + const inputNotes = ['Cb0', 'Eb4', 'G1', 'A#19', 'Bb8']; + const expectedNotes = ['B#0', 'D#4', 'G#1', 'A#19', 'A#8']; + + expect( + note(seq(inputNotes)) + .scale('A# minor') // A#, B#, C#, D#, E#, F#, G# + .firstCycleValues.map((h) => h.note), + ).toEqual(expectedNotes); + }); + it('handles scale names provided with colons', () => { + const inputNotes = ['Cb', 'E', 'G', 'A#', 'Bb']; + const expectedNotes = ['A#2', 'D#3', 'G#3', 'A#3', 'A#3']; + + expect( + note(seq(inputNotes)) + .scale('F#:pentatonic') // F#, G#, A#, C#, and D# + .firstCycleValues.map((h) => h.note), + ).toEqual(expectedNotes); + }); }); describe('transpose', () => { it('transposes note numbers with interval numbers', () => { diff --git a/packages/tonal/tonal.mjs b/packages/tonal/tonal.mjs index 5e505c75a..28e2606e1 100644 --- a/packages/tonal/tonal.mjs +++ b/packages/tonal/tonal.mjs @@ -6,20 +6,28 @@ This program is free software: you can redistribute it and/or modify it under th import { Note, Interval, Scale } from '@tonaljs/tonal'; import { register, _mod, silence, logger, pure, isNote } from '@strudel/core'; -import { stepInNamedScale, scaleToChromas } from './tonleiter.mjs'; +import { stepInNamedScale, nearestNumberIndex } from './tonleiter.mjs'; import { noteToMidi } from '../core/util.mjs'; const octavesInterval = (octaves) => (octaves <= 0 ? -1 : 1) + octaves * 7 + 'P'; -function scaleStep(step, scale) { - scale = scale.replaceAll(':', ' '); - step = Math.ceil(step); - let { intervals, tonic, empty } = Scale.get(scale); - if ((empty && isNote(scale)) || (empty && !tonic)) { - throw new Error(`incomplete scale. Make sure to use ":" instead of spaces, example: .scale("C:major")`); +function getScale(scaleName) { + scaleName = scaleName.replaceAll(':', ' '); + const scale = Scale.get(scaleName); + const { tonic, empty } = scale; + if ((empty && isNote(scaleName)) || (empty && !tonic)) { + throw new Error( + `Scale name ${scaleName} is incomplete. Make sure to use ":" instead of spaces, example: .scale("C:major")`, + ); } else if (empty) { - throw new Error(`invalid scale "${scale}"`); + throw new Error(`Invalid scale name "${scaleName}"`); } + return scale; +} + +function scaleStep(step, scale) { + step = Math.ceil(step); + let { intervals, tonic } = getScale(scale); tonic = tonic || 'C'; const { pc, oct = 3 } = Note.get(tonic); const octaveOffset = Math.floor(step / intervals.length); @@ -31,8 +39,7 @@ function scaleStep(step, scale) { // transpose note inside scale by offset steps // function scaleOffset(scale: string, offset: number, note: string) { function scaleOffset(scale, offset, note) { - let [tonic, scaleName] = Scale.tokenize(scale); - let { notes } = Scale.get(`${tonic} ${scaleName}`); + let { notes } = getScale(scale); notes = notes.map((note) => Note.get(note).pc); // use only pc! offset = Number(offset); if (isNaN(offset)) { @@ -197,19 +204,37 @@ function _convertStepToNumberAndOffset(step) { return [asNumber, offset]; } +let scaleToMidisAndNotes = {}; // Finds the nearest scale note to `note` -function _getNearestScaleNote(scaleName, note) { - let midiNote = typeof note === 'string' ? noteToMidi(note) : note; - const octave = (midiNote / 12) >> 0; - const targetChroma = midiNote % 12; - const scaleChromas = scaleToChromas(scaleName); - return ( - scaleChromas.reduce((prev, curr) => { - // Include equality so ties are broken upwards - return Math.abs(curr - targetChroma) <= Math.abs(prev - targetChroma) ? curr : prev; - }) + - octave * 12 - ); +function _getNearestScaleNote(scaleName, note, preferHigher = true) { + let noteMidi = typeof note === 'string' ? noteToMidi(note) : note; + noteMidi = Math.max(noteMidi, 24); // we will not play notes below C0 + if (scaleToMidisAndNotes[scaleName] === undefined) { + const { intervals, tonic } = getScale(scaleName); + const { pc } = Note.get(tonic); + const expandedIntervals = intervals.concat('8P'); // add the octave for wrapping + const sNotes = expandedIntervals.map((interval) => Note.transpose(pc + '0', interval)); + const sMidi = sNotes.map(noteToMidi); + // Cache + scaleToMidisAndNotes[scaleName] = [sMidi, sNotes]; + } + const [scaleMidis, scaleNotes] = scaleToMidisAndNotes[scaleName]; + const rootMidi = scaleMidis[0]; + const octaveDiff = Math.floor((noteMidi - rootMidi) / 12); + let filteredNotes = []; // we must filter the notes to avoid negative octave values + let filteredMidis = []; + for (let i = 0; i < scaleMidis.length; i++) { + const newMidi = scaleMidis[i] + 12 * octaveDiff; + if (newMidi < 24) { + continue; + } + filteredMidis.push(newMidi); + const oldNote = scaleNotes[i]; + const newNote = Note.transpose(oldNote, Interval.fromSemitones(12 * octaveDiff)); + filteredNotes.push(newNote); + } + const noteIdx = nearestNumberIndex(noteMidi, filteredMidis, preferHigher); + return filteredNotes[noteIdx]; } /** @@ -254,15 +279,15 @@ export const scale = register( pat .fmap((value) => { const isObject = typeof value === 'object'; - // The case where the note has been defined via `n` - if ((isObject && 'n' in value) || !isObject) { - let step = isObject ? value.n : value; + // The case where the note has been defined via `n` or `pure` + if (!isObject || (isObject && ('n' in value || 'value' in value))) { + const step = isObject ? (value.n ?? value.value) : value; delete value.n; // remove n so it won't cause trouble if (isNote(step)) { // legacy.. return pure(step); } - let [number, offset] = _convertStepToNumberAndOffset(step); + const [number, offset] = _convertStepToNumberAndOffset(step); try { let note; if (isObject && value.anchor) { @@ -280,7 +305,7 @@ export const scale = register( } // The case where the note has been defined via `note` else { - let note = _getNearestScaleNote(scale, value.note); + const note = _getNearestScaleNote(scale, value.note); return pure(isObject ? { ...value, note } : note); } }) diff --git a/packages/tonal/tonleiter.mjs b/packages/tonal/tonleiter.mjs index 39c819cd7..233129641 100644 --- a/packages/tonal/tonleiter.mjs +++ b/packages/tonal/tonleiter.mjs @@ -101,11 +101,11 @@ export function nearestNumberIndex(target, numbers, preferHigher) { let scaleSteps = {}; // [scaleName]: semitones[] export function stepInNamedScale(step, scale, anchor, preferHigher) { - let [root, scaleName] = Scale.tokenize(scale); + const [root, scaleName] = Scale.tokenize(scale); const rootMidi = x2midi(root); const rootChroma = midi2chroma(rootMidi); if (!scaleSteps[scaleName]) { - let { intervals } = Scale.get(`C ${scaleName}`); + const { intervals } = Scale.get(`C ${scaleName}`); // cache result scaleSteps[scaleName] = intervals.map(step2semitones); } @@ -236,16 +236,3 @@ export function transpose(note, step) { const offsetAccidentals = accidentalString(Step.accidentals(step) + Note.accidentals(note) + stepIndex - indexOffset); // "we need to add a # to to the G to make it a major third from E" return [targetNote, offsetAccidentals].join(''); } - -// Converts a `scaleName` into a corresponding list of chromas between 0 and 12 -export function scaleToChromas(scaleName) { - if (Array.isArray(scaleName)) { - scaleName = scaleName.flat().join(' '); - } - const [tonic, name] = Scale.tokenize(scaleName); - const rootMidi = noteToMidi(tonic); - const chroma = rootMidi % 12; - const intervals = Scale.get(name).intervals; - const scaleSteps = intervals.map(Interval.semitones); - return scaleSteps.map((s) => (s + chroma) % 12); -} From 79453ac2c3c71a1ba4d2ce34471cd125a2744cd5 Mon Sep 17 00:00:00 2001 From: Aria Date: Fri, 22 Aug 2025 13:17:13 -0500 Subject: [PATCH 079/335] Allow negatives and multi-accidentals --- packages/core/util.mjs | 4 ++-- packages/superdough/util.mjs | 2 +- packages/tonal/test/tonal.test.mjs | 2 +- packages/tonal/tonal.mjs | 24 +++++------------------- 4 files changed, 9 insertions(+), 23 deletions(-) diff --git a/packages/core/util.mjs b/packages/core/util.mjs index 2e7c6e026..ef3f1e961 100644 --- a/packages/core/util.mjs +++ b/packages/core/util.mjs @@ -8,12 +8,12 @@ import { logger } from './logger.mjs'; // returns true if the given string is a note export const isNoteWithOctave = (name) => /^[a-gA-G][#bs]*[0-9]$/.test(name); -export const isNote = (name) => /^[a-gA-G][#bsf]*[0-9]?$/.test(name); +export const isNote = (name) => /^[a-gA-G][#bsf]*-?[0-9]?$/.test(name); export const tokenizeNote = (note) => { if (typeof note !== 'string') { return []; } - const [pc, acc = '', oct] = note.match(/^([a-gA-G])([#bsf]*)([0-9]*)$/)?.slice(1) || []; + const [pc, acc = '', oct] = note.match(/^([a-gA-G])([#bsf]*)(-?[0-9]*)$/)?.slice(1) || []; if (!pc) { return []; } diff --git a/packages/superdough/util.mjs b/packages/superdough/util.mjs index f4d59024e..764ebb43e 100644 --- a/packages/superdough/util.mjs +++ b/packages/superdough/util.mjs @@ -7,7 +7,7 @@ export const tokenizeNote = (note) => { if (typeof note !== 'string') { return []; } - const [pc, acc = '', oct] = note.match(/^([a-gA-G])([#bsf]*)([0-9]*)$/)?.slice(1) || []; + const [pc, acc = '', oct] = note.match(/^([a-gA-G])([#bsf]*)(-?[0-9]*)$/)?.slice(1) || []; if (!pc) { return []; } diff --git a/packages/tonal/test/tonal.test.mjs b/packages/tonal/test/tonal.test.mjs index a64b455b9..cb856fa99 100644 --- a/packages/tonal/test/tonal.test.mjs +++ b/packages/tonal/test/tonal.test.mjs @@ -80,7 +80,7 @@ describe('tonal', () => { }); it('snaps notes to the correct octave', () => { const inputNotes = ['Cb0', 'Eb4', 'G1', 'A#19', 'Bb8']; - const expectedNotes = ['B#0', 'D#4', 'G#1', 'A#19', 'A#8']; + const expectedNotes = ['B#-1', 'D#4', 'G#1', 'A#19', 'A#8']; expect( note(seq(inputNotes)) diff --git a/packages/tonal/tonal.mjs b/packages/tonal/tonal.mjs index 28e2606e1..2ec698c38 100644 --- a/packages/tonal/tonal.mjs +++ b/packages/tonal/tonal.mjs @@ -128,10 +128,7 @@ export const { transpose, trans } = register(['transpose', 'trans'], function tr const interval = !isNaN(Number(intervalOrSemitones)) ? Interval.fromSemitones(intervalOrSemitones) : String(intervalOrSemitones); - // TODO: move simplify to player to preserve enharmonics - // tone.js doesn't understand multiple sharps flats e.g. F##3 has to be turned into G3 - // TODO: check if this is still relevant.. - const targetNote = Note.simplify(Note.transpose(note, interval)); + const targetNote = Note.transpose(note, interval); if (typeof hap.value === 'object') { return hap.withValue(() => ({ ...hap.value, note: targetNote })); } @@ -208,7 +205,6 @@ let scaleToMidisAndNotes = {}; // Finds the nearest scale note to `note` function _getNearestScaleNote(scaleName, note, preferHigher = true) { let noteMidi = typeof note === 'string' ? noteToMidi(note) : note; - noteMidi = Math.max(noteMidi, 24); // we will not play notes below C0 if (scaleToMidisAndNotes[scaleName] === undefined) { const { intervals, tonic } = getScale(scaleName); const { pc } = Note.get(tonic); @@ -221,20 +217,10 @@ function _getNearestScaleNote(scaleName, note, preferHigher = true) { const [scaleMidis, scaleNotes] = scaleToMidisAndNotes[scaleName]; const rootMidi = scaleMidis[0]; const octaveDiff = Math.floor((noteMidi - rootMidi) / 12); - let filteredNotes = []; // we must filter the notes to avoid negative octave values - let filteredMidis = []; - for (let i = 0; i < scaleMidis.length; i++) { - const newMidi = scaleMidis[i] + 12 * octaveDiff; - if (newMidi < 24) { - continue; - } - filteredMidis.push(newMidi); - const oldNote = scaleNotes[i]; - const newNote = Note.transpose(oldNote, Interval.fromSemitones(12 * octaveDiff)); - filteredNotes.push(newNote); - } - const noteIdx = nearestNumberIndex(noteMidi, filteredMidis, preferHigher); - return filteredNotes[noteIdx]; + const alignedMidis = scaleMidis.map((m) => m + 12 * octaveDiff); + const noteIdx = nearestNumberIndex(noteMidi, alignedMidis, preferHigher); + const noteMatch = scaleNotes[noteIdx]; + return Note.transpose(noteMatch, Interval.fromSemitones(12 * octaveDiff)); } /** From b8c46d6b26f7b3d5864c3f3b02e1ec90468a510d Mon Sep 17 00:00:00 2001 From: Aria Date: Fri, 22 Aug 2025 13:23:41 -0500 Subject: [PATCH 080/335] Added some description and examples of multi-accidentals and negative octaves --- packages/core/controls.mjs | 4 +- packages/tonal/tonal.mjs | 2 + test/__snapshots__/examples.test.mjs.snap | 90 +++++++++++++++++++++++ 3 files changed, 95 insertions(+), 1 deletion(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index e6181d453..de152d417 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -113,7 +113,7 @@ export const { n } = registerControl('n'); * * - a letter (a-g or A-G) * - optional accidentals (b or #) - * - optional octave number (0-9). Defaults to 3 + * - optional (possibly negative) octave number (0-9). Defaults to 3 * * Examples of valid note names: `c`, `bb`, `Bb`, `f#`, `c3`, `A4`, `Eb2`, `c#5` * @@ -126,6 +126,8 @@ export const { n } = registerControl('n'); * note("c4 a4 f4 e4") * @example * note("60 69 65 64") + * @example + * note("fbb1 a#0 cbbb-1 e##-2").sound("saw") */ export const { note } = registerControl(['note', 'n']); diff --git a/packages/tonal/tonal.mjs b/packages/tonal/tonal.mjs index 2ec698c38..4f189e3d6 100644 --- a/packages/tonal/tonal.mjs +++ b/packages/tonal/tonal.mjs @@ -252,6 +252,8 @@ function _getNearestScaleNote(scaleName, note, preferHigher = true) { * n("<[0,7b] [-4# -4] [-2,7##] 4 [0,7] [-4# -4b] [-2,7###] 4b>*4") * .scale("C:/2") * .s("piano") + * @example + * note("C1*16").transpose(irand(36)).scale('Cb2 major').scaleTranspose(3) */ export const scale = register( diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index 09482375e..77c2773ce 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -6436,6 +6436,27 @@ exports[`runs examples > example "note" example index 2 1`] = ` ] `; +exports[`runs examples > example "note" example index 3 1`] = ` +[ + "[ 0/1 → 1/4 | note:fbb1 s:saw ]", + "[ 1/4 → 1/2 | note:a#0 s:saw ]", + "[ 1/2 → 3/4 | note:cbbb-1 s:saw ]", + "[ 3/4 → 1/1 | note:e##-2 s:saw ]", + "[ 1/1 → 5/4 | note:fbb1 s:saw ]", + "[ 5/4 → 3/2 | note:a#0 s:saw ]", + "[ 3/2 → 7/4 | note:cbbb-1 s:saw ]", + "[ 7/4 → 2/1 | note:e##-2 s:saw ]", + "[ 2/1 → 9/4 | note:fbb1 s:saw ]", + "[ 9/4 → 5/2 | note:a#0 s:saw ]", + "[ 5/2 → 11/4 | note:cbbb-1 s:saw ]", + "[ 11/4 → 3/1 | note:e##-2 s:saw ]", + "[ 3/1 → 13/4 | note:fbb1 s:saw ]", + "[ 13/4 → 7/2 | note:a#0 s:saw ]", + "[ 7/2 → 15/4 | note:cbbb-1 s:saw ]", + "[ 15/4 → 4/1 | note:e##-2 s:saw ]", +] +`; + exports[`runs examples > example "nrpnn" example index 0 1`] = ` [ "[ 0/1 → 1/1 | note:c4 nrpnn:[1 8] nrpv:123 midichan:1 ]", @@ -8699,6 +8720,75 @@ exports[`runs examples > example "scale" example index 3 1`] = ` ] `; +exports[`runs examples > example "scale" example index 4 1`] = ` +[ + "[ 0/1 → 1/16 | note:Gb1 ]", + "[ 1/16 → 1/8 | note:Gb1 ]", + "[ 1/8 → 3/16 | note:Gb1 ]", + "[ 3/16 → 1/4 | note:Gb1 ]", + "[ 1/4 → 5/16 | note:Gb1 ]", + "[ 5/16 → 3/8 | note:Gb1 ]", + "[ 3/8 → 7/16 | note:Gb1 ]", + "[ 7/16 → 1/2 | note:Gb1 ]", + "[ 1/2 → 9/16 | note:Gb1 ]", + "[ 9/16 → 5/8 | note:Gb1 ]", + "[ 5/8 → 11/16 | note:Gb1 ]", + "[ 11/16 → 3/4 | note:Gb1 ]", + "[ 3/4 → 13/16 | note:Gb1 ]", + "[ 13/16 → 7/8 | note:Gb1 ]", + "[ 7/8 → 15/16 | note:Gb1 ]", + "[ 15/16 → 1/1 | note:Gb1 ]", + "[ 1/1 → 17/16 | note:Cb3 ]", + "[ 17/16 → 9/8 | note:Cb3 ]", + "[ 9/8 → 19/16 | note:Cb3 ]", + "[ 19/16 → 5/4 | note:Cb3 ]", + "[ 5/4 → 21/16 | note:Cb3 ]", + "[ 21/16 → 11/8 | note:Cb3 ]", + "[ 11/8 → 23/16 | note:Cb3 ]", + "[ 23/16 → 3/2 | note:Cb3 ]", + "[ 3/2 → 25/16 | note:Cb3 ]", + "[ 25/16 → 13/8 | note:Cb3 ]", + "[ 13/8 → 27/16 | note:Cb3 ]", + "[ 27/16 → 7/4 | note:Cb3 ]", + "[ 7/4 → 29/16 | note:Cb3 ]", + "[ 29/16 → 15/8 | note:Cb3 ]", + "[ 15/8 → 31/16 | note:Cb3 ]", + "[ 31/16 → 2/1 | note:Cb3 ]", + "[ 2/1 → 33/16 | note:Eb4 ]", + "[ 33/16 → 17/8 | note:Eb4 ]", + "[ 17/8 → 35/16 | note:Eb4 ]", + "[ 35/16 → 9/4 | note:Eb4 ]", + "[ 9/4 → 37/16 | note:Eb4 ]", + "[ 37/16 → 19/8 | note:Eb4 ]", + "[ 19/8 → 39/16 | note:Eb4 ]", + "[ 39/16 → 5/2 | note:Eb4 ]", + "[ 5/2 → 41/16 | note:Eb4 ]", + "[ 41/16 → 21/8 | note:Eb4 ]", + "[ 21/8 → 43/16 | note:Eb4 ]", + "[ 43/16 → 11/4 | note:Eb4 ]", + "[ 11/4 → 45/16 | note:Eb4 ]", + "[ 45/16 → 23/8 | note:Eb4 ]", + "[ 23/8 → 47/16 | note:Eb4 ]", + "[ 47/16 → 3/1 | note:Eb4 ]", + "[ 3/1 → 49/16 | note:Db2 ]", + "[ 49/16 → 25/8 | note:Db2 ]", + "[ 25/8 → 51/16 | note:Db2 ]", + "[ 51/16 → 13/4 | note:Db2 ]", + "[ 13/4 → 53/16 | note:Db2 ]", + "[ 53/16 → 27/8 | note:Db2 ]", + "[ 27/8 → 55/16 | note:Db2 ]", + "[ 55/16 → 7/2 | note:Db2 ]", + "[ 7/2 → 57/16 | note:Db2 ]", + "[ 57/16 → 29/8 | note:Db2 ]", + "[ 29/8 → 59/16 | note:Db2 ]", + "[ 59/16 → 15/4 | note:Db2 ]", + "[ 15/4 → 61/16 | note:Db2 ]", + "[ 61/16 → 31/8 | note:Db2 ]", + "[ 31/8 → 63/16 | note:Db2 ]", + "[ 63/16 → 4/1 | note:Db2 ]", +] +`; + exports[`runs examples > example "scaleTranspose" example index 0 1`] = ` [ "[ 0/1 → 1/2 | note:C3 ]", From 3d25aa1b91ec75532682c3d786ca5d862c0c374f Mon Sep 17 00:00:00 2001 From: Aria Date: Tue, 26 Aug 2025 12:06:10 -0500 Subject: [PATCH 081/335] Rename params, more examples --- packages/core/controls.mjs | 74 ++++++--- packages/superdough/superdough.mjs | 16 +- test/__snapshots__/examples.test.mjs.snap | 191 +++++++++++++++++----- 3 files changed, 217 insertions(+), 64 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 4d6f8d8b7..4deb6f77f 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -542,13 +542,19 @@ export const { tremoloshape } = registerControl('tremoloshape', 'tremshape'); */ /** - * Modulate the amplitude of an orbit to create a "sidechain" like effect + * Modulate the amplitude of an orbit to create a "sidechain" like effect. + * + * Can be applied to multiple orbits with the ':' mininotation, e.g. `duckorbit("2:3")` * * @name duckorbit * @param {number | Pattern} orbit target orbit * @example * $: n(run(16)).scale("c:minor:pentatonic").s("sawtooth").delay(.7).orbit(2) * $: s("bd:4!4").beat("0,4,8,11,14",16).duckorbit(2).duckattack(0.2).duckdepth(1) + * @example + * $: n(run(16)).scale("c:minor:pentatonic").s("sawtooth").delay(.7).orbit(2) + * $: s("hh*16").orbit(3) + * $: s("bd:4!4").beat("0,4,8,11,14",16).duckorbit("2:3").duckattack(0.2).duckdepth(1) * */ export const { duck } = registerControl('duckorbit', 'duck'); @@ -556,40 +562,70 @@ export const { duck } = registerControl('duckorbit', 'duck'); /** * The amount of ducking applied to target orbit * + * Can vary across orbits with the ':' mininotation, e.g. `duckdepth("0.3:0.1")`. + * Note: this requires first applying the effect to multiple orbits with e.g. `duckorbit("2:3")`. + * * @name duckdepth * @param {number | Pattern} depth depth of modulation from 0 to 1 * @example * stack( n(run(8)).scale("c:minor").s("sawtooth").delay(.7).orbit(2), s("bd:4!4").beat("0,4,8,11,14",16).duckorbit(2).duckattack(0.2).duckdepth("<1 .9 .6 0>")) + * @example + * $: n(run(16)).scale("c:minor:pentatonic").s("sawtooth").delay(.7).orbit(2) + * $: s("hh*16").orbit(3) + * $: s("bd:4!4").beat("0,4,8,11,14",16).duckorbit("2:3").duckattack(0.2).duckdepth("1:0.5") * */ - export const { duckdepth } = registerControl('duckdepth'); /** - * The attack time of the duck effect. Can be used to prevent clicking or for creative rhythmic effects + * The time required for the ducked signal(s) to reach their lowest volume. + * Can be used to prevent clicking or for creative rhythmic effects. + + * Can vary across orbits with the ':' mininotation, e.g. `duckonset("0:0.003")`. + * Note: this requires first applying the effect to multiple orbits with e.g. `duckorbit("2:3")`. + * + * @name duckonset + * @synonyms duckons + * + * @param {number | Pattern} time The onset time in seconds + * @example + * // Clicks + * sound: n(run(8)).scale("c:minor").s("sawtooth").lpf(200).delay(.7).orbit(2) + * duckerWithClick: s("bd*4").duckorbit(2).duckonset(0).postgain(0) + * @example + * // No clicks + * sound: n(run(8)).scale("c:minor").s("sawtooth").lpf(200).delay(.7).orbit(2) + * duckerWithoutClick: s("bd*4").duckorbit(2).duckonset(0.003).postgain(0) + * @example + * // Rhythmic + * noise: s("pink").distort("2:1").orbit(4) // used rhythmically with 0.3 onset below + * hhat: s("hh*16").orbit(7) + * ducker: s("bd*4").bank("tr909").duckorbit("4:7").duckonset("0.3:0.003").duckattack(0.25) + * + */ +export const { duckonset } = registerControl('duckonset', 'duckons'); + +/** + * The time required for the ducked signal(s) to return to their normal volume. + + * Can vary across orbits with the ':' mininotation, e.g. `duckonset("0:0.003")`. + * Note: this requires first applying the effect to multiple orbits with e.g. `duckorbit("2:3")`. * * @name duckattack - * @param {number | Pattern} time + * @synonyms duckatt + * + * @param {number | Pattern} time The attack time in seconds * @example - * sound: n(run(8)).scale("c:minor").s("sawtooth").lpf(200).delay(.7).orbit(2) - * duckerWithClick: s("bd*4").duckorbit(2).duckattack(0).postgain(0) - * _duckerWithoutClick: s("bd*4").duckorbit(2).duckattack(0.003).postgain(0) + * sound: n(run(8)).scale("c:minor").s("sawtooth").delay(.7).orbit(2) + * ducker: s("bd:4!4").beat("0,4,8,11,14",16).duckorbit(2).duckattack("<0.2 0 0.4>").duckdepth(1) + * @example + * moreduck: n(run(8)).scale("c:minor").s("sawtooth").delay(.7).orbit(2) + * lessduck: s("hh*16").orbit(5) + * ducker: s("bd:4!4").beat("0,4,8,11,14",16).duckorbit("2:5").duckattack("0.4:0.1") * */ export const { duckattack } = registerControl('duckattack', 'duckatt'); -/** - * The release time of the duck effect - * - * @name duckrelease - * @param {number | Pattern} time - * @example - * sound: n(run(8)).scale("c:minor").s("sawtooth").delay(.7).orbit(2) - * ducker: s("bd:4!4").beat("0,4,8,11,14",16).duckorbit(2).duckrelease("<0.2 0 0.4>").duckdepth(1) - * - */ -export const { duckrelease } = registerControl('duckrelease', 'duckrelease'); - export const { drive } = registerControl('drive'); /** diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index b8975a852..98ffae16a 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -421,10 +421,10 @@ function setOrbit(audioContext, orbit, channels) { } } -function duckOrbit(audioContext, targetOrbit, t, attacktime = 0.003, releasetime = 0.1, duckdepth = 1) { +function duckOrbit(audioContext, targetOrbit, t, onsettime = 0.003, attacktime = 0.1, duckdepth = 1) { const targetArr = [targetOrbit].flat(); + const onsetArr = [onsettime].flat(); const attackArr = [attacktime].flat(); - const releaseArr = [releasetime].flat(); const depthArr = [duckdepth].flat(); targetArr.forEach((target, idx) => { @@ -432,8 +432,8 @@ function duckOrbit(audioContext, targetOrbit, t, attacktime = 0.003, releasetime errorLogger(new Error(`duck target orbit ${target} does not exist`), 'superdough'); return; } - const attack = attackArr[idx] ?? attackArr[0]; - const release = Math.max(releaseArr[idx] ?? releaseArr[0], 0.002); + const onset = onsetArr[idx] ?? onsetArr[0]; + const attack = Math.max(attackArr[idx] ?? attackArr[0], 0.002); const depth = depthArr[idx] ?? depthArr[0]; const gainParam = orbits[target].output.gain; webAudioTimeout( @@ -448,8 +448,8 @@ function duckOrbit(audioContext, targetOrbit, t, attacktime = 0.003, releasetime // that method gainParam.setValueAtTime(currVal, t); - gainParam.exponentialRampToValueAtTime(duckedVal, t + attack); - gainParam.exponentialRampToValueAtTime(1, t + attack + release); + gainParam.exponentialRampToValueAtTime(duckedVal, t + onset); + gainParam.exponentialRampToValueAtTime(1, t + onset + attack); }, 0, t - 0.01, @@ -578,8 +578,8 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) postgain = getDefaultValue('postgain'), density = getDefaultValue('density'), duckorbit, + duckonset, duckattack, - duckrelease, duckdepth, // filters fanchor = getDefaultValue('fanchor'), @@ -658,7 +658,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) setOrbit(ac, orbit, channels, t, cycle, cps); if (duckorbit != null) { - duckOrbit(ac, duckorbit, t, duckattack, duckrelease, duckdepth); + duckOrbit(ac, duckorbit, t, duckonset, duckattack, duckdepth); } gain = applyGainCurve(nanFallback(gain, 1)); diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index 85079269e..4655b5cd9 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -3038,22 +3038,51 @@ exports[`runs examples > example "dry" example index 0 1`] = ` exports[`runs examples > example "duckattack" example index 0 1`] = ` [ - "[ 0/1 → 1/4 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", - "[ 1/4 → 1/2 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", - "[ 1/2 → 3/4 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", - "[ 3/4 → 1/1 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", - "[ 1/1 → 5/4 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", - "[ 5/4 → 3/2 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", - "[ 3/2 → 7/4 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", - "[ 7/4 → 2/1 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", - "[ 2/1 → 9/4 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", - "[ 9/4 → 5/2 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", - "[ 5/2 → 11/4 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", - "[ 11/4 → 3/1 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", - "[ 3/1 → 13/4 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", - "[ 13/4 → 7/2 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", - "[ 7/2 → 15/4 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", - "[ 15/4 → 4/1 | s:bd duckorbit:2 duckattack:0.003 postgain:0 ]", + "[ 0/1 → 1/16 | s:bd n:4 duckorbit:2 duckattack:0.2 duckdepth:1 ]", + "[ 1/4 → 5/16 | s:bd n:4 duckorbit:2 duckattack:0.2 duckdepth:1 ]", + "[ 1/2 → 9/16 | s:bd n:4 duckorbit:2 duckattack:0.2 duckdepth:1 ]", + "[ 11/16 → 3/4 | s:bd n:4 duckorbit:2 duckattack:0.2 duckdepth:1 ]", + "[ 7/8 → 15/16 | s:bd n:4 duckorbit:2 duckattack:0.2 duckdepth:1 ]", + "[ 1/1 → 17/16 | s:bd n:4 duckorbit:2 duckattack:0 duckdepth:1 ]", + "[ 5/4 → 21/16 | s:bd n:4 duckorbit:2 duckattack:0 duckdepth:1 ]", + "[ 3/2 → 25/16 | s:bd n:4 duckorbit:2 duckattack:0 duckdepth:1 ]", + "[ 27/16 → 7/4 | s:bd n:4 duckorbit:2 duckattack:0 duckdepth:1 ]", + "[ 15/8 → 31/16 | s:bd n:4 duckorbit:2 duckattack:0 duckdepth:1 ]", + "[ 2/1 → 33/16 | s:bd n:4 duckorbit:2 duckattack:0.4 duckdepth:1 ]", + "[ 9/4 → 37/16 | s:bd n:4 duckorbit:2 duckattack:0.4 duckdepth:1 ]", + "[ 5/2 → 41/16 | s:bd n:4 duckorbit:2 duckattack:0.4 duckdepth:1 ]", + "[ 43/16 → 11/4 | s:bd n:4 duckorbit:2 duckattack:0.4 duckdepth:1 ]", + "[ 23/8 → 47/16 | s:bd n:4 duckorbit:2 duckattack:0.4 duckdepth:1 ]", + "[ 3/1 → 49/16 | s:bd n:4 duckorbit:2 duckattack:0.2 duckdepth:1 ]", + "[ 13/4 → 53/16 | s:bd n:4 duckorbit:2 duckattack:0.2 duckdepth:1 ]", + "[ 7/2 → 57/16 | s:bd n:4 duckorbit:2 duckattack:0.2 duckdepth:1 ]", + "[ 59/16 → 15/4 | s:bd n:4 duckorbit:2 duckattack:0.2 duckdepth:1 ]", + "[ 31/8 → 63/16 | s:bd n:4 duckorbit:2 duckattack:0.2 duckdepth:1 ]", +] +`; + +exports[`runs examples > example "duckattack" example index 1 1`] = ` +[ + "[ 0/1 → 1/16 | s:bd n:4 duckorbit:[2 5] duckattack:[0.4 0.1] ]", + "[ 1/4 → 5/16 | s:bd n:4 duckorbit:[2 5] duckattack:[0.4 0.1] ]", + "[ 1/2 → 9/16 | s:bd n:4 duckorbit:[2 5] duckattack:[0.4 0.1] ]", + "[ 11/16 → 3/4 | s:bd n:4 duckorbit:[2 5] duckattack:[0.4 0.1] ]", + "[ 7/8 → 15/16 | s:bd n:4 duckorbit:[2 5] duckattack:[0.4 0.1] ]", + "[ 1/1 → 17/16 | s:bd n:4 duckorbit:[2 5] duckattack:[0.4 0.1] ]", + "[ 5/4 → 21/16 | s:bd n:4 duckorbit:[2 5] duckattack:[0.4 0.1] ]", + "[ 3/2 → 25/16 | s:bd n:4 duckorbit:[2 5] duckattack:[0.4 0.1] ]", + "[ 27/16 → 7/4 | s:bd n:4 duckorbit:[2 5] duckattack:[0.4 0.1] ]", + "[ 15/8 → 31/16 | s:bd n:4 duckorbit:[2 5] duckattack:[0.4 0.1] ]", + "[ 2/1 → 33/16 | s:bd n:4 duckorbit:[2 5] duckattack:[0.4 0.1] ]", + "[ 9/4 → 37/16 | s:bd n:4 duckorbit:[2 5] duckattack:[0.4 0.1] ]", + "[ 5/2 → 41/16 | s:bd n:4 duckorbit:[2 5] duckattack:[0.4 0.1] ]", + "[ 43/16 → 11/4 | s:bd n:4 duckorbit:[2 5] duckattack:[0.4 0.1] ]", + "[ 23/8 → 47/16 | s:bd n:4 duckorbit:[2 5] duckattack:[0.4 0.1] ]", + "[ 3/1 → 49/16 | s:bd n:4 duckorbit:[2 5] duckattack:[0.4 0.1] ]", + "[ 13/4 → 53/16 | s:bd n:4 duckorbit:[2 5] duckattack:[0.4 0.1] ]", + "[ 7/2 → 57/16 | s:bd n:4 duckorbit:[2 5] duckattack:[0.4 0.1] ]", + "[ 59/16 → 15/4 | s:bd n:4 duckorbit:[2 5] duckattack:[0.4 0.1] ]", + "[ 31/8 → 63/16 | s:bd n:4 duckorbit:[2 5] duckattack:[0.4 0.1] ]", ] `; @@ -3114,6 +3143,94 @@ exports[`runs examples > example "duckdepth" example index 0 1`] = ` ] `; +exports[`runs examples > example "duckdepth" example index 1 1`] = ` +[ + "[ 0/1 → 1/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:[1 0.5] ]", + "[ 1/4 → 5/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:[1 0.5] ]", + "[ 1/2 → 9/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:[1 0.5] ]", + "[ 11/16 → 3/4 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:[1 0.5] ]", + "[ 7/8 → 15/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:[1 0.5] ]", + "[ 1/1 → 17/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:[1 0.5] ]", + "[ 5/4 → 21/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:[1 0.5] ]", + "[ 3/2 → 25/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:[1 0.5] ]", + "[ 27/16 → 7/4 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:[1 0.5] ]", + "[ 15/8 → 31/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:[1 0.5] ]", + "[ 2/1 → 33/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:[1 0.5] ]", + "[ 9/4 → 37/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:[1 0.5] ]", + "[ 5/2 → 41/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:[1 0.5] ]", + "[ 43/16 → 11/4 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:[1 0.5] ]", + "[ 23/8 → 47/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:[1 0.5] ]", + "[ 3/1 → 49/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:[1 0.5] ]", + "[ 13/4 → 53/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:[1 0.5] ]", + "[ 7/2 → 57/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:[1 0.5] ]", + "[ 59/16 → 15/4 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:[1 0.5] ]", + "[ 31/8 → 63/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:[1 0.5] ]", +] +`; + +exports[`runs examples > example "duckonset" example index 0 1`] = ` +[ + "[ 0/1 → 1/4 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", + "[ 1/4 → 1/2 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", + "[ 1/2 → 3/4 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", + "[ 3/4 → 1/1 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", + "[ 1/1 → 5/4 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", + "[ 5/4 → 3/2 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", + "[ 3/2 → 7/4 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", + "[ 7/4 → 2/1 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", + "[ 2/1 → 9/4 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", + "[ 9/4 → 5/2 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", + "[ 5/2 → 11/4 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", + "[ 11/4 → 3/1 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", + "[ 3/1 → 13/4 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", + "[ 13/4 → 7/2 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", + "[ 7/2 → 15/4 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", + "[ 15/4 → 4/1 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", +] +`; + +exports[`runs examples > example "duckonset" example index 1 1`] = ` +[ + "[ 0/1 → 1/4 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", + "[ 1/4 → 1/2 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", + "[ 1/2 → 3/4 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", + "[ 3/4 → 1/1 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", + "[ 1/1 → 5/4 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", + "[ 5/4 → 3/2 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", + "[ 3/2 → 7/4 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", + "[ 7/4 → 2/1 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", + "[ 2/1 → 9/4 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", + "[ 9/4 → 5/2 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", + "[ 5/2 → 11/4 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", + "[ 11/4 → 3/1 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", + "[ 3/1 → 13/4 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", + "[ 13/4 → 7/2 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", + "[ 7/2 → 15/4 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", + "[ 15/4 → 4/1 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", +] +`; + +exports[`runs examples > example "duckonset" example index 2 1`] = ` +[ + "[ 0/1 → 1/4 | s:bd bank:tr909 duckorbit:[4 7] duckonset:[0.3 0.003] duckattack:0.25 ]", + "[ 1/4 → 1/2 | s:bd bank:tr909 duckorbit:[4 7] duckonset:[0.3 0.003] duckattack:0.25 ]", + "[ 1/2 → 3/4 | s:bd bank:tr909 duckorbit:[4 7] duckonset:[0.3 0.003] duckattack:0.25 ]", + "[ 3/4 → 1/1 | s:bd bank:tr909 duckorbit:[4 7] duckonset:[0.3 0.003] duckattack:0.25 ]", + "[ 1/1 → 5/4 | s:bd bank:tr909 duckorbit:[4 7] duckonset:[0.3 0.003] duckattack:0.25 ]", + "[ 5/4 → 3/2 | s:bd bank:tr909 duckorbit:[4 7] duckonset:[0.3 0.003] duckattack:0.25 ]", + "[ 3/2 → 7/4 | s:bd bank:tr909 duckorbit:[4 7] duckonset:[0.3 0.003] duckattack:0.25 ]", + "[ 7/4 → 2/1 | s:bd bank:tr909 duckorbit:[4 7] duckonset:[0.3 0.003] duckattack:0.25 ]", + "[ 2/1 → 9/4 | s:bd bank:tr909 duckorbit:[4 7] duckonset:[0.3 0.003] duckattack:0.25 ]", + "[ 9/4 → 5/2 | s:bd bank:tr909 duckorbit:[4 7] duckonset:[0.3 0.003] duckattack:0.25 ]", + "[ 5/2 → 11/4 | s:bd bank:tr909 duckorbit:[4 7] duckonset:[0.3 0.003] duckattack:0.25 ]", + "[ 11/4 → 3/1 | s:bd bank:tr909 duckorbit:[4 7] duckonset:[0.3 0.003] duckattack:0.25 ]", + "[ 3/1 → 13/4 | s:bd bank:tr909 duckorbit:[4 7] duckonset:[0.3 0.003] duckattack:0.25 ]", + "[ 13/4 → 7/2 | s:bd bank:tr909 duckorbit:[4 7] duckonset:[0.3 0.003] duckattack:0.25 ]", + "[ 7/2 → 15/4 | s:bd bank:tr909 duckorbit:[4 7] duckonset:[0.3 0.003] duckattack:0.25 ]", + "[ 15/4 → 4/1 | s:bd bank:tr909 duckorbit:[4 7] duckonset:[0.3 0.003] duckattack:0.25 ]", +] +`; + exports[`runs examples > example "duckorbit" example index 0 1`] = ` [ "[ 0/1 → 1/16 | s:bd n:4 duckorbit:2 duckattack:0.2 duckdepth:1 ]", @@ -3139,28 +3256,28 @@ exports[`runs examples > example "duckorbit" example index 0 1`] = ` ] `; -exports[`runs examples > example "duckrelease" example index 0 1`] = ` +exports[`runs examples > example "duckorbit" example index 1 1`] = ` [ - "[ 0/1 → 1/16 | s:bd n:4 duckorbit:2 duckrelease:0.2 duckdepth:1 ]", - "[ 1/4 → 5/16 | s:bd n:4 duckorbit:2 duckrelease:0.2 duckdepth:1 ]", - "[ 1/2 → 9/16 | s:bd n:4 duckorbit:2 duckrelease:0.2 duckdepth:1 ]", - "[ 11/16 → 3/4 | s:bd n:4 duckorbit:2 duckrelease:0.2 duckdepth:1 ]", - "[ 7/8 → 15/16 | s:bd n:4 duckorbit:2 duckrelease:0.2 duckdepth:1 ]", - "[ 1/1 → 17/16 | s:bd n:4 duckorbit:2 duckrelease:0 duckdepth:1 ]", - "[ 5/4 → 21/16 | s:bd n:4 duckorbit:2 duckrelease:0 duckdepth:1 ]", - "[ 3/2 → 25/16 | s:bd n:4 duckorbit:2 duckrelease:0 duckdepth:1 ]", - "[ 27/16 → 7/4 | s:bd n:4 duckorbit:2 duckrelease:0 duckdepth:1 ]", - "[ 15/8 → 31/16 | s:bd n:4 duckorbit:2 duckrelease:0 duckdepth:1 ]", - "[ 2/1 → 33/16 | s:bd n:4 duckorbit:2 duckrelease:0.4 duckdepth:1 ]", - "[ 9/4 → 37/16 | s:bd n:4 duckorbit:2 duckrelease:0.4 duckdepth:1 ]", - "[ 5/2 → 41/16 | s:bd n:4 duckorbit:2 duckrelease:0.4 duckdepth:1 ]", - "[ 43/16 → 11/4 | s:bd n:4 duckorbit:2 duckrelease:0.4 duckdepth:1 ]", - "[ 23/8 → 47/16 | s:bd n:4 duckorbit:2 duckrelease:0.4 duckdepth:1 ]", - "[ 3/1 → 49/16 | s:bd n:4 duckorbit:2 duckrelease:0.2 duckdepth:1 ]", - "[ 13/4 → 53/16 | s:bd n:4 duckorbit:2 duckrelease:0.2 duckdepth:1 ]", - "[ 7/2 → 57/16 | s:bd n:4 duckorbit:2 duckrelease:0.2 duckdepth:1 ]", - "[ 59/16 → 15/4 | s:bd n:4 duckorbit:2 duckrelease:0.2 duckdepth:1 ]", - "[ 31/8 → 63/16 | s:bd n:4 duckorbit:2 duckrelease:0.2 duckdepth:1 ]", + "[ 0/1 → 1/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:1 ]", + "[ 1/4 → 5/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:1 ]", + "[ 1/2 → 9/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:1 ]", + "[ 11/16 → 3/4 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:1 ]", + "[ 7/8 → 15/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:1 ]", + "[ 1/1 → 17/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:1 ]", + "[ 5/4 → 21/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:1 ]", + "[ 3/2 → 25/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:1 ]", + "[ 27/16 → 7/4 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:1 ]", + "[ 15/8 → 31/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:1 ]", + "[ 2/1 → 33/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:1 ]", + "[ 9/4 → 37/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:1 ]", + "[ 5/2 → 41/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:1 ]", + "[ 43/16 → 11/4 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:1 ]", + "[ 23/8 → 47/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:1 ]", + "[ 3/1 → 49/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:1 ]", + "[ 13/4 → 53/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:1 ]", + "[ 7/2 → 57/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:1 ]", + "[ 59/16 → 15/4 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:1 ]", + "[ 31/8 → 63/16 | s:bd n:4 duckorbit:[2 3] duckattack:0.2 duckdepth:1 ]", ] `; From 022ac95bbd169b9a490e3bbccaa9933d0ba61f8e Mon Sep 17 00:00:00 2001 From: Aria Date: Tue, 26 Aug 2025 12:09:12 -0500 Subject: [PATCH 082/335] Typo --- packages/core/controls.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 4deb6f77f..25d2e52f0 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -580,7 +580,7 @@ export const { duckdepth } = registerControl('duckdepth'); /** * The time required for the ducked signal(s) to reach their lowest volume. * Can be used to prevent clicking or for creative rhythmic effects. - + * * Can vary across orbits with the ':' mininotation, e.g. `duckonset("0:0.003")`. * Note: this requires first applying the effect to multiple orbits with e.g. `duckorbit("2:3")`. * @@ -607,7 +607,7 @@ export const { duckonset } = registerControl('duckonset', 'duckons'); /** * The time required for the ducked signal(s) to return to their normal volume. - + * * Can vary across orbits with the ':' mininotation, e.g. `duckonset("0:0.003")`. * Note: this requires first applying the effect to multiple orbits with e.g. `duckorbit("2:3")`. * From 18b1739b890b4659d936b80e17ccce74ffb1952e Mon Sep 17 00:00:00 2001 From: Aria Date: Tue, 26 Aug 2025 12:53:38 -0500 Subject: [PATCH 083/335] Add a space after paragraphs in descriptions and add padding to hover tooltips --- website/src/repl/Repl.css | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/website/src/repl/Repl.css b/website/src/repl/Repl.css index b8443081f..b74eff218 100644 --- a/website/src/repl/Repl.css +++ b/website/src/repl/Repl.css @@ -72,8 +72,7 @@ /* Override default styles from the codemirror inline css for autocomplete info tooltip*/ .cm-tooltip.cm-completionInfo { - padding: 12px !important; - padding-bottom: 12px !important; + padding: 0 !important; border: 1px solid var(--foreground) !important; border-radius: 4px !important; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3) !important; @@ -87,6 +86,8 @@ /* Main tooltip container */ .autocomplete-info-tooltip { + padding: 12px !important; + padding-bottom: 12px !important; border-radius: 4px !important; color: var(--foreground); font-family: var(--font-family, 'SF Mono', 'Monaco', monospace); @@ -97,6 +98,10 @@ min-width: 400px; } +.autocomplete-info-tooltip p { + margin-bottom: 1em; +} + .autocomplete-info-function-name { font-size: 15px; font-weight: 600; From 877bc95a5836bd4d45755dcc5ac673af1cc7e05b Mon Sep 17 00:00:00 2001 From: Aria Date: Tue, 26 Aug 2025 12:54:39 -0500 Subject: [PATCH 084/335] Switch to more specific class and fix p->div --- packages/codemirror/autocomplete.mjs | 2 +- website/src/repl/Repl.css | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/codemirror/autocomplete.mjs b/packages/codemirror/autocomplete.mjs index c0845895e..646107236 100644 --- a/packages/codemirror/autocomplete.mjs +++ b/packages/codemirror/autocomplete.mjs @@ -58,7 +58,7 @@ export const Autocomplete = ({ doc, label }) => h`

${label || getDocLabel(doc)}

- ${doc.description ? `

${doc.description}

` : ''} + ${doc.description ? `
${doc.description}
` : ''} ${buildParamsList(doc.params)} ${buildExamples(doc.examples)}
diff --git a/website/src/repl/Repl.css b/website/src/repl/Repl.css index b74eff218..ad8b6a40d 100644 --- a/website/src/repl/Repl.css +++ b/website/src/repl/Repl.css @@ -98,7 +98,7 @@ min-width: 400px; } -.autocomplete-info-tooltip p { +.autocomplete-info-function-description p { margin-bottom: 1em; } From a5886bb9d46259dea09539d29e7dc5bc9017e507 Mon Sep 17 00:00:00 2001 From: Aria Date: Tue, 26 Aug 2025 14:14:00 -0500 Subject: [PATCH 085/335] Use white-space instead; fix scrolling; don't close autocomplete tooltips on click --- packages/codemirror/autocomplete.mjs | 14 ++++++++------ website/src/repl/Repl.css | 15 +++++++++------ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/packages/codemirror/autocomplete.mjs b/packages/codemirror/autocomplete.mjs index 646107236..59ca8adf2 100644 --- a/packages/codemirror/autocomplete.mjs +++ b/packages/codemirror/autocomplete.mjs @@ -56,11 +56,13 @@ const buildExamples = (examples) => export const Autocomplete = ({ doc, label }) => h` -
-

${label || getDocLabel(doc)}

- ${doc.description ? `
${doc.description}
` : ''} - ${buildParamsList(doc.params)} - ${buildExamples(doc.examples)} +
+
+

${label || getDocLabel(doc)}

+ ${doc.description ? `
${doc.description}
` : ''} + ${buildParamsList(doc.params)} + ${buildExamples(doc.examples)} +
`[0]; @@ -98,4 +100,4 @@ export const strudelAutocomplete = (context) => { }; export const isAutoCompletionEnabled = (enabled) => - enabled ? [autocompletion({ override: [strudelAutocomplete] })] : []; + enabled ? [autocompletion({ override: [strudelAutocomplete], closeOnBlur: false })] : []; diff --git a/website/src/repl/Repl.css b/website/src/repl/Repl.css index ad8b6a40d..498679090 100644 --- a/website/src/repl/Repl.css +++ b/website/src/repl/Repl.css @@ -79,15 +79,12 @@ max-width: 500px !important; min-width: 300px !important; max-height: 400px !important; - white-space: normal !important; - overflow: auto !important; background-color: var(--lineHighlight) !important; } /* Main tooltip container */ -.autocomplete-info-tooltip { +.autocomplete-info-container { padding: 12px !important; - padding-bottom: 12px !important; border-radius: 4px !important; color: var(--foreground); font-family: var(--font-family, 'SF Mono', 'Monaco', monospace); @@ -96,10 +93,16 @@ max-width: 600px; max-height: 400px; min-width: 400px; + white-space: normal !important; + overflow-y: auto !important; } -.autocomplete-info-function-description p { - margin-bottom: 1em; +.autocomplete-info-tooltip { + overflow-y: auto !important; +} + +.autocomplete-info-function-description { + white-space: pre-wrap !important; } .autocomplete-info-function-name { From 02cd79a6d981df25f7d75ed6a47024565db29ed5 Mon Sep 17 00:00:00 2001 From: Aria Date: Mon, 25 Aug 2025 08:44:18 -0500 Subject: [PATCH 086/335] Add wavetable oscillator with scanning, warps, and detune --- packages/core/controls.mjs | 39 +++ packages/sampler/sample-server.mjs | 39 ++- packages/superdough/helpers.mjs | 28 +- packages/superdough/index.mjs | 1 + packages/superdough/superdough.mjs | 12 +- packages/superdough/synth.mjs | 27 +- packages/superdough/wavetable.mjs | 253 +++++++++++++++++++ packages/superdough/worklets.mjs | 393 ++++++++++++++++++++++++++--- 8 files changed, 715 insertions(+), 77 deletions(-) create mode 100644 packages/superdough/wavetable.mjs diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index e6181d453..ba77f1a35 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -87,6 +87,45 @@ export function registerControl(names, ...aliases) { */ export const { s, sound } = registerControl(['s', 'n', 'gain'], 'sound'); +/** + * Position in the wavetable of the wavetable oscillator + * + * @name wtPos + * @param {number | Pattern} position Position in the wavetable from 0 to 1 + * @synonyms wavetablePosition + * + */ +export const { wtPos, wavetablePosition } = registerControl('wtPos', 'wavetablePosition'); + +/** + * Amount of warp (alteration of the waveform) to apply to the wavetable oscillator + * + * @name wtWarp + * @param {number | Pattern} amount Warp of the wavetable from 0 to 1 + * @synonyms wavetableWarp + * + */ +export const { wtWarp, wavetableWarp } = registerControl('wtWarp', 'wavetableWarp'); + +/** + * Amount of warp (alteration of the waveform) to apply to the wavetable oscillator. + * + * The current options are: + * 0 = asym + * 1 = mirror + * 2 = bend+ + * 3 = bend- + * 4 = bend+/- + * 5 = sync + * 6 = quantize + * + * @name wtWarpMode + * @param {number | Pattern} mode Warp mode: an integer + * @synonyms wavetableWarpMode + * + */ +export const { wtWarpMode, wavetableWarpMode } = registerControl('wtWarpMode', 'wavetableWarpMode'); + /** * Define a custom webaudio node to use as a sound source. * diff --git a/packages/sampler/sample-server.mjs b/packages/sampler/sample-server.mjs index 08456add9..2832741aa 100644 --- a/packages/sampler/sample-server.mjs +++ b/packages/sampler/sample-server.mjs @@ -1,10 +1,10 @@ #!/usr/bin/env node import cowsay from 'cowsay'; -import { createReadStream, existsSync } from 'fs'; +import { createReadStream, existsSync, writeFileSync } from 'fs'; import { readdir } from 'fs/promises'; import http from 'http'; -import { join, sep } from 'path'; +import { join, sep, resolve } from 'path'; import os from 'os'; // eslint-disable-next-line @@ -36,17 +36,19 @@ async function getFilesInDirectory(directory) { return files; } -async function getBanks(directory) { +async function getBanks(directory, flat = false) { let files = await getFilesInDirectory(directory); let banks = {}; directory = directory.split(sep).join('/'); files = files.map((path) => { path = path.split(sep).join('/'); - const [bank] = path.split('/').slice(-2); + const subDir = path.replace(directory, ''); + const subDirFlat = subDir.replaceAll('/', '_').slice(1); // remove initial underscore + const subDirFlatStem = subDirFlat.replace(/\.[^.]+$/, ''); // remove extension + let bank = flat ? subDirFlatStem : subDir.split('/')[0]; banks[bank] = banks[bank] || []; - const relativeUrl = path.replace(directory, ''); - banks[bank].push(relativeUrl); - return relativeUrl; + banks[bank].push(subDir); + return subDir; }); banks._base = `http://localhost:5432`; return { banks, files }; @@ -54,14 +56,25 @@ async function getBanks(directory) { const args = process.argv.slice(2); +function getArgValue(flag) { + const i = args.indexOf(flag); + if (i !== -1) { + const nextIsFlag = args[i + 1]?.startsWith('--') ?? true; + if (nextIsFlag) return true; + return args[i + 1]; + } +} + // eslint-disable-next-line -const directory = process.cwd(); +let directory = getArgValue('--dir') || process.cwd(); +directory = resolve(directory); if (args.includes('--json')) { - const { banks, files } = await getBanks(directory); + const { banks } = await getBanks(directory, getArgValue('--flat')); const json = JSON.stringify(banks); - console.log(json); - process.exit(0); + const outFile = resolve(directory, 'strudel.json'); + writeFileSync(outFile, json, 'utf8'); + console.log(`Wrote json to ${outFile}`); } console.log( @@ -74,7 +87,7 @@ console.log( const server = http.createServer(async (req, res) => { res.setHeader('Access-Control-Allow-Origin', '*'); - const { banks, files } = await getBanks(directory); + const { banks, files } = await getBanks(directory, getArgValue('--flat')); if (req.url === '/') { res.setHeader('Content-Type', 'application/json'); return res.end(JSON.stringify(banks)); @@ -82,7 +95,7 @@ const server = http.createServer(async (req, res) => { let subpath = decodeURIComponent(req.url); const filePath = join(directory, subpath.split('/').join(sep)); - //console.log('GET:', filePath); + // console.log('GET:', filePath); const isFound = existsSync(filePath); if (!isFound) { res.statusCode = 404; diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index 81bec9399..7879cff00 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -1,5 +1,5 @@ import { getAudioContext } from './superdough.mjs'; -import { clamp, nanFallback } from './util.mjs'; +import { clamp, nanFallback, midiToFreq, noteToMidi } from './util.mjs'; import { getNoiseBuffer } from './noise.mjs'; export const noises = ['pink', 'white', 'brown', 'crackle']; @@ -21,7 +21,9 @@ const getSlope = (y1, y2, x1, x2) => { export function getWorklet(ac, processor, params, config) { const node = new AudioWorkletNode(ac, processor, config); Object.entries(params).forEach(([key, value]) => { - node.parameters.get(key).value = value; + if (value !== undefined) { + node.parameters.get(key).value = value; + } }); return node; } @@ -307,3 +309,25 @@ export function applyFM(param, value, begin) { } return { stop }; } + +export const getFrequencyFromValue = (value, defaultNote = 36) => { + let { note, freq } = value; + note = note || defaultNote; + if (typeof note === 'string') { + note = noteToMidi(note); // e.g. c3 => 48 + } + // get frequency + if (!freq && typeof note === 'number') { + freq = midiToFreq(note); // + 48); + } + + return Number(freq); +}; + +export const destroyAudioWorkletNode = (node) => { + if (node == null) { + return; + } + node.disconnect(); + node.parameters.get('end')?.setValueAtTime(0, 0); +}; diff --git a/packages/superdough/index.mjs b/packages/superdough/index.mjs index fd49fe338..a7e87ffae 100644 --- a/packages/superdough/index.mjs +++ b/packages/superdough/index.mjs @@ -11,3 +11,4 @@ export * from './synth.mjs'; export * from './zzfx.mjs'; export * from './logger.mjs'; export * from './dspworklet.mjs'; +export * from './wavetable.mjs'; diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index eb1466d91..37579005a 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -555,6 +555,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) tremolophase = 0, tremoloshape, s = getDefaultValue('s'), + wt, bank, source, gain = getDefaultValue('gain'), @@ -681,8 +682,13 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) let sourceNode; if (source) { sourceNode = source(t, value, hapDuration, cps); - } else if (getSound(s)) { - const { onTrigger } = getSound(s); + } else { + const soundSource = wt ?? s; + const sound = getSound(soundSource); + if (!sound) { + throw new Error(`sound ${soundSource} not found! Is it loaded?`); + } + const { onTrigger } = sound; const onEnded = () => { audioNodes.forEach((n) => n?.disconnect()); activeSoundSources.delete(chainID); @@ -693,8 +699,6 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) sourceNode = soundHandle.node; activeSoundSources.set(chainID, soundHandle); } - } else { - throw new Error(`sound ${s} not found! Is it loaded?`); } if (!sourceNode) { // if onTrigger does not return anything, we will just silently skip diff --git a/packages/superdough/synth.mjs b/packages/superdough/synth.mjs index 71138ae41..5b1b4edf1 100644 --- a/packages/superdough/synth.mjs +++ b/packages/superdough/synth.mjs @@ -1,39 +1,20 @@ -import { clamp, midiToFreq, noteToMidi } from './util.mjs'; +import { clamp } from './util.mjs'; import { registerSound, getAudioContext, soundMap, getLfo } from './superdough.mjs'; import { applyFM, + destroyAudioWorkletNode, gainNode, getADSRValues, + getFrequencyFromValue, getParamADSR, getPitchEnvelope, getVibratoOscillator, - webAudioTimeout, getWorklet, noises, + webAudioTimeout, } from './helpers.mjs'; import { getNoiseMix, getNoiseOscillator } from './noise.mjs'; -const getFrequencyFromValue = (value, defaultNote = 36) => { - let { note, freq } = value; - note = note || defaultNote; - if (typeof note === 'string') { - note = noteToMidi(note); // e.g. c3 => 48 - } - // get frequency - if (!freq && typeof note === 'number') { - freq = midiToFreq(note); // + 48); - } - - return Number(freq); -}; -function destroyAudioWorkletNode(node) { - if (node == null) { - return; - } - node.disconnect(); - node.parameters.get('end')?.setValueAtTime(0, 0); -} - const waveforms = ['triangle', 'square', 'sawtooth', 'sine']; const waveformAliases = [ ['tri', 'triangle'], diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs new file mode 100644 index 000000000..d18f1fdff --- /dev/null +++ b/packages/superdough/wavetable.mjs @@ -0,0 +1,253 @@ +import { getAudioContext, registerSound } from './index.mjs'; +import { clamp, getSoundIndex, valueToMidi } from './util.mjs'; +import { + destroyAudioWorkletNode, + getADSRValues, + getFrequencyFromValue, + getParamADSR, + getPitchEnvelope, + getVibratoOscillator, + getWorklet, + webAudioTimeout, +} from './helpers.mjs'; +import { logger } from './logger.mjs'; + +const WT_MAX_MIP_LEVELS = 6; +export const WarpMode = Object.freeze({ + NONE: 0, + ASYM: 1, + MIRROR: 2, + BENDP: 3, + BENDM: 4, + BENDMP: 5, + SYNC: 6, + QUANT: 7, + FOLD: 8, + PWM: 9, + ORBIT: 10, + SPIN: 11, + CHAOS: 12, + PRIMES: 13, + BINARY: 14, + BROWNIAN: 15, + RECIPROCAL: 16, + WORMHOLE: 17, + LOGISTIC: 18, + SIGMOID: 19, + FRACTAL: 20, + FLIP: 21, +}); + +async function loadWavetableFrames(url, label, frameLen = 256) { + const ac = getAudioContext(); + const buf = await loadBuffer(url, ac, label); + const ch0 = buf.getChannelData(0); + const total = ch0.length; + const numFrames = Math.floor(total / frameLen); + const frames = new Array(numFrames); + for (let i = 0; i < numFrames; i++) { + const start = i * frameLen; + frames[i] = ch0.subarray(start, start + frameLen); + } + + // build mipmaps + const mipmaps = [frames]; + let levelFrames = frames; + for (let level = 1; level < WT_MAX_MIP_LEVELS; level++) { + const prevLen = levelFrames[0].length; + if (prevLen <= 32) break; + const nextLen = prevLen >> 1; + const next = levelFrames.map((src) => { + const out = new Float32Array(nextLen); + for (let j = 0; j < nextLen; j++) { + out[j] = (src[2 * j] + src[2 * j + 1]) / 2; + } + return out; + }); + mipmaps.push(next); + levelFrames = next; + } + return { frames, mipmaps, frameLen, numFrames }; +} + +const loadCache = {}; + +function humanFileSize(bytes, si) { + var thresh = si ? 1000 : 1024; + if (bytes < thresh) return bytes + ' B'; + var units = si + ? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] + : ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']; + var u = -1; + do { + bytes /= thresh; + ++u; + } while (bytes >= thresh); + return bytes.toFixed(1) + ' ' + units[u]; +} + +export function getTableInfo(hapValue, bank) { + const { wt, n = 0 } = hapValue; + let midi = valueToMidi(hapValue, 36); + let transpose = midi - 36; // C3 is middle C; + const index = getSoundIndex(n, bank.length); + const tableUrl = bank[index]; + const label = `${wt}:${index}`; + return { transpose, tableUrl, index, midi, label }; +} + +const loadBuffer = (url, ac, wt, n = 0) => { + const label = wt ? `table "${wt}:${n}"` : 'table'; + url = url.replace('#', '%23'); + if (!loadCache[url]) { + logger(`[wavetable] load ${label}..`, 'load-table', { url }); + const timestamp = Date.now(); + loadCache[url] = fetch(url) + .then((res) => res.arrayBuffer()) + .then(async (res) => { + const took = Date.now() - timestamp; + const size = humanFileSize(res.byteLength); + logger(`[wavetable] load ${label}... done! loaded ${size} in ${took}ms`, 'loaded-table', { url }); + const decoded = await ac.decodeAudioData(res); + return decoded; + }); + } + return loadCache[url]; +}; + +function githubPath(base, subpath = '') { + if (!base.startsWith('github:')) { + throw new Error('expected "github:" at the start of pseudoUrl'); + } + let [_, path] = base.split('github:'); + path = path.endsWith('/') ? path.slice(0, -1) : path; + if (path.split('/').length === 2) { + // assume main as default branch if none set + path += '/main'; + } + return `https://raw.githubusercontent.com/${path}/${subpath}`; +} + +const _processTables = (json, baseUrl, frameLen) => { + return Object.entries(json).forEach(([key, value]) => { + if (typeof value === 'string') { + value = [value]; + } + if (typeof value !== 'object') { + throw new Error('wrong json format for ' + key); + } + baseUrl = value._base || baseUrl; + if (baseUrl.startsWith('github:')) { + baseUrl = githubPath(baseUrl, ''); + } + value = value.map((v) => baseUrl + v); + registerSound(key, (t, hapValue, onended) => onTriggerSynth(t, hapValue, onended, value, frameLen), { + type: 'wavetable', + tables: value, + baseUrl, + frameLen, + }); + }); +}; + +/** + * Loads a collection of wavetables to use with `wt` + * + * @name tables + */ +export const tables = async (url, frameLen, json) => { + if (json !== undefined) return _processTables(json, url, frameLen); + if (url.startsWith('github:')) { + url = githubPath(url, 'strudel.json'); + } + if (url.startsWith('local:')) { + url = `http://localhost:5432`; + } + if (typeof fetch !== 'function') { + // not a browser + return; + } + const base = url.split('/').slice(0, -1).join('/'); + if (typeof fetch === 'undefined') { + // skip fetch when in node / testing + return; + } + return fetch(url) + .then((res) => res.json()) + .then((json) => _processTables(json, url, frameLen)) + .catch((error) => { + console.error(error); + throw new Error(`error loading "${url}"`); + }); +}; + +async function onTriggerSynth(t, value, onended, bank, frameLen) { + let { s, n = 0, duration } = value; + const ac = getAudioContext(); + let [attack, decay, sustain, release] = getADSRValues([value.attack, value.decay, value.sustain, value.release]); + let sourceDesc, holdEnd, envEnd; + let { unison = 5, spread = 0.6, detune, wtPos, wtWarp, wtWarpMode } = value; + if (typeof wtWarpMode === 'string') { + wtWarpMode = WarpMode[wtWarpMode.toUpperCase()] ?? WarpMode.NONE; + } + detune = detune ?? 0.18; + const frequency = getFrequencyFromValue(value); + const voices = clamp(unison, 1, 100); + let { tableUrl, label } = getTableInfo(value, bank); + const payload = await loadWavetableFrames(tableUrl, label, frameLen); + holdEnd = t + duration; + envEnd = holdEnd + release + 0.01; + const worklet = getWorklet( + ac, + 'wavetable-oscillator-processor', + { + begin: t, + end: envEnd, + frequency, + detune, + position: wtPos, + warp: wtWarp, + warpMode: wtWarpMode, + voices, + spread, + }, + { outputChannelCount: [2] }, + ); + worklet.port.postMessage({ type: 'tables', payload }); + sourceDesc = { source: worklet }; + const { source } = sourceDesc; + if (ac.currentTime > t) { + logger(`[wavetable] still loading sound "${s}:${n}"`, 'highlight'); + return; + } + if (!source) { + logger(`[wavetable] could not load "${s}:${n}"`, 'error'); + return; + } + let vibratoOscillator = getVibratoOscillator(source.detune, value, t); + const envGain = ac.createGain(); + const node = source.connect(envGain); + getParamADSR(node.gain, attack, decay, sustain, release, 0, 1, t, holdEnd, 'linear'); + getPitchEnvelope(source.detune, value, t, holdEnd); + + const out = ac.createGain(); // we need a separate gain for the cutgroups because firefox... + node.connect(out); + let handle = { node: out, bufferSource: source }; + let timeoutNode = webAudioTimeout( + ac, + () => { + source.disconnect(); + destroyAudioWorkletNode(source); + vibratoOscillator?.stop(); + node.disconnect(); + out.disconnect(); + onended(); + }, + t, + envEnd, + ); + handle.stop = (time) => { + timeoutNode.stop(time); + }; + return handle; +} diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 2406d56dc..7775803d9 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -6,7 +6,21 @@ import OLAProcessor from './ola-processor'; import FFT from './fft.js'; const clamp = (num, min, max) => Math.min(Math.max(num, min), max); -const _mod = (n, m) => ((n % m) + m) % m; +const mod = (n, m) => ((n % m) + m) % m; +const lerp = (a, b, n) => n * (b - a) + a; +const pv = (arr, n) => arr[n] ?? arr[0]; +const frac = (x) => x - Math.floor(x); +const ffloor = (x) => x | 0; // fast floor for non-negative + +const getUnisonDetune = (unison, detune, voiceIndex) => { + if (unison < 2) { + return 0; + } + return lerp(-detune * 0.5, detune * 0.5, voiceIndex / (unison - 1)); +}; +const applySemitoneDetuneToFrequency = (frequency, detune) => { + return frequency * Math.pow(2, detune / 12); +}; // Restrict phase to the range [0, maxPhase) via wrapping function wrapPhase(phase, maxPhase = 1) { @@ -150,7 +164,7 @@ class LFOProcessor extends AudioWorkletProcessor { const blockSize = output[0].length ?? 0; if (this.phase == null) { - this.phase = _mod(time * frequency + phaseoffset, 1); + this.phase = mod(time * frequency + phaseoffset, 1); } const dt = frequency / sampleRate; for (let n = 0; n < blockSize; n++) { @@ -378,21 +392,6 @@ class DistortProcessor extends AudioWorkletProcessor { registerProcessor('distort-processor', DistortProcessor); // SUPERSAW -function lerp(a, b, n) { - return n * (b - a) + a; -} - -function getUnisonDetune(unison, detune, voiceIndex) { - if (unison < 2) { - return 0; - } - return lerp(-detune * 0.5, detune * 0.5, voiceIndex / (unison - 1)); -} - -function applySemitoneDetuneToFrequency(frequency, detune) { - return frequency * Math.pow(2, detune / 12); -} - class SuperSawOscillatorProcessor extends AudioWorkletProcessor { constructor() { super(); @@ -454,29 +453,31 @@ class SuperSawOscillatorProcessor extends AudioWorkletProcessor { } const output = outputs[0]; - const voices = params.voices[0]; - const freqspread = params.freqspread[0]; - const panspread = params.panspread[0] * 0.5 + 0.5; - const gain1 = Math.sqrt(1 - panspread); - const gain2 = Math.sqrt(panspread); - for (let n = 0; n < voices; n++) { - const isOdd = (n & 1) == 1; - let gainL = gain1; - let gainR = gain2; - // invert right and left gain - if (isOdd) { - gainL = gain2; - gainR = gain1; - } - for (let i = 0; i < output[0].length; i++) { - // Main detuning - let freq = applySemitoneDetuneToFrequency(params.frequency[i] ?? params.frequency[0], params.detune[0] / 100); + for (let i = 0; i < output[0].length; i++) { + const detune = pv(params.detune, i); + const voices = pv(params.voices, i); + const freqspread = pv(params.freqspread, i); + const panspread = pv(params.panspread, i) * 0.5 + 0.5; + const gain1 = Math.sqrt(1 - panspread); + const gain2 = Math.sqrt(panspread); + let freq = pv(params.frequency, i); + // Main detuning + freq = applySemitoneDetuneToFrequency(freq, detune / 100); + for (let n = 0; n < voices; n++) { + const isOdd = (n & 1) == 1; + let gainL = gain1; + let gainR = gain2; + // invert right and left gain + if (isOdd) { + gainL = gain2; + gainR = gain1; + } // Individual voice detuning freq = applySemitoneDetuneToFrequency(freq, getUnisonDetune(voices, freqspread, n)); // We must wrap this here because it is passed into sawblep below which // has domain [0, 1] - const dt = _mod(freq / sampleRate, 1); + const dt = mod(freq / sampleRate, 1); this.phase[n] = this.phase[n] ?? Math.random(); const v = waveshapes.sawblep(this.phase[n], dt); @@ -907,3 +908,325 @@ class ByteBeatProcessor extends AudioWorkletProcessor { } registerProcessor('byte-beat-processor', ByteBeatProcessor); + + +export const WarpMode = Object.freeze({ + NONE: 0, + ASYM: 1, + MIRROR: 2, + BENDP: 3, + BENDM: 4, + BENDMP: 5, + SYNC: 6, + QUANT: 7, + FOLD: 8, + PWM: 9, + ORBIT: 10, + SPIN: 11, + CHAOS: 12, + PRIMES: 13, + BINARY: 14, + BROWNIAN: 15, + RECIPROCAL: 16, + WORMHOLE: 17, + LOGISTIC: 18, + SIGMOID: 19, + FRACTAL: 20, + FLIP: 21, +}); + +function hash32(u) { + u = u + 0x7ed55d16 + (u << 12); + u = u ^ 0xc761c23c ^ (u >>> 19); + u = u + 0x165667b1 + (u << 5); + u = (u + 0xd3a2646c) ^ (u << 9); + u = u + 0xfd7046c5 + (u << 3); + u = u ^ 0xb55a4f09 ^ (u >>> 16); + return u >>> 0; +} +const hash01 = (i) => (hash32(i) >>> 8) / 0x01000000; + +function bitReverse(i, n) { + let r = 0; + for (let b = 0; b < n; b++) { + r = (r << 1) | (i & 1); + i >>>= 1; + } + return r; +} + +function noise(x) { + const i = Math.floor(x), + f = x - i; + const a = hash01(i), + b = hash01(i + 1); + return a + (b - a) * f; +} + +function brownian(x, oct = 4) { + let amp = 0.5, + sum = 0, + norm = 0, + freq = 1; + for (let o = 0; o < oct; o++) { + sum += amp * noise(x * freq); + norm += amp; + amp *= 0.5; + freq *= 2; + } + return (sum / norm) * 2 - 1; +} + +class WavetableOscillatorProcessor extends AudioWorkletProcessor { + static get parameterDescriptors() { + return [ + { name: 'begin', defaultValue: 0, min: 0, max: Number.POSITIVE_INFINITY }, + { name: 'end', defaultValue: 0, min: 0, max: Number.POSITIVE_INFINITY }, + { name: 'frequency', defaultValue: 220, minValue: 0.01, maxValue: 20000 }, + { name: 'detune', defaultValue: 0 }, + { name: 'position', defaultValue: 0, minValue: 0, maxValue: 1 }, + { name: 'warp', defaultValue: 0, minValue: 0, maxValue: 1 }, + { name: 'warpMode', defaultValue: 0 }, + { name: 'voices', defaultValue: 1, minValue: 1, maxValue: 32 }, + { name: 'spread', defaultValue: 0, minValue: 0, maxValue: 1 }, + ]; + } + + constructor(options) { + super(options); + this.tables = null; + this.frameLen = 0; + this.numFrames = 0; + this.phase = []; + this.syncRatio = 1; + + this.port.onmessage = (e) => { + const { type, payload } = e.data || {}; + if (type === 'tables') { + this.tables = payload.mipmaps; + this.frameLen = payload.frameLen; + this.numFrames = this.tables[0].length; + } + }; + this.lfoPhase = 0; + } + + _chooseMip(dphi) { + const approxHarm = Math.min(64, 1 / Math.max(1e-6, dphi)); + let level = 0; + while (level + 1 < (this.tables?.length || 1) && approxHarm < this.tables[level][0].length / 8) { + level++; + } + return level; + } + + _mirror(x) { + return 1 - Math.abs(2 * x - 1); + } + + _toBits(amt, min = 2, max = 12) { + const b = max + (min - max) * amt; + return { b, n: Math.round(Math.pow(2, b)) }; + } + + _warpPhase(phase, amt, mode) { + switch (mode) { + case WarpMode.NONE: { + return phase; + } + case WarpMode.ASYM: { + const a = 0.01 + 0.99 * amt; + return phase < a ? (0.5 * phase) / a : 0.5 + (0.5 * (phase - a)) / (1 - a); + } + case WarpMode.MIRROR: { + // Asym, then mirror + return this._mirror(this._warpPhase(phase, amt, WarpMode.ASYM)); + } + case WarpMode.BENDP: { + return Math.pow(phase, 1 + 3 * amt); + } + case WarpMode.BENDM: { + return Math.pow(phase, 1 / (1 + 3 * amt)); + } + case WarpMode.BENDMP: { + return amt < 0.5 ? this._warpPhase(phase, 1 - 2 * amt, 3) : this._warpPhase(phase, 2 * amt - 1, 2); + } + case WarpMode.SYNC: { + const syncRatio = Math.pow(16, amt * amt); + return (phase * syncRatio) % 1; + } + case WarpMode.QUANT: { + const { n } = this._toBits(amt); + return ffloor(phase * n) / n; + } + case WarpMode.FOLD: { + const K = 7; + const k = 1 + Math.max(1, Math.round(K * amt)); + return Math.abs(frac(k * phase) - 0.5) * 2; + } + case WarpMode.PWM: { + const w = clamp(0.5 + 0.49 * (2 * amt - 1), 0, 1); + if (phase < w) return (phase / w) * 0.5; + return 0.5 + ((phase - w) / (1 - w)) * 0.5; + } + case WarpMode.ORBIT: { + const depth = 0.5 * amt; + const n = 3; + return frac(phase + depth * Math.sin(2 * Math.PI * n * phase)); + } + case WarpMode.SPIN: { + const depth = 0.5 * amt; + const { n } = this._toBits(amt, 1, 6); + return frac(phase + depth * Math.sin(2 * Math.PI * n * phase)); + } + case WarpMode.CHAOS: { + const r = 3.7 + 0.3 * amt; + const logistic = r * phase * (1 - phase); + return clamp((1 - amt) * phase + amt * logistic, 0, 1); + } + case WarpMode.PRIMES: { + const isPrime = (n) => { + if (n < 2) return false; + if (n % 2 === 0) return n === 2; + for (let d = 3; d * d <= n; d += 2) if (n % d === 0) return false; + return true; + }; + let { n } = this._toBits(amt, 3); + while (!isPrime(n)) n++; + return ffloor(phase * n) / n; + } + case WarpMode.BINARY: { + let { b } = this._toBits(amt, 3); + b = Math.round(b); + const n = 1 << b; + const idx = ffloor(phase * n); + const ridx = bitReverse(idx, b); + return ridx / n; + } + case WarpMode.MODULAR: { + const { n } = this._toBits(amt); + const depth = 0.5 * amt; + const jump = frac(phase * n) / n; + return frac(phase + depth * jump); + } + case WarpMode.BROWNIAN: { + const disp = 0.25 * amt * brownian(64 * phase, 4); + return frac(phase + disp); + } + case WarpMode.RECIPROCAL: { + const g = 2 + 4 * amt; + const num = phase * g; + const den = phase + (1 - phase) * g; + const y = den > 1e-12 ? num / den : 0; + return clamp(y, 0, 1); + } + case WarpMode.WORMHOLE: { + const gap = clamp(0.8 * amt, 0, 1); + const a = 0.5 * (1 - gap); + const b = 0.5 * (1 + gap); + if (phase < a) return (phase / a) * 0.5; + if (phase > b) return 0.5 * (1 + (phase - b) / (1 - b)); + return 0.5; + } + case WarpMode.LOGISTIC: { + let x = phase; + const r = 3.6 + 0.4 * amt; + const iters = 1 + Math.round(2 * amt); + for (let i = 0; i < iters; i++) x = r * x * (1 - x); + return clamp(x, 0, 1); + } + case WarpMode.SIGMOID: { + const k = 1 + 10 * amt; + const x = phase - 0.5; + const y = 1 / (1 + Math.exp(-k * x)); + const y0 = 1 / (1 + Math.exp(0.5 * k)); + const y1 = 1 / (1 + Math.exp(-0.5 * k)); + return (y - y0) / (y1 - y0); + } + case WarpMode.FRACTAL: { + const d = 0.5 * Math.sin(2 * Math.PI * phase) * amt; + return frac(phase + d); + } + case WarpMode.FLIP: { + return phase; + } + default: + return phase; + } + } + + _sampleFrame(frame, phase) { + const pos = phase * (frame.length - 1); + const i = pos | 0; + const frac = pos - i; + const a = frame[i]; + const b = frame[(i + 1) % frame.length]; + return a + (b - a) * frac; + } + + process(_inputs, outputs, parameters) { + if (currentTime >= parameters.end[0]) { + return false; + } + if (currentTime <= parameters.begin[0]) { + return true; + } + const outL = outputs[0][0]; + const outR = outputs[0][1] || outputs[0][0]; + + if (!this.tables) { + outL.fill(0); + if (outR !== outL) outR.set(outL); + return true; + } + + for (let i = 0; i < outL.length; i++) { + const detune = pv(parameters.detune, i); + const spread = pv(parameters.spread, i) * 0.5 + 0.5; + const tablePos = pv(parameters.position, i); //Math.sin(2 * Math.PI * this.lfoPhase); + // morph across frames + const idx = tablePos * (this.numFrames - 1); + const fIdx = idx | 0; + const frac = idx - fIdx; + const warpAmount = 0.5 * Math.sin(2 * Math.PI * this.lfoPhase) + 0.5; // pv(parameters.warp, i); + const warpMode = pv(parameters.warpMode, i); + const voices = pv(parameters.voices, i); + const gain1 = Math.sqrt(1 - spread); + const gain2 = Math.sqrt(spread); + let f = pv(parameters.frequency, i); + f = applySemitoneDetuneToFrequency(f, detune / 100); // overall detune + for (let n = 0; n < voices; n++) { + const isOdd = (n & 1) == 1; + let gainL = gain1; + let gainR = gain2; + // invert right and left gain + if (isOdd) { + gainL = gain2; + gainR = gain1; + } + let fVoice = applySemitoneDetuneToFrequency(f, getUnisonDetune(voices, detune, n)); // voice detune + const dPhase = fVoice / sampleRate; + const level = this._chooseMip(dPhase); + const bank = this.tables[level]; + + // warp phase then sample + this.phase[n] = this.phase[n] ?? Math.random(); + let ph = this._warpPhase(this.phase[n], warpAmount, warpMode); + const s0 = this._sampleFrame(bank[fIdx], ph); + const s1 = this._sampleFrame(bank[Math.min(this.numFrames - 1, fIdx + 1)], ph); + let s = s0 + (s1 - s0) * frac; + if (warpMode === WarpMode.FLIP && this.phase[n] < warpAmount) { + s = -s; + } + outL[i] += (s * gainL) / Math.sqrt(voices); + outR[i] += (s * gainR) / Math.sqrt(voices); + this.phase[n] = wrapPhase(this.phase[n] + dPhase); + } + this.lfoPhase += 1 / sampleRate; + if (this.lfoPhase >= 1) this.lfoPhase -= 1; + } + return true; + } +} + +registerProcessor('wavetable-oscillator-processor', WavetableOscillatorProcessor); From d1869c18ba526e8ca251fdcc3aaff048d8f9ba4c Mon Sep 17 00:00:00 2001 From: Aria Date: Thu, 28 Aug 2025 16:23:40 -0500 Subject: [PATCH 087/335] Remove internal LFO --- packages/superdough/wavetable.mjs | 2 +- packages/superdough/worklets.mjs | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index d18f1fdff..9b9e325f7 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -232,7 +232,7 @@ async function onTriggerSynth(t, value, onended, bank, frameLen) { const out = ac.createGain(); // we need a separate gain for the cutgroups because firefox... node.connect(out); - let handle = { node: out, bufferSource: source }; + let handle = { node: out, bufferSource: source, oscillator: worklet }; let timeoutNode = webAudioTimeout( ac, () => { diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 7775803d9..ce0e7ac80 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -1008,7 +1008,6 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { this.numFrames = this.tables[0].length; } }; - this.lfoPhase = 0; } _chooseMip(dphi) { @@ -1183,12 +1182,11 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { for (let i = 0; i < outL.length; i++) { const detune = pv(parameters.detune, i); const spread = pv(parameters.spread, i) * 0.5 + 0.5; - const tablePos = pv(parameters.position, i); //Math.sin(2 * Math.PI * this.lfoPhase); - // morph across frames + const tablePos = pv(parameters.position, i); const idx = tablePos * (this.numFrames - 1); const fIdx = idx | 0; const frac = idx - fIdx; - const warpAmount = 0.5 * Math.sin(2 * Math.PI * this.lfoPhase) + 0.5; // pv(parameters.warp, i); + const warpAmount = pv(parameters.warp, i); const warpMode = pv(parameters.warpMode, i); const voices = pv(parameters.voices, i); const gain1 = Math.sqrt(1 - spread); @@ -1222,8 +1220,6 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { outR[i] += (s * gainR) / Math.sqrt(voices); this.phase[n] = wrapPhase(this.phase[n] + dPhase); } - this.lfoPhase += 1 / sampleRate; - if (this.lfoPhase >= 1) this.lfoPhase -= 1; } return true; } From fe46e1da5372ddf3c86e023566e9984012fd070e Mon Sep 17 00:00:00 2001 From: Aria Date: Thu, 28 Aug 2025 16:28:33 -0500 Subject: [PATCH 088/335] Update docstring to include new warp modes; save sample server for a separate PR --- packages/core/controls.mjs | 10 ++------ packages/sampler/sample-server.mjs | 39 ++++++++++-------------------- 2 files changed, 15 insertions(+), 34 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index ba77f1a35..1099fe9ec 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -110,14 +110,8 @@ export const { wtWarp, wavetableWarp } = registerControl('wtWarp', 'wavetableWar /** * Amount of warp (alteration of the waveform) to apply to the wavetable oscillator. * - * The current options are: - * 0 = asym - * 1 = mirror - * 2 = bend+ - * 3 = bend- - * 4 = bend+/- - * 5 = sync - * 6 = quantize + * The current options are: none, asym, bendp, bendm, bendmp, sync, quant, fold, pwm, orbit, + * spin, chaos, primes, binary, brownian, reciprocal, wormhole, logistic, sigmoid, fractal, flip * * @name wtWarpMode * @param {number | Pattern} mode Warp mode: an integer diff --git a/packages/sampler/sample-server.mjs b/packages/sampler/sample-server.mjs index 2832741aa..08456add9 100644 --- a/packages/sampler/sample-server.mjs +++ b/packages/sampler/sample-server.mjs @@ -1,10 +1,10 @@ #!/usr/bin/env node import cowsay from 'cowsay'; -import { createReadStream, existsSync, writeFileSync } from 'fs'; +import { createReadStream, existsSync } from 'fs'; import { readdir } from 'fs/promises'; import http from 'http'; -import { join, sep, resolve } from 'path'; +import { join, sep } from 'path'; import os from 'os'; // eslint-disable-next-line @@ -36,19 +36,17 @@ async function getFilesInDirectory(directory) { return files; } -async function getBanks(directory, flat = false) { +async function getBanks(directory) { let files = await getFilesInDirectory(directory); let banks = {}; directory = directory.split(sep).join('/'); files = files.map((path) => { path = path.split(sep).join('/'); - const subDir = path.replace(directory, ''); - const subDirFlat = subDir.replaceAll('/', '_').slice(1); // remove initial underscore - const subDirFlatStem = subDirFlat.replace(/\.[^.]+$/, ''); // remove extension - let bank = flat ? subDirFlatStem : subDir.split('/')[0]; + const [bank] = path.split('/').slice(-2); banks[bank] = banks[bank] || []; - banks[bank].push(subDir); - return subDir; + const relativeUrl = path.replace(directory, ''); + banks[bank].push(relativeUrl); + return relativeUrl; }); banks._base = `http://localhost:5432`; return { banks, files }; @@ -56,25 +54,14 @@ async function getBanks(directory, flat = false) { const args = process.argv.slice(2); -function getArgValue(flag) { - const i = args.indexOf(flag); - if (i !== -1) { - const nextIsFlag = args[i + 1]?.startsWith('--') ?? true; - if (nextIsFlag) return true; - return args[i + 1]; - } -} - // eslint-disable-next-line -let directory = getArgValue('--dir') || process.cwd(); -directory = resolve(directory); +const directory = process.cwd(); if (args.includes('--json')) { - const { banks } = await getBanks(directory, getArgValue('--flat')); + const { banks, files } = await getBanks(directory); const json = JSON.stringify(banks); - const outFile = resolve(directory, 'strudel.json'); - writeFileSync(outFile, json, 'utf8'); - console.log(`Wrote json to ${outFile}`); + console.log(json); + process.exit(0); } console.log( @@ -87,7 +74,7 @@ console.log( const server = http.createServer(async (req, res) => { res.setHeader('Access-Control-Allow-Origin', '*'); - const { banks, files } = await getBanks(directory, getArgValue('--flat')); + const { banks, files } = await getBanks(directory); if (req.url === '/') { res.setHeader('Content-Type', 'application/json'); return res.end(JSON.stringify(banks)); @@ -95,7 +82,7 @@ const server = http.createServer(async (req, res) => { let subpath = decodeURIComponent(req.url); const filePath = join(directory, subpath.split('/').join(sep)); - // console.log('GET:', filePath); + //console.log('GET:', filePath); const isFound = existsSync(filePath); if (!isFound) { res.statusCode = 404; From 189e650a733b85d183babc680b8e14fc49b1c486 Mon Sep 17 00:00:00 2001 From: Aria Date: Fri, 29 Aug 2025 12:18:28 -0500 Subject: [PATCH 089/335] Add flat flag, automatic json saving; filter out non-audio at base dir --- packages/sampler/sample-server.mjs | 74 ++++++++++++++++++++++-------- 1 file changed, 55 insertions(+), 19 deletions(-) diff --git a/packages/sampler/sample-server.mjs b/packages/sampler/sample-server.mjs index 08456add9..31b83f5a3 100644 --- a/packages/sampler/sample-server.mjs +++ b/packages/sampler/sample-server.mjs @@ -1,14 +1,20 @@ #!/usr/bin/env node import cowsay from 'cowsay'; -import { createReadStream, existsSync } from 'fs'; +import { createReadStream, existsSync, writeFileSync } from 'fs'; import { readdir } from 'fs/promises'; import http from 'http'; -import { join, sep } from 'path'; +import { join, resolve, sep } from 'path'; +import readline from 'readline'; import os from 'os'; -// eslint-disable-next-line const LOG = !!process.env.LOG || false; +const VALID_AUDIO_EXTENSIONS = ['wav', 'mp3', 'ogg']; + +const isAudioFile = (f) => { + const ext = f.split('.').slice(-1)[0].toLowerCase(); + return VALID_AUDIO_EXTENSIONS.includes(ext); +}; async function getFilesInDirectory(directory) { let files = []; @@ -21,32 +27,32 @@ async function getFilesInDirectory(directory) { continue; } try { - const subFiles = (await getFilesInDirectory(fullPath)).filter((f) => - ['wav', 'mp3', 'ogg'].includes(f.split('.').slice(-1)[0].toLowerCase()), - ); + const subFiles = (await getFilesInDirectory(fullPath)).filter(isAudioFile); files = files.concat(subFiles); LOG && console.log(`${dirent.name} (${subFiles.length})`); } catch (err) { LOG && console.warn(`skipped due to error: ${fullPath}`); } } else { - files.push(fullPath); + isAudioFile(fullPath) && files.push(fullPath); } } return files; } -async function getBanks(directory) { +async function getBanks(directory, flat = false) { let files = await getFilesInDirectory(directory); let banks = {}; directory = directory.split(sep).join('/'); files = files.map((path) => { path = path.split(sep).join('/'); - const [bank] = path.split('/').slice(-2); + const subDir = path.replace(directory, ''); + const subDirFlat = subDir.replaceAll('/', '_').slice(1); // remove initial underscore + const subDirFlatStem = subDirFlat.replace(/\.[^.]+$/, ''); // remove extension + let bank = flat ? subDirFlatStem : path.split('/').slice(-2)[0]; banks[bank] = banks[bank] || []; - const relativeUrl = path.replace(directory, ''); - banks[bank].push(relativeUrl); - return relativeUrl; + banks[bank].push(subDir); + return subDir; }); banks._base = `http://localhost:5432`; return { banks, files }; @@ -54,14 +60,44 @@ async function getBanks(directory) { const args = process.argv.slice(2); -// eslint-disable-next-line -const directory = process.cwd(); +function getArgValue(flag) { + const i = args.indexOf(flag); + if (i !== -1) { + const nextIsFlag = args[i + 1]?.startsWith('--') ?? true; + if (nextIsFlag) return true; + return args[i + 1]; + } +} +function getInput(query) { + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + }); + + return new Promise((resolve) => + rl.question(query, (response) => { + rl.close(); + resolve(response); + }), + ); +} + +let directory = getArgValue('--dir') || process.cwd(); +directory = resolve(directory); if (args.includes('--json')) { - const { banks, files } = await getBanks(directory); + const { banks } = await getBanks(directory, getArgValue('--flat')); const json = JSON.stringify(banks); - console.log(json); - process.exit(0); + const outFile = resolve(directory, 'strudel.json'); + if (existsSync(outFile)) { + const answer = await getInput(`Warning: File already exists at ${outFile}. Overwrite? (y/N): `); + if (answer.toLowerCase() !== 'y') { + console.log('Aborted.'); + process.exit(0); + } + } + writeFileSync(outFile, json, 'utf8'); + console.log(`Wrote json to ${outFile}`); } console.log( @@ -74,7 +110,7 @@ console.log( const server = http.createServer(async (req, res) => { res.setHeader('Access-Control-Allow-Origin', '*'); - const { banks, files } = await getBanks(directory); + const { banks, files } = await getBanks(directory, getArgValue('--flat')); if (req.url === '/') { res.setHeader('Content-Type', 'application/json'); return res.end(JSON.stringify(banks)); @@ -82,7 +118,7 @@ const server = http.createServer(async (req, res) => { let subpath = decodeURIComponent(req.url); const filePath = join(directory, subpath.split('/').join(sep)); - //console.log('GET:', filePath); + // console.log('GET:', filePath); const isFound = existsSync(filePath); if (!isFound) { res.statusCode = 404; From 9eb3c9410de3734fabee94a007f910d8d45b43ff Mon Sep 17 00:00:00 2001 From: yaxu Date: Sat, 30 Aug 2025 12:46:00 +0200 Subject: [PATCH 090/335] Add verify link to mastodon a/c --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 4aa90fd38..21c5b8b6b 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,7 @@ Live coding patterns on the web https://strudel.cc/ - -Development is moving to https://codeberg.org/uzu/strudel +Mastodon: social.toplap.org/@strudel - Try it here: - Docs: From dc6b766ab7420fbd8eb025a73d69e7f2f2644e9f Mon Sep 17 00:00:00 2001 From: yaxu Date: Sat, 30 Aug 2025 12:47:06 +0200 Subject: [PATCH 091/335] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 21c5b8b6b..baaac82b2 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,6 @@ Live coding patterns on the web https://strudel.cc/ -Mastodon: social.toplap.org/@strudel - Try it here: - Docs: @@ -46,3 +45,5 @@ There is a #strudel channel on the TidalCycles discord: The discord and forum is shared with the haskell (tidal) and python (vortex) siblings of this project. + +We also have a mastodon account: social.toplap.org/@strudel From 6a09f54b25ebaa12abca4178412e94548f78ebac Mon Sep 17 00:00:00 2001 From: Aria Date: Sun, 31 Aug 2025 01:03:09 -0500 Subject: [PATCH 092/335] Add vibrato to list of continuous modulators --- website/src/pages/learn/effects.mdx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/website/src/pages/learn/effects.mdx b/website/src/pages/learn/effects.mdx index d9efe8f8a..15df506c8 100644 --- a/website/src/pages/learn/effects.mdx +++ b/website/src/pages/learn/effects.mdx @@ -129,8 +129,9 @@ Some parameters _do_ induce continuous variations in time, though: - The pitch envelope curve (governed by `penv` and its associated ADSR) - The FM curve (`fmenv`) - The filter envelopes (`lpenv`, `hpenv`, `bpenv`) -- Tremolo -- Phaser +- Tremolo (`tremolo`) +- Phaser (`phaser`) +- Vibrato (`vib`) - Ducking (`duckorbit`) # Filters From 9b9176325b04d6607e831e37bc32efef8f497d87 Mon Sep 17 00:00:00 2001 From: Aria Date: Fri, 22 Aug 2025 15:38:50 -0500 Subject: [PATCH 093/335] Update restore defaults to not delete patterns --- website/src/repl/components/panel/SettingsTab.jsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/website/src/repl/components/panel/SettingsTab.jsx b/website/src/repl/components/panel/SettingsTab.jsx index cf2978a1a..8f02ca8b8 100644 --- a/website/src/repl/components/panel/SettingsTab.jsx +++ b/website/src/repl/components/panel/SettingsTab.jsx @@ -311,7 +311,8 @@ export function SettingsTab({ started }) { onClick={() => { confirmDialog('Sure?').then((r) => { if (r) { - settingsMap.set(defaultSettings); + const { userPatterns } = settingsMap.get(); // keep current patterns + settingsMap.set({...defaultSettings, userPatterns}); } }); }} From 142160d79ae7a2eef1a6f38996b30352134b6cfc Mon Sep 17 00:00:00 2001 From: James Walker Date: Mon, 1 Sep 2025 21:08:06 +0100 Subject: [PATCH 094/335] Add examples for ? and | operators --- website/src/pages/learn/mini-notation.mdx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/website/src/pages/learn/mini-notation.mdx b/website/src/pages/learn/mini-notation.mdx index 7dbf67ce2..c7327bb86 100644 --- a/website/src/pages/learn/mini-notation.mdx +++ b/website/src/pages/learn/mini-notation.mdx @@ -168,6 +168,16 @@ Using "!" we can repeat without speeding up: *2")`} punchcard /> +## Randomness + +Events with a "?" placed after them will have a 50% chance of playing: + + + +Events separated by a "|" will be chosen from at random: + + + ## Mini-notation review To recap what we've learned so far, compare the following patterns: @@ -179,6 +189,8 @@ To recap what we've learned so far, compare the following patterns: *2")`} /> *2")`} /> *2")`} /> +*2")`} /> +*2")`} /> ## Euclidian rhythms From 4e2e79086446e7b82c5bf382125ef69b09ceba16 Mon Sep 17 00:00:00 2001 From: Aria Date: Mon, 1 Sep 2025 20:45:53 -0500 Subject: [PATCH 095/335] Set delay and reverb nodes properly --- packages/superdough/superdough.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 0c205bcca..290796956 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -336,7 +336,7 @@ function getDelay(orbit, delaytime, delayfeedback, t) { const dly = ac.createFeedbackDelay(1, delaytime, delayfeedback); dly.start?.(t); // for some reason, this throws when audion extension is installed.. connectToOrbit(dly, orbit); - delayNode = dly; + orbits[orbit].delayNode = dly; } delayNode.delayTime.value !== delaytime && delayNode.delayTime.setValueAtTime(delaytime, t); delayNode.feedback.value !== delayfeedback && delayNode.feedback.setValueAtTime(delayfeedback, t); @@ -464,7 +464,7 @@ function getReverb(orbit, duration, fade, lp, dim, ir, irspeed, irbegin) { const ac = getAudioContext(); const reverb = ac.createReverb(duration, fade, lp, dim, ir, irspeed, irbegin); connectToOrbit(reverb, orbit); - reverbNode = reverb; + orbits[orbit].reverbNode = reverb; } if ( From 439a7dc5e6b825a5270958ff04b869d52b37387b Mon Sep 17 00:00:00 2001 From: Aria Date: Tue, 2 Sep 2025 16:05:40 -0500 Subject: [PATCH 096/335] Include synonyms in autocomplete --- packages/codemirror/autocomplete.mjs | 29 +++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/packages/codemirror/autocomplete.mjs b/packages/codemirror/autocomplete.mjs index 59ca8adf2..bfbf7b333 100644 --- a/packages/codemirror/autocomplete.mjs +++ b/packages/codemirror/autocomplete.mjs @@ -74,15 +74,26 @@ const isValidDoc = (doc) => { const hasExcludedTags = (doc) => ['superdirtOnly', 'noAutocomplete'].some((tag) => doc.tags?.find((t) => t.originalTitle === tag)); -const jsdocCompletions = jsdoc.docs - .filter((doc) => isValidDoc(doc) && !hasExcludedTags(doc)) - // https://codemirror.net/docs/ref/#autocomplete.Completion - .map((doc) => ({ - label: getDocLabel(doc), - // detail: 'xxx', // An optional short piece of information to show (with a different style) after the label. - info: () => Autocomplete({ doc }), - type: 'function', // https://codemirror.net/docs/ref/#autocomplete.Completion.type - })); +const jsdocCompletions = (() => { + const seen = new Set(); // avoid repetition + const completions = []; + for (const doc of jsdoc.docs) { + if (!isValidDoc(doc) || hasExcludedTags(doc)) continue; + let labels = [getDocLabel(doc), ...(doc.synonyms || [])]; + for (const label of labels) { + // https://codemirror.net/docs/ref/#autocomplete.Completion + if (label && !seen.has(label)) { + seen.add(label); + completions.push({ + label, + info: () => Autocomplete({ doc }), + type: 'function', // https://codemirror.net/docs/ref/#autocomplete.Completion.type + }); + } + } + } + return completions; +})(); export const strudelAutocomplete = (context) => { const word = context.matchBefore(/\w*/); From 052d09e892f2ec8022381e72d690a4c3905b23ea Mon Sep 17 00:00:00 2001 From: Aria Date: Tue, 2 Sep 2025 16:14:38 -0500 Subject: [PATCH 097/335] Add synonyms to reference --- .../src/repl/components/panel/Reference.jsx | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/website/src/repl/components/panel/Reference.jsx b/website/src/repl/components/panel/Reference.jsx index 1b617341b..2e2ef4cbc 100644 --- a/website/src/repl/components/panel/Reference.jsx +++ b/website/src/repl/components/panel/Reference.jsx @@ -2,9 +2,28 @@ import { useMemo, useState } from 'react'; import jsdocJson from '../../../../../doc.json'; import { Textbox } from '../textbox/Textbox'; -const availableFunctions = jsdocJson.docs - .filter(({ name, description }) => name && !name.startsWith('_') && !!description) - .sort((a, b) => /* a.meta.filename.localeCompare(b.meta.filename) + */ a.name.localeCompare(b.name)); + +const isValid = ({ name, description }) => + name && !name.startsWith('_') && !!description; + +const availableFunctions = (() => { + const seen = new Set(); // avoid repetition + const functions = []; + for (const doc of jsdocJson.docs) { + if (!isValid(doc)) continue; + let docAndSynonyms = [doc.name, ...(doc.synonyms || [])]; + for (const s of docAndSynonyms) { + if (!s || seen.has(s)) continue; + seen.add(s); + functions.push({ + ...doc, + name: s, // update names for the synonym + longname: s, + }); + } + } + return functions.sort((a, b) => /* a.meta.filename.localeCompare(b.meta.filename) + */ a.name.localeCompare(b.name)); +})(); const getInnerText = (html) => { var div = document.createElement('div'); From 8d2a368da91d84307779e8e969bb0828c649c2a2 Mon Sep 17 00:00:00 2001 From: Aria Date: Tue, 2 Sep 2025 16:14:50 -0500 Subject: [PATCH 098/335] Add some more synonyms to controls docs --- packages/core/controls.mjs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 58a30652c..1c025313d 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -91,6 +91,7 @@ export const { s, sound } = registerControl(['s', 'n', 'gain'], 'sound'); * Define a custom webaudio node to use as a sound source. * * @name source + * @synonyms src * @param {function} getSource * @synonyms src * @@ -525,6 +526,7 @@ export const { tremolophase } = registerControl('tremolophase', 'tremphase'); * shape of amplitude modulation * * @name tremoloshape + * @synonyms tremshape * @param {number | Pattern} shape tri | square | sine | saw | ramp * @example * note("{f g c d}%16").tremsync(4).tremoloshape("").s("sawtooth") @@ -540,11 +542,13 @@ export const { tremoloshape } = registerControl('tremoloshape', 'tremshape'); * note("{f g g c d a a#}%16".sub(17)).s("supersaw").lpenv(8).lpf(150).lpq(.8).ftype('ladder').drive("<.5 4>") * */ +export const { drive } = registerControl('drive'); /** * modulate the amplitude of an orbit to create a "sidechain" like effect * * @name duckorbit + * @synonyms duck * @param {number | Pattern} orbit target orbit * @example * $: n(run(16)).scale("c:minor:pentatonic").s("sawtooth").delay(.7).orbit(2) @@ -569,6 +573,7 @@ export const { duckdepth } = registerControl('duckdepth'); * the attack time of the duck effect * * @name duckattack + * @synonyms duckatt * @param {number | Pattern} time * @example * stack( n(run(8)).scale("c:minor").s("sawtooth").delay(.7).orbit(2), s("bd:4!4").beat("0,4,8,11,14",16).duckorbit(2).duckattack("<0.2 0 0.4>").duckdepth(1)) @@ -576,8 +581,6 @@ export const { duckdepth } = registerControl('duckdepth'); */ export const { duckattack } = registerControl('duckattack', 'duckatt'); -export const { drive } = registerControl('drive'); - /** * Create byte beats with custom expressions * @@ -700,7 +703,7 @@ export const { phasercenter, phc } = registerControl('phasercenter', 'phc'); * The amount the signal is affected by the phaser effect. Defaults to 0.75 * * @name phaserdepth - * @synonyms phd + * @synonyms phd, phasdp * @param {number | Pattern} depth number between 0 and 1 * @example * n(run(8)).scale("D:pentatonic").s("sawtooth").release(0.5) @@ -1182,6 +1185,7 @@ export const { dry } = registerControl('dry'); * Used when using `begin`/`end` or `chop`/`striate` and friends, to change the fade out time of the 'grain' envelope. * * @name fadeTime + * @synonyms fadeOutTime * @param {number | Pattern} time between 0 and 1 * @example * s("oh*4").end(.1).fadeTime("<0 .2 .4 .8>").osc() From c199b51645f899940fa5e5a63e72b57877086e82 Mon Sep 17 00:00:00 2001 From: Aria Date: Tue, 2 Sep 2025 16:29:01 -0500 Subject: [PATCH 099/335] Update autocomplete name to be the label and update ref to use main name as a synonym --- packages/codemirror/autocomplete.mjs | 2 +- website/src/repl/components/panel/Reference.jsx | 13 +++++++++---- website/src/repl/components/panel/SettingsTab.jsx | 2 +- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/codemirror/autocomplete.mjs b/packages/codemirror/autocomplete.mjs index bfbf7b333..b56cab826 100644 --- a/packages/codemirror/autocomplete.mjs +++ b/packages/codemirror/autocomplete.mjs @@ -86,7 +86,7 @@ const jsdocCompletions = (() => { seen.add(label); completions.push({ label, - info: () => Autocomplete({ doc }), + info: () => Autocomplete({ doc, label }), type: 'function', // https://codemirror.net/docs/ref/#autocomplete.Completion.type }); } diff --git a/website/src/repl/components/panel/Reference.jsx b/website/src/repl/components/panel/Reference.jsx index 2e2ef4cbc..81826aca2 100644 --- a/website/src/repl/components/panel/Reference.jsx +++ b/website/src/repl/components/panel/Reference.jsx @@ -3,22 +3,27 @@ import { useMemo, useState } from 'react'; import jsdocJson from '../../../../../doc.json'; import { Textbox } from '../textbox/Textbox'; -const isValid = ({ name, description }) => - name && !name.startsWith('_') && !!description; +const isValid = ({ name, description }) => name && !name.startsWith('_') && !!description; const availableFunctions = (() => { const seen = new Set(); // avoid repetition const functions = []; for (const doc of jsdocJson.docs) { if (!isValid(doc)) continue; - let docAndSynonyms = [doc.name, ...(doc.synonyms || [])]; - for (const s of docAndSynonyms) { + functions.push(doc); + const synonyms = doc.synonyms || []; + for (const s of synonyms) { if (!s || seen.has(s)) continue; seen.add(s); + // Swap `doc.name` in for `s` in the list of synonyms + const notS = synonyms.filter((x) => x && x !== s); + const synonymsWithDoc = Array.from(new Set([doc.name, ...notS])); functions.push({ ...doc, name: s, // update names for the synonym longname: s, + synonyms: synonymsWithDoc, + synonyms_text: synonymsWithDoc.join(', '), }); } } diff --git a/website/src/repl/components/panel/SettingsTab.jsx b/website/src/repl/components/panel/SettingsTab.jsx index 8f02ca8b8..26c9ae287 100644 --- a/website/src/repl/components/panel/SettingsTab.jsx +++ b/website/src/repl/components/panel/SettingsTab.jsx @@ -312,7 +312,7 @@ export function SettingsTab({ started }) { confirmDialog('Sure?').then((r) => { if (r) { const { userPatterns } = settingsMap.get(); // keep current patterns - settingsMap.set({...defaultSettings, userPatterns}); + settingsMap.set({ ...defaultSettings, userPatterns }); } }); }} From 56b1ea3fa50b7a8921f3159f4e1c715aa502bf71 Mon Sep 17 00:00:00 2001 From: Antipathie Date: Wed, 3 Sep 2025 00:15:47 +0200 Subject: [PATCH 100/335] Add soundAlias function --- packages/superdough/superdough.mjs | 13 +++++++++++++ website/src/pages/learn/samples.mdx | 8 ++++++++ 2 files changed, 21 insertions(+) diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index a518f49b6..6f8717d05 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -113,6 +113,19 @@ export async function aliasBank(...args) { } } +/** + * Register an alias for a sound. + * @param {string} original - The original sound name + * @param {string} alias - The alias to use for the sound + */ +export function soundAlias(original, alias) { + if (getSound(original) == null) { + logger('soundAlias: original sound not found'); + return; + } + soundMap.setKey(alias, getSound(original)); +} + export function getSound(s) { if (typeof s !== 'string') { console.warn(`getSound: expected string got "${s}". fall back to triangle`); diff --git a/website/src/pages/learn/samples.mdx b/website/src/pages/learn/samples.mdx index a87b8f7dd..eb79cccf7 100644 --- a/website/src/pages/learn/samples.mdx +++ b/website/src/pages/learn/samples.mdx @@ -59,6 +59,14 @@ Furthermore, strudel also loads instrument samples from [VCSL](https://github.co To see which sample names are available, open the `sounds` tab in the [REPL](https://strudel.cc/). +You can also create custom aliases for existing sounds using the `soundAlias` function: + + + Note that only the sample maps (mapping names to URLs) are loaded initially, while the audio samples themselves are not loaded until they are actually played. This behaviour of loading things only when they are needed is also called `lazy loading`. While it saves resources, it can also lead to sounds not being audible the first time they are triggered, because the sound is still loading. From 591c3fe08f26ad8b21c5559b3dcdd3adc9ced236 Mon Sep 17 00:00:00 2001 From: James Walker Date: Wed, 3 Sep 2025 19:16:47 +0100 Subject: [PATCH 101/335] Add documentation for ?n in mini-notation --- website/src/pages/learn/mini-notation.mdx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/website/src/pages/learn/mini-notation.mdx b/website/src/pages/learn/mini-notation.mdx index c7327bb86..02ead7434 100644 --- a/website/src/pages/learn/mini-notation.mdx +++ b/website/src/pages/learn/mini-notation.mdx @@ -170,10 +170,14 @@ Using "!" we can repeat without speeding up: ## Randomness -Events with a "?" placed after them will have a 50% chance of playing: +Events with a "?" placed after them will have a 50% chance of being removed from the pattern: +Adding a number between 0 and 1 after the "?" will affect the likelihood of the event being removed. For example, events with "?0.1" placed after them will have a 10% chance of being removed: + + + Events separated by a "|" will be chosen from at random: From bb982e6b9b9a0a80a334fcdf11248e4d9d12a0c9 Mon Sep 17 00:00:00 2001 From: Aria Date: Wed, 3 Sep 2025 21:55:48 -0500 Subject: [PATCH 102/335] First pass at modes --- packages/core/controls.mjs | 35 +++++++- packages/superdough/helpers.mjs | 4 + packages/superdough/superdough.mjs | 6 +- packages/superdough/worklets.mjs | 89 +++++++++++++++++-- .../src/repl/components/panel/SettingsTab.jsx | 2 +- 5 files changed, 124 insertions(+), 12 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 58a30652c..01679529c 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -1575,7 +1575,7 @@ export const { roomsize, size, sz, rsize } = registerControl('roomsize', 'size', export const { shape } = registerControl(['shape', 'shapevol']); /** * Wave shaping distortion. CAUTION: it can get loud. - * Second option in optional array syntax (ex: ".9:.5") applies a postgain to the output. + * Second option in optional array syntax (ex: ".9:.5") applies a postgain to the output. Third option sets the waveshaping type. * Most useful values are usually between 0 and 10 (depending on source gain). If you are feeling adventurous, you can turn it up to 11 and beyond ;) * * @name distort @@ -1585,9 +1585,40 @@ export const { shape } = registerControl(['shape', 'shapevol']); * s("bd sd [~ bd] sd,hh*8").distort("<0 2 3 10:.5>") * @example * note("d1!8").s("sine").penv(36).pdecay(.12).decay(.23).distort("8:.4") + * @example + * s("bd*4").bank("tr909").distort("4:0.5:fold") * */ -export const { distort, dist } = registerControl(['distort', 'distortvol'], 'dist'); +export const { distort, dist } = registerControl(['distort', 'distortvol', 'distorttype'], 'dist'); + +/** + * Postgain for waveshaping distortion. + * + * @name distortvol + * @synonyms distvol + * @param {number | Pattern} type + * @example + * s("bd*4").bank("tr909").distort(2).distortvol(0.8) + */ +export const { distortvol } = registerControl('distortvol', 'distvol'); + +/** + * Type of waveshaping distortion to apply. + * + * @name distorttype + * @synonyms disttype + * @param {number | string | Pattern} type + * @example + * s("bd*4").bank("tr909").distort(2).distorttype("<0 1 2>") + * + * @example + * s("sine").note("F1*2").release(1) + * .penv(24).pdecay(0.05) + * .distort(70) + * .distorttype("") + */ +export const { distorttype } = registerControl('distorttype', 'disttype'); + /** * Dynamics Compressor. The params are `compressor("threshold:ratio:knee:attack:release")` * More info [here](https://developer.mozilla.org/en-US/docs/Web/API/DynamicsCompressorNode?retiredLocale=de#instance_properties) diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index 81bec9399..def49c4d1 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -307,3 +307,7 @@ export function applyFM(param, value, begin) { } return { stop }; } + +export const getDistortion = (distort, postgain, algorithm) => { + return getWorklet(getAudioContext(), 'distort-processor', { distort, postgain, algorithm }); +}; diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index a518f49b6..98306115c 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -9,7 +9,7 @@ import './reverb.mjs'; import './vowel.mjs'; import { clamp, nanFallback, _mod, cycleToSeconds, secondsToCycle } from './util.mjs'; import workletsUrl from './worklets.mjs?audioworklet'; -import { createFilter, gainNode, getCompressor, getWorklet, webAudioTimeout } from './helpers.mjs'; +import { createFilter, gainNode, getCompressor, getDistortion, getWorklet, webAudioTimeout } from './helpers.mjs'; import { map } from 'nanostores'; import { logger, errorLogger } from './logger.mjs'; import { loadBuffer } from './sampler.mjs'; @@ -608,6 +608,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) shapevol = getDefaultValue('shapevol'), distort, distortvol = getDefaultValue('distortvol'), + distorttype, pan, vowel, delay = getDefaultValue('delay'), @@ -782,8 +783,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) // effects coarse !== undefined && chain.push(getWorklet(ac, 'coarse-processor', { coarse })); crush !== undefined && chain.push(getWorklet(ac, 'crush-processor', { crush })); - shape !== undefined && chain.push(getWorklet(ac, 'shape-processor', { shape, postgain: shapevol })); - distort !== undefined && chain.push(getWorklet(ac, 'distort-processor', { distort, postgain: distortvol })); + distort !== undefined && chain.push(getDistortion(distort, distortvol, distorttype)); if (tremolosync != null) { tremolo = cps * tremolosync; diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 2406d56dc..0eb2bc72f 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -7,6 +7,9 @@ import FFT from './fft.js'; const clamp = (num, min, max) => Math.min(Math.max(num, min), max); const _mod = (n, m) => ((n % m) + m) % m; +const ffloor = (x) => x | 0; +const pv = (arr, n) => arr[n] ?? arr[0]; +const mix = (a, b, t) => (1 - t) * a + t * b; // Restrict phase to the range [0, maxPhase) via wrapping function wrapPhase(phase, maxPhase = 1) { @@ -341,11 +344,85 @@ class LadderProcessor extends AudioWorkletProcessor { } registerProcessor('ladder-processor', LadderProcessor); +// Saturation curves + +const __squash = (x) => x / (1 + x); // [0, inf) to [0, 1) + +const _scurve = (x, k) => ((1 + k) * x) / (1 + k * Math.abs(x)); +const _soft = (x, k) => Math.tanh(x * (1 + k)); +const _hard = (x, k) => clamp((1 + k) * x, -1, 1); +const _sine = (x, k) => Math.sin(x * (1 + k)); + +const _fold = (x, k) => { + let y = (1 + k) * x; + while (y > 1 || y < -1) { + y = y > 1 ? 2 - y : -2 - y; + } + return y; +}; + +const _sineFold = (x, k) => Math.sin((Math.PI / 2) * _fold(x, k)); + +const _pow = (x, k) => { + const t = __squash(k); + const p = 1 / (1 + 0.5 * t); // tame k + return _soft(Math.sign(x) * Math.pow(Math.abs(x), p), 0.5 * k); +}; + +const _diode = (x, k, asym = false) => { + const g = 1 + k; // gain + const t = __squash(k); + const bias = 0.15 * t; + const pos = _soft(x + bias, k); + const neg = _soft(asym ? bias : -x + bias, k); + const y = pos - neg; + // We divide by the derivative at 0 so that the distortion is roughly + // the identity map near 0 => small values are preserved and undistorted + const sech = 1 / Math.cosh(g * bias); + const sech2 = sech * sech; // derivative of tanh is sech^2 + const denom = Math.max(1e-8, (asym ? 1 : 2) * g * sech2); // g from chain rule; 2 if both pos/neg have x + return _soft(y / denom, k); +}; + +const _asym = (x, k) => _diode(x, k, true); + +const _cubic = (x, k) => { + const t = __squash(k); + const cubic = (x - (t / 3) * x * x * x) / (1 - t / 3); // normalized to go from (-1, 1) + return _soft(cubic, k); +}; + +export const saturationAlgos = { + scurve: _scurve, + soft: _soft, + hard: _hard, + sine: _sine, + fold: _fold, + sinefold: _sineFold, + pow: _pow, + cubic: _cubic, + diode: _diode, + asym: _asym, +}; +const _algoNames = Object.freeze(Object.keys(saturationAlgos)); + +const _getAlgorithm = (algo) => { + let algoName = typeof algo === 'string' ? algo : _algoNames[algo % _algoNames.length]; + if (!_algoNames.includes(algoName)) { + algoName = _algoNames[0]; + logger(`[superdough] Could not find waveshaping algorithm ${algo}. + Available options are ${_algoNames.join(', ')}. + Defaulting to ${algoName}.`); + } + return saturationAlgos[algoName]; +}; + class DistortProcessor extends AudioWorkletProcessor { static get parameterDescriptors() { return [ { name: 'distort', defaultValue: 0 }, { name: 'postgain', defaultValue: 1 }, + { name: 'algorithm', defaultValue: 0, min: 0, max: _algoNames.length - 1 }, ]; } @@ -363,13 +440,13 @@ class DistortProcessor extends AudioWorkletProcessor { return false; } this.started = hasInput; - - const shape = Math.expm1(parameters.distort[0]); - const postgain = Math.max(0.001, Math.min(1, parameters.postgain[0])); - for (let n = 0; n < blockSize; n++) { - for (let i = 0; i < input.length; i++) { - output[i][n] = (((1 + shape) * input[i][n]) / (1 + shape * Math.abs(input[i][n]))) * postgain; + const postgain = clamp(pv(parameters.postgain, n), 0.001, 1); + const shape = Math.expm1(pv(parameters.distort, n)); + const algorithm = _getAlgorithm(pv(parameters.algorithm, n)); + for (let ch = 0; ch < input.length; ch++) { + const x = input[ch][n]; + output[ch][n] = postgain * algorithm(x, shape); } } return true; diff --git a/website/src/repl/components/panel/SettingsTab.jsx b/website/src/repl/components/panel/SettingsTab.jsx index 8f02ca8b8..26c9ae287 100644 --- a/website/src/repl/components/panel/SettingsTab.jsx +++ b/website/src/repl/components/panel/SettingsTab.jsx @@ -312,7 +312,7 @@ export function SettingsTab({ started }) { confirmDialog('Sure?').then((r) => { if (r) { const { userPatterns } = settingsMap.get(); // keep current patterns - settingsMap.set({...defaultSettings, userPatterns}); + settingsMap.set({ ...defaultSettings, userPatterns }); } }); }} From 42ab65abdb6d55e8227f39c6318652519efa3ef8 Mon Sep 17 00:00:00 2001 From: Aria Date: Thu, 4 Sep 2025 11:47:01 -0500 Subject: [PATCH 103/335] Move things around to allow selection by name and avoid circular imports; fixed chebyshev --- packages/superdough/audioContext.mjs | 18 +++++ packages/superdough/dspworklet.mjs | 2 +- packages/superdough/helpers.mjs | 112 ++++++++++++++++++++++++++- packages/superdough/index.mjs | 1 + packages/superdough/noise.mjs | 2 +- packages/superdough/sampler.mjs | 3 +- packages/superdough/superdough.mjs | 20 +---- packages/superdough/synth.mjs | 3 +- packages/superdough/util.mjs | 2 + packages/superdough/worklets.mjs | 80 +------------------ packages/superdough/zzfx.mjs | 3 +- packages/superdough/zzfx_fork.mjs | 2 +- 12 files changed, 142 insertions(+), 106 deletions(-) create mode 100644 packages/superdough/audioContext.mjs diff --git a/packages/superdough/audioContext.mjs b/packages/superdough/audioContext.mjs new file mode 100644 index 000000000..9a3c71167 --- /dev/null +++ b/packages/superdough/audioContext.mjs @@ -0,0 +1,18 @@ +let audioContext; + +export const setDefaultAudioContext = () => { + audioContext = new AudioContext(); + return audioContext; +}; + +export const getAudioContext = () => { + if (!audioContext) { + return setDefaultAudioContext(); + } + + return audioContext; +}; + +export function getAudioContextCurrentTime() { + return getAudioContext().currentTime; +} \ No newline at end of file diff --git a/packages/superdough/dspworklet.mjs b/packages/superdough/dspworklet.mjs index 5b02ad298..aac08061e 100644 --- a/packages/superdough/dspworklet.mjs +++ b/packages/superdough/dspworklet.mjs @@ -1,4 +1,4 @@ -import { getAudioContext } from './superdough.mjs'; +import { getAudioContext } from './audioContext.mjs'; let worklet; export async function dspWorklet(ac, code) { diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index def49c4d1..b5d83e7bc 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -1,5 +1,5 @@ -import { getAudioContext } from './superdough.mjs'; -import { clamp, nanFallback } from './util.mjs'; +import { getAudioContext } from './audioContext.mjs'; +import { clamp, ffloor, nanFallback } from './util.mjs'; import { getNoiseBuffer } from './noise.mjs'; export const noises = ['pink', 'white', 'brown', 'crackle']; @@ -308,6 +308,110 @@ export function applyFM(param, value, begin) { return { stop }; } -export const getDistortion = (distort, postgain, algorithm) => { - return getWorklet(getAudioContext(), 'distort-processor', { distort, postgain, algorithm }); +// Saturation curves + +const __squash = (x) => x / (1 + x); // [0, inf) to [0, 1) + +const _scurve = (x, k) => ((1 + k) * x) / (1 + k * Math.abs(x)); +const _soft = (x, k) => Math.tanh(x * (1 + k)); +const _hard = (x, k) => clamp((1 + k) * x, -1, 1); +const _sine = (x, k) => Math.sin(x * (1 + k)); + +const _fold = (x, k) => { + let y = (1 + k) * x; + while (y > 1 || y < -1) { + y = y > 1 ? 2 - y : -2 - y; + } + return y; +}; + +const _sineFold = (x, k) => Math.sin((Math.PI / 2) * _fold(x, k)); + +const _pow = (x, k) => { + const t = __squash(k); + const p = 1 / (1 + 0.5 * t); // tame k + return _soft(Math.sign(x) * Math.pow(Math.abs(x), p), 0.5 * k); +}; + +const _cubic = (x, k) => { + const t = __squash(k); + const cubic = (x - (t / 3) * x * x * x) / (1 - t / 3); // normalized to go from (-1, 1) + return _soft(cubic, k); +}; + +const _diode = (x, k, asym = false) => { + const g = 1 + k; // gain + const t = __squash(k); + const bias = 0.15 * t; + const pos = _soft(x + bias, k); + const neg = _soft(asym ? bias : -x + bias, k); + const y = pos - neg; + // We divide by the derivative at 0 so that the distortion is roughly + // the identity map near 0 => small values are preserved and undistorted + const sech = 1 / Math.cosh(g * bias); + const sech2 = sech * sech; // derivative of tanh is sech^2 + const denom = Math.max(1e-8, (asym ? 1 : 2) * g * sech2); // g from chain rule; 2 if both pos/neg have x + return _soft(y / denom, k); +}; + +const _asym = (x, k) => _diode(x, k, true); + +const _chebyshev = (x, k) => { + const kl = Math.log1p(k); + let tnm1 = 1; + let tnm2 = x; + let tn; + let y = 0; + const iterations = 1 + ffloor(Math.min(16 * kl, 255)); + for (let i = 1; i < iterations; i++) { + if (i < 2) { + // Already set inital conditions + y += i == 0 ? tnm1 : tnm2; + continue; + } + tn = 2 * x * tnm1 - tnm2; // https://en.wikipedia.org/wiki/Chebyshev_polynomials#Recurrence_definition + tnm2 = tnm1; + tnm1 = tn; + if (i % 2 === 0) { + y += tn; + } + } + // Soft clip + return _soft(y, 0); +}; + +export const distortionAlgorithms = { + scurve: _scurve, + soft: _soft, + hard: _hard, + sine: _sine, + fold: _fold, + sinefold: _sineFold, + pow: _pow, + cubic: _cubic, + diode: _diode, + asym: _asym, + chebyshev: _chebyshev, +}; +const _algoNames = Object.freeze(Object.keys(distortionAlgorithms)); + +export const getDistortionAlgorithm = (algo) => { + let index = algo; + if (typeof algo === 'string') { + index = _algoNames.indexOf(algo); + if (index === -1) { + logger(`[superdough] Could not find waveshaping algorithm ${algo}. + Available options are ${_algoNames.join(', ')}. + Defaulting to ${_algoNames[0]}.`); + index = 0; + } + } + const name = _algoNames[index % _algoNames.length]; // allow for wrapping if algo was a number + const algorithm = distortionAlgorithms[name]; + return { algorithm, index }; +}; + +export const getDistortion = (distort, postgain, algorithm) => { + const { _algorithm, index } = getDistortionAlgorithm(algorithm); + return getWorklet(getAudioContext(), 'distort-processor', { distort, postgain, algorithm: index }); }; diff --git a/packages/superdough/index.mjs b/packages/superdough/index.mjs index fd49fe338..184fc078c 100644 --- a/packages/superdough/index.mjs +++ b/packages/superdough/index.mjs @@ -11,3 +11,4 @@ export * from './synth.mjs'; export * from './zzfx.mjs'; export * from './logger.mjs'; export * from './dspworklet.mjs'; +export * from './audioContext.mjs'; diff --git a/packages/superdough/noise.mjs b/packages/superdough/noise.mjs index 5411f2f2f..816dd252b 100644 --- a/packages/superdough/noise.mjs +++ b/packages/superdough/noise.mjs @@ -1,5 +1,5 @@ import { drywet } from './helpers.mjs'; -import { getAudioContext } from './superdough.mjs'; +import { getAudioContext } from './audioContext.mjs'; let noiseCache = {}; diff --git a/packages/superdough/sampler.mjs b/packages/superdough/sampler.mjs index 18d1b7797..7d69aef02 100644 --- a/packages/superdough/sampler.mjs +++ b/packages/superdough/sampler.mjs @@ -1,5 +1,6 @@ import { noteToMidi, valueToMidi, getSoundIndex } from './util.mjs'; -import { getAudioContext, registerSound } from './index.mjs'; +import { registerSound } from './index.mjs'; +import { getAudioContext } from './audioContext.mjs'; import { getADSRValues, getParamADSR, getPitchEnvelope, getVibratoOscillator } from './helpers.mjs'; import { logger } from './logger.mjs'; diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 98306115c..10d8ed9f4 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -13,6 +13,7 @@ import { createFilter, gainNode, getCompressor, getDistortion, getWorklet, webAu import { map } from 'nanostores'; import { logger, errorLogger } from './logger.mjs'; import { loadBuffer } from './sampler.mjs'; +import { getAudioContext } from './audioContext.mjs'; export const DEFAULT_MAX_POLYPHONY = 128; const DEFAULT_AUDIO_DEVICE_NAME = 'System Standard'; @@ -193,25 +194,6 @@ export function setVersionDefaults(version) { export const resetLoadedSounds = () => soundMap.set({}); -let audioContext; - -export const setDefaultAudioContext = () => { - audioContext = new AudioContext(); - return audioContext; -}; - -export const getAudioContext = () => { - if (!audioContext) { - return setDefaultAudioContext(); - } - - return audioContext; -}; - -export function getAudioContextCurrentTime() { - return getAudioContext().currentTime; -} - let workletsLoading; function loadWorklets() { if (!workletsLoading) { diff --git a/packages/superdough/synth.mjs b/packages/superdough/synth.mjs index 71138ae41..5f303753a 100644 --- a/packages/superdough/synth.mjs +++ b/packages/superdough/synth.mjs @@ -1,5 +1,6 @@ import { clamp, midiToFreq, noteToMidi } from './util.mjs'; -import { registerSound, getAudioContext, soundMap, getLfo } from './superdough.mjs'; +import { registerSound, soundMap, getLfo } from './superdough.mjs'; +import { getAudioContext } from './audioContext.mjs'; import { applyFM, gainNode, diff --git a/packages/superdough/util.mjs b/packages/superdough/util.mjs index f4d59024e..c3d511fd4 100644 --- a/packages/superdough/util.mjs +++ b/packages/superdough/util.mjs @@ -76,3 +76,5 @@ export function cycleToSeconds(cycle, cps) { export function secondsToCycle(t, cps) { return t * cps; } + +export const ffloor = (x) => x | 0; // fast floor for positive numbers \ No newline at end of file diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 0eb2bc72f..ae03e9603 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -4,12 +4,11 @@ import OLAProcessor from './ola-processor'; import FFT from './fft.js'; +import { getDistortionAlgorithm } from './helpers.mjs'; const clamp = (num, min, max) => Math.min(Math.max(num, min), max); const _mod = (n, m) => ((n % m) + m) % m; -const ffloor = (x) => x | 0; const pv = (arr, n) => arr[n] ?? arr[0]; -const mix = (a, b, t) => (1 - t) * a + t * b; // Restrict phase to the range [0, maxPhase) via wrapping function wrapPhase(phase, maxPhase = 1) { @@ -344,85 +343,12 @@ class LadderProcessor extends AudioWorkletProcessor { } registerProcessor('ladder-processor', LadderProcessor); -// Saturation curves - -const __squash = (x) => x / (1 + x); // [0, inf) to [0, 1) - -const _scurve = (x, k) => ((1 + k) * x) / (1 + k * Math.abs(x)); -const _soft = (x, k) => Math.tanh(x * (1 + k)); -const _hard = (x, k) => clamp((1 + k) * x, -1, 1); -const _sine = (x, k) => Math.sin(x * (1 + k)); - -const _fold = (x, k) => { - let y = (1 + k) * x; - while (y > 1 || y < -1) { - y = y > 1 ? 2 - y : -2 - y; - } - return y; -}; - -const _sineFold = (x, k) => Math.sin((Math.PI / 2) * _fold(x, k)); - -const _pow = (x, k) => { - const t = __squash(k); - const p = 1 / (1 + 0.5 * t); // tame k - return _soft(Math.sign(x) * Math.pow(Math.abs(x), p), 0.5 * k); -}; - -const _diode = (x, k, asym = false) => { - const g = 1 + k; // gain - const t = __squash(k); - const bias = 0.15 * t; - const pos = _soft(x + bias, k); - const neg = _soft(asym ? bias : -x + bias, k); - const y = pos - neg; - // We divide by the derivative at 0 so that the distortion is roughly - // the identity map near 0 => small values are preserved and undistorted - const sech = 1 / Math.cosh(g * bias); - const sech2 = sech * sech; // derivative of tanh is sech^2 - const denom = Math.max(1e-8, (asym ? 1 : 2) * g * sech2); // g from chain rule; 2 if both pos/neg have x - return _soft(y / denom, k); -}; - -const _asym = (x, k) => _diode(x, k, true); - -const _cubic = (x, k) => { - const t = __squash(k); - const cubic = (x - (t / 3) * x * x * x) / (1 - t / 3); // normalized to go from (-1, 1) - return _soft(cubic, k); -}; - -export const saturationAlgos = { - scurve: _scurve, - soft: _soft, - hard: _hard, - sine: _sine, - fold: _fold, - sinefold: _sineFold, - pow: _pow, - cubic: _cubic, - diode: _diode, - asym: _asym, -}; -const _algoNames = Object.freeze(Object.keys(saturationAlgos)); - -const _getAlgorithm = (algo) => { - let algoName = typeof algo === 'string' ? algo : _algoNames[algo % _algoNames.length]; - if (!_algoNames.includes(algoName)) { - algoName = _algoNames[0]; - logger(`[superdough] Could not find waveshaping algorithm ${algo}. - Available options are ${_algoNames.join(', ')}. - Defaulting to ${algoName}.`); - } - return saturationAlgos[algoName]; -}; - class DistortProcessor extends AudioWorkletProcessor { static get parameterDescriptors() { return [ { name: 'distort', defaultValue: 0 }, { name: 'postgain', defaultValue: 1 }, - { name: 'algorithm', defaultValue: 0, min: 0, max: _algoNames.length - 1 }, + { name: 'algorithm', defaultValue: 0, min: 0 }, ]; } @@ -440,10 +366,10 @@ class DistortProcessor extends AudioWorkletProcessor { return false; } this.started = hasInput; + const { algorithm } = getDistortionAlgorithm(pv(parameters.algorithm, 0)); // do not allow audio rate algo changes for (let n = 0; n < blockSize; n++) { const postgain = clamp(pv(parameters.postgain, n), 0.001, 1); const shape = Math.expm1(pv(parameters.distort, n)); - const algorithm = _getAlgorithm(pv(parameters.algorithm, n)); for (let ch = 0; ch < input.length; ch++) { const x = input[ch][n]; output[ch][n] = postgain * algorithm(x, shape); diff --git a/packages/superdough/zzfx.mjs b/packages/superdough/zzfx.mjs index a6af82609..32db0395a 100644 --- a/packages/superdough/zzfx.mjs +++ b/packages/superdough/zzfx.mjs @@ -1,6 +1,7 @@ //import { ZZFX } from 'zzfx'; import { midiToFreq, noteToMidi } from './util.mjs'; -import { registerSound, getAudioContext } from './superdough.mjs'; +import { registerSound } from './superdough.mjs'; +import { getAudioContext } from './audioContext.mjs'; import { buildSamples } from './zzfx_fork.mjs'; export const getZZFX = (value, t) => { diff --git a/packages/superdough/zzfx_fork.mjs b/packages/superdough/zzfx_fork.mjs index 7235d1bf8..f3ee6a051 100644 --- a/packages/superdough/zzfx_fork.mjs +++ b/packages/superdough/zzfx_fork.mjs @@ -1,4 +1,4 @@ -import { getAudioContext } from './superdough.mjs'; +import { getAudioContext } from './audioContext.mjs'; // https://github.com/KilledByAPixel/ZzFX/blob/master/ZzFX.js#L85C5-L180C6 // changes: replaced this.volume with 1 + using sampleRate from getAudioContext() From 9b1c23d49f6cdddc792f74a6af06991d9bb6c951 Mon Sep 17 00:00:00 2001 From: Aria Date: Thu, 4 Sep 2025 20:05:28 -0500 Subject: [PATCH 104/335] Some tuning experimentally and adding back chebyshev --- packages/superdough/helpers.mjs | 38 ++++++++++++--------------------- 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index b5d83e7bc..28c14f79d 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -315,10 +315,9 @@ const __squash = (x) => x / (1 + x); // [0, inf) to [0, 1) const _scurve = (x, k) => ((1 + k) * x) / (1 + k * Math.abs(x)); const _soft = (x, k) => Math.tanh(x * (1 + k)); const _hard = (x, k) => clamp((1 + k) * x, -1, 1); -const _sine = (x, k) => Math.sin(x * (1 + k)); const _fold = (x, k) => { - let y = (1 + k) * x; + let y = (1 + 0.5 * k) * x; while (y > 1 || y < -1) { y = y > 1 ? 2 - y : -2 - y; } @@ -327,29 +326,23 @@ const _fold = (x, k) => { const _sineFold = (x, k) => Math.sin((Math.PI / 2) * _fold(x, k)); -const _pow = (x, k) => { - const t = __squash(k); - const p = 1 / (1 + 0.5 * t); // tame k - return _soft(Math.sign(x) * Math.pow(Math.abs(x), p), 0.5 * k); -}; - const _cubic = (x, k) => { - const t = __squash(k); + const t = __squash(Math.log1p(k)); const cubic = (x - (t / 3) * x * x * x) / (1 - t / 3); // normalized to go from (-1, 1) return _soft(cubic, k); }; const _diode = (x, k, asym = false) => { - const g = 1 + k; // gain - const t = __squash(k); - const bias = 0.15 * t; - const pos = _soft(x + bias, k); - const neg = _soft(asym ? bias : -x + bias, k); + const g = 1 + 2 * k; // gain + const t = __squash(Math.log1p(k)); + const bias = 0.07 * t; + const pos = _soft(x + bias, 2 * k); + const neg = _soft(asym ? bias : -x + bias, 2 * k); const y = pos - neg; // We divide by the derivative at 0 so that the distortion is roughly // the identity map near 0 => small values are preserved and undistorted const sech = 1 / Math.cosh(g * bias); - const sech2 = sech * sech; // derivative of tanh is sech^2 + const sech2 = sech * sech; // derivative of soft (i.e. tanh) is sech^2 const denom = Math.max(1e-8, (asym ? 1 : 2) * g * sech2); // g from chain rule; 2 if both pos/neg have x return _soft(y / denom, k); }; @@ -357,13 +350,12 @@ const _diode = (x, k, asym = false) => { const _asym = (x, k) => _diode(x, k, true); const _chebyshev = (x, k) => { - const kl = Math.log1p(k); + const kl = 10 * Math.log1p(k); let tnm1 = 1; let tnm2 = x; let tn; let y = 0; - const iterations = 1 + ffloor(Math.min(16 * kl, 255)); - for (let i = 1; i < iterations; i++) { + for (let i = 1; i < 64; i++) { if (i < 2) { // Already set inital conditions y += i == 0 ? tnm1 : tnm2; @@ -373,24 +365,22 @@ const _chebyshev = (x, k) => { tnm2 = tnm1; tnm1 = tn; if (i % 2 === 0) { - y += tn; + y += Math.min(1.3 * kl / i, 2) * tn; } } // Soft clip - return _soft(y, 0); + return _soft(y, kl / 20); }; export const distortionAlgorithms = { scurve: _scurve, soft: _soft, hard: _hard, - sine: _sine, - fold: _fold, - sinefold: _sineFold, - pow: _pow, cubic: _cubic, diode: _diode, asym: _asym, + fold: _fold, + sinefold: _sineFold, chebyshev: _chebyshev, }; const _algoNames = Object.freeze(Object.keys(distortionAlgorithms)); From 46a45b4596902e734cada6dfadf3742cd8b445f9 Mon Sep 17 00:00:00 2001 From: Aria Date: Thu, 4 Sep 2025 20:51:06 -0500 Subject: [PATCH 105/335] Some missing cleanup --- packages/superdough/superdough.mjs | 11 ++++------- packages/superdough/worklets.mjs | 1 - website/src/repl/components/panel/SettingsTab.jsx | 2 +- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 8ee3ee4c3..d436a816a 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -686,13 +686,8 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) let sourceNode; if (source) { sourceNode = source(t, value, hapDuration, cps); - } else { - const soundSource = wt ?? s; - const sound = getSound(soundSource); - if (!sound) { - throw new Error(`sound ${soundSource} not found! Is it loaded?`); - } - const { onTrigger } = sound; + } else if (getSound(s)) { + const { onTrigger } = getSound(s); const onEnded = () => { audioNodes.forEach((n) => n?.disconnect()); activeSoundSources.delete(chainID); @@ -703,6 +698,8 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) sourceNode = soundHandle.node; activeSoundSources.set(chainID, soundHandle); } + } else { + throw new Error(`sound ${s} not found! Is it loaded?`); } if (!sourceNode) { // if onTrigger does not return anything, we will just silently skip diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index ce0e7ac80..b0c0e8e2d 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -909,7 +909,6 @@ class ByteBeatProcessor extends AudioWorkletProcessor { registerProcessor('byte-beat-processor', ByteBeatProcessor); - export const WarpMode = Object.freeze({ NONE: 0, ASYM: 1, diff --git a/website/src/repl/components/panel/SettingsTab.jsx b/website/src/repl/components/panel/SettingsTab.jsx index 8f02ca8b8..26c9ae287 100644 --- a/website/src/repl/components/panel/SettingsTab.jsx +++ b/website/src/repl/components/panel/SettingsTab.jsx @@ -312,7 +312,7 @@ export function SettingsTab({ started }) { confirmDialog('Sure?').then((r) => { if (r) { const { userPatterns } = settingsMap.get(); // keep current patterns - settingsMap.set({...defaultSettings, userPatterns}); + settingsMap.set({ ...defaultSettings, userPatterns }); } }); }} From 0a96fa5896848d83a7fed79a00d98d029cf8e6e5 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sat, 6 Sep 2025 00:42:36 +0200 Subject: [PATCH 106/335] hotfix: comment out tauri stuff to fix osc --- packages/osc/superdirtoutput.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/osc/superdirtoutput.js b/packages/osc/superdirtoutput.js index 3f48e66bd..e8fef0301 100644 --- a/packages/osc/superdirtoutput.js +++ b/packages/osc/superdirtoutput.js @@ -1,8 +1,8 @@ -import { oscTriggerTauri } from '../desktopbridge/oscbridge.mjs'; -import { isTauri } from '../desktopbridge/utils.mjs'; +/* import { oscTriggerTauri } from '../desktopbridge/oscbridge.mjs'; +import { isTauri } from '../desktopbridge/utils.mjs'; */ import { oscTrigger } from './osc.mjs'; -const trigger = isTauri() ? oscTriggerTauri : oscTrigger; +const trigger = /* isTauri() ? oscTriggerTauri : */ oscTrigger; export const superdirtOutput = (hap, deadline, hapDuration, cps, targetTime) => { const currentTime = performance.now() / 1000; From 2fbdc9fdd730a147b1e38398e7d3d8a2ba9cb89a Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sat, 6 Sep 2025 00:43:03 +0200 Subject: [PATCH 107/335] hotfix: formatting --- website/src/repl/components/panel/SettingsTab.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/repl/components/panel/SettingsTab.jsx b/website/src/repl/components/panel/SettingsTab.jsx index 8f02ca8b8..26c9ae287 100644 --- a/website/src/repl/components/panel/SettingsTab.jsx +++ b/website/src/repl/components/panel/SettingsTab.jsx @@ -312,7 +312,7 @@ export function SettingsTab({ started }) { confirmDialog('Sure?').then((r) => { if (r) { const { userPatterns } = settingsMap.get(); // keep current patterns - settingsMap.set({...defaultSettings, userPatterns}); + settingsMap.set({ ...defaultSettings, userPatterns }); } }); }} From 9c108862ef0edfe1d2c50e51337ff4f646bfbe2f Mon Sep 17 00:00:00 2001 From: Aria Date: Fri, 5 Sep 2025 22:09:50 -0500 Subject: [PATCH 108/335] Corrected piping --- packages/superdough/superdough.mjs | 14 +++++++------- website/src/repl/components/panel/SettingsTab.jsx | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 290796956..5e5969fed 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -333,10 +333,10 @@ function getDelay(orbit, delaytime, delayfeedback, t) { let delayNode = orbits[orbit].delayNode; if (delayNode === undefined) { const ac = getAudioContext(); - const dly = ac.createFeedbackDelay(1, delaytime, delayfeedback); - dly.start?.(t); // for some reason, this throws when audion extension is installed.. - connectToOrbit(dly, orbit); - orbits[orbit].delayNode = dly; + delayNode = ac.createFeedbackDelay(1, delaytime, delayfeedback); + delayNode.start?.(t); // for some reason, this throws when audion extension is installed.. + connectToOrbit(delayNode, orbit); + orbits[orbit].delayNode = delayNode; } delayNode.delayTime.value !== delaytime && delayNode.delayTime.setValueAtTime(delaytime, t); delayNode.feedback.value !== delayfeedback && delayNode.feedback.setValueAtTime(delayfeedback, t); @@ -462,9 +462,9 @@ function getReverb(orbit, duration, fade, lp, dim, ir, irspeed, irbegin) { let reverbNode = orbits[orbit].reverbNode; if (reverbNode === undefined) { const ac = getAudioContext(); - const reverb = ac.createReverb(duration, fade, lp, dim, ir, irspeed, irbegin); - connectToOrbit(reverb, orbit); - orbits[orbit].reverbNode = reverb; + reverbNode = ac.createReverb(duration, fade, lp, dim, ir, irspeed, irbegin); + connectToOrbit(reverbNode, orbit); + orbits[orbit].reverbNode = reverbNode; } if ( diff --git a/website/src/repl/components/panel/SettingsTab.jsx b/website/src/repl/components/panel/SettingsTab.jsx index 8f02ca8b8..26c9ae287 100644 --- a/website/src/repl/components/panel/SettingsTab.jsx +++ b/website/src/repl/components/panel/SettingsTab.jsx @@ -312,7 +312,7 @@ export function SettingsTab({ started }) { confirmDialog('Sure?').then((r) => { if (r) { const { userPatterns } = settingsMap.get(); // keep current patterns - settingsMap.set({...defaultSettings, userPatterns}); + settingsMap.set({ ...defaultSettings, userPatterns }); } }); }} From 977420e74dfe4a0e2c93b94f6d346a21f765a77e Mon Sep 17 00:00:00 2001 From: "Daniel D. Beck" Date: Sat, 6 Sep 2025 15:33:08 +0200 Subject: [PATCH 109/335] Fix formatting of REPL footnote --- website/src/pages/technical-manual/repl.mdx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/website/src/pages/technical-manual/repl.mdx b/website/src/pages/technical-manual/repl.mdx index f53efac41..8c4287af5 100644 --- a/website/src/pages/technical-manual/repl.mdx +++ b/website/src/pages/technical-manual/repl.mdx @@ -9,7 +9,9 @@ import { MiniRepl } from '../../docs/MiniRepl'; {/* The [REPL](https://strudel.cc/) is the place where all packages come together to form a live coding system. It can also be seen as a reference implementation for users of the library. */} -While Strudel can be used as a library in any JavaScript codebase, its main, reference user interface is the Strudel REPL^[REPL stands for read, evaluate, print/play, loop. It is friendly jargon for an interactive programming interface from computing heritage, usually for a commandline interface but also applied to live coding editors.], which is a browser-based live coding environment. This live code editor is dedicated to manipulating Strudel patterns while they play. The REPL features built-in visual feedback, highlighting which elements in the patterned (mini-notation) sequences are influencing the event that is currently being played. This feedback is designed to support both learning and live use of Strudel. +While Strudel can be used as a library in any JavaScript codebase, its main, reference user interface is the Strudel REPL[^1], which is a browser-based live coding environment. This live code editor is dedicated to manipulating Strudel patterns while they play. The REPL features built-in visual feedback, highlighting which elements in the patterned (mini-notation) sequences are influencing the event that is currently being played. This feedback is designed to support both learning and live use of Strudel. + +[^1]: REPL stands for read, evaluate, print/play, loop. It is friendly jargon for an interactive programming interface from computing heritage, usually for a commandline interface but also applied to live coding editors. Besides a UI for playback control and meta information, the main part of the REPL interface is the code editor powered by CodeMirror. In it, the user can edit and evaluate pattern code live, using one of the available synthesis outputs to create music and/or sound art. The control flow of the REPL follows 3 basic steps: From 798eb22d9a5a5be342b2e78a34f845a3c748d184 Mon Sep 17 00:00:00 2001 From: Aria Date: Sat, 6 Sep 2025 10:09:44 -0500 Subject: [PATCH 110/335] Use currentTime for exact scheduling --- packages/core/controls.mjs | 8 +-- packages/superdough/superdough.mjs | 21 ++++---- test/__snapshots__/examples.test.mjs.snap | 64 +++++++++++------------ 3 files changed, 47 insertions(+), 46 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 589a0634f..af0c4b1ab 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -590,12 +590,12 @@ export const { duckdepth } = registerControl('duckdepth'); * @param {number | Pattern} time The onset time in seconds * @example * // Clicks - * sound: n(run(8)).scale("c:minor").s("sawtooth").lpf(200).delay(.7).orbit(2) - * duckerWithClick: s("bd*4").duckorbit(2).duckonset(0).postgain(0) + * sound: freq("63.2388").s("sine").orbit(2).gain(4) + * duckerWithClick: s("bd*4").duckorbit(2).duckattack(0.3).duckonset(0).postgain(0) * @example * // No clicks - * sound: n(run(8)).scale("c:minor").s("sawtooth").lpf(200).delay(.7).orbit(2) - * duckerWithoutClick: s("bd*4").duckorbit(2).duckonset(0.003).postgain(0) + * sound: freq("63.2388").s("sine").orbit(2).gain(4) + * duckerWithoutClick: s("bd*4").duckorbit(2).duckattack(0.3).duckonset(0.01).postgain(0) * @example * // Rhythmic * noise: s("pink").distort("2:1").orbit(4) // used rhythmically with 0.3 onset below diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 5e5969fed..59590db6d 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -420,7 +420,7 @@ function setOrbit(audioContext, orbit, channels) { } } -function duckOrbit(audioContext, targetOrbit, t, onsettime = 0.003, attacktime = 0.1, duckdepth = 1) { +function duckOrbit(audioContext, targetOrbit, t, onsettime = 0, attacktime = 0.1, duckdepth = 1) { const targetArr = [targetOrbit].flat(); const onsetArr = [onsettime].flat(); const attackArr = [attacktime].flat(); @@ -438,17 +438,18 @@ function duckOrbit(audioContext, targetOrbit, t, onsettime = 0.003, attacktime = webAudioTimeout( audioContext, () => { - gainParam.cancelScheduledValues(t); + const now = audioContext.currentTime; + + // cancelScheduledValues and setValueAtTime together emulate cancelAndHoldAtTime + // on browsers which lack that method const currVal = gainParam.value; + gainParam.cancelScheduledValues(now); + gainParam.setValueAtTime(currVal, now); + + const t0 = Math.max(t, now); // guard against now > t const duckedVal = clamp(1 - Math.sqrt(depth), 0.01, currVal); - - // Guarantees the value is set to currVal at time t. This in conjunction with - // cancelScheduledValues above emulates cancelAndHoldAtTime on browsers which lack - // that method - gainParam.setValueAtTime(currVal, t); - - gainParam.exponentialRampToValueAtTime(duckedVal, t + onset); - gainParam.exponentialRampToValueAtTime(1, t + onset + attack); + gainParam.exponentialRampToValueAtTime(duckedVal, t0 + onset); + gainParam.exponentialRampToValueAtTime(1, t0 + onset + attack); }, 0, t - 0.01, diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index ba54328b7..7579794fd 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -3170,43 +3170,43 @@ exports[`runs examples > example "duckdepth" example index 1 1`] = ` exports[`runs examples > example "duckonset" example index 0 1`] = ` [ - "[ 0/1 → 1/4 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", - "[ 1/4 → 1/2 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", - "[ 1/2 → 3/4 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", - "[ 3/4 → 1/1 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", - "[ 1/1 → 5/4 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", - "[ 5/4 → 3/2 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", - "[ 3/2 → 7/4 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", - "[ 7/4 → 2/1 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", - "[ 2/1 → 9/4 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", - "[ 9/4 → 5/2 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", - "[ 5/2 → 11/4 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", - "[ 11/4 → 3/1 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", - "[ 3/1 → 13/4 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", - "[ 13/4 → 7/2 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", - "[ 7/2 → 15/4 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", - "[ 15/4 → 4/1 | s:bd duckorbit:2 duckonset:0 postgain:0 ]", + "[ 0/1 → 1/4 | s:bd duckorbit:2 duckattack:0.3 duckonset:0 postgain:0 ]", + "[ 1/4 → 1/2 | s:bd duckorbit:2 duckattack:0.3 duckonset:0 postgain:0 ]", + "[ 1/2 → 3/4 | s:bd duckorbit:2 duckattack:0.3 duckonset:0 postgain:0 ]", + "[ 3/4 → 1/1 | s:bd duckorbit:2 duckattack:0.3 duckonset:0 postgain:0 ]", + "[ 1/1 → 5/4 | s:bd duckorbit:2 duckattack:0.3 duckonset:0 postgain:0 ]", + "[ 5/4 → 3/2 | s:bd duckorbit:2 duckattack:0.3 duckonset:0 postgain:0 ]", + "[ 3/2 → 7/4 | s:bd duckorbit:2 duckattack:0.3 duckonset:0 postgain:0 ]", + "[ 7/4 → 2/1 | s:bd duckorbit:2 duckattack:0.3 duckonset:0 postgain:0 ]", + "[ 2/1 → 9/4 | s:bd duckorbit:2 duckattack:0.3 duckonset:0 postgain:0 ]", + "[ 9/4 → 5/2 | s:bd duckorbit:2 duckattack:0.3 duckonset:0 postgain:0 ]", + "[ 5/2 → 11/4 | s:bd duckorbit:2 duckattack:0.3 duckonset:0 postgain:0 ]", + "[ 11/4 → 3/1 | s:bd duckorbit:2 duckattack:0.3 duckonset:0 postgain:0 ]", + "[ 3/1 → 13/4 | s:bd duckorbit:2 duckattack:0.3 duckonset:0 postgain:0 ]", + "[ 13/4 → 7/2 | s:bd duckorbit:2 duckattack:0.3 duckonset:0 postgain:0 ]", + "[ 7/2 → 15/4 | s:bd duckorbit:2 duckattack:0.3 duckonset:0 postgain:0 ]", + "[ 15/4 → 4/1 | s:bd duckorbit:2 duckattack:0.3 duckonset:0 postgain:0 ]", ] `; exports[`runs examples > example "duckonset" example index 1 1`] = ` [ - "[ 0/1 → 1/4 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", - "[ 1/4 → 1/2 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", - "[ 1/2 → 3/4 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", - "[ 3/4 → 1/1 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", - "[ 1/1 → 5/4 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", - "[ 5/4 → 3/2 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", - "[ 3/2 → 7/4 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", - "[ 7/4 → 2/1 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", - "[ 2/1 → 9/4 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", - "[ 9/4 → 5/2 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", - "[ 5/2 → 11/4 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", - "[ 11/4 → 3/1 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", - "[ 3/1 → 13/4 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", - "[ 13/4 → 7/2 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", - "[ 7/2 → 15/4 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", - "[ 15/4 → 4/1 | s:bd duckorbit:2 duckonset:0.003 postgain:0 ]", + "[ 0/1 → 1/4 | s:bd duckorbit:2 duckattack:0.3 duckonset:0.01 postgain:0 ]", + "[ 1/4 → 1/2 | s:bd duckorbit:2 duckattack:0.3 duckonset:0.01 postgain:0 ]", + "[ 1/2 → 3/4 | s:bd duckorbit:2 duckattack:0.3 duckonset:0.01 postgain:0 ]", + "[ 3/4 → 1/1 | s:bd duckorbit:2 duckattack:0.3 duckonset:0.01 postgain:0 ]", + "[ 1/1 → 5/4 | s:bd duckorbit:2 duckattack:0.3 duckonset:0.01 postgain:0 ]", + "[ 5/4 → 3/2 | s:bd duckorbit:2 duckattack:0.3 duckonset:0.01 postgain:0 ]", + "[ 3/2 → 7/4 | s:bd duckorbit:2 duckattack:0.3 duckonset:0.01 postgain:0 ]", + "[ 7/4 → 2/1 | s:bd duckorbit:2 duckattack:0.3 duckonset:0.01 postgain:0 ]", + "[ 2/1 → 9/4 | s:bd duckorbit:2 duckattack:0.3 duckonset:0.01 postgain:0 ]", + "[ 9/4 → 5/2 | s:bd duckorbit:2 duckattack:0.3 duckonset:0.01 postgain:0 ]", + "[ 5/2 → 11/4 | s:bd duckorbit:2 duckattack:0.3 duckonset:0.01 postgain:0 ]", + "[ 11/4 → 3/1 | s:bd duckorbit:2 duckattack:0.3 duckonset:0.01 postgain:0 ]", + "[ 3/1 → 13/4 | s:bd duckorbit:2 duckattack:0.3 duckonset:0.01 postgain:0 ]", + "[ 13/4 → 7/2 | s:bd duckorbit:2 duckattack:0.3 duckonset:0.01 postgain:0 ]", + "[ 7/2 → 15/4 | s:bd duckorbit:2 duckattack:0.3 duckonset:0.01 postgain:0 ]", + "[ 15/4 → 4/1 | s:bd duckorbit:2 duckattack:0.3 duckonset:0.01 postgain:0 ]", ] `; From 2511dcc09e180d9b5fdb3ac1591ddc0059999739 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sun, 7 Sep 2025 15:02:13 -0400 Subject: [PATCH 111/335] working --- packages/superdough/superdough.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index a518f49b6..792e5a28d 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -413,7 +413,7 @@ function connectToOrbit(node, orbit) { function setOrbit(audioContext, orbit, channels) { if (orbits[orbit] == null) { orbits[orbit] = { - gain: new GainNode(audioContext, { gain: 1 }), + gain: new GainNode(audioContext, { gain: 1, channelCount: 2, channelCountMode: 'explicit' }), }; connectToDestination(orbits[orbit].gain, channels); } From e7e80bfd83b3661e92a93def0c84011e330fb512 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sun, 7 Sep 2025 22:21:03 -0400 Subject: [PATCH 112/335] working --- .../repl/components/button/action-button.jsx | 10 +++++ .../src/repl/components/panel/PatternsTab.jsx | 13 +----- .../src/repl/components/panel/SoundsTab.jsx | 41 ++++++++++++++----- website/src/repl/idbutils.mjs | 8 +++- website/src/settings.mjs | 10 ++++- 5 files changed, 58 insertions(+), 24 deletions(-) create mode 100644 website/src/repl/components/button/action-button.jsx diff --git a/website/src/repl/components/button/action-button.jsx b/website/src/repl/components/button/action-button.jsx new file mode 100644 index 000000000..d589b7bed --- /dev/null +++ b/website/src/repl/components/button/action-button.jsx @@ -0,0 +1,10 @@ +import cx from '@src/cx.mjs'; + +export function ActionButton({ children, label, labelIsHidden, className, ...buttonProps }) { + return ( + + ); +} diff --git a/website/src/repl/components/panel/PatternsTab.jsx b/website/src/repl/components/panel/PatternsTab.jsx index 8a43e4a1b..8e2b75b96 100644 --- a/website/src/repl/components/panel/PatternsTab.jsx +++ b/website/src/repl/components/panel/PatternsTab.jsx @@ -12,8 +12,8 @@ import { useMemo } from 'react'; import { getMetadata } from '../../../metadata_parser.js'; import { useExamplePatterns } from '../../useExamplePatterns.jsx'; import { parseJSON, isUdels } from '../../util.mjs'; -import { ButtonGroup } from './Forms.jsx'; -import { settingsMap, useSettings } from '../../../settings.mjs'; +import { useSettings } from '../../../settings.mjs'; +import { ActionButton } from '../button/action-button.jsx'; import { Pagination } from '../pagination/Pagination.jsx'; import { useState } from 'react'; import { useDebounce } from '../usedebounce.jsx'; @@ -75,15 +75,6 @@ function PatternButtons({ patterns, activePattern, onClick, started }) { ); } -function ActionButton({ children, onClick, label, labelIsHidden }) { - return ( - - ); -} - const updateCodeWindow = (context, patternData, reset = false) => { context.handleUpdate(patternData, reset); }; diff --git a/website/src/repl/components/panel/SoundsTab.jsx b/website/src/repl/components/panel/SoundsTab.jsx index a976eb3d2..7b91f4cf2 100644 --- a/website/src/repl/components/panel/SoundsTab.jsx +++ b/website/src/repl/components/panel/SoundsTab.jsx @@ -2,16 +2,21 @@ import useEvent from '@src/useEvent.mjs'; import { useStore } from '@nanostores/react'; import { getAudioContext, soundMap, connectToDestination } from '@strudel/webaudio'; import { useMemo, useRef, useState } from 'react'; -import { settingsMap, useSettings } from '../../../settings.mjs'; +import { settingsMap, soundFilterType, useSettings } from '../../../settings.mjs'; import { ButtonGroup } from './Forms.jsx'; import ImportSoundsButton from './ImportSoundsButton.jsx'; import { Textbox } from '../textbox/Textbox.jsx'; +import { ActionButton } from '../button/action-button.jsx'; +import { confirmDialog } from '@src/repl/util.mjs'; +import { clearIDB, userSamplesDBConfig } from '@src/repl/idbutils.mjs'; +import { prebake } from '@src/repl/prebake.mjs'; const getSamples = (samples) => Array.isArray(samples) ? samples.length : typeof samples === 'object' ? Object.values(samples).length : 1; export function SoundsTab() { const sounds = useStore(soundMap); + const { soundsFilter } = useSettings(); const [search, setSearch] = useState(''); const { BASE_URL } = import.meta.env; @@ -27,18 +32,19 @@ export function SoundsTab() { .sort((a, b) => a[0].localeCompare(b[0])) .filter(([name]) => name.toLowerCase().includes(search.toLowerCase())); - if (soundsFilter === 'user') { + if (soundsFilter === soundFilterType.USER) { return filtered.filter(([_, { data }]) => !data.prebake); } - if (soundsFilter === 'drums') { + if (soundsFilter === soundFilterType.DRUMS) { return filtered.filter(([_, { data }]) => data.type === 'sample' && data.tag === 'drum-machines'); } - if (soundsFilter === 'samples') { + if (soundsFilter === soundFilterType.SAMPLES) { return filtered.filter(([_, { data }]) => data.type === 'sample' && data.tag !== 'drum-machines'); } - if (soundsFilter === 'synths') { + if (soundsFilter === soundFilterType.SYNTHS) { return filtered.filter(([_, { data }]) => ['synth', 'soundfont'].includes(data.type)); } + //TODO: tidy this up, it does not need to be saved in settings if (soundsFilter === 'importSounds') { return []; } @@ -57,10 +63,10 @@ export function SoundsTab() { }); }); return ( -
+
setSearch(v)} /> -
+
settingsMap.setKey('soundsFilter', value)} @@ -73,6 +79,23 @@ export function SoundsTab() { }} >
+ { + { + try { + const confirmed = await confirmDialog('Delete all imported user samples?'); + if (confirmed) { + clearIDB(userSamplesDBConfig.dbName); + soundMap.set({}); + await prebake(); + } + } catch (e) { + console.error(e); + } + }} + /> + }
{soundEntries.map(([name, { data, onTrigger }]) => { @@ -151,9 +174,7 @@ export function SoundsTab() { ) : ( '' )} - {!soundEntries.length && soundsFilter !== 'importSounds' - ? 'No custom sounds loaded in this pattern (yet).' - : ''} + {!soundEntries.length && soundsFilter !== 'importSounds' ? 'No custom sounds loaded (yet).' : ''}
); diff --git a/website/src/repl/idbutils.mjs b/website/src/repl/idbutils.mjs index 5fc62c576..f26ee0479 100644 --- a/website/src/repl/idbutils.mjs +++ b/website/src/repl/idbutils.mjs @@ -12,17 +12,21 @@ export const userSamplesDBConfig = { }; // deletes all of the databases, useful for debugging -function clearIDB() { +function clearAllIDB() { window.indexedDB .databases() .then((r) => { - for (var i = 0; i < r.length; i++) window.indexedDB.deleteDatabase(r[i].name); + for (var i = 0; i < r.length; i++) clearIDB(r[i].name); }) .then(() => { alert('All data cleared.'); }); } +export function clearIDB(dbName) { + return window.indexedDB.deleteDatabase(dbName); +} + // queries the DB, and registers the sounds so they can be played export function registerSamplesFromDB(config = userSamplesDBConfig, onComplete = () => {}) { openDB(config, (objectStore) => { diff --git a/website/src/settings.mjs b/website/src/settings.mjs index 3d99b656c..9c3d78146 100644 --- a/website/src/settings.mjs +++ b/website/src/settings.mjs @@ -8,6 +8,14 @@ export const audioEngineTargets = { osc: 'osc', }; +export const soundFilterType = { + USER: 'user', + DRUMS: 'drums', + SAMPLES: 'samples', + SYNTHS: 'synths', + ALL: 'all', +}; + export const defaultSettings = { activeFooter: 'intro', keybindings: 'codemirror', @@ -28,7 +36,7 @@ export const defaultSettings = { fontSize: 18, latestCode: '', isZen: false, - soundsFilter: 'all', + soundsFilter: soundFilterType.ALL, patternFilter: 'community', // panelPosition: window.innerWidth > 1000 ? 'right' : 'bottom', //FIX: does not work on astro panelPosition: 'right', From 5414bbe85ddec4729506bd6891593ba8418f2e7f Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sun, 7 Sep 2025 22:27:48 -0400 Subject: [PATCH 113/335] only show button on user samples --- website/src/repl/components/panel/SoundsTab.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/src/repl/components/panel/SoundsTab.jsx b/website/src/repl/components/panel/SoundsTab.jsx index 7b91f4cf2..de22fb3e8 100644 --- a/website/src/repl/components/panel/SoundsTab.jsx +++ b/website/src/repl/components/panel/SoundsTab.jsx @@ -79,7 +79,7 @@ export function SoundsTab() { }} >
- { + {soundsFilter === soundFilterType.USER && soundEntries.length > 0 && ( { @@ -95,7 +95,7 @@ export function SoundsTab() { } }} /> - } + )}
{soundEntries.map(([name, { data, onTrigger }]) => { @@ -174,7 +174,7 @@ export function SoundsTab() { ) : ( '' )} - {!soundEntries.length && soundsFilter !== 'importSounds' ? 'No custom sounds loaded (yet).' : ''} + {!soundEntries.length && soundsFilter !== 'importSounds' ? 'No sounds loaded' : ''}
); From a96854545823a3d8a546d3590c07797df539316d Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sun, 7 Sep 2025 22:41:03 -0400 Subject: [PATCH 114/335] change sound background to distinguish action buttons --- website/src/repl/components/panel/SoundsTab.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/repl/components/panel/SoundsTab.jsx b/website/src/repl/components/panel/SoundsTab.jsx index de22fb3e8..d1845bfa8 100644 --- a/website/src/repl/components/panel/SoundsTab.jsx +++ b/website/src/repl/components/panel/SoundsTab.jsx @@ -97,7 +97,7 @@ export function SoundsTab() { /> )} -
+
{soundEntries.map(([name, { data, onTrigger }]) => { return ( Date: Sun, 7 Sep 2025 22:43:13 -0400 Subject: [PATCH 115/335] fix formatting --- .../src/repl/components/panel/SoundsTab.jsx | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/website/src/repl/components/panel/SoundsTab.jsx b/website/src/repl/components/panel/SoundsTab.jsx index d1845bfa8..92f30070e 100644 --- a/website/src/repl/components/panel/SoundsTab.jsx +++ b/website/src/repl/components/panel/SoundsTab.jsx @@ -79,23 +79,26 @@ export function SoundsTab() { }} >
- {soundsFilter === soundFilterType.USER && soundEntries.length > 0 && ( - { - try { - const confirmed = await confirmDialog('Delete all imported user samples?'); - if (confirmed) { - clearIDB(userSamplesDBConfig.dbName); - soundMap.set({}); - await prebake(); +
+ {soundsFilter === soundFilterType.USER && soundEntries.length > 0 && ( + { + try { + const confirmed = await confirmDialog('Delete all imported user samples?'); + if (confirmed) { + clearIDB(userSamplesDBConfig.dbName); + soundMap.set({}); + await prebake(); + } + } catch (e) { + console.error(e); } - } catch (e) { - console.error(e); - } - }} - /> - )} + }} + /> + )} +
{soundEntries.map(([name, { data, onTrigger }]) => { From 70e776e799e586f1ffb787db6d15fae871f08399 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sun, 7 Sep 2025 22:44:09 -0400 Subject: [PATCH 116/335] cleanup div --- .../src/repl/components/panel/SoundsTab.jsx | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/website/src/repl/components/panel/SoundsTab.jsx b/website/src/repl/components/panel/SoundsTab.jsx index 92f30070e..433d53712 100644 --- a/website/src/repl/components/panel/SoundsTab.jsx +++ b/website/src/repl/components/panel/SoundsTab.jsx @@ -79,26 +79,26 @@ export function SoundsTab() { }} >
-
- {soundsFilter === soundFilterType.USER && soundEntries.length > 0 && ( - { - try { - const confirmed = await confirmDialog('Delete all imported user samples?'); - if (confirmed) { - clearIDB(userSamplesDBConfig.dbName); - soundMap.set({}); - await prebake(); - } - } catch (e) { - console.error(e); + + {soundsFilter === soundFilterType.USER && soundEntries.length > 0 && ( + { + try { + const confirmed = await confirmDialog('Delete all imported user samples?'); + if (confirmed) { + clearIDB(userSamplesDBConfig.dbName); + soundMap.set({}); + await prebake(); } - }} - /> - )} -
+ } catch (e) { + console.error(e); + } + }} + /> + )} +
{soundEntries.map(([name, { data, onTrigger }]) => { From 99bb227cf480e67a59bac1432908e8a77c8be0f6 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sun, 7 Sep 2025 22:48:04 -0400 Subject: [PATCH 117/335] format --- website/src/repl/components/panel/SoundsTab.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/website/src/repl/components/panel/SoundsTab.jsx b/website/src/repl/components/panel/SoundsTab.jsx index 433d53712..0484da02d 100644 --- a/website/src/repl/components/panel/SoundsTab.jsx +++ b/website/src/repl/components/panel/SoundsTab.jsx @@ -99,7 +99,6 @@ export function SoundsTab() { /> )} -
{soundEntries.map(([name, { data, onTrigger }]) => { return ( From 89e7d5230885e2ca372e6df2f4ba4343f08eb648 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sun, 7 Sep 2025 23:28:18 -0400 Subject: [PATCH 118/335] fixed --- packages/osc/superdirtoutput.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/osc/superdirtoutput.js b/packages/osc/superdirtoutput.js index e8fef0301..a317af8f1 100644 --- a/packages/osc/superdirtoutput.js +++ b/packages/osc/superdirtoutput.js @@ -6,5 +6,5 @@ const trigger = /* isTauri() ? oscTriggerTauri : */ oscTrigger; export const superdirtOutput = (hap, deadline, hapDuration, cps, targetTime) => { const currentTime = performance.now() / 1000; - return trigger(null, hap, currentTime, cps, targetTime); + return trigger(hap, currentTime, cps, targetTime); }; From 5e5e7730c1cd2ccc133766e369998e672d0021dd Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sun, 7 Sep 2025 23:29:24 -0400 Subject: [PATCH 119/335] rm errorlogger console --- packages/core/logger.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/logger.mjs b/packages/core/logger.mjs index 488bce5e8..4f2002319 100644 --- a/packages/core/logger.mjs +++ b/packages/core/logger.mjs @@ -6,7 +6,7 @@ let debounce = 1000, export function errorLogger(e, origin = 'cyclist') { //TODO: add some kind of debug flag that enables this while in dev mode - console.error(e); + // console.error(e); logger(`[${origin}] error: ${e.message}`); } From 38ce593c602659a594b81047dd9633790ef7c010 Mon Sep 17 00:00:00 2001 From: Aria Date: Tue, 9 Sep 2025 20:43:05 -0500 Subject: [PATCH 120/335] Allow penv values to be falsy --- packages/superdough/helpers.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index 81bec9399..69e7e8560 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -174,7 +174,7 @@ let curves = ['linear', 'exponential']; export function getPitchEnvelope(param, value, t, holdEnd) { // envelope is active when any of these values is set const hasEnvelope = value.pattack ?? value.pdecay ?? value.psustain ?? value.prelease ?? value.penv; - if (!hasEnvelope) { + if (hasEnvelope === undefined) { return; } const penv = nanFallback(value.penv, 1, true); From d0ce82e3cd37e6299329fefec23c5af9e5441d0e Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Wed, 10 Sep 2025 23:08:16 +0200 Subject: [PATCH 121/335] Publish - @strudel/codemirror@1.2.4 - @strudel/core@1.2.4 - @strudel/csound@1.2.5 - @strudel/draw@1.2.4 - @strudel/gamepad@1.2.4 - @strudel/hydra@1.2.4 - @strudel/midi@1.2.5 - @strudel/mini@1.2.4 - @strudel/mondo@1.1.2 - @strudel/motion@1.2.4 - @strudel/mqtt@1.2.4 - @strudel/osc@1.2.4 - @strudel/repl@1.2.5 - @strudel/sampler@0.2.3 - @strudel/serial@1.2.4 - @strudel/soundfonts@1.2.5 - superdough@1.2.5 - @strudel/tonal@1.2.4 - @strudel/transpiler@1.2.4 - @strudel/web@1.2.5 - @strudel/webaudio@1.2.5 - @strudel/xen@1.2.4 --- packages/codemirror/package.json | 2 +- packages/core/package.json | 2 +- packages/csound/package.json | 2 +- packages/draw/package.json | 2 +- packages/gamepad/package.json | 2 +- packages/hydra/package.json | 2 +- packages/midi/package.json | 2 +- packages/mini/package.json | 2 +- packages/mondough/package.json | 2 +- packages/motion/package.json | 2 +- packages/mqtt/package.json | 2 +- packages/osc/package.json | 2 +- packages/repl/package.json | 2 +- packages/sampler/package.json | 2 +- packages/serial/package.json | 2 +- packages/soundfonts/package.json | 2 +- packages/superdough/package.json | 2 +- packages/tonal/package.json | 2 +- packages/transpiler/package.json | 2 +- packages/web/package.json | 2 +- packages/webaudio/package.json | 2 +- packages/xen/package.json | 2 +- 22 files changed, 22 insertions(+), 22 deletions(-) diff --git a/packages/codemirror/package.json b/packages/codemirror/package.json index 797a4312b..609df6ede 100644 --- a/packages/codemirror/package.json +++ b/packages/codemirror/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/codemirror", - "version": "1.2.3", + "version": "1.2.4", "description": "Codemirror Extensions for Strudel", "main": "index.mjs", "publishConfig": { diff --git a/packages/core/package.json b/packages/core/package.json index 33540c8bf..7cf20cea7 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/core", - "version": "1.2.3", + "version": "1.2.4", "description": "Port of Tidal Cycles to JavaScript", "main": "index.mjs", "type": "module", diff --git a/packages/csound/package.json b/packages/csound/package.json index 19b1dd6fd..90130a101 100644 --- a/packages/csound/package.json +++ b/packages/csound/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/csound", - "version": "1.2.4", + "version": "1.2.5", "description": "csound bindings for strudel", "main": "index.mjs", "type": "module", diff --git a/packages/draw/package.json b/packages/draw/package.json index f63367402..6a4c57540 100644 --- a/packages/draw/package.json +++ b/packages/draw/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/draw", - "version": "1.2.3", + "version": "1.2.4", "description": "Helpers for drawing with Strudel", "main": "index.mjs", "type": "module", diff --git a/packages/gamepad/package.json b/packages/gamepad/package.json index 53fad18a6..555eac03f 100644 --- a/packages/gamepad/package.json +++ b/packages/gamepad/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/gamepad", - "version": "1.2.3", + "version": "1.2.4", "description": "Gamepad Inputs for strudel", "main": "index.mjs", "type": "module", diff --git a/packages/hydra/package.json b/packages/hydra/package.json index 1553264d4..7ba79d5d0 100644 --- a/packages/hydra/package.json +++ b/packages/hydra/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/hydra", - "version": "1.2.3", + "version": "1.2.4", "description": "Hydra integration for strudel", "main": "hydra.mjs", "type": "module", diff --git a/packages/midi/package.json b/packages/midi/package.json index 8dde35984..2342cf7e9 100644 --- a/packages/midi/package.json +++ b/packages/midi/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/midi", - "version": "1.2.4", + "version": "1.2.5", "description": "Midi API for strudel", "main": "index.mjs", "type": "module", diff --git a/packages/mini/package.json b/packages/mini/package.json index e8fca4ac6..6eeaab0da 100644 --- a/packages/mini/package.json +++ b/packages/mini/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/mini", - "version": "1.2.3", + "version": "1.2.4", "description": "Mini notation for strudel", "main": "index.mjs", "type": "module", diff --git a/packages/mondough/package.json b/packages/mondough/package.json index 99a87f098..f26281490 100644 --- a/packages/mondough/package.json +++ b/packages/mondough/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/mondo", - "version": "1.1.1", + "version": "1.1.2", "description": "mondo notation for strudel", "main": "mondough.mjs", "type": "module", diff --git a/packages/motion/package.json b/packages/motion/package.json index acacc154f..57cac9cc8 100644 --- a/packages/motion/package.json +++ b/packages/motion/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/motion", - "version": "1.2.3", + "version": "1.2.4", "description": "DeviceMotion API for strudel", "main": "index.mjs", "type": "module", diff --git a/packages/mqtt/package.json b/packages/mqtt/package.json index d5ac6dd71..2e32825fe 100644 --- a/packages/mqtt/package.json +++ b/packages/mqtt/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/mqtt", - "version": "1.2.3", + "version": "1.2.4", "description": "MQTT API for strudel", "main": "mqtt.mjs", "type": "module", diff --git a/packages/osc/package.json b/packages/osc/package.json index 6e8b57813..d5a272328 100644 --- a/packages/osc/package.json +++ b/packages/osc/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/osc", - "version": "1.2.3", + "version": "1.2.4", "description": "OSC messaging for strudel", "main": "osc.mjs", "type": "module", diff --git a/packages/repl/package.json b/packages/repl/package.json index aabd1b8c7..547ec979f 100644 --- a/packages/repl/package.json +++ b/packages/repl/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/repl", - "version": "1.2.4", + "version": "1.2.5", "description": "Strudel REPL as a Web Component", "module": "index.mjs", "publishConfig": { diff --git a/packages/sampler/package.json b/packages/sampler/package.json index dd701bcfb..2bf0607b1 100644 --- a/packages/sampler/package.json +++ b/packages/sampler/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/sampler", - "version": "0.2.2", + "version": "0.2.3", "description": "", "keywords": [ "tidalcycles", diff --git a/packages/serial/package.json b/packages/serial/package.json index 8abbe7692..9ed89cf2a 100644 --- a/packages/serial/package.json +++ b/packages/serial/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/serial", - "version": "1.2.3", + "version": "1.2.4", "description": "Webserial API for strudel", "main": "serial.mjs", "type": "module", diff --git a/packages/soundfonts/package.json b/packages/soundfonts/package.json index e5c1780ed..07e35674b 100644 --- a/packages/soundfonts/package.json +++ b/packages/soundfonts/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/soundfonts", - "version": "1.2.4", + "version": "1.2.5", "description": "Soundsfont support for strudel", "main": "index.mjs", "publishConfig": { diff --git a/packages/superdough/package.json b/packages/superdough/package.json index 809da0227..a82117774 100644 --- a/packages/superdough/package.json +++ b/packages/superdough/package.json @@ -1,6 +1,6 @@ { "name": "superdough", - "version": "1.2.4", + "version": "1.2.5", "description": "simple web audio synth and sampler intended for live coding. inspired by superdirt and webdirt.", "main": "index.mjs", "type": "module", diff --git a/packages/tonal/package.json b/packages/tonal/package.json index de02e4b1f..1461bdc8e 100644 --- a/packages/tonal/package.json +++ b/packages/tonal/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/tonal", - "version": "1.2.3", + "version": "1.2.4", "description": "Tonal functions for strudel", "main": "index.mjs", "publishConfig": { diff --git a/packages/transpiler/package.json b/packages/transpiler/package.json index f9ebdfde1..18722bdc2 100644 --- a/packages/transpiler/package.json +++ b/packages/transpiler/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/transpiler", - "version": "1.2.3", + "version": "1.2.4", "description": "Transpiler for strudel user code. Converts syntactically correct but semantically meaningless JS into evaluatable strudel code.", "main": "index.mjs", "type": "module", diff --git a/packages/web/package.json b/packages/web/package.json index 3f9cc50d1..df21f4055 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/web", - "version": "1.2.4", + "version": "1.2.5", "description": "Easy to setup, opiniated bundle of Strudel for the browser.", "module": "web.mjs", "publishConfig": { diff --git a/packages/webaudio/package.json b/packages/webaudio/package.json index 78988340a..cbe673a5a 100644 --- a/packages/webaudio/package.json +++ b/packages/webaudio/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/webaudio", - "version": "1.2.4", + "version": "1.2.5", "description": "Web Audio helpers for Strudel", "main": "index.mjs", "type": "module", diff --git a/packages/xen/package.json b/packages/xen/package.json index 1cb751157..0a6736d9c 100644 --- a/packages/xen/package.json +++ b/packages/xen/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/xen", - "version": "1.2.3", + "version": "1.2.4", "description": "Xenharmonic API for strudel", "main": "index.mjs", "type": "module", From 51b150b8298ba2839ef787d7bb58b17d03e995c1 Mon Sep 17 00:00:00 2001 From: Aria Date: Wed, 10 Sep 2025 21:27:56 -0500 Subject: [PATCH 122/335] Optimize folding for audio rate --- packages/superdough/helpers.mjs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index 28c14f79d..b56065856 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -311,17 +311,17 @@ export function applyFM(param, value, begin) { // Saturation curves const __squash = (x) => x / (1 + x); // [0, inf) to [0, 1) +const _mod = (n, m) => ((n % m) + m) % m; const _scurve = (x, k) => ((1 + k) * x) / (1 + k * Math.abs(x)); const _soft = (x, k) => Math.tanh(x * (1 + k)); const _hard = (x, k) => clamp((1 + k) * x, -1, 1); const _fold = (x, k) => { + // Closed form folding for audio rate let y = (1 + 0.5 * k) * x; - while (y > 1 || y < -1) { - y = y > 1 ? 2 - y : -2 - y; - } - return y; + const window = _mod(y + 1, 4); + return 1 - Math.abs(window - 2); }; const _sineFold = (x, k) => Math.sin((Math.PI / 2) * _fold(x, k)); From 9848740e180c920384ef6cba01d70ac481b66df3 Mon Sep 17 00:00:00 2001 From: Aria Date: Wed, 10 Sep 2025 21:39:02 -0500 Subject: [PATCH 123/335] Formatting and tests --- packages/core/controls.mjs | 6 +- packages/superdough/audioContext.mjs | 2 +- packages/superdough/helpers.mjs | 5 +- packages/superdough/util.mjs | 2 +- packages/superdough/worklets.mjs | 2 +- test/__snapshots__/examples.test.mjs.snap | 76 +++++++++++++++++++++++ 6 files changed, 85 insertions(+), 8 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 01679529c..47626fda9 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -1586,7 +1586,7 @@ export const { shape } = registerControl(['shape', 'shapevol']); * @example * note("d1!8").s("sine").penv(36).pdecay(.12).decay(.23).distort("8:.4") * @example - * s("bd*4").bank("tr909").distort("4:0.5:fold") + * s("bd:4*4").bank("tr808").distort("3:0.5:diode") * */ export const { distort, dist } = registerControl(['distort', 'distortvol', 'distorttype'], 'dist'); @@ -1614,8 +1614,8 @@ export const { distortvol } = registerControl('distortvol', 'distvol'); * @example * s("sine").note("F1*2").release(1) * .penv(24).pdecay(0.05) - * .distort(70) - * .distorttype("") + * .distort(rand.range(1, 8)) + * .distorttype("") */ export const { distorttype } = registerControl('distorttype', 'disttype'); diff --git a/packages/superdough/audioContext.mjs b/packages/superdough/audioContext.mjs index 9a3c71167..71e01d57d 100644 --- a/packages/superdough/audioContext.mjs +++ b/packages/superdough/audioContext.mjs @@ -15,4 +15,4 @@ export const getAudioContext = () => { export function getAudioContextCurrentTime() { return getAudioContext().currentTime; -} \ No newline at end of file +} diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index b56065856..9ee660ae2 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -1,6 +1,7 @@ import { getAudioContext } from './audioContext.mjs'; -import { clamp, ffloor, nanFallback } from './util.mjs'; +import { clamp, nanFallback } from './util.mjs'; import { getNoiseBuffer } from './noise.mjs'; +import { logger } from './logger.mjs'; export const noises = ['pink', 'white', 'brown', 'crackle']; @@ -365,7 +366,7 @@ const _chebyshev = (x, k) => { tnm2 = tnm1; tnm1 = tn; if (i % 2 === 0) { - y += Math.min(1.3 * kl / i, 2) * tn; + y += Math.min((1.3 * kl) / i, 2) * tn; } } // Soft clip diff --git a/packages/superdough/util.mjs b/packages/superdough/util.mjs index c3d511fd4..2477e3413 100644 --- a/packages/superdough/util.mjs +++ b/packages/superdough/util.mjs @@ -77,4 +77,4 @@ export function secondsToCycle(t, cps) { return t * cps; } -export const ffloor = (x) => x | 0; // fast floor for positive numbers \ No newline at end of file +export const ffloor = (x) => x | 0; // fast floor for positive numbers diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index ae03e9603..e593db17e 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -4,7 +4,7 @@ import OLAProcessor from './ola-processor'; import FFT from './fft.js'; -import { getDistortionAlgorithm } from './helpers.mjs'; +import { getDistortionAlgorithm } from './helpers.mjs'; const clamp = (num, min, max) => Math.min(Math.max(num, min), max); const _mod = (n, m) => ((n % m) + m) % m; diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index 41207620f..e70a5d494 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -2775,6 +2775,82 @@ exports[`runs examples > example "distort" example index 1 1`] = ` ] `; +exports[`runs examples > example "distort" example index 2 1`] = ` +[ + "[ 0/1 → 1/4 | s:bd n:4 bank:tr808 distort:3 distortvol:0.5 distorttype:diode ]", + "[ 1/4 → 1/2 | s:bd n:4 bank:tr808 distort:3 distortvol:0.5 distorttype:diode ]", + "[ 1/2 → 3/4 | s:bd n:4 bank:tr808 distort:3 distortvol:0.5 distorttype:diode ]", + "[ 3/4 → 1/1 | s:bd n:4 bank:tr808 distort:3 distortvol:0.5 distorttype:diode ]", + "[ 1/1 → 5/4 | s:bd n:4 bank:tr808 distort:3 distortvol:0.5 distorttype:diode ]", + "[ 5/4 → 3/2 | s:bd n:4 bank:tr808 distort:3 distortvol:0.5 distorttype:diode ]", + "[ 3/2 → 7/4 | s:bd n:4 bank:tr808 distort:3 distortvol:0.5 distorttype:diode ]", + "[ 7/4 → 2/1 | s:bd n:4 bank:tr808 distort:3 distortvol:0.5 distorttype:diode ]", + "[ 2/1 → 9/4 | s:bd n:4 bank:tr808 distort:3 distortvol:0.5 distorttype:diode ]", + "[ 9/4 → 5/2 | s:bd n:4 bank:tr808 distort:3 distortvol:0.5 distorttype:diode ]", + "[ 5/2 → 11/4 | s:bd n:4 bank:tr808 distort:3 distortvol:0.5 distorttype:diode ]", + "[ 11/4 → 3/1 | s:bd n:4 bank:tr808 distort:3 distortvol:0.5 distorttype:diode ]", + "[ 3/1 → 13/4 | s:bd n:4 bank:tr808 distort:3 distortvol:0.5 distorttype:diode ]", + "[ 13/4 → 7/2 | s:bd n:4 bank:tr808 distort:3 distortvol:0.5 distorttype:diode ]", + "[ 7/2 → 15/4 | s:bd n:4 bank:tr808 distort:3 distortvol:0.5 distorttype:diode ]", + "[ 15/4 → 4/1 | s:bd n:4 bank:tr808 distort:3 distortvol:0.5 distorttype:diode ]", +] +`; + +exports[`runs examples > example "distorttype" example index 0 1`] = ` +[ + "[ 0/1 → 1/4 | s:bd bank:tr909 distort:2 distorttype:0 ]", + "[ 1/4 → 1/2 | s:bd bank:tr909 distort:2 distorttype:0 ]", + "[ 1/2 → 3/4 | s:bd bank:tr909 distort:2 distorttype:0 ]", + "[ 3/4 → 1/1 | s:bd bank:tr909 distort:2 distorttype:0 ]", + "[ 1/1 → 5/4 | s:bd bank:tr909 distort:2 distorttype:1 ]", + "[ 5/4 → 3/2 | s:bd bank:tr909 distort:2 distorttype:1 ]", + "[ 3/2 → 7/4 | s:bd bank:tr909 distort:2 distorttype:1 ]", + "[ 7/4 → 2/1 | s:bd bank:tr909 distort:2 distorttype:1 ]", + "[ 2/1 → 9/4 | s:bd bank:tr909 distort:2 distorttype:2 ]", + "[ 9/4 → 5/2 | s:bd bank:tr909 distort:2 distorttype:2 ]", + "[ 5/2 → 11/4 | s:bd bank:tr909 distort:2 distorttype:2 ]", + "[ 11/4 → 3/1 | s:bd bank:tr909 distort:2 distorttype:2 ]", + "[ 3/1 → 13/4 | s:bd bank:tr909 distort:2 distorttype:0 ]", + "[ 13/4 → 7/2 | s:bd bank:tr909 distort:2 distorttype:0 ]", + "[ 7/2 → 15/4 | s:bd bank:tr909 distort:2 distorttype:0 ]", + "[ 15/4 → 4/1 | s:bd bank:tr909 distort:2 distorttype:0 ]", +] +`; + +exports[`runs examples > example "distorttype" example index 1 1`] = ` +[ + "[ (0/1 → 1/2) ⇝ 1/1 | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:1 distorttype:fold ]", + "[ 0/1 ⇜ (1/2 → 1/1) | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:1 distorttype:fold ]", + "[ (1/1 → 3/2) ⇝ 2/1 | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:4.6367951557040215 distorttype:chebyshev ]", + "[ 1/1 ⇜ (3/2 → 2/1) | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:4.6367951557040215 distorttype:chebyshev ]", + "[ (2/1 → 5/2) ⇝ 3/1 | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:7.716689839959145 distorttype:scurve ]", + "[ 2/1 ⇜ (5/2 → 3/1) | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:7.716689839959145 distorttype:scurve ]", + "[ (3/1 → 7/2) ⇝ 4/1 | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:2.5210237745195627 distorttype:diode ]", + "[ 3/1 ⇜ (7/2 → 4/1) | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:2.5210237745195627 distorttype:diode ]", +] +`; + +exports[`runs examples > example "distortvol" example index 0 1`] = ` +[ + "[ 0/1 → 1/4 | s:bd bank:tr909 distort:2 distortvol:0.8 ]", + "[ 1/4 → 1/2 | s:bd bank:tr909 distort:2 distortvol:0.8 ]", + "[ 1/2 → 3/4 | s:bd bank:tr909 distort:2 distortvol:0.8 ]", + "[ 3/4 → 1/1 | s:bd bank:tr909 distort:2 distortvol:0.8 ]", + "[ 1/1 → 5/4 | s:bd bank:tr909 distort:2 distortvol:0.8 ]", + "[ 5/4 → 3/2 | s:bd bank:tr909 distort:2 distortvol:0.8 ]", + "[ 3/2 → 7/4 | s:bd bank:tr909 distort:2 distortvol:0.8 ]", + "[ 7/4 → 2/1 | s:bd bank:tr909 distort:2 distortvol:0.8 ]", + "[ 2/1 → 9/4 | s:bd bank:tr909 distort:2 distortvol:0.8 ]", + "[ 9/4 → 5/2 | s:bd bank:tr909 distort:2 distortvol:0.8 ]", + "[ 5/2 → 11/4 | s:bd bank:tr909 distort:2 distortvol:0.8 ]", + "[ 11/4 → 3/1 | s:bd bank:tr909 distort:2 distortvol:0.8 ]", + "[ 3/1 → 13/4 | s:bd bank:tr909 distort:2 distortvol:0.8 ]", + "[ 13/4 → 7/2 | s:bd bank:tr909 distort:2 distortvol:0.8 ]", + "[ 7/2 → 15/4 | s:bd bank:tr909 distort:2 distortvol:0.8 ]", + "[ 15/4 → 4/1 | s:bd bank:tr909 distort:2 distortvol:0.8 ]", +] +`; + exports[`runs examples > example "djf" example index 0 1`] = ` [ "[ 0/1 → 1/4 | n:0 s:superzow octave:3 djf:0.5 ]", From 5e2e6411e5e67cb2458132f3e643ebe1d265c5cd Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 11 Sep 2025 08:26:20 +0200 Subject: [PATCH 124/335] Publish - @strudel/codemirror@1.2.5 - @strudel/repl@1.2.6 --- packages/codemirror/package.json | 2 +- packages/repl/package.json | 2 +- pnpm-lock.yaml | 18 ++---------------- 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/packages/codemirror/package.json b/packages/codemirror/package.json index be240a338..803b33f3d 100644 --- a/packages/codemirror/package.json +++ b/packages/codemirror/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/codemirror", - "version": "1.2.4", + "version": "1.2.5", "description": "Codemirror Extensions for Strudel", "main": "index.mjs", "publishConfig": { diff --git a/packages/repl/package.json b/packages/repl/package.json index 547ec979f..41a165c34 100644 --- a/packages/repl/package.json +++ b/packages/repl/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/repl", - "version": "1.2.5", + "version": "1.2.6", "description": "Strudel REPL as a Web Component", "module": "index.mjs", "publishConfig": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 810ffb9d5..f4a24f61c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -215,9 +215,6 @@ importers: '@strudel/transpiler': specifier: workspace:* version: link:../transpiler - codemirror: - specifier: ^6.0.2 - version: 6.0.2 nanostores: specifier: ^0.11.3 version: 0.11.3 @@ -3448,9 +3445,6 @@ packages: resolution: {integrity: sha512-FMabTRlc5t5zjdenF6mS0MBeFZm0XqHqeOkcskKFb/LYCcRQ5fVgLOHVc4Lq9CqABd9zhjwPjMBCJvMCziSVtA==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - codemirror@6.0.2: - resolution: {integrity: sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw==} - collapse-white-space@2.1.0: resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} @@ -5720,6 +5714,7 @@ packages: node-domexception@1.0.0: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} + deprecated: Use your platform's native DOMException instead node-fetch-native@1.6.6: resolution: {integrity: sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==} @@ -6809,6 +6804,7 @@ packages: source-map@0.8.0-beta.0: resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} engines: {node: '>= 8'} + deprecated: The work that was done in this beta branch won't be included in future versions sourcemap-codec@1.4.8: resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} @@ -11050,16 +11046,6 @@ snapshots: cmd-shim@6.0.3: {} - codemirror@6.0.2: - dependencies: - '@codemirror/autocomplete': 6.18.4 - '@codemirror/commands': 6.8.0 - '@codemirror/language': 6.10.8 - '@codemirror/lint': 6.8.4 - '@codemirror/search': 6.5.8 - '@codemirror/state': 6.5.1 - '@codemirror/view': 6.36.2 - collapse-white-space@2.1.0: {} color-convert@2.0.1: From 27339715b77c57d30a6bc5841ff7f5103a6c876b Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 11 Sep 2025 17:22:06 +0200 Subject: [PATCH 125/335] fix: exclude mondough dependencies --- packages/mondough/vite.config.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/mondough/vite.config.js b/packages/mondough/vite.config.js index c46972e96..06c8c4559 100644 --- a/packages/mondough/vite.config.js +++ b/packages/mondough/vite.config.js @@ -1,5 +1,5 @@ import { defineConfig } from 'vite'; -//import { dependencies } from './package.json'; +import { dependencies } from './package.json'; import { resolve } from 'path'; // https://vitejs.dev/config/ @@ -12,7 +12,7 @@ export default defineConfig({ fileName: (ext) => ({ es: 'mondough.mjs' })[ext], }, rollupOptions: { - // external: [...Object.keys(dependencies)], + external: [...Object.keys(dependencies)], }, target: 'esnext', }, From 702e558d1a76813e71e143bef25bec68a81ecc04 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 11 Sep 2025 17:30:38 +0200 Subject: [PATCH 126/335] Publish - @strudel/mondo@1.1.3 --- packages/mondough/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mondough/package.json b/packages/mondough/package.json index f26281490..7cec4fd02 100644 --- a/packages/mondough/package.json +++ b/packages/mondough/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/mondo", - "version": "1.1.2", + "version": "1.1.3", "description": "mondo notation for strudel", "main": "mondough.mjs", "type": "module", From c42d00f04866a19f31ded90ed9e582b09f79b813 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 11 Sep 2025 19:11:45 +0200 Subject: [PATCH 127/335] hotfix: export mondo getLocations --- packages/mondough/mondough.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mondough/mondough.mjs b/packages/mondough/mondough.mjs index 15feb5d86..e409d5a3b 100644 --- a/packages/mondough/mondough.mjs +++ b/packages/mondough/mondough.mjs @@ -108,7 +108,7 @@ export function mondo(code, offset = 0) { return pat.markcss('color: var(--caret,--foreground);text-decoration:underline'); } -let getLocations = (code, offset) => runner.parser.get_locations(code, offset); +export let getLocations = (code, offset) => runner.parser.get_locations(code, offset); export const mondi = (str, offset) => { const code = `[${str}]`; From 637d714ab27e5bf29499c2cce0a15b7cadb58f71 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 11 Sep 2025 19:14:00 +0200 Subject: [PATCH 128/335] Publish - @strudel/mondo@1.1.4 --- packages/mondough/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mondough/package.json b/packages/mondough/package.json index 7cec4fd02..c81d76cb6 100644 --- a/packages/mondough/package.json +++ b/packages/mondough/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/mondo", - "version": "1.1.3", + "version": "1.1.4", "description": "mondo notation for strudel", "main": "mondough.mjs", "type": "module", From 7ff7e8852bd41b1eb524da84fd73840dcd7cff1c Mon Sep 17 00:00:00 2001 From: drdozer Date: Thu, 11 Sep 2025 18:42:23 +0100 Subject: [PATCH 129/335] feat: implement context-aware autocomplete Adds context-sensitive autocompletion for: - Sound names in s("...") and sound("...") after the opening quote or after whitespace/bracket - Bank names in bank("...") with quote handling and live filtering - Scale types in .scale("...") after the colon, inserting colon-form for multi-word names - Pitch names (C, C#, Db, etc.) for scale keys on explicit completion (Ctrl+Space) before the colon - Blocks fallback completions in scale context before colon to avoid function list cross-talk --- packages/codemirror/autocomplete.mjs | 166 +++++++++++++++++++++++++-- 1 file changed, 155 insertions(+), 11 deletions(-) diff --git a/packages/codemirror/autocomplete.mjs b/packages/codemirror/autocomplete.mjs index 59ca8adf2..c1c7bb14e 100644 --- a/packages/codemirror/autocomplete.mjs +++ b/packages/codemirror/autocomplete.mjs @@ -1,6 +1,11 @@ + import jsdoc from '../../doc.json'; import { autocompletion } from '@codemirror/autocomplete'; import { h } from './html'; +import { Scale } from '@tonaljs/tonal'; +import { soundMap } from 'superdough'; + + const escapeHtml = (str) => { const div = document.createElement('div'); @@ -74,6 +79,31 @@ const isValidDoc = (doc) => { const hasExcludedTags = (doc) => ['superdirtOnly', 'noAutocomplete'].some((tag) => doc.tags?.find((t) => t.originalTitle === tag)); + + +export function bankCompletions() { + const soundDict = soundMap.get(); + const banks = new Set(); + for (const key of Object.keys(soundDict)) { + const [bank, suffix] = key.split('_'); + if (suffix && bank) banks.add(bank); + } + return Array.from(banks).sort().map((name) => ({ label: name, type: 'bank' })); +} + +// Placeholder: Replace with actual logic to get live sound names +const soundCompletions = [ + // Example: { label: 'clap', type: 'sound' }, ... +]; + +// Attempt to get all scale names from Tonal +let scaleCompletions = []; +try { + scaleCompletions = (Scale.names ? Scale.names() : []).map((name) => ({ label: name, type: 'scale' })); +} catch (e) { + console.warn('[autocomplete] Could not load scale names from Tonal:', e); +} + const jsdocCompletions = jsdoc.docs .filter((doc) => isValidDoc(doc) && !hasExcludedTags(doc)) // https://codemirror.net/docs/ref/#autocomplete.Completion @@ -85,18 +115,132 @@ const jsdocCompletions = jsdoc.docs })); export const strudelAutocomplete = (context) => { - const word = context.matchBefore(/\w*/); - if (word.from === word.to && !context.explicit) return null; + // --- Pitch names for scale key completion --- + // Ideally, these should be imported from packages/tonal/tonleiter.mjs + // but are duplicated here as they are not exported. + const pitchNames = [ + 'C', 'C#', 'Db', 'D', 'D#', 'Eb', 'E', 'Fb', 'F', 'F#', 'Gb', + 'G', 'G#', 'Ab', 'A', 'A#', 'Bb', 'B', 'Cb' + ]; + + // Block fallback completions inside .scale("..."), even before the colon + let scalePreColonContext = context.matchBefore(/\.scale\(\s*['"][^'"]*$/); + if (scalePreColonContext) { + // Only yield completions if a colon is present (handled below) + if (!scalePreColonContext.text.includes(':')) { + if (context.explicit) { + // Provide pitch completions on explicit request + // (Union of sharps and flats from tonleiter.mjs) + const text = scalePreColonContext.text; + const match = text.match(/([A-Ga-g][#b]*)?$/); + const fragment = match ? match[0] : ''; + const filtered = pitchNames.filter((p) => p.toLowerCase().startsWith(fragment.toLowerCase())); + const from = scalePreColonContext.to - fragment.length; + const options = filtered.map((p) => ({ label: p, type: 'pitch' })); + return { from, options }; + } else { + // Block fallback completions + return { from: scalePreColonContext.to, options: [] }; + } + } - return { - from: word.from, - options: jsdocCompletions, - /* options: [ - { label: 'match', type: 'keyword' }, - { label: 'hello', type: 'variable', info: '(World)' }, - { label: 'magic', type: 'text', apply: '⠁⭒*.✩.*⭒⠁', detail: 'macro' }, - ], */ - }; + // (second block removed, handled above) + if (!scalePreColonContext.text.includes(':')) { + return { from: scalePreColonContext.to, options: [] }; + } + } + + // 1. Check for sound context: s("..."), sound("...") + // Trigger after at least one letter is typed after whitespace or bracket inside the quotes + let soundContext = context.matchBefore(/(s|sound)\(\s*['"][^'"]*$/); + if (soundContext) { + const text = soundContext.text; + const quoteIdx = Math.max(text.lastIndexOf('"'), text.lastIndexOf("'")); + if (quoteIdx === -1) return null; + const inside = text.slice(quoteIdx + 1); + const fragMatch = inside.match(/(?:[\s\[\{\(<])([\w]*)$/); + const fragment = fragMatch ? fragMatch[1] : inside; + if (!fragment || fragment.length === 0) return null; + const soundNames = Object.keys(soundMap.get()).sort(); + const filteredSounds = soundNames.filter((name) => name.startsWith(fragment)); + let options = filteredSounds.map((name) => ({ label: name, type: 'sound' })); + const from = soundContext.to - fragment.length; + return { + from, + options, + }; + } + + let bankMatch = context.matchBefore(/bank\(\s*(['"])?([\w]*)$/); + if (bankMatch) { + let banks = bankCompletions(); + console.log('[autocomplete] Bank context detected:', bankMatch.text); + console.log('[autocomplete] soundMap keys:', Object.keys(soundMap.get())); + console.log('[autocomplete] bankCompletions:', banks); + // Extract quote and fragment using regex groups on match.text + const groups = bankMatch.text.match(/(['"])?([\w]*)$/); + const quote = groups ? groups[1] : undefined; + const fragment = groups ? groups[2] || '' : ''; + let from; + if (quote) { + from = bankMatch.from + bankMatch.text.indexOf(quote) + 1; + } else { + from = bankMatch.to - fragment.length; + } + const filteredBanks = banks.filter((b) => b.label.startsWith(fragment)); + let options; + if (!quote) { + options = filteredBanks.map((b) => ({ ...b, apply: '"' + b.label + '"' })); + } else { + const afterCursor = context.state.sliceDoc(bankMatch.to, bankMatch.to + 1); + options = filteredBanks.map((b) => { + if (afterCursor !== quote) { + return { ...b, apply: b.label + quote }; + } + return b; + }); + } + return { + from, + options, + }; + } + + // 3. Check for scale context: .scale("..."), only after colon + let scaleContext = context.matchBefore(/\.scale\(\s*['"][^'"]*:[^'"]*$/); + if (scaleContext) { + // Find the last colon in the text + const text = scaleContext.text; + const colonIdx = text.lastIndexOf(':'); + if (colonIdx === -1) return null; + // Get the fragment after the colon + const fragment = text.slice(colonIdx + 1); + // Filter scale completions by fragment + const filteredScales = scaleCompletions.filter((s) => s.label.startsWith(fragment)); + // Insert colon-form (replace spaces with colons) for completions + const options = filteredScales.map((s) => ({ + ...s, + apply: s.label.replace(/\s+/g, ':') + })); + const from = scaleContext.from + colonIdx + 1; + return { + from, + options, + }; + } + + // fallback: original logic + const word = context.matchBefore(/\w*/); + if (word && word.from === word.to && !context.explicit) return null; + + if (word) { + console.log('[autocomplete] Default context:', word.text); + return { + from: word.from, + options: jsdocCompletions, + }; + } + return null; }; export const isAutoCompletionEnabled = (enabled) => From 085e839bfe3f0e4f9404afecba943b70fe106c0f Mon Sep 17 00:00:00 2001 From: drdozer Date: Thu, 11 Sep 2025 18:59:26 +0100 Subject: [PATCH 130/335] refactor: modularize autocomplete context handlers using strategy array --- packages/codemirror/autocomplete.mjs | 68 ++++++++++++++++------------ 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/packages/codemirror/autocomplete.mjs b/packages/codemirror/autocomplete.mjs index c1c7bb14e..591552cc7 100644 --- a/packages/codemirror/autocomplete.mjs +++ b/packages/codemirror/autocomplete.mjs @@ -114,23 +114,18 @@ const jsdocCompletions = jsdoc.docs type: 'function', // https://codemirror.net/docs/ref/#autocomplete.Completion.type })); -export const strudelAutocomplete = (context) => { - // --- Pitch names for scale key completion --- - // Ideally, these should be imported from packages/tonal/tonleiter.mjs - // but are duplicated here as they are not exported. - const pitchNames = [ - 'C', 'C#', 'Db', 'D', 'D#', 'Eb', 'E', 'Fb', 'F', 'F#', 'Gb', - 'G', 'G#', 'Ab', 'A', 'A#', 'Bb', 'B', 'Cb' - ]; - - // Block fallback completions inside .scale("..."), even before the colon + +// --- Handler functions for each context --- +const pitchNames = [ + 'C', 'C#', 'Db', 'D', 'D#', 'Eb', 'E', 'Fb', 'F', 'F#', 'Gb', + 'G', 'G#', 'Ab', 'A', 'A#', 'Bb', 'B', 'Cb' +]; + +function scalePreColonHandler(context) { let scalePreColonContext = context.matchBefore(/\.scale\(\s*['"][^'"]*$/); if (scalePreColonContext) { - // Only yield completions if a colon is present (handled below) if (!scalePreColonContext.text.includes(':')) { if (context.explicit) { - // Provide pitch completions on explicit request - // (Union of sharps and flats from tonleiter.mjs) const text = scalePreColonContext.text; const match = text.match(/([A-Ga-g][#b]*)?$/); const fragment = match ? match[0] : ''; @@ -139,19 +134,17 @@ export const strudelAutocomplete = (context) => { const options = filtered.map((p) => ({ label: p, type: 'pitch' })); return { from, options }; } else { - // Block fallback completions return { from: scalePreColonContext.to, options: [] }; } } - - // (second block removed, handled above) if (!scalePreColonContext.text.includes(':')) { return { from: scalePreColonContext.to, options: [] }; } } - - // 1. Check for sound context: s("..."), sound("...") - // Trigger after at least one letter is typed after whitespace or bracket inside the quotes + return null; +} + +function soundHandler(context) { let soundContext = context.matchBefore(/(s|sound)\(\s*['"][^'"]*$/); if (soundContext) { const text = soundContext.text; @@ -170,13 +163,13 @@ export const strudelAutocomplete = (context) => { options, }; } + return null; +} +function bankHandler(context) { let bankMatch = context.matchBefore(/bank\(\s*(['"])?([\w]*)$/); if (bankMatch) { let banks = bankCompletions(); - console.log('[autocomplete] Bank context detected:', bankMatch.text); - console.log('[autocomplete] soundMap keys:', Object.keys(soundMap.get())); - console.log('[autocomplete] bankCompletions:', banks); // Extract quote and fragment using regex groups on match.text const groups = bankMatch.text.match(/(['"])?([\w]*)$/); const quote = groups ? groups[1] : undefined; @@ -205,19 +198,17 @@ export const strudelAutocomplete = (context) => { options, }; } + return null; +} - // 3. Check for scale context: .scale("..."), only after colon +function scaleAfterColonHandler(context) { let scaleContext = context.matchBefore(/\.scale\(\s*['"][^'"]*:[^'"]*$/); if (scaleContext) { - // Find the last colon in the text const text = scaleContext.text; const colonIdx = text.lastIndexOf(':'); if (colonIdx === -1) return null; - // Get the fragment after the colon const fragment = text.slice(colonIdx + 1); - // Filter scale completions by fragment const filteredScales = scaleCompletions.filter((s) => s.label.startsWith(fragment)); - // Insert colon-form (replace spaces with colons) for completions const options = filteredScales.map((s) => ({ ...s, apply: s.label.replace(/\s+/g, ':') @@ -228,19 +219,36 @@ export const strudelAutocomplete = (context) => { options, }; } + return null; +} - // fallback: original logic +function fallbackHandler(context) { const word = context.matchBefore(/\w*/); if (word && word.from === word.to && !context.explicit) return null; - if (word) { - console.log('[autocomplete] Default context:', word.text); return { from: word.from, options: jsdocCompletions, }; } return null; +} + +const handlers = [ + scalePreColonHandler, + soundHandler, + bankHandler, + scaleAfterColonHandler, + // this handler *must* be last + fallbackHandler +]; + +export const strudelAutocomplete = (context) => { + for (const handler of handlers) { + const result = handler(context); + if (result) return result; + } + return null; }; export const isAutoCompletionEnabled = (enabled) => From 80fe5b81401741175411692f00604cb16dfc4cb6 Mon Sep 17 00:00:00 2001 From: drdozer Date: Thu, 11 Sep 2025 18:59:50 +0100 Subject: [PATCH 131/335] refactor: modularize autocomplete context handlers using strategy array From 9200a67a600471309162dabeeb8bce915f915c55 Mon Sep 17 00:00:00 2001 From: drdozer Date: Thu, 11 Sep 2025 19:00:05 +0100 Subject: [PATCH 132/335] feat: add E# and B# to pitchNames for complete enharmonic coverage --- packages/codemirror/autocomplete.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/codemirror/autocomplete.mjs b/packages/codemirror/autocomplete.mjs index 591552cc7..5d6c7233d 100644 --- a/packages/codemirror/autocomplete.mjs +++ b/packages/codemirror/autocomplete.mjs @@ -117,8 +117,8 @@ const jsdocCompletions = jsdoc.docs // --- Handler functions for each context --- const pitchNames = [ - 'C', 'C#', 'Db', 'D', 'D#', 'Eb', 'E', 'Fb', 'F', 'F#', 'Gb', - 'G', 'G#', 'Ab', 'A', 'A#', 'Bb', 'B', 'Cb' + 'C', 'C#', 'Db', 'D', 'D#', 'Eb', 'E', 'E#', 'Fb', 'F', 'F#', 'Gb', + 'G', 'G#', 'Ab', 'A', 'A#', 'Bb', 'B', 'B#', 'Cb' ]; function scalePreColonHandler(context) { From 2a00fcdf5d70a2b0789b11376cf71b9c60cdc3cf Mon Sep 17 00:00:00 2001 From: drdozer Date: Thu, 11 Sep 2025 19:01:22 +0100 Subject: [PATCH 133/335] Updated the codemirror packages to be able to access additional imports. --- packages/codemirror/package.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/codemirror/package.json b/packages/codemirror/package.json index 803b33f3d..bb1059f11 100644 --- a/packages/codemirror/package.json +++ b/packages/codemirror/package.json @@ -47,6 +47,8 @@ "@strudel/core": "workspace:*", "@strudel/draw": "workspace:*", "@strudel/transpiler": "workspace:*", + "@tonaljs/tonal": "^4.10.0", + "superdough": "workspace:*", "nanostores": "^0.11.3" }, "devDependencies": { From 41d6f1b5da98e3929ae71d2e2adf5ea00768664b Mon Sep 17 00:00:00 2001 From: drdozer Date: Thu, 11 Sep 2025 21:37:35 +0100 Subject: [PATCH 134/335] feat: sound autocomplete matches anywhere in name using includes() --- packages/codemirror/autocomplete.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/codemirror/autocomplete.mjs b/packages/codemirror/autocomplete.mjs index 5d6c7233d..110a9165a 100644 --- a/packages/codemirror/autocomplete.mjs +++ b/packages/codemirror/autocomplete.mjs @@ -155,7 +155,7 @@ function soundHandler(context) { const fragment = fragMatch ? fragMatch[1] : inside; if (!fragment || fragment.length === 0) return null; const soundNames = Object.keys(soundMap.get()).sort(); - const filteredSounds = soundNames.filter((name) => name.startsWith(fragment)); + const filteredSounds = soundNames.filter((name) => name.includes(fragment)); let options = filteredSounds.map((name) => ({ label: name, type: 'sound' })); const from = soundContext.to - fragment.length; return { From c0bf86d11e3d795558b5dd01821f700a5e962070 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 11 Sep 2025 23:19:22 +0200 Subject: [PATCH 135/335] Revert "Merge pull request 'supradough poc' (#1362) from supradough into main" This reverts commit 6f06683d707ed5d04464af94d1a978ef21df84bd, reversing changes made to 637d714ab27e5bf29499c2cce0a15b7cadb58f71. --- eslint.config.mjs | 1 - packages/core/controls.mjs | 30 +- packages/superdough/sampler.mjs | 91 +- packages/superdough/superdough.mjs | 10 +- packages/supradough/.gitignore | 1 - packages/supradough/README.md | 3 - packages/supradough/dough-export.mjs | 123 --- packages/supradough/dough-worklet.mjs | 39 - packages/supradough/dough.mjs | 976 ---------------------- packages/supradough/index.mjs | 4 - packages/supradough/package.json | 37 - packages/webaudio/index.mjs | 1 - packages/webaudio/package.json | 3 +- packages/webaudio/supradough.mjs | 130 --- packages/webaudio/webaudio.mjs | 7 +- pnpm-lock.yaml | 20 - test/__snapshots__/examples.test.mjs.snap | 80 +- 17 files changed, 63 insertions(+), 1493 deletions(-) delete mode 100644 packages/supradough/.gitignore delete mode 100644 packages/supradough/README.md delete mode 100644 packages/supradough/dough-export.mjs delete mode 100644 packages/supradough/dough-worklet.mjs delete mode 100644 packages/supradough/dough.mjs delete mode 100644 packages/supradough/index.mjs delete mode 100644 packages/supradough/package.json delete mode 100644 packages/webaudio/supradough.mjs diff --git a/eslint.config.mjs b/eslint.config.mjs index c9ff40ca1..e30b8e8a6 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -42,7 +42,6 @@ export default [ '**/hydra.mjs', '**/jsdoc-synonyms.js', 'packages/hs2js/src/hs2js.mjs', - 'packages/supradough/dough-export.mjs', '**/samples', ], }, diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 473ea82d1..58a30652c 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -309,17 +309,6 @@ export const { fmvelocity } = registerControl('fmvelocity'); */ export const { bank } = registerControl('bank'); -/** - * mix control for the chorus effect - * - * @name chorus - * @param {string | Pattern} chorus mix amount between 0 and 1 - * @example - * note("d d a# a").s("sawtooth").chorus(.5) - * - */ -export const { chorus } = registerControl('chorus'); - // analyser node send amount 0 - 1 (used by scope) export const { analyze } = registerControl('analyze'); // fftSize of analyser @@ -1108,27 +1097,14 @@ export const { delay } = registerControl(['delay', 'delaytime', 'delayfeedback'] * */ export const { delayfeedback, delayfb, dfb } = registerControl('delayfeedback', 'delayfb', 'dfb'); - -/** - * Sets the level of the signal that is fed back into the delay. - * Caution: Values >= 1 will result in a signal that gets louder and louder! Don't do it - * - * @name delayfeedback - * @param {number | Pattern} feedback between 0 and 1 - * @synonyms delayfb, dfb - * @example - * s("bd").delay(.25).delayfeedback("<.25 .5 .75 1>") - * - */ -export const { delayspeed } = registerControl('delayspeed'); /** * Sets the time of the delay effect. * - * @name delayspeed - * @param {number | Pattern} delayspeed controls the pitch of the delay feedback + * @name delaytime + * @param {number | Pattern} seconds between 0 and Infinity * @synonyms delayt, dt * @example - * note("d d a# a".fast(2)).s("sawtooth").delay(.8).delaytime(1/2).delayspeed("<2 .5 -1 -2>") + * s("bd bd").delay(.25).delaytime("<.125 .25 .5 1>") * */ export const { delaytime, delayt, dt } = registerControl('delaytime', 'delayt', 'dt'); diff --git a/packages/superdough/sampler.mjs b/packages/superdough/sampler.mjs index 9188c17c3..18d1b7797 100644 --- a/packages/superdough/sampler.mjs +++ b/packages/superdough/sampler.mjs @@ -196,52 +196,6 @@ function getSamplesPrefixHandler(url) { return; } -export async function fetchSampleMap(url) { - // check if custom prefix handler - const handler = getSamplesPrefixHandler(url); - if (handler) { - return handler(url); - } - url = resolveSpecialPaths(url); - if (url.startsWith('github:')) { - url = githubPath(url, 'strudel.json'); - } - if (url.startsWith('local:')) { - url = `http://localhost:5432`; - } - if (url.startsWith('shabda:')) { - let [_, path] = url.split('shabda:'); - url = `https://shabda.ndre.gr/${path}.json?strudel=1`; - } - if (url.startsWith('shabda/speech')) { - let [_, path] = url.split('shabda/speech'); - path = path.startsWith('/') ? path.substring(1) : path; - let [params, words] = path.split(':'); - let gender = 'f'; - let language = 'en-GB'; - if (params) { - [language, gender] = params.split('/'); - } - url = `https://shabda.ndre.gr/speech/${words}.json?gender=${gender}&language=${language}&strudel=1'`; - } - if (typeof fetch !== 'function') { - // not a browser - return; - } - const base = url.split('/').slice(0, -1).join('/'); - if (typeof fetch === 'undefined') { - // skip fetch when in node / testing - return; - } - const json = await fetch(url) - .then((res) => res.json()) - .catch((error) => { - console.error(error); - throw new Error(`error loading "${url}"`); - }); - return [json, json._base || base]; -} - /** * Loads a collection of samples to use with `s` * @example @@ -263,8 +217,49 @@ export async function fetchSampleMap(url) { export const samples = async (sampleMap, baseUrl = sampleMap._base || '', options = {}) => { if (typeof sampleMap === 'string') { - const [json, base] = await fetchSampleMap(sampleMap); - return samples(json, baseUrl || base, options); + // check if custom prefix handler + const handler = getSamplesPrefixHandler(sampleMap); + if (handler) { + return handler(sampleMap); + } + sampleMap = resolveSpecialPaths(sampleMap); + if (sampleMap.startsWith('github:')) { + sampleMap = githubPath(sampleMap, 'strudel.json'); + } + if (sampleMap.startsWith('local:')) { + sampleMap = `http://localhost:5432`; + } + if (sampleMap.startsWith('shabda:')) { + let [_, path] = sampleMap.split('shabda:'); + sampleMap = `https://shabda.ndre.gr/${path}.json?strudel=1`; + } + if (sampleMap.startsWith('shabda/speech')) { + let [_, path] = sampleMap.split('shabda/speech'); + path = path.startsWith('/') ? path.substring(1) : path; + let [params, words] = path.split(':'); + let gender = 'f'; + let language = 'en-GB'; + if (params) { + [language, gender] = params.split('/'); + } + sampleMap = `https://shabda.ndre.gr/speech/${words}.json?gender=${gender}&language=${language}&strudel=1'`; + } + if (typeof fetch !== 'function') { + // not a browser + return; + } + const base = sampleMap.split('/').slice(0, -1).join('/'); + if (typeof fetch === 'undefined') { + // skip fetch when in node / testing + return; + } + return fetch(sampleMap) + .then((res) => res.json()) + .then((json) => samples(json, baseUrl || json._base || base, options)) + .catch((error) => { + console.error(error); + throw new Error(`error loading "${sampleMap}"`); + }); } const { prebake, tag } = options; processSampleMap( diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 0c084e3e9..792e5a28d 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -196,7 +196,7 @@ export const resetLoadedSounds = () => soundMap.set({}); let audioContext; export const setDefaultAudioContext = () => { - audioContext = new AudioContext({ latencyHint: 'playback' }); + audioContext = new AudioContext(); return audioContext; }; @@ -212,17 +212,11 @@ export function getAudioContextCurrentTime() { return getAudioContext().currentTime; } -let externalWorklets = []; -export function registerWorklet(url) { - externalWorklets.push(url); -} - let workletsLoading; function loadWorklets() { if (!workletsLoading) { const audioCtx = getAudioContext(); - const allWorkletURLs = externalWorklets.concat([workletsUrl]); - workletsLoading = Promise.all(allWorkletURLs.map((workletURL) => audioCtx.audioWorklet.addModule(workletURL))); + workletsLoading = audioCtx.audioWorklet.addModule(workletsUrl); } return workletsLoading; diff --git a/packages/supradough/.gitignore b/packages/supradough/.gitignore deleted file mode 100644 index d21cbdf3e..000000000 --- a/packages/supradough/.gitignore +++ /dev/null @@ -1 +0,0 @@ -pattern.wav diff --git a/packages/supradough/README.md b/packages/supradough/README.md deleted file mode 100644 index a8cfa84b3..000000000 --- a/packages/supradough/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# supradough - -platform agnostic synth and sampler intended for live coding. a reimplementation of superdough. \ No newline at end of file diff --git a/packages/supradough/dough-export.mjs b/packages/supradough/dough-export.mjs deleted file mode 100644 index bd4b530b3..000000000 --- a/packages/supradough/dough-export.mjs +++ /dev/null @@ -1,123 +0,0 @@ -// this is a poc of how a pattern can be rendered as a wav file using node -// run via: node dough-export.mjs -import fs from 'node:fs'; -import WavEncoder from 'wav-encoder'; -import { evalScope } from '@strudel/core'; -import { miniAllStrings } from '@strudel/mini'; -import { Dough } from './dough.mjs'; - -await evalScope( - import('@strudel/core'), - import('@strudel/mini'), - import('@strudel/tonal'), - // import('@strudel/tonal'), -); - -miniAllStrings(); // allows using single quotes for mini notation / skip transpilation - -let sampleRate = 48000, - cps = 0.4; - -/* await doughsamples('github:eddyflux/crate'); -await doughsamples('github:eddyflux/wax'); */ - -let pat = note('c,eb,g,') - .s('sine') - .press() - .add(note(24)) - .fmi(3) - .fmh(5.01) - .dec(0.4) - .delay('.6:<.12 .22>:.8') - .jux(press) - .rarely(add(note('12'))) - .lpf(400) - .lpq(0.2) - .lpd(0.4) - .lpenv(3) - .fmdecay(0.4) - .fmenv(1) - .postgain(0.6) - .stack(s('*8').dec(0.07).rarely(ply('2')).delay(0.5).hpf(sine.range(200, 2000).slow(4)).hpq(0.2)) - .stack( - s('[- white@3]*2') - .dec(0.4) - .hpf('<2000!3 <4000 8000>>*4') - .hpq(0.6) - .ply('<1 2>*4') - .postgain(0.5) - .delay(0.5) - .jux(rev) - .lpf(5000), - ) - .stack( - note('*2') - .s('square') - .lpf(sine.range(100, 300).slow(4)) - .lpe(1) - .segment(8) - .lpd(0.3) - .lpq(0.2) - .dec(0.2) - .speed('<1 2>') - .ply('<1 2>') - .postgain(1), - ) - .stack( - chord('') - .voicing() - .s('') - .clip(1) - .rel(0.4) - .vib('4:.2') - .gain(0.7) - .hpf(1200) - .fm(0.5) - .att(1) - .lpa(0.5) - .lpf(200) - .lpenv(4) - .chorus(0.8), - ) - .slow(1 / cps); - -let cycles = 30; -let seconds = cycles + 1; // 1s release tail -const haps = pat.queryArc(0, cycles); - -const dough = new Dough(sampleRate); - -console.log('spawn voices...'); -haps.forEach((hap) => { - hap.value._begin = Number(hap.whole.begin); - hap.value._duration = hap.duration /* / cps */; - dough.scheduleSpawn(hap.value); -}); -console.log(`render ${seconds}s long buffer, each dot is 1 second:`); -const buffers = [new Float32Array(seconds * sampleRate), new Float32Array(seconds * sampleRate)]; -let t = performance.now(); -while (dough.t <= buffers[0].length) { - dough.update(); - buffers[0][dough.t] = dough.out[0]; - buffers[1][dough.t] = dough.out[1]; - if (dough.t % sampleRate === 0) { - process.stdout.write('.'); - } -} -const took = (performance.now() - t) / 1000; -const load = (took / seconds) * 100; -const speed = (seconds / took).toFixed(2); -console.log(''); -console.log(`done! -rendered ${seconds}s in ${took.toFixed(2)}s -speed: ${speed}x -load: ${load.toFixed(2)}%`); - -const patternAudio = { - sampleRate, - channelData: buffers, -}; - -WavEncoder.encode(patternAudio).then((buffer) => { - fs.writeFileSync('pattern.wav', new Float32Array(buffer)); -}); diff --git a/packages/supradough/dough-worklet.mjs b/packages/supradough/dough-worklet.mjs deleted file mode 100644 index 18c316b2d..000000000 --- a/packages/supradough/dough-worklet.mjs +++ /dev/null @@ -1,39 +0,0 @@ -import { Dough } from './dough.mjs'; - -const clamp = (num, min, max) => Math.min(Math.max(num, min), max); - -class DoughProcessor extends AudioWorkletProcessor { - constructor() { - super(); - this.dough = new Dough(sampleRate, currentTime); - this.port.onmessage = (event) => { - if (event.data.spawn) { - this.dough.scheduleSpawn(event.data.spawn); - } else if (event.data.sample) { - this.dough.loadSample(event.data.sample, event.data.channels, event.data.sampleRate); - } else if (event.data.samples) { - event.data.samples.forEach(([name, channels, sampleRate]) => { - this.dough.loadSample(name, channels, sampleRate); - }); - } else { - console.log('unrecognized event type', event.data); - } - }; - } - process(inputs, outputs, params) { - if (this.disconnected) { - return false; - } - const output = outputs[0]; - for (let i = 0; i < output[0].length; i++) { - this.dough.update(); - for (let c = 0; c < output.length; c++) { - //prevent speaker blowout via clipping if threshold exceeds - output[c][i] = clamp(this.dough.out[c], -1, 1); - } - } - return true; // keep the audio processing going - } -} - -registerProcessor('dough-processor', DoughProcessor); diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs deleted file mode 100644 index 711922b63..000000000 --- a/packages/supradough/dough.mjs +++ /dev/null @@ -1,976 +0,0 @@ -// this is dough, the superdough without dependencies -const SAMPLE_RATE = typeof sampleRate !== 'undefined' ? sampleRate : 48000; -const PI_DIV_SR = Math.PI / SAMPLE_RATE; -const ISR = 1 / SAMPLE_RATE; - -let gainCurveFunc = (val) => Math.pow(val, 2); - -function applyGainCurve(val) { - return gainCurveFunc(val); -} - -/** - * Equal Power Crossfade function. - * Smoothly transitions between signals A and B, maintaining consistent perceived loudness. - * - * @param {number} a - Signal A (can be a single value or an array value in buffer processing). - * @param {number} b - Signal B (can be a single value or an array value in buffer processing). - * @param {number} m - Crossfade parameter (0.0 = all A, 1.0 = all B, 0.5 = equal mix). - * @returns {number} Crossfaded output value. - */ -function crossfade(a, b, m) { - const aGain = Math.sin((1 - m) * 0.5 * Math.PI); - const bGain = Math.sin(m * 0.5 * Math.PI); - return a * aGain + b * bGain; -} - -// function setGainCurve(newGainCurveFunc) { -// gainCurveFunc = newGainCurveFunc; -// } -// https://garten.salat.dev/audio-DSP/oscillators.html -export class SineOsc { - phase = 0; - update(freq) { - const value = Math.sin(this.phase * 2 * Math.PI); - this.phase = (this.phase + freq / SAMPLE_RATE) % 1; - return value; - } -} - -export class ZawOsc { - phase = 0; - update(freq) { - this.phase += ISR * freq; - return (this.phase % 1) * 2 - 1; - } -} - -function polyBlep(t, dt) { - // 0 <= t < 1 - if (t < dt) { - t /= dt; - // 2 * (t - t^2/2 - 0.5) - return t + t - t * t - 1; - } - // -1 < t < 0 - if (t > 1 - dt) { - t = (t - 1) / dt; - // 2 * (t^2/2 + t + 0.5) - return t * t + t + t + 1; - } - // 0 otherwise - return 0; -} - -export class SawOsc { - constructor(props = {}) { - this.phase = props.phase ?? 0; - } - update(freq) { - const dt = freq / SAMPLE_RATE; - let p = polyBlep(this.phase, dt); - let s = 2 * this.phase - 1 - p; - this.phase += dt; - if (this.phase > 1) { - this.phase -= 1; - } - return s; - } -} - -function getUnisonDetune(unison, detune, voiceIndex) { - if (unison < 2) { - return 0; - } - const lerp = (a, b, n) => { - return n * (b - a) + a; - }; - return lerp(-detune * 0.5, detune * 0.5, voiceIndex / (unison - 1)); -} -function applySemitoneDetuneToFrequency(frequency, detune) { - return frequency * Math.pow(2, detune / 12); -} -export class SupersawOsc { - constructor(props = {}) { - //TODO: figure out a good way to pass in these params - this.voices = props.voices ?? 5; - this.freqspread = props.freqspread ?? 0.2; - this.panspread = props.panspread ?? 0.4; - this.phase = new Float32Array(this.voices).map(() => Math.random()); - } - update(freq) { - const gain1 = Math.sqrt(1 - this.panspread); - const gain2 = Math.sqrt(this.panspread); - let sl = 0; - let sr = 0; - for (let n = 0; n < this.voices; n++) { - const freqAdjusted = applySemitoneDetuneToFrequency(freq, getUnisonDetune(this.voices, this.freqspread, n)); - const dt = freqAdjusted / SAMPLE_RATE; - const isOdd = (n & 1) == 1; - let gainL = gain1; - let gainR = gain2; - // invert right and left gain - if (isOdd) { - gainL = gain2; - gainR = gain1; - } - let p = polyBlep(this.phase[n], dt); - let s = 2 * this.phase[n] - 1 - p; - sl = sl + s * gainL; - sr = sr + s * gainL; - - this.phase[n] += dt; - if (this.phase[n] > 1) { - this.phase[n] -= 1; - } - } - - return sl + sr; - //TODO: make stereo - // return [sl, sr]; - } -} - -export class TriOsc { - phase = 0; - update(freq) { - this.phase += ISR * freq; - let phase = this.phase % 1; - let value = phase < 0.5 ? 2 * phase : 1 - 2 * (phase - 0.5); - return value * 2 - 1; - } -} - -export class TwoPoleFilter { - s0 = 0; - s1 = 0; - update(s, cutoff, resonance = 0) { - // Out of bound values can produce NaNs - resonance = Math.max(resonance, 0); - - cutoff = Math.min(cutoff, 20000); - const c = 2 * Math.sin(cutoff * PI_DIV_SR); - - const r = Math.pow(0.5, (resonance + 0.125) / 0.125); - const mrc = 1 - r * c; - - this.s0 = mrc * this.s0 - c * this.s1 + c * s; // bpf - this.s1 = mrc * this.s1 + c * this.s0; // lpf - return this.s1; // return lpf by default - } -} - -class PulseOsc { - constructor(phase = 0) { - this.phase = phase; - } - saw(offset, dt) { - let phase = (this.phase + offset) % 1; - let p = polyBlep(phase, dt); - return 2 * phase - 1 - p; - } - update(freq, pw = 0.5) { - const dt = freq / SAMPLE_RATE; - let pulse = this.saw(0, dt) - this.saw(pw, dt); - this.phase = (this.phase + dt) % 1; - return pulse + pw * 2 - 1; - } -} - -// non bandlimited (has aliasing) -export class PulzeOsc { - phase = 0; - update(freq, duty = 0.5) { - this.phase += ISR * freq; - let cyclePos = this.phase % 1; - return cyclePos < duty ? 1 : -1; - } -} - -export class Dust { - update = (density) => (Math.random() < density * ISR ? Math.random() : 0); -} - -export class WhiteNoise { - update() { - return Math.random() * 2 - 1; - } -} - -export class BrownNoise { - constructor() { - this.out = 0; - } - update() { - let white = Math.random() * 2 - 1; - this.out = (this.out + 0.02 * white) / 1.02; - return this.out; - } -} - -export class PinkNoise { - constructor() { - this.b0 = 0; - this.b1 = 0; - this.b2 = 0; - this.b3 = 0; - this.b4 = 0; - this.b5 = 0; - this.b6 = 0; - } - - update() { - const white = Math.random() * 2 - 1; - - this.b0 = 0.99886 * this.b0 + white * 0.0555179; - this.b1 = 0.99332 * this.b1 + white * 0.0750759; - this.b2 = 0.969 * this.b2 + white * 0.153852; - this.b3 = 0.8665 * this.b3 + white * 0.3104856; - this.b4 = 0.55 * this.b4 + white * 0.5329522; - this.b5 = -0.7616 * this.b5 - white * 0.016898; - - const pink = this.b0 + this.b1 + this.b2 + this.b3 + this.b4 + this.b5 + this.b6 + white * 0.5362; - this.b6 = white * 0.115926; - - return pink * 0.11; - } -} - -export class Impulse { - phase = 1; - update(freq) { - this.phase += ISR * freq; - let v = this.phase >= 1 ? 1 : 0; - this.phase = this.phase % 1; - return v; - } -} - -export class ClockDiv { - inSgn = true; - outSgn = true; - clockCnt = 0; - update(clock, factor) { - let curSgn = clock > 0; - if (this.inSgn != curSgn) { - this.clockCnt++; - if (this.clockCnt >= factor) { - this.clockCnt = 0; - this.outSgn = !this.outSgn; - } - } - - this.inSgn = curSgn; - return this.outSgn ? 1 : -1; - } -} - -export class Hold { - value = 0; - trigSgn = false; - update(input, trig) { - if (!this.trigSgn && trig > 0) this.value = input; - this.trigSgn = trig > 0; - return this.value; - } -} - -function lerp(x, y0, y1, exponent = 1) { - if (x <= 0) return y0; - if (x >= 1) return y1; - - let curvedX; - - if (exponent === 0) { - curvedX = x; // linear - } else if (exponent > 0) { - curvedX = Math.pow(x, exponent); // ease-in - } else { - curvedX = 1 - Math.pow(1 - x, -exponent); // ease-out - } - - return y0 + (y1 - y0) * curvedX; -} - -export class ADSR { - constructor(props = {}) { - this.state = 'off'; - this.startTime = 0; - this.startVal = 0; - this.decayCurve = props.decayCurve ?? 1; - } - - update(curTime, gate, attack, decay, susVal, release) { - switch (this.state) { - case 'off': { - if (gate > 0) { - this.state = 'attack'; - this.startTime = curTime; - this.startVal = 0; - } - return 0; - } - case 'attack': { - let time = curTime - this.startTime; - if (time > attack) { - this.state = 'decay'; - this.startTime = curTime; - return 1; - } - return lerp(time / attack, this.startVal, 1, 1); - } - case 'decay': { - let time = curTime - this.startTime; - let curVal = lerp(time / decay, 1, susVal, -this.decayCurve); - if (gate <= 0) { - this.state = 'release'; - this.startTime = curTime; - this.startVal = curVal; - return curVal; - } - if (time > decay) { - this.state = 'sustain'; - this.startTime = curTime; - return susVal; - } - return curVal; - } - case 'sustain': { - if (gate <= 0) { - this.state = 'release'; - this.startTime = curTime; - this.startVal = susVal; - } - return susVal; - } - case 'release': { - let time = curTime - this.startTime; - - if (time > release) { - this.state = 'off'; - return 0; - } - let curVal = lerp(time / release, this.startVal, 0, -this.decayCurve); - if (gate > 0) { - this.state = 'attack'; - this.startTime = curTime; - this.startVal = curVal; - } - return curVal; - } - } - throw 'invalid envelope state'; - } -} - -/* - impulse(1).ad(.1).mul(sine(200)) -.add(x=>x.delay(.1).mul(.8)) -.out()*/ -const MAX_DELAY_TIME = 10; -export class PitchDelay { - lpf = new TwoPoleFilter(); - constructor(_props = {}) { - this.buffer = new Float32Array(MAX_DELAY_TIME * SAMPLE_RATE); - this.writeIdx = 0; - this.readIdx = 0; - this.numSamples = 0; - } - write(s, delayTime) { - // Calculate how far in the past to read - this.numSamples = Math.min(Math.floor(SAMPLE_RATE * delayTime), this.buffer.length - 1); - this.writeIdx = (this.writeIdx + 1) % this.numSamples; - this.buffer[this.writeIdx] = s; - this.readIdx = this.writeIdx - this.numSamples + 1; - - // If past the start of the buffer, wrap around (Q: is this possible?) - if (this.readIdx < 0) this.readIdx += this.numSamples; - } - update(input, delayTime, speed = 1) { - this.write(input, delayTime); - let index = this.readIdx; - if (speed < 0) { - index = this.numSamples - Math.floor(Math.abs(this.readIdx * speed) % this.numSamples); - } else { - index = Math.floor(this.readIdx * speed) % this.numSamples; - } - const s = this.lpf.update(this.buffer[index], 0.9, 0); - - return s; - } -} - -export class Delay { - writeIdx = 0; - readIdx = 0; - buffer = new Float32Array(MAX_DELAY_TIME * SAMPLE_RATE); //.fill(0) - write(s, delayTime) { - this.writeIdx = (this.writeIdx + 1) % this.buffer.length; - this.buffer[this.writeIdx] = s; - // Calculate how far in the past to read - let numSamples = Math.min(Math.floor(SAMPLE_RATE * delayTime), this.buffer.length - 1); - this.readIdx = this.writeIdx - numSamples; - // If past the start of the buffer, wrap around - if (this.readIdx < 0) this.readIdx += this.buffer.length; - } - update(input, delayTime) { - this.write(input, delayTime); - return this.buffer[this.readIdx]; - } -} -//TODO: Figure out why clicking at the start off the buffer -export class Chorus { - delay = new Delay(); - modulator = new TriOsc(); - update(input, mix, delayTime, modulationFreq, modulationDepth) { - const m = this.modulator.update(modulationFreq) * modulationDepth; - const c = this.delay.update(input, delayTime * (1 + m)); - return crossfade(input, c, mix); - } -} - -export class Fold { - update(input = 0, rate = 0) { - if (rate < 0) rate = 0; - rate = rate + 1; - input = input * rate; - return 4 * (Math.abs(0.25 * input + 0.25 - Math.round(0.25 * input + 0.25)) - 0.25); - } -} - -export class Lag { - lagUnit = 4410; - s = 0; - update(input, rate) { - // Remap so the useful range is around [0, 1] - rate = rate * this.lagUnit; - if (rate < 1) rate = 1; - this.s += (1 / rate) * (input - this.s); - return this.s; - } -} - -export class Slew { - last = 0; - update(input, up, dn) { - const upStep = up * ISR; - const downStep = dn * ISR; - let delta = input - this.last; - if (delta > upStep) { - delta = upStep; - } else if (delta < -downStep) { - delta = -downStep; - } - this.last += delta; - return this.last; - } -} - -// overdrive style distortion (adapted from noisecraft) currently unused -export function applyDistortion(x, amount) { - amount = Math.min(Math.max(amount, 0), 1); - amount -= 0.01; - var k = (2 * amount) / (1 - amount); - var y = ((1 + k) * x) / (1 + k * Math.abs(x)); - return y; -} - -export class Sequence { - clockSgn = true; - step = 0; - first = true; - update(clock, ...ins) { - if (!this.clockSgn && clock > 0) { - this.step = (this.step + 1) % ins.length; - this.clockSgn = clock > 0; - return 0; // set first sample to zero to retrigger gates on step change... - } - this.clockSgn = clock > 0; - return ins[this.step]; - } -} - -// sample rate bit crusher -export class Coarse { - hold = 0; - t = 0; - update(input, coarse) { - if (this.t++ % coarse === 0) { - this.t = 0; - this.hold = input; - } - return this.hold; - } -} - -// amplitude bit crusher -export class Crush { - update(input, crush) { - crush = Math.max(1, crush); - const x = Math.pow(2, crush - 1); - return Math.round(input * x) / x; - } -} - -// this is the distort from superdough -export class Distort { - update(input, distort = 0, postgain = 1) { - postgain = Math.max(0.001, Math.min(1, postgain)); - const shape = Math.expm1(distort); - return (((1 + shape) * input) / (1 + shape * Math.abs(input))) * postgain; - } -} -// distortion could be expressed as a function, because it's stateless - -export class BufferPlayer { - static samples = new Map(); // string -> { channels, sampleRate } - buffer; // Float32Array - sampleRate; - pos = 0; - sampleFreq = note2freq(); - constructor(buffer, sampleRate, normalize) { - this.buffer = buffer; - this.sampleRate = sampleRate; - this.duration = this.buffer.length / this.sampleRate; - this.speed = SAMPLE_RATE / this.sampleRate; - if (normalize) { - // this will make the buffer last 1s if freq = sampleFreq - // it's useful to loop samples (e.g. fit function) - this.speed *= this.duration; - } - } - update(freq) { - if (this.pos >= this.buffer.length) { - return 0; - } - const speed = (freq / this.sampleFreq) * this.speed; - let s = this.buffer[Math.floor(this.pos)]; - this.pos = this.pos + speed; - return s; - } -} - -export function _rangex(sig, min, max) { - let logmin = Math.log(min); - let range = Math.log(max) - logmin; - const unipolar = (sig + 1) / 2; - return Math.exp(unipolar * range + logmin); -} - -// duplicate -export const getADSR = (params, curve = 'linear', defaultValues) => { - const envmin = curve === 'exponential' ? 0.001 : 0.001; - const releaseMin = 0.01; - const envmax = 1; - const [a, d, s, r] = params; - if (a == null && d == null && s == null && r == null) { - return defaultValues ?? [envmin, envmin, envmax, releaseMin]; - } - const sustain = s != null ? s : (a != null && d == null) || (a == null && d == null) ? envmax : envmin; - return [Math.max(a ?? 0, envmin), Math.max(d ?? 0, envmin), Math.min(sustain, envmax), Math.max(r ?? 0, releaseMin)]; -}; - -let shapes = { - sine: SineOsc, - saw: SawOsc, - zaw: ZawOsc, - sawtooth: SawOsc, - zawtooth: ZawOsc, - supersaw: SupersawOsc, - tri: TriOsc, - triangle: TriOsc, - pulse: PulseOsc, - square: PulseOsc, - pulze: PulzeOsc, - dust: Dust, - crackle: Dust, - impulse: Impulse, - white: WhiteNoise, - brown: BrownNoise, - pink: PinkNoise, -}; - -const defaultDefaultValues = { - chorus: 0, - note: 48, - s: 'triangle', - bank: '', - gain: 1, - postgain: 1, - velocity: 1, - density: '.03', - ftype: '12db', - fanchor: 0, - //resonance: 1, // superdough resonance is scaled differently - resonance: 0, - //hresonance: 1, // superdough resonance is scaled differently - hresonance: 0, - // bandq: 1, // superdough resonance is scaled differently - bandq: 0, - channels: [1, 2], - phaserdepth: 0.75, - shapevol: 1, - distortvol: 1, - delay: 0, - byteBeatExpression: '0', - delayfeedback: 0.5, - delayspeed: 1, - delaytime: 0.25, - orbit: 1, - i: 1, - fft: 8, - z: 'triangle', - pan: 0.5, - fmh: 1, - fmenv: 0, // differs from superdough - speed: 1, - pw: 0.5, -}; - -let getDefaultValue = (key) => defaultDefaultValues[key]; - -const chromas = { c: 0, d: 2, e: 4, f: 5, g: 7, a: 9, b: 11 }; -const accs = { '#': 1, b: -1, s: 1, f: -1 }; -const note2midi = (note, defaultOctave = 3) => { - let [pc, acc = '', oct = ''] = - String(note) - .match(/^([a-gA-G])([#bsf]*)([0-9]*)$/) - ?.slice(1) || []; - if (!pc) { - throw new Error('not a note: "' + note + '"'); - } - const chroma = chromas[pc.toLowerCase()]; - const offset = acc?.split('').reduce((o, char) => o + accs[char], 0) || 0; - oct = Number(oct || defaultOctave); - return (oct + 1) * 12 + chroma + offset; -}; -const midi2freq = (midi) => Math.pow(2, (midi - 69) / 12) * 440; -const note2freq = (note) => { - note = note || getDefaultValue('note'); - if (typeof note === 'string') { - note = note2midi(note, 3); // e.g. c3 => 48 - } - return midi2freq(note); -}; - -export class DoughVoice { - out = [0, 0]; - constructor(value) { - value.freq ??= note2freq(value.note); - let $ = this; - Object.assign($, value); - $.s = $.s ?? getDefaultValue('s'); - $.gain = applyGainCurve($.gain ?? getDefaultValue('gain')); - $.velocity = applyGainCurve($.velocity ?? getDefaultValue('velocity')); - $.postgain = applyGainCurve($.postgain ?? getDefaultValue('postgain')); - $.density = $.density ?? getDefaultValue('density'); - $.fanchor = $.fanchor ?? getDefaultValue('fanchor'); - $.drive = $.drive ?? 0.69; - $.phaserdepth = $.phaserdepth ?? getDefaultValue('phaserdepth'); - $.shapevol = applyGainCurve($.shapevol ?? getDefaultValue('shapevol')); - $.distortvol = applyGainCurve($.distortvol ?? getDefaultValue('distortvol')); - $.i = $.i ?? getDefaultValue('i'); - $.chorus = $.chorus ?? getDefaultValue('chorus'); - $.fft = $.fft ?? getDefaultValue('fft'); - $.pan = $.pan ?? getDefaultValue('pan'); - $.orbit = $.orbit ?? getDefaultValue('orbit'); - $.fmenv = $.fmenv ?? getDefaultValue('fmenv'); - $.resonance = $.resonance ?? getDefaultValue('resonance'); - $.hresonance = $.hresonance ?? getDefaultValue('hresonance'); - $.bandq = $.bandq ?? getDefaultValue('bandq'); - $.speed = $.speed ?? getDefaultValue('speed'); - $.pw = $.pw ?? getDefaultValue('pw'); - - [$.attack, $.decay, $.sustain, $.release] = getADSR([$.attack, $.decay, $.sustain, $.release]); - - $._holdEnd = $._begin + $._duration; // needed for gate - $._end = $._holdEnd + $.release + 0.01; // needed for despawn - - if ($.fmi && ($.s === 'saw' || $.s === 'sawtooth')) { - $.s = 'zaw'; // polyblepped saw when fm is applied - } - - if (shapes[$.s]) { - const SourceClass = shapes[$.s]; - $._sound = new SourceClass(); - $._channels = 1; - } else if (BufferPlayer.samples.has($.s)) { - const sample = BufferPlayer.samples.get($.s); - $._buffers = []; - $._channels = sample.channels.length; - for (let i = 0; i < $._channels; i++) { - $._buffers.push(new BufferPlayer(sample.channels[i], sample.sampleRate, $.unit === 'c')); // tbd unit === 'c' - } - } else { - console.warn('sound not loaded', $.s); - } - - if ($.penv) { - $._penv = new ADSR({ decayCurve: 4 }); - [$.pattack, $.pdecay, $.psustain, $.prelease] = getADSR([$.pattack, $.pdecay, $.psustain, $.prelease]); - } - - if ($.vib) { - $._vib = new SineOsc(); - $.vibmod = $.vibmod ?? getDefaultValue('vibmod'); - } - - if ($.fmi) { - $._fm = new SineOsc(); - $.fmh = $.fmh ?? getDefaultValue('fmh'); - if ($.fmenv) { - $._fmenv = new ADSR({ decayCurve: 2 }); - [$.fmattack, $.fmdecay, $.fmsustain, $.fmrelease] = getADSR([$.fmattack, $.fmdecay, $.fmsustain, $.fmrelease]); - } - } - - // gain envelope - $._adsr = new ADSR({ decayCurve: 2 }); - // delay - $.delay = applyGainCurve($.delay ?? getDefaultValue('delay')); - $.delayfeedback = $.delayfeedback ?? getDefaultValue('delayfeedback'); - $.delayspeed = $.delayspeed ?? getDefaultValue('delayspeed'); - $.delaytime = $.delaytime ?? getDefaultValue('delaytime'); - - // filter setup - if ($.lpenv) { - $._lpenv = new ADSR({ decayCurve: 4 }); - [$.lpattack, $.lpdecay, $.lpsustain, $.lprelease] = getADSR([$.lpattack, $.lpdecay, $.lpsustain, $.lprelease]); - } - if ($.hpenv) { - $._hpenv = new ADSR({ decayCurve: 4 }); - [$.hpattack, $.hpdecay, $.hpsustain, $.hprelease] = getADSR([$.hpattack, $.hpdecay, $.hpsustain, $.hprelease]); - } - if ($.bpenv) { - $._bpenv = new ADSR({ decayCurve: 4 }); - [$.bpattack, $.bpdecay, $.bpsustain, $.bprelease] = getADSR([$.bpattack, $.bpdecay, $.bpsustain, $.bprelease]); - } - - // channelwise effects setup - $._chorus = $.chorus ? [] : null; - $._lpf = $.cutoff ? [] : null; - $._hpf = $.hcutoff ? [] : null; - $._bpf = $.bandf ? [] : null; - $._coarse = $.coarse ? [] : null; - $._crush = $.crush ? [] : null; - $._distort = $.distort ? [] : null; - for (let i = 0; i < this._channels; i++) { - $._lpf?.push(new TwoPoleFilter()); - $._hpf?.push(new TwoPoleFilter()); - $._bpf?.push(new TwoPoleFilter()); - $._chorus?.push(new Chorus()); - $._coarse?.push(new Coarse()); - $._crush?.push(new Crush()); - $._distort?.push(new Distort()); - } - } - update(t) { - if (!this._sound && !this._buffers) { - return 0; - } - let gate = Number(t >= this._begin && t <= this._holdEnd); - - let freq = this.freq * this.speed; - - // frequency modulation - if (this._fm) { - let fmi = this.fmi; - if (this._fmenv) { - const env = this._fmenv.update(t, gate, this.fmattack, this.fmdecay, this.fmsustain, this.fmrelease); - fmi = this.fmenv * env * fmi; - } - const modfreq = freq * this.fmh; - const modgain = modfreq * fmi; - freq = freq + this._fm.update(modfreq) * modgain; - } - - // vibrato - if (this._vib) { - freq = freq * 2 ** ((this._vib.update(this.vib) * this.vibmod) / 12); - } - - // pitch envelope - if (this._penv) { - const env = this._penv.update(t, gate, this.pattack, this.pdecay, this.psustain, this.prelease); - freq = freq + env * this.penv; - } - - // filters - let lpf = this.cutoff; - if (this._lpf) { - if (this._lpenv) { - const env = this._lpenv.update(t, gate, this.lpattack, this.lpdecay, this.lpsustain, this.lprelease); - lpf = this.lpenv * env * lpf + lpf; - } - } - let hpf = this.hcutoff; - if (this._hpf) { - if (this._hpenv) { - const env = this._hpenv.update(t, gate, this.hpattack, this.hpdecay, this.hpsustain, this.hprelease); - hpf = 2 ** this.hpenv * env * hpf + hpf; - } - } - let bpf = this.bandf; - if (this._bpf) { - if (this._bpenv) { - const env = this._bpenv.update(t, gate, this.bpattack, this.bpdecay, this.bpsustain, this.bprelease); - bpf = 2 ** this.bpenv * env * bpf + bpf; - } - } - // gain envelope - const env = this._adsr.update(t, gate, this.attack, this.decay, this.sustain, this.release); - - // channelwise dsp - for (let i = 0; i < this._channels; i++) { - // sound source - if (this._sound && this.s === 'pulse') { - this.out[i] = this._sound.update(freq, this.pw); - } else if (this._sound) { - this.out[i] = this._sound.update(freq); - } else if (this._buffers) { - this.out[i] = this._buffers[i].update(freq); - } - this.out[i] = this.out[i] * this.gain * this.velocity; - if (this._chorus) { - const c = this._chorus[i].update(this.out[i], this.chorus, 0.03 + 0.05 * i, 1, 0.11); - this.out[i] = c + this.out[i]; - } - - if (this._lpf) { - this._lpf[i].update(this.out[i], lpf, this.resonance); - this.out[i] = this._lpf[i].s1; - } - if (this._hpf) { - this._hpf[i].update(this.out[i], hpf, this.hresonance); - this.out[i] = this.out[i] - this._hpf[i].s1; - } - if (this._bpf) { - this._bpf[i].update(this.out[i], bpf, this.bandq); - this.out[i] = this._bpf[i].s0; - } - if (this._coarse) { - this.out[i] = this._coarse[i].update(this.out[i], this.coarse); - } - if (this._crush) { - this.out[i] = this._crush[i].update(this.out[i], this.crush); - } - if (this._distort) { - this.out[i] = this._distort[i].update(this.out[i], this.distort, this.distortvol); - } - this.out[i] = this.out[i] * env; - this.out[i] = this.out[i] * this.postgain; - if (!this._buffers) { - this.out[i] = this.out[i] * 0.2; // turn down waveform - } - } - if (this._channels === 1) { - this.out[1] = this.out[0]; - } - if (this.pan !== 0.5) { - const panpos = (this.pan * Math.PI) / 2; - this.out[0] = this.out[0] * Math.cos(panpos); - this.out[1] = this.out[1] * Math.sin(panpos); - } - } -} - -// this class is the interface to the "outer world" -// it handles spawning and despawning of DoughVoice's -export class Dough { - voices = []; // DoughVoice[] - vid = 0; - q = []; - out = [0, 0]; - delaysend = [0, 0]; - delaytime = getDefaultValue('delaytime'); - delayfeedback = getDefaultValue('delayfeedback'); - delayspeed = getDefaultValue('delayspeed'); - t = 0; - // sampleRate: number, currentTime: number (seconds) - constructor(sampleRate = 48000, currentTime = 0) { - this.sampleRate = sampleRate; - this.t = Math.floor(currentTime * sampleRate); // samples - // console.log('init dough', this.sampleRate, this.t); - this._delayL = new PitchDelay(); - this._delayR = new PitchDelay(); - } - loadSample(name, channels, sampleRate) { - BufferPlayer.samples.set(name, { channels, sampleRate }); - } - scheduleSpawn(value) { - if (value._begin === undefined) { - throw new Error('[dough]: scheduleSpawn expected _begin to be set'); - } - if (value._duration === undefined) { - throw new Error('[dough]: scheduleSpawn expected _duration to be set'); - } - value.sampleRate = this.sampleRate; - // convert seconds to samples - const time = Math.floor(value._begin * this.sampleRate); // set from supradough.mjs - this.schedule({ time, type: 'spawn', arg: value }); - } - spawn(value) { - value.id = this.vid++; - const voice = new DoughVoice(value); - this.voices.push(voice); - // console.log('spawn', voice.id, 'voices:', this.voices.length); - // schedule removal - const endTime = Math.ceil(voice._end * this.sampleRate); - this.schedule({ time: endTime /* + 48000 */, type: 'despawn', arg: voice.id }); - } - despawn(vid) { - this.voices = this.voices.filter((v) => v.id !== vid); - // console.log('despawn', vid, 'voices:', this.voices.length); - } - // schedules a function call with a single argument - // msg = {time:number,type:string, arg: any} - // the Dough method "type" will be called with "arg" at "time" - schedule(msg) { - if (!this.q.length) { - // if empty, just push - this.q.push(msg); - return; - } - // not empty - // find index where msg.time fits in - let i = 0; - while (i < this.q.length && this.q[i].time < msg.time) { - i++; - } - // this ensures q stays sorted by time, so we only need to check q[0] - this.q.splice(i, 0, msg); - } - // maybe update should be called once per block instead for perf reasons? - update() { - // go over q - while (this.q.length > 0 && this.q[0].time <= this.t) { - // console.log('schedule', this.q[0]); - // trigger due messages. q is sorted, so we only need to check q[0] - this[this.q[0].type](this.q[0].arg); // type is expected to be a Dough method - this.q.shift(); - } - // add active voices - this.out[0] = 0; - this.out[1] = 0; - for (let v = 0; v < this.voices.length; v++) { - this.voices[v].update(this.t / this.sampleRate); - this.out[0] += this.voices[v].out[0]; - this.out[1] += this.voices[v].out[1]; - if (this.voices[v].delay) { - this.delaysend[0] += this.voices[v].out[0] * this.voices[v].delay; - this.delaysend[1] += this.voices[v].out[1] * this.voices[v].delay; - this.delaytime = this.voices[v].delaytime; // we trust that these are initialized in the voice - this.delayspeed = this.voices[v].delayspeed; // we trust that these are initialized in the voice - this.delayfeedback = this.voices[v].delayfeedback; - } - } - // todo: how to change delaytime / delayfeedback from a voice? - const delayL = this._delayL.update(this.delaysend[0], this.delaytime, this.delayspeed); - const delayR = this._delayR.update(this.delaysend[1], this.delaytime, this.delayspeed); - this.delaysend[0] = delayL * this.delayfeedback; - this.delaysend[1] = delayR * this.delayfeedback; - this.out[0] += delayL; - this.out[1] += delayR; - this.t++; - } -} diff --git a/packages/supradough/index.mjs b/packages/supradough/index.mjs deleted file mode 100644 index 54a835495..000000000 --- a/packages/supradough/index.mjs +++ /dev/null @@ -1,4 +0,0 @@ -import _workletUrl from './dough-worklet.mjs?url'; // todo: change ?url to ?audioworklet before build (?audioworklet doesn't hot reload) - -export * from './dough.mjs'; -export const workletUrl = _workletUrl; diff --git a/packages/supradough/package.json b/packages/supradough/package.json deleted file mode 100644 index 7e465c0a9..000000000 --- a/packages/supradough/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "supradough", - "version": "1.2.3", - "description": "platform agnostic synth and sampler intended for live coding. a reimplementation of superdough.", - "main": "index.mjs", - "type": "module", - "publishConfig": { - "main": "dist/index.mjs" - }, - "scripts": { - "build": "vite build", - "prepublishOnly": "npm run build" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/tidalcycles/strudel.git" - }, - "keywords": [ - "tidalcycles", - "strudel", - "pattern", - "livecoding", - "algorave" - ], - "author": "Felix Roos ", - "license": "AGPL-3.0-or-later", - "bugs": { - "url": "https://github.com/tidalcycles/strudel/issues" - }, - "homepage": "https://github.com/tidalcycles/strudel#readme", - "devDependencies": { - "vite": "^6.0.11", - "vite-plugin-bundle-audioworklet": "workspace:*", - "wav-encoder": "^1.3.0" - }, - "dependencies": {} -} diff --git a/packages/webaudio/index.mjs b/packages/webaudio/index.mjs index 4933b7a01..362e61c44 100644 --- a/packages/webaudio/index.mjs +++ b/packages/webaudio/index.mjs @@ -7,5 +7,4 @@ This program is free software: you can redistribute it and/or modify it under th export * from './webaudio.mjs'; export * from './scope.mjs'; export * from './spectrum.mjs'; -export * from './supradough.mjs'; export * from 'superdough'; diff --git a/packages/webaudio/package.json b/packages/webaudio/package.json index 49da00f23..cbe673a5a 100644 --- a/packages/webaudio/package.json +++ b/packages/webaudio/package.json @@ -35,8 +35,7 @@ "dependencies": { "@strudel/core": "workspace:*", "@strudel/draw": "workspace:*", - "superdough": "workspace:*", - "supradough": "workspace:*" + "superdough": "workspace:*" }, "devDependencies": { "vite": "^6.0.11" diff --git a/packages/webaudio/supradough.mjs b/packages/webaudio/supradough.mjs deleted file mode 100644 index f97251a07..000000000 --- a/packages/webaudio/supradough.mjs +++ /dev/null @@ -1,130 +0,0 @@ -import { Pattern } from '@strudel/core'; -import { connectToDestination, getAudioContext, getWorklet } from 'superdough'; - -let doughWorklet; - -function initDoughWorklet() { - const ac = getAudioContext(); - doughWorklet = getWorklet( - ac, - 'dough-processor', - {}, - { - outputChannelCount: [2], - }, - ); - connectToDestination(doughWorklet); // channels? -} - -const soundMap = new Map(); -const loadedSounds = new Map(); - -Pattern.prototype.supradough = function () { - return this.onTrigger((hap, __, cps, begin) => { - hap.value._begin = begin; - hap.value._duration = hap.duration / cps; - !doughWorklet && initDoughWorklet(); - const s = (hap.value.bank ? hap.value.bank + '_' : '') + hap.value.s; - const n = hap.value.n ?? 0; - const soundKey = `${s}:${n}`; - if (soundMap.has(s)) { - hap.value.s = soundKey; // dough.mjs is unaware of bank and n (only maps keys to buffers) - } - if (soundMap.has(s) && !loadedSounds.has(soundKey)) { - const urls = soundMap.get(s); - const url = urls[n % urls.length]; - console.log(`load ${soundKey} from ${url}`); - const loadSample = fetchSample(url); - loadedSounds.set(soundKey, loadSample); - loadSample.then(({ channels, sampleRate }) => - doughWorklet.port.postMessage({ - sample: soundKey, - channels, - sampleRate, - }), - ); - } - - doughWorklet.port.postMessage({ spawn: hap.value }); - }, 1); -}; - -function githubPath(base, subpath = '') { - if (!base.startsWith('github:')) { - throw new Error('expected "github:" at the start of pseudoUrl'); - } - let [_, path] = base.split('github:'); - path = path.endsWith('/') ? path.slice(0, -1) : path; - if (path.split('/').length === 2) { - // assume main as default branch if none set - path += '/main'; - } - return `https://raw.githubusercontent.com/${path}/${subpath}`; -} -export async function fetchSampleMap(url) { - if (url.startsWith('github:')) { - url = githubPath(url, 'strudel.json'); - } - if (url.startsWith('local:')) { - url = `http://localhost:5432`; - } - if (url.startsWith('shabda:')) { - let [_, path] = url.split('shabda:'); - url = `https://shabda.ndre.gr/${path}.json?strudel=1`; - } - if (url.startsWith('shabda/speech')) { - let [_, path] = url.split('shabda/speech'); - path = path.startsWith('/') ? path.substring(1) : path; - let [params, words] = path.split(':'); - let gender = 'f'; - let language = 'en-GB'; - if (params) { - [language, gender] = params.split('/'); - } - url = `https://shabda.ndre.gr/speech/${words}.json?gender=${gender}&language=${language}&strudel=1'`; - } - if (typeof fetch !== 'function') { - // not a browser - return; - } - const base = url.split('/').slice(0, -1).join('/'); - if (typeof fetch === 'undefined') { - // skip fetch when in node / testing - return; - } - const json = await fetch(url) - .then((res) => res.json()) - .catch((error) => { - console.error(error); - throw new Error(`error loading "${url}"`); - }); - return [json, json._base || base]; -} - -// for some reason, only piano and flute work.. is it because mp3?? - -async function fetchSample(url) { - const buffer = await fetch(url) - .then((res) => res.arrayBuffer()) - .then((buf) => getAudioContext().decodeAudioData(buf)); - let channels = []; - for (let i = 0; i < buffer.numberOfChannels; i++) { - channels.push(buffer.getChannelData(i)); - } - return { channels, sampleRate: buffer.sampleRate }; -} - -export async function doughsamples(sampleMap, baseUrl) { - if (typeof sampleMap === 'string') { - const [json, base] = await fetchSampleMap(sampleMap); - // console.log('json', json, 'base', base); - return doughsamples(json, base); - } - Object.entries(sampleMap).map(async ([key, urls]) => { - if (key !== '_base') { - urls = urls.map((url) => baseUrl + url); - // console.log('set', key, urls); - soundMap.set(key, urls); - } - }); -} diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 383e87f87..429d2a26b 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -5,12 +5,7 @@ This program is free software: you can redistribute it and/or modify it under th */ import * as strudel from '@strudel/core'; -import { superdough, getAudioContext, setLogger, doughTrigger, registerWorklet } from 'superdough'; -import './supradough.mjs'; -import { workletUrl } from 'supradough'; - -registerWorklet(workletUrl); - +import { superdough, getAudioContext, setLogger, doughTrigger } from 'superdough'; const { Pattern, logger, repl } = strudel; setLogger(logger); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c225057f3..f4a24f61c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -517,18 +517,6 @@ importers: specifier: workspace:* version: link:../vite-plugin-bundle-audioworklet - packages/supradough: - devDependencies: - vite: - specifier: ^6.0.11 - version: 6.0.11(@types/node@22.10.10)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.37.0)(yaml@2.7.0) - vite-plugin-bundle-audioworklet: - specifier: workspace:* - version: link:../vite-plugin-bundle-audioworklet - wav-encoder: - specifier: ^1.3.0 - version: 1.3.0 - packages/tidal: dependencies: '@strudel/core': @@ -637,9 +625,6 @@ importers: superdough: specifier: workspace:* version: link:../superdough - supradough: - specifier: workspace:* - version: link:../supradough devDependencies: vite: specifier: ^6.0.11 @@ -7552,9 +7537,6 @@ packages: walk-up-path@3.0.1: resolution: {integrity: sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==} - wav-encoder@1.3.0: - resolution: {integrity: sha512-FXJdEu2qDOI+wbVYZpu21CS1vPEg5NaxNskBr4SaULpOJMrLE6xkH8dECa7PiS+ZoeyvP7GllWUAxPN3AvFSEw==} - wav@1.0.2: resolution: {integrity: sha512-viHtz3cDd/Tcr/HbNqzQCofKdF6kWUymH9LGDdskfWFoIy/HJ+RTihgjEcHfnsy1PO4e9B+y4HwgTwMrByquhg==} @@ -15976,8 +15958,6 @@ snapshots: walk-up-path@3.0.1: {} - wav-encoder@1.3.0: {} - wav@1.0.2: dependencies: buffer-alloc: 1.2.0 diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index ecbc33eac..41207620f 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -1847,27 +1847,6 @@ exports[`runs examples > example "chop" example index 0 1`] = ` ] `; -exports[`runs examples > example "chorus" example index 0 1`] = ` -[ - "[ 0/1 → 1/4 | note:d s:sawtooth chorus:0.5 ]", - "[ 1/4 → 1/2 | note:d s:sawtooth chorus:0.5 ]", - "[ 1/2 → 3/4 | note:a# s:sawtooth chorus:0.5 ]", - "[ 3/4 → 1/1 | note:a s:sawtooth chorus:0.5 ]", - "[ 1/1 → 5/4 | note:d s:sawtooth chorus:0.5 ]", - "[ 5/4 → 3/2 | note:d s:sawtooth chorus:0.5 ]", - "[ 3/2 → 7/4 | note:a# s:sawtooth chorus:0.5 ]", - "[ 7/4 → 2/1 | note:a s:sawtooth chorus:0.5 ]", - "[ 2/1 → 9/4 | note:d s:sawtooth chorus:0.5 ]", - "[ 9/4 → 5/2 | note:d s:sawtooth chorus:0.5 ]", - "[ 5/2 → 11/4 | note:a# s:sawtooth chorus:0.5 ]", - "[ 11/4 → 3/1 | note:a s:sawtooth chorus:0.5 ]", - "[ 3/1 → 13/4 | note:d s:sawtooth chorus:0.5 ]", - "[ 13/4 → 7/2 | note:d s:sawtooth chorus:0.5 ]", - "[ 7/2 → 15/4 | note:a# s:sawtooth chorus:0.5 ]", - "[ 15/4 → 4/1 | note:a s:sawtooth chorus:0.5 ]", -] -`; - exports[`runs examples > example "chunk" example index 0 1`] = ` [ "[ 0/1 → 1/4 | note:A4 ]", @@ -2606,52 +2585,6 @@ exports[`runs examples > example "delayfeedback" example index 0 1`] = ` ] `; -exports[`runs examples > example "delayfeedback" example index 0 2`] = ` -[ - "[ 0/1 → 1/1 | s:bd delay:0.25 delayfeedback:0.25 ]", - "[ 1/1 → 2/1 | s:bd delay:0.25 delayfeedback:0.5 ]", - "[ 2/1 → 3/1 | s:bd delay:0.25 delayfeedback:0.75 ]", - "[ 3/1 → 4/1 | s:bd delay:0.25 delayfeedback:1 ]", -] -`; - -exports[`runs examples > example "delayspeed" example index 0 1`] = ` -[ - "[ 0/1 → 1/8 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:2 ]", - "[ 1/8 → 1/4 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:2 ]", - "[ 1/4 → 3/8 | note:a# s:sawtooth delay:0.8 delaytime:0.5 delayspeed:2 ]", - "[ 3/8 → 1/2 | note:a s:sawtooth delay:0.8 delaytime:0.5 delayspeed:2 ]", - "[ 1/2 → 5/8 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:2 ]", - "[ 5/8 → 3/4 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:2 ]", - "[ 3/4 → 7/8 | note:a# s:sawtooth delay:0.8 delaytime:0.5 delayspeed:2 ]", - "[ 7/8 → 1/1 | note:a s:sawtooth delay:0.8 delaytime:0.5 delayspeed:2 ]", - "[ 1/1 → 9/8 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:0.5 ]", - "[ 9/8 → 5/4 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:0.5 ]", - "[ 5/4 → 11/8 | note:a# s:sawtooth delay:0.8 delaytime:0.5 delayspeed:0.5 ]", - "[ 11/8 → 3/2 | note:a s:sawtooth delay:0.8 delaytime:0.5 delayspeed:0.5 ]", - "[ 3/2 → 13/8 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:0.5 ]", - "[ 13/8 → 7/4 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:0.5 ]", - "[ 7/4 → 15/8 | note:a# s:sawtooth delay:0.8 delaytime:0.5 delayspeed:0.5 ]", - "[ 15/8 → 2/1 | note:a s:sawtooth delay:0.8 delaytime:0.5 delayspeed:0.5 ]", - "[ 2/1 → 17/8 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-1 ]", - "[ 17/8 → 9/4 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-1 ]", - "[ 9/4 → 19/8 | note:a# s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-1 ]", - "[ 19/8 → 5/2 | note:a s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-1 ]", - "[ 5/2 → 21/8 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-1 ]", - "[ 21/8 → 11/4 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-1 ]", - "[ 11/4 → 23/8 | note:a# s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-1 ]", - "[ 23/8 → 3/1 | note:a s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-1 ]", - "[ 3/1 → 25/8 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-2 ]", - "[ 25/8 → 13/4 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-2 ]", - "[ 13/4 → 27/8 | note:a# s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-2 ]", - "[ 27/8 → 7/2 | note:a s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-2 ]", - "[ 7/2 → 29/8 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-2 ]", - "[ 29/8 → 15/4 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-2 ]", - "[ 15/4 → 31/8 | note:a# s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-2 ]", - "[ 31/8 → 4/1 | note:a s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-2 ]", -] -`; - exports[`runs examples > example "delaysync" example index 0 1`] = ` [ "[ 0/1 → 1/2 | s:bd delay:0.25 delaysync:0.125 ]", @@ -2665,6 +2598,19 @@ exports[`runs examples > example "delaysync" example index 0 1`] = ` ] `; +exports[`runs examples > example "delaytime" example index 0 1`] = ` +[ + "[ 0/1 → 1/2 | s:bd delay:0.25 delaytime:0.125 ]", + "[ 1/2 → 1/1 | s:bd delay:0.25 delaytime:0.125 ]", + "[ 1/1 → 3/2 | s:bd delay:0.25 delaytime:0.25 ]", + "[ 3/2 → 2/1 | s:bd delay:0.25 delaytime:0.25 ]", + "[ 2/1 → 5/2 | s:bd delay:0.25 delaytime:0.5 ]", + "[ 5/2 → 3/1 | s:bd delay:0.25 delaytime:0.5 ]", + "[ 3/1 → 7/2 | s:bd delay:0.25 delaytime:1 ]", + "[ 7/2 → 4/1 | s:bd delay:0.25 delaytime:1 ]", +] +`; + exports[`runs examples > example "density" example index 0 1`] = ` [ "[ 0/1 → 1/4 | s:crackle density:0.01 ]", From d164b5e7f5694f10bdd40c849878400b6275a3fe Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 12 Sep 2025 10:08:55 +0200 Subject: [PATCH 136/335] Revert "Revert "Merge pull request 'supradough poc' (#1362) from supradough into main"" This reverts commit c0bf86d11e3d795558b5dd01821f700a5e962070. --- eslint.config.mjs | 1 + packages/core/controls.mjs | 30 +- packages/superdough/sampler.mjs | 91 +- packages/superdough/superdough.mjs | 10 +- packages/supradough/.gitignore | 1 + packages/supradough/README.md | 3 + packages/supradough/dough-export.mjs | 123 +++ packages/supradough/dough-worklet.mjs | 39 + packages/supradough/dough.mjs | 976 ++++++++++++++++++++++ packages/supradough/index.mjs | 4 + packages/supradough/package.json | 37 + packages/webaudio/index.mjs | 1 + packages/webaudio/package.json | 3 +- packages/webaudio/supradough.mjs | 130 +++ packages/webaudio/webaudio.mjs | 7 +- pnpm-lock.yaml | 20 + test/__snapshots__/examples.test.mjs.snap | 80 +- 17 files changed, 1493 insertions(+), 63 deletions(-) create mode 100644 packages/supradough/.gitignore create mode 100644 packages/supradough/README.md create mode 100644 packages/supradough/dough-export.mjs create mode 100644 packages/supradough/dough-worklet.mjs create mode 100644 packages/supradough/dough.mjs create mode 100644 packages/supradough/index.mjs create mode 100644 packages/supradough/package.json create mode 100644 packages/webaudio/supradough.mjs diff --git a/eslint.config.mjs b/eslint.config.mjs index e30b8e8a6..c9ff40ca1 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -42,6 +42,7 @@ export default [ '**/hydra.mjs', '**/jsdoc-synonyms.js', 'packages/hs2js/src/hs2js.mjs', + 'packages/supradough/dough-export.mjs', '**/samples', ], }, diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 58a30652c..473ea82d1 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -309,6 +309,17 @@ export const { fmvelocity } = registerControl('fmvelocity'); */ export const { bank } = registerControl('bank'); +/** + * mix control for the chorus effect + * + * @name chorus + * @param {string | Pattern} chorus mix amount between 0 and 1 + * @example + * note("d d a# a").s("sawtooth").chorus(.5) + * + */ +export const { chorus } = registerControl('chorus'); + // analyser node send amount 0 - 1 (used by scope) export const { analyze } = registerControl('analyze'); // fftSize of analyser @@ -1097,14 +1108,27 @@ export const { delay } = registerControl(['delay', 'delaytime', 'delayfeedback'] * */ export const { delayfeedback, delayfb, dfb } = registerControl('delayfeedback', 'delayfb', 'dfb'); + +/** + * Sets the level of the signal that is fed back into the delay. + * Caution: Values >= 1 will result in a signal that gets louder and louder! Don't do it + * + * @name delayfeedback + * @param {number | Pattern} feedback between 0 and 1 + * @synonyms delayfb, dfb + * @example + * s("bd").delay(.25).delayfeedback("<.25 .5 .75 1>") + * + */ +export const { delayspeed } = registerControl('delayspeed'); /** * Sets the time of the delay effect. * - * @name delaytime - * @param {number | Pattern} seconds between 0 and Infinity + * @name delayspeed + * @param {number | Pattern} delayspeed controls the pitch of the delay feedback * @synonyms delayt, dt * @example - * s("bd bd").delay(.25).delaytime("<.125 .25 .5 1>") + * note("d d a# a".fast(2)).s("sawtooth").delay(.8).delaytime(1/2).delayspeed("<2 .5 -1 -2>") * */ export const { delaytime, delayt, dt } = registerControl('delaytime', 'delayt', 'dt'); diff --git a/packages/superdough/sampler.mjs b/packages/superdough/sampler.mjs index 18d1b7797..9188c17c3 100644 --- a/packages/superdough/sampler.mjs +++ b/packages/superdough/sampler.mjs @@ -196,6 +196,52 @@ function getSamplesPrefixHandler(url) { return; } +export async function fetchSampleMap(url) { + // check if custom prefix handler + const handler = getSamplesPrefixHandler(url); + if (handler) { + return handler(url); + } + url = resolveSpecialPaths(url); + if (url.startsWith('github:')) { + url = githubPath(url, 'strudel.json'); + } + if (url.startsWith('local:')) { + url = `http://localhost:5432`; + } + if (url.startsWith('shabda:')) { + let [_, path] = url.split('shabda:'); + url = `https://shabda.ndre.gr/${path}.json?strudel=1`; + } + if (url.startsWith('shabda/speech')) { + let [_, path] = url.split('shabda/speech'); + path = path.startsWith('/') ? path.substring(1) : path; + let [params, words] = path.split(':'); + let gender = 'f'; + let language = 'en-GB'; + if (params) { + [language, gender] = params.split('/'); + } + url = `https://shabda.ndre.gr/speech/${words}.json?gender=${gender}&language=${language}&strudel=1'`; + } + if (typeof fetch !== 'function') { + // not a browser + return; + } + const base = url.split('/').slice(0, -1).join('/'); + if (typeof fetch === 'undefined') { + // skip fetch when in node / testing + return; + } + const json = await fetch(url) + .then((res) => res.json()) + .catch((error) => { + console.error(error); + throw new Error(`error loading "${url}"`); + }); + return [json, json._base || base]; +} + /** * Loads a collection of samples to use with `s` * @example @@ -217,49 +263,8 @@ function getSamplesPrefixHandler(url) { export const samples = async (sampleMap, baseUrl = sampleMap._base || '', options = {}) => { if (typeof sampleMap === 'string') { - // check if custom prefix handler - const handler = getSamplesPrefixHandler(sampleMap); - if (handler) { - return handler(sampleMap); - } - sampleMap = resolveSpecialPaths(sampleMap); - if (sampleMap.startsWith('github:')) { - sampleMap = githubPath(sampleMap, 'strudel.json'); - } - if (sampleMap.startsWith('local:')) { - sampleMap = `http://localhost:5432`; - } - if (sampleMap.startsWith('shabda:')) { - let [_, path] = sampleMap.split('shabda:'); - sampleMap = `https://shabda.ndre.gr/${path}.json?strudel=1`; - } - if (sampleMap.startsWith('shabda/speech')) { - let [_, path] = sampleMap.split('shabda/speech'); - path = path.startsWith('/') ? path.substring(1) : path; - let [params, words] = path.split(':'); - let gender = 'f'; - let language = 'en-GB'; - if (params) { - [language, gender] = params.split('/'); - } - sampleMap = `https://shabda.ndre.gr/speech/${words}.json?gender=${gender}&language=${language}&strudel=1'`; - } - if (typeof fetch !== 'function') { - // not a browser - return; - } - const base = sampleMap.split('/').slice(0, -1).join('/'); - if (typeof fetch === 'undefined') { - // skip fetch when in node / testing - return; - } - return fetch(sampleMap) - .then((res) => res.json()) - .then((json) => samples(json, baseUrl || json._base || base, options)) - .catch((error) => { - console.error(error); - throw new Error(`error loading "${sampleMap}"`); - }); + const [json, base] = await fetchSampleMap(sampleMap); + return samples(json, baseUrl || base, options); } const { prebake, tag } = options; processSampleMap( diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 792e5a28d..0c084e3e9 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -196,7 +196,7 @@ export const resetLoadedSounds = () => soundMap.set({}); let audioContext; export const setDefaultAudioContext = () => { - audioContext = new AudioContext(); + audioContext = new AudioContext({ latencyHint: 'playback' }); return audioContext; }; @@ -212,11 +212,17 @@ export function getAudioContextCurrentTime() { return getAudioContext().currentTime; } +let externalWorklets = []; +export function registerWorklet(url) { + externalWorklets.push(url); +} + let workletsLoading; function loadWorklets() { if (!workletsLoading) { const audioCtx = getAudioContext(); - workletsLoading = audioCtx.audioWorklet.addModule(workletsUrl); + const allWorkletURLs = externalWorklets.concat([workletsUrl]); + workletsLoading = Promise.all(allWorkletURLs.map((workletURL) => audioCtx.audioWorklet.addModule(workletURL))); } return workletsLoading; diff --git a/packages/supradough/.gitignore b/packages/supradough/.gitignore new file mode 100644 index 000000000..d21cbdf3e --- /dev/null +++ b/packages/supradough/.gitignore @@ -0,0 +1 @@ +pattern.wav diff --git a/packages/supradough/README.md b/packages/supradough/README.md new file mode 100644 index 000000000..a8cfa84b3 --- /dev/null +++ b/packages/supradough/README.md @@ -0,0 +1,3 @@ +# supradough + +platform agnostic synth and sampler intended for live coding. a reimplementation of superdough. \ No newline at end of file diff --git a/packages/supradough/dough-export.mjs b/packages/supradough/dough-export.mjs new file mode 100644 index 000000000..bd4b530b3 --- /dev/null +++ b/packages/supradough/dough-export.mjs @@ -0,0 +1,123 @@ +// this is a poc of how a pattern can be rendered as a wav file using node +// run via: node dough-export.mjs +import fs from 'node:fs'; +import WavEncoder from 'wav-encoder'; +import { evalScope } from '@strudel/core'; +import { miniAllStrings } from '@strudel/mini'; +import { Dough } from './dough.mjs'; + +await evalScope( + import('@strudel/core'), + import('@strudel/mini'), + import('@strudel/tonal'), + // import('@strudel/tonal'), +); + +miniAllStrings(); // allows using single quotes for mini notation / skip transpilation + +let sampleRate = 48000, + cps = 0.4; + +/* await doughsamples('github:eddyflux/crate'); +await doughsamples('github:eddyflux/wax'); */ + +let pat = note('c,eb,g,') + .s('sine') + .press() + .add(note(24)) + .fmi(3) + .fmh(5.01) + .dec(0.4) + .delay('.6:<.12 .22>:.8') + .jux(press) + .rarely(add(note('12'))) + .lpf(400) + .lpq(0.2) + .lpd(0.4) + .lpenv(3) + .fmdecay(0.4) + .fmenv(1) + .postgain(0.6) + .stack(s('*8').dec(0.07).rarely(ply('2')).delay(0.5).hpf(sine.range(200, 2000).slow(4)).hpq(0.2)) + .stack( + s('[- white@3]*2') + .dec(0.4) + .hpf('<2000!3 <4000 8000>>*4') + .hpq(0.6) + .ply('<1 2>*4') + .postgain(0.5) + .delay(0.5) + .jux(rev) + .lpf(5000), + ) + .stack( + note('*2') + .s('square') + .lpf(sine.range(100, 300).slow(4)) + .lpe(1) + .segment(8) + .lpd(0.3) + .lpq(0.2) + .dec(0.2) + .speed('<1 2>') + .ply('<1 2>') + .postgain(1), + ) + .stack( + chord('') + .voicing() + .s('') + .clip(1) + .rel(0.4) + .vib('4:.2') + .gain(0.7) + .hpf(1200) + .fm(0.5) + .att(1) + .lpa(0.5) + .lpf(200) + .lpenv(4) + .chorus(0.8), + ) + .slow(1 / cps); + +let cycles = 30; +let seconds = cycles + 1; // 1s release tail +const haps = pat.queryArc(0, cycles); + +const dough = new Dough(sampleRate); + +console.log('spawn voices...'); +haps.forEach((hap) => { + hap.value._begin = Number(hap.whole.begin); + hap.value._duration = hap.duration /* / cps */; + dough.scheduleSpawn(hap.value); +}); +console.log(`render ${seconds}s long buffer, each dot is 1 second:`); +const buffers = [new Float32Array(seconds * sampleRate), new Float32Array(seconds * sampleRate)]; +let t = performance.now(); +while (dough.t <= buffers[0].length) { + dough.update(); + buffers[0][dough.t] = dough.out[0]; + buffers[1][dough.t] = dough.out[1]; + if (dough.t % sampleRate === 0) { + process.stdout.write('.'); + } +} +const took = (performance.now() - t) / 1000; +const load = (took / seconds) * 100; +const speed = (seconds / took).toFixed(2); +console.log(''); +console.log(`done! +rendered ${seconds}s in ${took.toFixed(2)}s +speed: ${speed}x +load: ${load.toFixed(2)}%`); + +const patternAudio = { + sampleRate, + channelData: buffers, +}; + +WavEncoder.encode(patternAudio).then((buffer) => { + fs.writeFileSync('pattern.wav', new Float32Array(buffer)); +}); diff --git a/packages/supradough/dough-worklet.mjs b/packages/supradough/dough-worklet.mjs new file mode 100644 index 000000000..18c316b2d --- /dev/null +++ b/packages/supradough/dough-worklet.mjs @@ -0,0 +1,39 @@ +import { Dough } from './dough.mjs'; + +const clamp = (num, min, max) => Math.min(Math.max(num, min), max); + +class DoughProcessor extends AudioWorkletProcessor { + constructor() { + super(); + this.dough = new Dough(sampleRate, currentTime); + this.port.onmessage = (event) => { + if (event.data.spawn) { + this.dough.scheduleSpawn(event.data.spawn); + } else if (event.data.sample) { + this.dough.loadSample(event.data.sample, event.data.channels, event.data.sampleRate); + } else if (event.data.samples) { + event.data.samples.forEach(([name, channels, sampleRate]) => { + this.dough.loadSample(name, channels, sampleRate); + }); + } else { + console.log('unrecognized event type', event.data); + } + }; + } + process(inputs, outputs, params) { + if (this.disconnected) { + return false; + } + const output = outputs[0]; + for (let i = 0; i < output[0].length; i++) { + this.dough.update(); + for (let c = 0; c < output.length; c++) { + //prevent speaker blowout via clipping if threshold exceeds + output[c][i] = clamp(this.dough.out[c], -1, 1); + } + } + return true; // keep the audio processing going + } +} + +registerProcessor('dough-processor', DoughProcessor); diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs new file mode 100644 index 000000000..711922b63 --- /dev/null +++ b/packages/supradough/dough.mjs @@ -0,0 +1,976 @@ +// this is dough, the superdough without dependencies +const SAMPLE_RATE = typeof sampleRate !== 'undefined' ? sampleRate : 48000; +const PI_DIV_SR = Math.PI / SAMPLE_RATE; +const ISR = 1 / SAMPLE_RATE; + +let gainCurveFunc = (val) => Math.pow(val, 2); + +function applyGainCurve(val) { + return gainCurveFunc(val); +} + +/** + * Equal Power Crossfade function. + * Smoothly transitions between signals A and B, maintaining consistent perceived loudness. + * + * @param {number} a - Signal A (can be a single value or an array value in buffer processing). + * @param {number} b - Signal B (can be a single value or an array value in buffer processing). + * @param {number} m - Crossfade parameter (0.0 = all A, 1.0 = all B, 0.5 = equal mix). + * @returns {number} Crossfaded output value. + */ +function crossfade(a, b, m) { + const aGain = Math.sin((1 - m) * 0.5 * Math.PI); + const bGain = Math.sin(m * 0.5 * Math.PI); + return a * aGain + b * bGain; +} + +// function setGainCurve(newGainCurveFunc) { +// gainCurveFunc = newGainCurveFunc; +// } +// https://garten.salat.dev/audio-DSP/oscillators.html +export class SineOsc { + phase = 0; + update(freq) { + const value = Math.sin(this.phase * 2 * Math.PI); + this.phase = (this.phase + freq / SAMPLE_RATE) % 1; + return value; + } +} + +export class ZawOsc { + phase = 0; + update(freq) { + this.phase += ISR * freq; + return (this.phase % 1) * 2 - 1; + } +} + +function polyBlep(t, dt) { + // 0 <= t < 1 + if (t < dt) { + t /= dt; + // 2 * (t - t^2/2 - 0.5) + return t + t - t * t - 1; + } + // -1 < t < 0 + if (t > 1 - dt) { + t = (t - 1) / dt; + // 2 * (t^2/2 + t + 0.5) + return t * t + t + t + 1; + } + // 0 otherwise + return 0; +} + +export class SawOsc { + constructor(props = {}) { + this.phase = props.phase ?? 0; + } + update(freq) { + const dt = freq / SAMPLE_RATE; + let p = polyBlep(this.phase, dt); + let s = 2 * this.phase - 1 - p; + this.phase += dt; + if (this.phase > 1) { + this.phase -= 1; + } + return s; + } +} + +function getUnisonDetune(unison, detune, voiceIndex) { + if (unison < 2) { + return 0; + } + const lerp = (a, b, n) => { + return n * (b - a) + a; + }; + return lerp(-detune * 0.5, detune * 0.5, voiceIndex / (unison - 1)); +} +function applySemitoneDetuneToFrequency(frequency, detune) { + return frequency * Math.pow(2, detune / 12); +} +export class SupersawOsc { + constructor(props = {}) { + //TODO: figure out a good way to pass in these params + this.voices = props.voices ?? 5; + this.freqspread = props.freqspread ?? 0.2; + this.panspread = props.panspread ?? 0.4; + this.phase = new Float32Array(this.voices).map(() => Math.random()); + } + update(freq) { + const gain1 = Math.sqrt(1 - this.panspread); + const gain2 = Math.sqrt(this.panspread); + let sl = 0; + let sr = 0; + for (let n = 0; n < this.voices; n++) { + const freqAdjusted = applySemitoneDetuneToFrequency(freq, getUnisonDetune(this.voices, this.freqspread, n)); + const dt = freqAdjusted / SAMPLE_RATE; + const isOdd = (n & 1) == 1; + let gainL = gain1; + let gainR = gain2; + // invert right and left gain + if (isOdd) { + gainL = gain2; + gainR = gain1; + } + let p = polyBlep(this.phase[n], dt); + let s = 2 * this.phase[n] - 1 - p; + sl = sl + s * gainL; + sr = sr + s * gainL; + + this.phase[n] += dt; + if (this.phase[n] > 1) { + this.phase[n] -= 1; + } + } + + return sl + sr; + //TODO: make stereo + // return [sl, sr]; + } +} + +export class TriOsc { + phase = 0; + update(freq) { + this.phase += ISR * freq; + let phase = this.phase % 1; + let value = phase < 0.5 ? 2 * phase : 1 - 2 * (phase - 0.5); + return value * 2 - 1; + } +} + +export class TwoPoleFilter { + s0 = 0; + s1 = 0; + update(s, cutoff, resonance = 0) { + // Out of bound values can produce NaNs + resonance = Math.max(resonance, 0); + + cutoff = Math.min(cutoff, 20000); + const c = 2 * Math.sin(cutoff * PI_DIV_SR); + + const r = Math.pow(0.5, (resonance + 0.125) / 0.125); + const mrc = 1 - r * c; + + this.s0 = mrc * this.s0 - c * this.s1 + c * s; // bpf + this.s1 = mrc * this.s1 + c * this.s0; // lpf + return this.s1; // return lpf by default + } +} + +class PulseOsc { + constructor(phase = 0) { + this.phase = phase; + } + saw(offset, dt) { + let phase = (this.phase + offset) % 1; + let p = polyBlep(phase, dt); + return 2 * phase - 1 - p; + } + update(freq, pw = 0.5) { + const dt = freq / SAMPLE_RATE; + let pulse = this.saw(0, dt) - this.saw(pw, dt); + this.phase = (this.phase + dt) % 1; + return pulse + pw * 2 - 1; + } +} + +// non bandlimited (has aliasing) +export class PulzeOsc { + phase = 0; + update(freq, duty = 0.5) { + this.phase += ISR * freq; + let cyclePos = this.phase % 1; + return cyclePos < duty ? 1 : -1; + } +} + +export class Dust { + update = (density) => (Math.random() < density * ISR ? Math.random() : 0); +} + +export class WhiteNoise { + update() { + return Math.random() * 2 - 1; + } +} + +export class BrownNoise { + constructor() { + this.out = 0; + } + update() { + let white = Math.random() * 2 - 1; + this.out = (this.out + 0.02 * white) / 1.02; + return this.out; + } +} + +export class PinkNoise { + constructor() { + this.b0 = 0; + this.b1 = 0; + this.b2 = 0; + this.b3 = 0; + this.b4 = 0; + this.b5 = 0; + this.b6 = 0; + } + + update() { + const white = Math.random() * 2 - 1; + + this.b0 = 0.99886 * this.b0 + white * 0.0555179; + this.b1 = 0.99332 * this.b1 + white * 0.0750759; + this.b2 = 0.969 * this.b2 + white * 0.153852; + this.b3 = 0.8665 * this.b3 + white * 0.3104856; + this.b4 = 0.55 * this.b4 + white * 0.5329522; + this.b5 = -0.7616 * this.b5 - white * 0.016898; + + const pink = this.b0 + this.b1 + this.b2 + this.b3 + this.b4 + this.b5 + this.b6 + white * 0.5362; + this.b6 = white * 0.115926; + + return pink * 0.11; + } +} + +export class Impulse { + phase = 1; + update(freq) { + this.phase += ISR * freq; + let v = this.phase >= 1 ? 1 : 0; + this.phase = this.phase % 1; + return v; + } +} + +export class ClockDiv { + inSgn = true; + outSgn = true; + clockCnt = 0; + update(clock, factor) { + let curSgn = clock > 0; + if (this.inSgn != curSgn) { + this.clockCnt++; + if (this.clockCnt >= factor) { + this.clockCnt = 0; + this.outSgn = !this.outSgn; + } + } + + this.inSgn = curSgn; + return this.outSgn ? 1 : -1; + } +} + +export class Hold { + value = 0; + trigSgn = false; + update(input, trig) { + if (!this.trigSgn && trig > 0) this.value = input; + this.trigSgn = trig > 0; + return this.value; + } +} + +function lerp(x, y0, y1, exponent = 1) { + if (x <= 0) return y0; + if (x >= 1) return y1; + + let curvedX; + + if (exponent === 0) { + curvedX = x; // linear + } else if (exponent > 0) { + curvedX = Math.pow(x, exponent); // ease-in + } else { + curvedX = 1 - Math.pow(1 - x, -exponent); // ease-out + } + + return y0 + (y1 - y0) * curvedX; +} + +export class ADSR { + constructor(props = {}) { + this.state = 'off'; + this.startTime = 0; + this.startVal = 0; + this.decayCurve = props.decayCurve ?? 1; + } + + update(curTime, gate, attack, decay, susVal, release) { + switch (this.state) { + case 'off': { + if (gate > 0) { + this.state = 'attack'; + this.startTime = curTime; + this.startVal = 0; + } + return 0; + } + case 'attack': { + let time = curTime - this.startTime; + if (time > attack) { + this.state = 'decay'; + this.startTime = curTime; + return 1; + } + return lerp(time / attack, this.startVal, 1, 1); + } + case 'decay': { + let time = curTime - this.startTime; + let curVal = lerp(time / decay, 1, susVal, -this.decayCurve); + if (gate <= 0) { + this.state = 'release'; + this.startTime = curTime; + this.startVal = curVal; + return curVal; + } + if (time > decay) { + this.state = 'sustain'; + this.startTime = curTime; + return susVal; + } + return curVal; + } + case 'sustain': { + if (gate <= 0) { + this.state = 'release'; + this.startTime = curTime; + this.startVal = susVal; + } + return susVal; + } + case 'release': { + let time = curTime - this.startTime; + + if (time > release) { + this.state = 'off'; + return 0; + } + let curVal = lerp(time / release, this.startVal, 0, -this.decayCurve); + if (gate > 0) { + this.state = 'attack'; + this.startTime = curTime; + this.startVal = curVal; + } + return curVal; + } + } + throw 'invalid envelope state'; + } +} + +/* + impulse(1).ad(.1).mul(sine(200)) +.add(x=>x.delay(.1).mul(.8)) +.out()*/ +const MAX_DELAY_TIME = 10; +export class PitchDelay { + lpf = new TwoPoleFilter(); + constructor(_props = {}) { + this.buffer = new Float32Array(MAX_DELAY_TIME * SAMPLE_RATE); + this.writeIdx = 0; + this.readIdx = 0; + this.numSamples = 0; + } + write(s, delayTime) { + // Calculate how far in the past to read + this.numSamples = Math.min(Math.floor(SAMPLE_RATE * delayTime), this.buffer.length - 1); + this.writeIdx = (this.writeIdx + 1) % this.numSamples; + this.buffer[this.writeIdx] = s; + this.readIdx = this.writeIdx - this.numSamples + 1; + + // If past the start of the buffer, wrap around (Q: is this possible?) + if (this.readIdx < 0) this.readIdx += this.numSamples; + } + update(input, delayTime, speed = 1) { + this.write(input, delayTime); + let index = this.readIdx; + if (speed < 0) { + index = this.numSamples - Math.floor(Math.abs(this.readIdx * speed) % this.numSamples); + } else { + index = Math.floor(this.readIdx * speed) % this.numSamples; + } + const s = this.lpf.update(this.buffer[index], 0.9, 0); + + return s; + } +} + +export class Delay { + writeIdx = 0; + readIdx = 0; + buffer = new Float32Array(MAX_DELAY_TIME * SAMPLE_RATE); //.fill(0) + write(s, delayTime) { + this.writeIdx = (this.writeIdx + 1) % this.buffer.length; + this.buffer[this.writeIdx] = s; + // Calculate how far in the past to read + let numSamples = Math.min(Math.floor(SAMPLE_RATE * delayTime), this.buffer.length - 1); + this.readIdx = this.writeIdx - numSamples; + // If past the start of the buffer, wrap around + if (this.readIdx < 0) this.readIdx += this.buffer.length; + } + update(input, delayTime) { + this.write(input, delayTime); + return this.buffer[this.readIdx]; + } +} +//TODO: Figure out why clicking at the start off the buffer +export class Chorus { + delay = new Delay(); + modulator = new TriOsc(); + update(input, mix, delayTime, modulationFreq, modulationDepth) { + const m = this.modulator.update(modulationFreq) * modulationDepth; + const c = this.delay.update(input, delayTime * (1 + m)); + return crossfade(input, c, mix); + } +} + +export class Fold { + update(input = 0, rate = 0) { + if (rate < 0) rate = 0; + rate = rate + 1; + input = input * rate; + return 4 * (Math.abs(0.25 * input + 0.25 - Math.round(0.25 * input + 0.25)) - 0.25); + } +} + +export class Lag { + lagUnit = 4410; + s = 0; + update(input, rate) { + // Remap so the useful range is around [0, 1] + rate = rate * this.lagUnit; + if (rate < 1) rate = 1; + this.s += (1 / rate) * (input - this.s); + return this.s; + } +} + +export class Slew { + last = 0; + update(input, up, dn) { + const upStep = up * ISR; + const downStep = dn * ISR; + let delta = input - this.last; + if (delta > upStep) { + delta = upStep; + } else if (delta < -downStep) { + delta = -downStep; + } + this.last += delta; + return this.last; + } +} + +// overdrive style distortion (adapted from noisecraft) currently unused +export function applyDistortion(x, amount) { + amount = Math.min(Math.max(amount, 0), 1); + amount -= 0.01; + var k = (2 * amount) / (1 - amount); + var y = ((1 + k) * x) / (1 + k * Math.abs(x)); + return y; +} + +export class Sequence { + clockSgn = true; + step = 0; + first = true; + update(clock, ...ins) { + if (!this.clockSgn && clock > 0) { + this.step = (this.step + 1) % ins.length; + this.clockSgn = clock > 0; + return 0; // set first sample to zero to retrigger gates on step change... + } + this.clockSgn = clock > 0; + return ins[this.step]; + } +} + +// sample rate bit crusher +export class Coarse { + hold = 0; + t = 0; + update(input, coarse) { + if (this.t++ % coarse === 0) { + this.t = 0; + this.hold = input; + } + return this.hold; + } +} + +// amplitude bit crusher +export class Crush { + update(input, crush) { + crush = Math.max(1, crush); + const x = Math.pow(2, crush - 1); + return Math.round(input * x) / x; + } +} + +// this is the distort from superdough +export class Distort { + update(input, distort = 0, postgain = 1) { + postgain = Math.max(0.001, Math.min(1, postgain)); + const shape = Math.expm1(distort); + return (((1 + shape) * input) / (1 + shape * Math.abs(input))) * postgain; + } +} +// distortion could be expressed as a function, because it's stateless + +export class BufferPlayer { + static samples = new Map(); // string -> { channels, sampleRate } + buffer; // Float32Array + sampleRate; + pos = 0; + sampleFreq = note2freq(); + constructor(buffer, sampleRate, normalize) { + this.buffer = buffer; + this.sampleRate = sampleRate; + this.duration = this.buffer.length / this.sampleRate; + this.speed = SAMPLE_RATE / this.sampleRate; + if (normalize) { + // this will make the buffer last 1s if freq = sampleFreq + // it's useful to loop samples (e.g. fit function) + this.speed *= this.duration; + } + } + update(freq) { + if (this.pos >= this.buffer.length) { + return 0; + } + const speed = (freq / this.sampleFreq) * this.speed; + let s = this.buffer[Math.floor(this.pos)]; + this.pos = this.pos + speed; + return s; + } +} + +export function _rangex(sig, min, max) { + let logmin = Math.log(min); + let range = Math.log(max) - logmin; + const unipolar = (sig + 1) / 2; + return Math.exp(unipolar * range + logmin); +} + +// duplicate +export const getADSR = (params, curve = 'linear', defaultValues) => { + const envmin = curve === 'exponential' ? 0.001 : 0.001; + const releaseMin = 0.01; + const envmax = 1; + const [a, d, s, r] = params; + if (a == null && d == null && s == null && r == null) { + return defaultValues ?? [envmin, envmin, envmax, releaseMin]; + } + const sustain = s != null ? s : (a != null && d == null) || (a == null && d == null) ? envmax : envmin; + return [Math.max(a ?? 0, envmin), Math.max(d ?? 0, envmin), Math.min(sustain, envmax), Math.max(r ?? 0, releaseMin)]; +}; + +let shapes = { + sine: SineOsc, + saw: SawOsc, + zaw: ZawOsc, + sawtooth: SawOsc, + zawtooth: ZawOsc, + supersaw: SupersawOsc, + tri: TriOsc, + triangle: TriOsc, + pulse: PulseOsc, + square: PulseOsc, + pulze: PulzeOsc, + dust: Dust, + crackle: Dust, + impulse: Impulse, + white: WhiteNoise, + brown: BrownNoise, + pink: PinkNoise, +}; + +const defaultDefaultValues = { + chorus: 0, + note: 48, + s: 'triangle', + bank: '', + gain: 1, + postgain: 1, + velocity: 1, + density: '.03', + ftype: '12db', + fanchor: 0, + //resonance: 1, // superdough resonance is scaled differently + resonance: 0, + //hresonance: 1, // superdough resonance is scaled differently + hresonance: 0, + // bandq: 1, // superdough resonance is scaled differently + bandq: 0, + channels: [1, 2], + phaserdepth: 0.75, + shapevol: 1, + distortvol: 1, + delay: 0, + byteBeatExpression: '0', + delayfeedback: 0.5, + delayspeed: 1, + delaytime: 0.25, + orbit: 1, + i: 1, + fft: 8, + z: 'triangle', + pan: 0.5, + fmh: 1, + fmenv: 0, // differs from superdough + speed: 1, + pw: 0.5, +}; + +let getDefaultValue = (key) => defaultDefaultValues[key]; + +const chromas = { c: 0, d: 2, e: 4, f: 5, g: 7, a: 9, b: 11 }; +const accs = { '#': 1, b: -1, s: 1, f: -1 }; +const note2midi = (note, defaultOctave = 3) => { + let [pc, acc = '', oct = ''] = + String(note) + .match(/^([a-gA-G])([#bsf]*)([0-9]*)$/) + ?.slice(1) || []; + if (!pc) { + throw new Error('not a note: "' + note + '"'); + } + const chroma = chromas[pc.toLowerCase()]; + const offset = acc?.split('').reduce((o, char) => o + accs[char], 0) || 0; + oct = Number(oct || defaultOctave); + return (oct + 1) * 12 + chroma + offset; +}; +const midi2freq = (midi) => Math.pow(2, (midi - 69) / 12) * 440; +const note2freq = (note) => { + note = note || getDefaultValue('note'); + if (typeof note === 'string') { + note = note2midi(note, 3); // e.g. c3 => 48 + } + return midi2freq(note); +}; + +export class DoughVoice { + out = [0, 0]; + constructor(value) { + value.freq ??= note2freq(value.note); + let $ = this; + Object.assign($, value); + $.s = $.s ?? getDefaultValue('s'); + $.gain = applyGainCurve($.gain ?? getDefaultValue('gain')); + $.velocity = applyGainCurve($.velocity ?? getDefaultValue('velocity')); + $.postgain = applyGainCurve($.postgain ?? getDefaultValue('postgain')); + $.density = $.density ?? getDefaultValue('density'); + $.fanchor = $.fanchor ?? getDefaultValue('fanchor'); + $.drive = $.drive ?? 0.69; + $.phaserdepth = $.phaserdepth ?? getDefaultValue('phaserdepth'); + $.shapevol = applyGainCurve($.shapevol ?? getDefaultValue('shapevol')); + $.distortvol = applyGainCurve($.distortvol ?? getDefaultValue('distortvol')); + $.i = $.i ?? getDefaultValue('i'); + $.chorus = $.chorus ?? getDefaultValue('chorus'); + $.fft = $.fft ?? getDefaultValue('fft'); + $.pan = $.pan ?? getDefaultValue('pan'); + $.orbit = $.orbit ?? getDefaultValue('orbit'); + $.fmenv = $.fmenv ?? getDefaultValue('fmenv'); + $.resonance = $.resonance ?? getDefaultValue('resonance'); + $.hresonance = $.hresonance ?? getDefaultValue('hresonance'); + $.bandq = $.bandq ?? getDefaultValue('bandq'); + $.speed = $.speed ?? getDefaultValue('speed'); + $.pw = $.pw ?? getDefaultValue('pw'); + + [$.attack, $.decay, $.sustain, $.release] = getADSR([$.attack, $.decay, $.sustain, $.release]); + + $._holdEnd = $._begin + $._duration; // needed for gate + $._end = $._holdEnd + $.release + 0.01; // needed for despawn + + if ($.fmi && ($.s === 'saw' || $.s === 'sawtooth')) { + $.s = 'zaw'; // polyblepped saw when fm is applied + } + + if (shapes[$.s]) { + const SourceClass = shapes[$.s]; + $._sound = new SourceClass(); + $._channels = 1; + } else if (BufferPlayer.samples.has($.s)) { + const sample = BufferPlayer.samples.get($.s); + $._buffers = []; + $._channels = sample.channels.length; + for (let i = 0; i < $._channels; i++) { + $._buffers.push(new BufferPlayer(sample.channels[i], sample.sampleRate, $.unit === 'c')); // tbd unit === 'c' + } + } else { + console.warn('sound not loaded', $.s); + } + + if ($.penv) { + $._penv = new ADSR({ decayCurve: 4 }); + [$.pattack, $.pdecay, $.psustain, $.prelease] = getADSR([$.pattack, $.pdecay, $.psustain, $.prelease]); + } + + if ($.vib) { + $._vib = new SineOsc(); + $.vibmod = $.vibmod ?? getDefaultValue('vibmod'); + } + + if ($.fmi) { + $._fm = new SineOsc(); + $.fmh = $.fmh ?? getDefaultValue('fmh'); + if ($.fmenv) { + $._fmenv = new ADSR({ decayCurve: 2 }); + [$.fmattack, $.fmdecay, $.fmsustain, $.fmrelease] = getADSR([$.fmattack, $.fmdecay, $.fmsustain, $.fmrelease]); + } + } + + // gain envelope + $._adsr = new ADSR({ decayCurve: 2 }); + // delay + $.delay = applyGainCurve($.delay ?? getDefaultValue('delay')); + $.delayfeedback = $.delayfeedback ?? getDefaultValue('delayfeedback'); + $.delayspeed = $.delayspeed ?? getDefaultValue('delayspeed'); + $.delaytime = $.delaytime ?? getDefaultValue('delaytime'); + + // filter setup + if ($.lpenv) { + $._lpenv = new ADSR({ decayCurve: 4 }); + [$.lpattack, $.lpdecay, $.lpsustain, $.lprelease] = getADSR([$.lpattack, $.lpdecay, $.lpsustain, $.lprelease]); + } + if ($.hpenv) { + $._hpenv = new ADSR({ decayCurve: 4 }); + [$.hpattack, $.hpdecay, $.hpsustain, $.hprelease] = getADSR([$.hpattack, $.hpdecay, $.hpsustain, $.hprelease]); + } + if ($.bpenv) { + $._bpenv = new ADSR({ decayCurve: 4 }); + [$.bpattack, $.bpdecay, $.bpsustain, $.bprelease] = getADSR([$.bpattack, $.bpdecay, $.bpsustain, $.bprelease]); + } + + // channelwise effects setup + $._chorus = $.chorus ? [] : null; + $._lpf = $.cutoff ? [] : null; + $._hpf = $.hcutoff ? [] : null; + $._bpf = $.bandf ? [] : null; + $._coarse = $.coarse ? [] : null; + $._crush = $.crush ? [] : null; + $._distort = $.distort ? [] : null; + for (let i = 0; i < this._channels; i++) { + $._lpf?.push(new TwoPoleFilter()); + $._hpf?.push(new TwoPoleFilter()); + $._bpf?.push(new TwoPoleFilter()); + $._chorus?.push(new Chorus()); + $._coarse?.push(new Coarse()); + $._crush?.push(new Crush()); + $._distort?.push(new Distort()); + } + } + update(t) { + if (!this._sound && !this._buffers) { + return 0; + } + let gate = Number(t >= this._begin && t <= this._holdEnd); + + let freq = this.freq * this.speed; + + // frequency modulation + if (this._fm) { + let fmi = this.fmi; + if (this._fmenv) { + const env = this._fmenv.update(t, gate, this.fmattack, this.fmdecay, this.fmsustain, this.fmrelease); + fmi = this.fmenv * env * fmi; + } + const modfreq = freq * this.fmh; + const modgain = modfreq * fmi; + freq = freq + this._fm.update(modfreq) * modgain; + } + + // vibrato + if (this._vib) { + freq = freq * 2 ** ((this._vib.update(this.vib) * this.vibmod) / 12); + } + + // pitch envelope + if (this._penv) { + const env = this._penv.update(t, gate, this.pattack, this.pdecay, this.psustain, this.prelease); + freq = freq + env * this.penv; + } + + // filters + let lpf = this.cutoff; + if (this._lpf) { + if (this._lpenv) { + const env = this._lpenv.update(t, gate, this.lpattack, this.lpdecay, this.lpsustain, this.lprelease); + lpf = this.lpenv * env * lpf + lpf; + } + } + let hpf = this.hcutoff; + if (this._hpf) { + if (this._hpenv) { + const env = this._hpenv.update(t, gate, this.hpattack, this.hpdecay, this.hpsustain, this.hprelease); + hpf = 2 ** this.hpenv * env * hpf + hpf; + } + } + let bpf = this.bandf; + if (this._bpf) { + if (this._bpenv) { + const env = this._bpenv.update(t, gate, this.bpattack, this.bpdecay, this.bpsustain, this.bprelease); + bpf = 2 ** this.bpenv * env * bpf + bpf; + } + } + // gain envelope + const env = this._adsr.update(t, gate, this.attack, this.decay, this.sustain, this.release); + + // channelwise dsp + for (let i = 0; i < this._channels; i++) { + // sound source + if (this._sound && this.s === 'pulse') { + this.out[i] = this._sound.update(freq, this.pw); + } else if (this._sound) { + this.out[i] = this._sound.update(freq); + } else if (this._buffers) { + this.out[i] = this._buffers[i].update(freq); + } + this.out[i] = this.out[i] * this.gain * this.velocity; + if (this._chorus) { + const c = this._chorus[i].update(this.out[i], this.chorus, 0.03 + 0.05 * i, 1, 0.11); + this.out[i] = c + this.out[i]; + } + + if (this._lpf) { + this._lpf[i].update(this.out[i], lpf, this.resonance); + this.out[i] = this._lpf[i].s1; + } + if (this._hpf) { + this._hpf[i].update(this.out[i], hpf, this.hresonance); + this.out[i] = this.out[i] - this._hpf[i].s1; + } + if (this._bpf) { + this._bpf[i].update(this.out[i], bpf, this.bandq); + this.out[i] = this._bpf[i].s0; + } + if (this._coarse) { + this.out[i] = this._coarse[i].update(this.out[i], this.coarse); + } + if (this._crush) { + this.out[i] = this._crush[i].update(this.out[i], this.crush); + } + if (this._distort) { + this.out[i] = this._distort[i].update(this.out[i], this.distort, this.distortvol); + } + this.out[i] = this.out[i] * env; + this.out[i] = this.out[i] * this.postgain; + if (!this._buffers) { + this.out[i] = this.out[i] * 0.2; // turn down waveform + } + } + if (this._channels === 1) { + this.out[1] = this.out[0]; + } + if (this.pan !== 0.5) { + const panpos = (this.pan * Math.PI) / 2; + this.out[0] = this.out[0] * Math.cos(panpos); + this.out[1] = this.out[1] * Math.sin(panpos); + } + } +} + +// this class is the interface to the "outer world" +// it handles spawning and despawning of DoughVoice's +export class Dough { + voices = []; // DoughVoice[] + vid = 0; + q = []; + out = [0, 0]; + delaysend = [0, 0]; + delaytime = getDefaultValue('delaytime'); + delayfeedback = getDefaultValue('delayfeedback'); + delayspeed = getDefaultValue('delayspeed'); + t = 0; + // sampleRate: number, currentTime: number (seconds) + constructor(sampleRate = 48000, currentTime = 0) { + this.sampleRate = sampleRate; + this.t = Math.floor(currentTime * sampleRate); // samples + // console.log('init dough', this.sampleRate, this.t); + this._delayL = new PitchDelay(); + this._delayR = new PitchDelay(); + } + loadSample(name, channels, sampleRate) { + BufferPlayer.samples.set(name, { channels, sampleRate }); + } + scheduleSpawn(value) { + if (value._begin === undefined) { + throw new Error('[dough]: scheduleSpawn expected _begin to be set'); + } + if (value._duration === undefined) { + throw new Error('[dough]: scheduleSpawn expected _duration to be set'); + } + value.sampleRate = this.sampleRate; + // convert seconds to samples + const time = Math.floor(value._begin * this.sampleRate); // set from supradough.mjs + this.schedule({ time, type: 'spawn', arg: value }); + } + spawn(value) { + value.id = this.vid++; + const voice = new DoughVoice(value); + this.voices.push(voice); + // console.log('spawn', voice.id, 'voices:', this.voices.length); + // schedule removal + const endTime = Math.ceil(voice._end * this.sampleRate); + this.schedule({ time: endTime /* + 48000 */, type: 'despawn', arg: voice.id }); + } + despawn(vid) { + this.voices = this.voices.filter((v) => v.id !== vid); + // console.log('despawn', vid, 'voices:', this.voices.length); + } + // schedules a function call with a single argument + // msg = {time:number,type:string, arg: any} + // the Dough method "type" will be called with "arg" at "time" + schedule(msg) { + if (!this.q.length) { + // if empty, just push + this.q.push(msg); + return; + } + // not empty + // find index where msg.time fits in + let i = 0; + while (i < this.q.length && this.q[i].time < msg.time) { + i++; + } + // this ensures q stays sorted by time, so we only need to check q[0] + this.q.splice(i, 0, msg); + } + // maybe update should be called once per block instead for perf reasons? + update() { + // go over q + while (this.q.length > 0 && this.q[0].time <= this.t) { + // console.log('schedule', this.q[0]); + // trigger due messages. q is sorted, so we only need to check q[0] + this[this.q[0].type](this.q[0].arg); // type is expected to be a Dough method + this.q.shift(); + } + // add active voices + this.out[0] = 0; + this.out[1] = 0; + for (let v = 0; v < this.voices.length; v++) { + this.voices[v].update(this.t / this.sampleRate); + this.out[0] += this.voices[v].out[0]; + this.out[1] += this.voices[v].out[1]; + if (this.voices[v].delay) { + this.delaysend[0] += this.voices[v].out[0] * this.voices[v].delay; + this.delaysend[1] += this.voices[v].out[1] * this.voices[v].delay; + this.delaytime = this.voices[v].delaytime; // we trust that these are initialized in the voice + this.delayspeed = this.voices[v].delayspeed; // we trust that these are initialized in the voice + this.delayfeedback = this.voices[v].delayfeedback; + } + } + // todo: how to change delaytime / delayfeedback from a voice? + const delayL = this._delayL.update(this.delaysend[0], this.delaytime, this.delayspeed); + const delayR = this._delayR.update(this.delaysend[1], this.delaytime, this.delayspeed); + this.delaysend[0] = delayL * this.delayfeedback; + this.delaysend[1] = delayR * this.delayfeedback; + this.out[0] += delayL; + this.out[1] += delayR; + this.t++; + } +} diff --git a/packages/supradough/index.mjs b/packages/supradough/index.mjs new file mode 100644 index 000000000..54a835495 --- /dev/null +++ b/packages/supradough/index.mjs @@ -0,0 +1,4 @@ +import _workletUrl from './dough-worklet.mjs?url'; // todo: change ?url to ?audioworklet before build (?audioworklet doesn't hot reload) + +export * from './dough.mjs'; +export const workletUrl = _workletUrl; diff --git a/packages/supradough/package.json b/packages/supradough/package.json new file mode 100644 index 000000000..7e465c0a9 --- /dev/null +++ b/packages/supradough/package.json @@ -0,0 +1,37 @@ +{ + "name": "supradough", + "version": "1.2.3", + "description": "platform agnostic synth and sampler intended for live coding. a reimplementation of superdough.", + "main": "index.mjs", + "type": "module", + "publishConfig": { + "main": "dist/index.mjs" + }, + "scripts": { + "build": "vite build", + "prepublishOnly": "npm run build" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/tidalcycles/strudel.git" + }, + "keywords": [ + "tidalcycles", + "strudel", + "pattern", + "livecoding", + "algorave" + ], + "author": "Felix Roos ", + "license": "AGPL-3.0-or-later", + "bugs": { + "url": "https://github.com/tidalcycles/strudel/issues" + }, + "homepage": "https://github.com/tidalcycles/strudel#readme", + "devDependencies": { + "vite": "^6.0.11", + "vite-plugin-bundle-audioworklet": "workspace:*", + "wav-encoder": "^1.3.0" + }, + "dependencies": {} +} diff --git a/packages/webaudio/index.mjs b/packages/webaudio/index.mjs index 362e61c44..4933b7a01 100644 --- a/packages/webaudio/index.mjs +++ b/packages/webaudio/index.mjs @@ -7,4 +7,5 @@ This program is free software: you can redistribute it and/or modify it under th export * from './webaudio.mjs'; export * from './scope.mjs'; export * from './spectrum.mjs'; +export * from './supradough.mjs'; export * from 'superdough'; diff --git a/packages/webaudio/package.json b/packages/webaudio/package.json index cbe673a5a..49da00f23 100644 --- a/packages/webaudio/package.json +++ b/packages/webaudio/package.json @@ -35,7 +35,8 @@ "dependencies": { "@strudel/core": "workspace:*", "@strudel/draw": "workspace:*", - "superdough": "workspace:*" + "superdough": "workspace:*", + "supradough": "workspace:*" }, "devDependencies": { "vite": "^6.0.11" diff --git a/packages/webaudio/supradough.mjs b/packages/webaudio/supradough.mjs new file mode 100644 index 000000000..f97251a07 --- /dev/null +++ b/packages/webaudio/supradough.mjs @@ -0,0 +1,130 @@ +import { Pattern } from '@strudel/core'; +import { connectToDestination, getAudioContext, getWorklet } from 'superdough'; + +let doughWorklet; + +function initDoughWorklet() { + const ac = getAudioContext(); + doughWorklet = getWorklet( + ac, + 'dough-processor', + {}, + { + outputChannelCount: [2], + }, + ); + connectToDestination(doughWorklet); // channels? +} + +const soundMap = new Map(); +const loadedSounds = new Map(); + +Pattern.prototype.supradough = function () { + return this.onTrigger((hap, __, cps, begin) => { + hap.value._begin = begin; + hap.value._duration = hap.duration / cps; + !doughWorklet && initDoughWorklet(); + const s = (hap.value.bank ? hap.value.bank + '_' : '') + hap.value.s; + const n = hap.value.n ?? 0; + const soundKey = `${s}:${n}`; + if (soundMap.has(s)) { + hap.value.s = soundKey; // dough.mjs is unaware of bank and n (only maps keys to buffers) + } + if (soundMap.has(s) && !loadedSounds.has(soundKey)) { + const urls = soundMap.get(s); + const url = urls[n % urls.length]; + console.log(`load ${soundKey} from ${url}`); + const loadSample = fetchSample(url); + loadedSounds.set(soundKey, loadSample); + loadSample.then(({ channels, sampleRate }) => + doughWorklet.port.postMessage({ + sample: soundKey, + channels, + sampleRate, + }), + ); + } + + doughWorklet.port.postMessage({ spawn: hap.value }); + }, 1); +}; + +function githubPath(base, subpath = '') { + if (!base.startsWith('github:')) { + throw new Error('expected "github:" at the start of pseudoUrl'); + } + let [_, path] = base.split('github:'); + path = path.endsWith('/') ? path.slice(0, -1) : path; + if (path.split('/').length === 2) { + // assume main as default branch if none set + path += '/main'; + } + return `https://raw.githubusercontent.com/${path}/${subpath}`; +} +export async function fetchSampleMap(url) { + if (url.startsWith('github:')) { + url = githubPath(url, 'strudel.json'); + } + if (url.startsWith('local:')) { + url = `http://localhost:5432`; + } + if (url.startsWith('shabda:')) { + let [_, path] = url.split('shabda:'); + url = `https://shabda.ndre.gr/${path}.json?strudel=1`; + } + if (url.startsWith('shabda/speech')) { + let [_, path] = url.split('shabda/speech'); + path = path.startsWith('/') ? path.substring(1) : path; + let [params, words] = path.split(':'); + let gender = 'f'; + let language = 'en-GB'; + if (params) { + [language, gender] = params.split('/'); + } + url = `https://shabda.ndre.gr/speech/${words}.json?gender=${gender}&language=${language}&strudel=1'`; + } + if (typeof fetch !== 'function') { + // not a browser + return; + } + const base = url.split('/').slice(0, -1).join('/'); + if (typeof fetch === 'undefined') { + // skip fetch when in node / testing + return; + } + const json = await fetch(url) + .then((res) => res.json()) + .catch((error) => { + console.error(error); + throw new Error(`error loading "${url}"`); + }); + return [json, json._base || base]; +} + +// for some reason, only piano and flute work.. is it because mp3?? + +async function fetchSample(url) { + const buffer = await fetch(url) + .then((res) => res.arrayBuffer()) + .then((buf) => getAudioContext().decodeAudioData(buf)); + let channels = []; + for (let i = 0; i < buffer.numberOfChannels; i++) { + channels.push(buffer.getChannelData(i)); + } + return { channels, sampleRate: buffer.sampleRate }; +} + +export async function doughsamples(sampleMap, baseUrl) { + if (typeof sampleMap === 'string') { + const [json, base] = await fetchSampleMap(sampleMap); + // console.log('json', json, 'base', base); + return doughsamples(json, base); + } + Object.entries(sampleMap).map(async ([key, urls]) => { + if (key !== '_base') { + urls = urls.map((url) => baseUrl + url); + // console.log('set', key, urls); + soundMap.set(key, urls); + } + }); +} diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 429d2a26b..383e87f87 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -5,7 +5,12 @@ This program is free software: you can redistribute it and/or modify it under th */ import * as strudel from '@strudel/core'; -import { superdough, getAudioContext, setLogger, doughTrigger } from 'superdough'; +import { superdough, getAudioContext, setLogger, doughTrigger, registerWorklet } from 'superdough'; +import './supradough.mjs'; +import { workletUrl } from 'supradough'; + +registerWorklet(workletUrl); + const { Pattern, logger, repl } = strudel; setLogger(logger); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f4a24f61c..c225057f3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -517,6 +517,18 @@ importers: specifier: workspace:* version: link:../vite-plugin-bundle-audioworklet + packages/supradough: + devDependencies: + vite: + specifier: ^6.0.11 + version: 6.0.11(@types/node@22.10.10)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.37.0)(yaml@2.7.0) + vite-plugin-bundle-audioworklet: + specifier: workspace:* + version: link:../vite-plugin-bundle-audioworklet + wav-encoder: + specifier: ^1.3.0 + version: 1.3.0 + packages/tidal: dependencies: '@strudel/core': @@ -625,6 +637,9 @@ importers: superdough: specifier: workspace:* version: link:../superdough + supradough: + specifier: workspace:* + version: link:../supradough devDependencies: vite: specifier: ^6.0.11 @@ -7537,6 +7552,9 @@ packages: walk-up-path@3.0.1: resolution: {integrity: sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==} + wav-encoder@1.3.0: + resolution: {integrity: sha512-FXJdEu2qDOI+wbVYZpu21CS1vPEg5NaxNskBr4SaULpOJMrLE6xkH8dECa7PiS+ZoeyvP7GllWUAxPN3AvFSEw==} + wav@1.0.2: resolution: {integrity: sha512-viHtz3cDd/Tcr/HbNqzQCofKdF6kWUymH9LGDdskfWFoIy/HJ+RTihgjEcHfnsy1PO4e9B+y4HwgTwMrByquhg==} @@ -15958,6 +15976,8 @@ snapshots: walk-up-path@3.0.1: {} + wav-encoder@1.3.0: {} + wav@1.0.2: dependencies: buffer-alloc: 1.2.0 diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index 41207620f..ecbc33eac 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -1847,6 +1847,27 @@ exports[`runs examples > example "chop" example index 0 1`] = ` ] `; +exports[`runs examples > example "chorus" example index 0 1`] = ` +[ + "[ 0/1 → 1/4 | note:d s:sawtooth chorus:0.5 ]", + "[ 1/4 → 1/2 | note:d s:sawtooth chorus:0.5 ]", + "[ 1/2 → 3/4 | note:a# s:sawtooth chorus:0.5 ]", + "[ 3/4 → 1/1 | note:a s:sawtooth chorus:0.5 ]", + "[ 1/1 → 5/4 | note:d s:sawtooth chorus:0.5 ]", + "[ 5/4 → 3/2 | note:d s:sawtooth chorus:0.5 ]", + "[ 3/2 → 7/4 | note:a# s:sawtooth chorus:0.5 ]", + "[ 7/4 → 2/1 | note:a s:sawtooth chorus:0.5 ]", + "[ 2/1 → 9/4 | note:d s:sawtooth chorus:0.5 ]", + "[ 9/4 → 5/2 | note:d s:sawtooth chorus:0.5 ]", + "[ 5/2 → 11/4 | note:a# s:sawtooth chorus:0.5 ]", + "[ 11/4 → 3/1 | note:a s:sawtooth chorus:0.5 ]", + "[ 3/1 → 13/4 | note:d s:sawtooth chorus:0.5 ]", + "[ 13/4 → 7/2 | note:d s:sawtooth chorus:0.5 ]", + "[ 7/2 → 15/4 | note:a# s:sawtooth chorus:0.5 ]", + "[ 15/4 → 4/1 | note:a s:sawtooth chorus:0.5 ]", +] +`; + exports[`runs examples > example "chunk" example index 0 1`] = ` [ "[ 0/1 → 1/4 | note:A4 ]", @@ -2585,6 +2606,52 @@ exports[`runs examples > example "delayfeedback" example index 0 1`] = ` ] `; +exports[`runs examples > example "delayfeedback" example index 0 2`] = ` +[ + "[ 0/1 → 1/1 | s:bd delay:0.25 delayfeedback:0.25 ]", + "[ 1/1 → 2/1 | s:bd delay:0.25 delayfeedback:0.5 ]", + "[ 2/1 → 3/1 | s:bd delay:0.25 delayfeedback:0.75 ]", + "[ 3/1 → 4/1 | s:bd delay:0.25 delayfeedback:1 ]", +] +`; + +exports[`runs examples > example "delayspeed" example index 0 1`] = ` +[ + "[ 0/1 → 1/8 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:2 ]", + "[ 1/8 → 1/4 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:2 ]", + "[ 1/4 → 3/8 | note:a# s:sawtooth delay:0.8 delaytime:0.5 delayspeed:2 ]", + "[ 3/8 → 1/2 | note:a s:sawtooth delay:0.8 delaytime:0.5 delayspeed:2 ]", + "[ 1/2 → 5/8 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:2 ]", + "[ 5/8 → 3/4 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:2 ]", + "[ 3/4 → 7/8 | note:a# s:sawtooth delay:0.8 delaytime:0.5 delayspeed:2 ]", + "[ 7/8 → 1/1 | note:a s:sawtooth delay:0.8 delaytime:0.5 delayspeed:2 ]", + "[ 1/1 → 9/8 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:0.5 ]", + "[ 9/8 → 5/4 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:0.5 ]", + "[ 5/4 → 11/8 | note:a# s:sawtooth delay:0.8 delaytime:0.5 delayspeed:0.5 ]", + "[ 11/8 → 3/2 | note:a s:sawtooth delay:0.8 delaytime:0.5 delayspeed:0.5 ]", + "[ 3/2 → 13/8 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:0.5 ]", + "[ 13/8 → 7/4 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:0.5 ]", + "[ 7/4 → 15/8 | note:a# s:sawtooth delay:0.8 delaytime:0.5 delayspeed:0.5 ]", + "[ 15/8 → 2/1 | note:a s:sawtooth delay:0.8 delaytime:0.5 delayspeed:0.5 ]", + "[ 2/1 → 17/8 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-1 ]", + "[ 17/8 → 9/4 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-1 ]", + "[ 9/4 → 19/8 | note:a# s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-1 ]", + "[ 19/8 → 5/2 | note:a s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-1 ]", + "[ 5/2 → 21/8 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-1 ]", + "[ 21/8 → 11/4 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-1 ]", + "[ 11/4 → 23/8 | note:a# s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-1 ]", + "[ 23/8 → 3/1 | note:a s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-1 ]", + "[ 3/1 → 25/8 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-2 ]", + "[ 25/8 → 13/4 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-2 ]", + "[ 13/4 → 27/8 | note:a# s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-2 ]", + "[ 27/8 → 7/2 | note:a s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-2 ]", + "[ 7/2 → 29/8 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-2 ]", + "[ 29/8 → 15/4 | note:d s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-2 ]", + "[ 15/4 → 31/8 | note:a# s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-2 ]", + "[ 31/8 → 4/1 | note:a s:sawtooth delay:0.8 delaytime:0.5 delayspeed:-2 ]", +] +`; + exports[`runs examples > example "delaysync" example index 0 1`] = ` [ "[ 0/1 → 1/2 | s:bd delay:0.25 delaysync:0.125 ]", @@ -2598,19 +2665,6 @@ exports[`runs examples > example "delaysync" example index 0 1`] = ` ] `; -exports[`runs examples > example "delaytime" example index 0 1`] = ` -[ - "[ 0/1 → 1/2 | s:bd delay:0.25 delaytime:0.125 ]", - "[ 1/2 → 1/1 | s:bd delay:0.25 delaytime:0.125 ]", - "[ 1/1 → 3/2 | s:bd delay:0.25 delaytime:0.25 ]", - "[ 3/2 → 2/1 | s:bd delay:0.25 delaytime:0.25 ]", - "[ 2/1 → 5/2 | s:bd delay:0.25 delaytime:0.5 ]", - "[ 5/2 → 3/1 | s:bd delay:0.25 delaytime:0.5 ]", - "[ 3/1 → 7/2 | s:bd delay:0.25 delaytime:1 ]", - "[ 7/2 → 4/1 | s:bd delay:0.25 delaytime:1 ]", -] -`; - exports[`runs examples > example "density" example index 0 1`] = ` [ "[ 0/1 → 1/4 | s:crackle density:0.01 ]", From a46617f3f0898ae417b993bbfbee8bfa5daf0765 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 12 Sep 2025 10:16:37 +0200 Subject: [PATCH 137/335] hotfix: use ?audioworklet for supradough worklet import --- packages/supradough/index.mjs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/supradough/index.mjs b/packages/supradough/index.mjs index 54a835495..cb132fb3f 100644 --- a/packages/supradough/index.mjs +++ b/packages/supradough/index.mjs @@ -1,4 +1,5 @@ -import _workletUrl from './dough-worklet.mjs?url'; // todo: change ?url to ?audioworklet before build (?audioworklet doesn't hot reload) +// import _workletUrl from './dough-worklet.mjs?url'; // only for dev (breaks for production build) +import _workletUrl from './dough-worklet.mjs?audioworklet'; // only for prod (breaks in development?!) export * from './dough.mjs'; export const workletUrl = _workletUrl; From 7676641c9ef8a631a47fc7ef0d6877442eb5c509 Mon Sep 17 00:00:00 2001 From: drdozer Date: Fri, 12 Sep 2025 12:11:36 +0100 Subject: [PATCH 138/335] Commiting lockfile. --- pnpm-lock.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f4a24f61c..4cf7ea602 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -215,9 +215,15 @@ importers: '@strudel/transpiler': specifier: workspace:* version: link:../transpiler + '@tonaljs/tonal': + specifier: ^4.10.0 + version: 4.10.0 nanostores: specifier: ^0.11.3 version: 0.11.3 + superdough: + specifier: workspace:* + version: link:../superdough devDependencies: vite: specifier: ^6.0.11 From 352a3c39d7fd050348825d752239bc9e39f05f5e Mon Sep 17 00:00:00 2001 From: fesmith Date: Sat, 13 Sep 2025 00:00:36 +0200 Subject: [PATCH 139/335] Update website/src/pages/workshop/first-sounds.mdx --- website/src/pages/workshop/first-sounds.mdx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/website/src/pages/workshop/first-sounds.mdx b/website/src/pages/workshop/first-sounds.mdx index 74daf4bab..f120f332a 100644 --- a/website/src/pages/workshop/first-sounds.mdx +++ b/website/src/pages/workshop/first-sounds.mdx @@ -260,16 +260,16 @@ It is quite common that there are many ways to express the same idea. punchcard /> -**selecting sample numbers separately** +**selecting sample numbers separately** -Instead of using ":", we can also use the `n` function to select sample numbers: - - - -This is shorter and more readable than: +Instead of selecting sample numbers one by one: +We can also use the `n` function to make it shorter and more readable: + + + ## Recap Now we've learned the basics of the so called Mini-Notation, the rhythm language of Tidal. From e18296e76095b18a883b977979b4cf18c8139df8 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sat, 13 Sep 2025 19:52:07 +0200 Subject: [PATCH 140/335] hotfix: word --- website/src/pages/learn/code.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/pages/learn/code.mdx b/website/src/pages/learn/code.mdx index 7057c4576..f9c6b3a25 100644 --- a/website/src/pages/learn/code.mdx +++ b/website/src/pages/learn/code.mdx @@ -44,7 +44,7 @@ xxx("foo").yyy("bar") Generally, `xxx` and `yyy` are called [_functions_](), while `foo` and `bar` are called function [_arguments_ or _parameters_](). So far, we've used the functions to declare which aspect of the sound we want to control, and their arguments for the actual data. -The `yyy` function is called a [_chained_ function](https://en.wikipedia.org/wiki/Method_chaining), because it is prepended with a dot (`.`). +The `yyy` function is called a [_chained_ function](https://en.wikipedia.org/wiki/Method_chaining), because it is preceded with a dot (`.`). Generally, the idea with chaining is that code such as `a("this").b("that").c("other")` allows `a`, `b` and `c` functions to happen in a specified order, without needing to write them as three separate lines of code. You can think of this as being similar to chaining audio effects together using guitar pedals or digital audio effects. From ed00686804fecfa05609f7c21c93f2ce3512fded Mon Sep 17 00:00:00 2001 From: Aria Date: Sat, 13 Sep 2025 14:29:28 -0500 Subject: [PATCH 141/335] Codeformat --- website/src/pages/learn/xen.mdx | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/website/src/pages/learn/xen.mdx b/website/src/pages/learn/xen.mdx index 32e2c0b43..b8b27ac7f 100644 --- a/website/src/pages/learn/xen.mdx +++ b/website/src/pages/learn/xen.mdx @@ -16,10 +16,7 @@ These functions allow the use of scales other than your typical chromatic 12 bas Here's an example of how to configure a basic hexany scale: - + Try other scales like `hexany1`, `iraq`, `gumbeng`, `gunkali`, or `tranh3` @@ -67,6 +64,7 @@ Another helpful trick when exploring new tunings is to strum them. Many have a much more enchanting sound that was chosen over many generations of musicians for being strummed. Take the `sanza` tuning: + + This quality is often due to how the tunings were formed with instruments that were played differently than a piano. As such, some tunings are much better strummed, with the subtle clash of the detuned notes actually making the sound much more magical: From 69b034349a02a9db8c0406f6a530e00403a0037f Mon Sep 17 00:00:00 2001 From: Aria Date: Sat, 13 Sep 2025 14:30:05 -0500 Subject: [PATCH 142/335] Codeformat --- website/src/pages/learn/xen.mdx | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/website/src/pages/learn/xen.mdx b/website/src/pages/learn/xen.mdx index 32e2c0b43..b8b27ac7f 100644 --- a/website/src/pages/learn/xen.mdx +++ b/website/src/pages/learn/xen.mdx @@ -16,10 +16,7 @@ These functions allow the use of scales other than your typical chromatic 12 bas Here's an example of how to configure a basic hexany scale: - + Try other scales like `hexany1`, `iraq`, `gumbeng`, `gunkali`, or `tranh3` @@ -67,6 +64,7 @@ Another helpful trick when exploring new tunings is to strum them. Many have a much more enchanting sound that was chosen over many generations of musicians for being strummed. Take the `sanza` tuning: + + This quality is often due to how the tunings were formed with instruments that were played differently than a piano. As such, some tunings are much better strummed, with the subtle clash of the detuned notes actually making the sound much more magical: From d87ce960d218f00c8adfd2c3cfd1658e39eaa8b3 Mon Sep 17 00:00:00 2001 From: drdozer Date: Thu, 11 Sep 2025 18:42:23 +0100 Subject: [PATCH 143/335] feat: implement context-aware autocomplete Adds context-sensitive autocompletion for: - Sound names in s("...") and sound("...") after the opening quote or after whitespace/bracket - Bank names in bank("...") with quote handling and live filtering - Scale types in .scale("...") after the colon, inserting colon-form for multi-word names - Pitch names (C, C#, Db, etc.) for scale keys on explicit completion (Ctrl+Space) before the colon - Blocks fallback completions in scale context before colon to avoid function list cross-talk --- packages/codemirror/autocomplete.mjs | 166 +++++++++++++++++++++++++-- 1 file changed, 155 insertions(+), 11 deletions(-) diff --git a/packages/codemirror/autocomplete.mjs b/packages/codemirror/autocomplete.mjs index 59ca8adf2..c1c7bb14e 100644 --- a/packages/codemirror/autocomplete.mjs +++ b/packages/codemirror/autocomplete.mjs @@ -1,6 +1,11 @@ + import jsdoc from '../../doc.json'; import { autocompletion } from '@codemirror/autocomplete'; import { h } from './html'; +import { Scale } from '@tonaljs/tonal'; +import { soundMap } from 'superdough'; + + const escapeHtml = (str) => { const div = document.createElement('div'); @@ -74,6 +79,31 @@ const isValidDoc = (doc) => { const hasExcludedTags = (doc) => ['superdirtOnly', 'noAutocomplete'].some((tag) => doc.tags?.find((t) => t.originalTitle === tag)); + + +export function bankCompletions() { + const soundDict = soundMap.get(); + const banks = new Set(); + for (const key of Object.keys(soundDict)) { + const [bank, suffix] = key.split('_'); + if (suffix && bank) banks.add(bank); + } + return Array.from(banks).sort().map((name) => ({ label: name, type: 'bank' })); +} + +// Placeholder: Replace with actual logic to get live sound names +const soundCompletions = [ + // Example: { label: 'clap', type: 'sound' }, ... +]; + +// Attempt to get all scale names from Tonal +let scaleCompletions = []; +try { + scaleCompletions = (Scale.names ? Scale.names() : []).map((name) => ({ label: name, type: 'scale' })); +} catch (e) { + console.warn('[autocomplete] Could not load scale names from Tonal:', e); +} + const jsdocCompletions = jsdoc.docs .filter((doc) => isValidDoc(doc) && !hasExcludedTags(doc)) // https://codemirror.net/docs/ref/#autocomplete.Completion @@ -85,18 +115,132 @@ const jsdocCompletions = jsdoc.docs })); export const strudelAutocomplete = (context) => { - const word = context.matchBefore(/\w*/); - if (word.from === word.to && !context.explicit) return null; + // --- Pitch names for scale key completion --- + // Ideally, these should be imported from packages/tonal/tonleiter.mjs + // but are duplicated here as they are not exported. + const pitchNames = [ + 'C', 'C#', 'Db', 'D', 'D#', 'Eb', 'E', 'Fb', 'F', 'F#', 'Gb', + 'G', 'G#', 'Ab', 'A', 'A#', 'Bb', 'B', 'Cb' + ]; + + // Block fallback completions inside .scale("..."), even before the colon + let scalePreColonContext = context.matchBefore(/\.scale\(\s*['"][^'"]*$/); + if (scalePreColonContext) { + // Only yield completions if a colon is present (handled below) + if (!scalePreColonContext.text.includes(':')) { + if (context.explicit) { + // Provide pitch completions on explicit request + // (Union of sharps and flats from tonleiter.mjs) + const text = scalePreColonContext.text; + const match = text.match(/([A-Ga-g][#b]*)?$/); + const fragment = match ? match[0] : ''; + const filtered = pitchNames.filter((p) => p.toLowerCase().startsWith(fragment.toLowerCase())); + const from = scalePreColonContext.to - fragment.length; + const options = filtered.map((p) => ({ label: p, type: 'pitch' })); + return { from, options }; + } else { + // Block fallback completions + return { from: scalePreColonContext.to, options: [] }; + } + } - return { - from: word.from, - options: jsdocCompletions, - /* options: [ - { label: 'match', type: 'keyword' }, - { label: 'hello', type: 'variable', info: '(World)' }, - { label: 'magic', type: 'text', apply: '⠁⭒*.✩.*⭒⠁', detail: 'macro' }, - ], */ - }; + // (second block removed, handled above) + if (!scalePreColonContext.text.includes(':')) { + return { from: scalePreColonContext.to, options: [] }; + } + } + + // 1. Check for sound context: s("..."), sound("...") + // Trigger after at least one letter is typed after whitespace or bracket inside the quotes + let soundContext = context.matchBefore(/(s|sound)\(\s*['"][^'"]*$/); + if (soundContext) { + const text = soundContext.text; + const quoteIdx = Math.max(text.lastIndexOf('"'), text.lastIndexOf("'")); + if (quoteIdx === -1) return null; + const inside = text.slice(quoteIdx + 1); + const fragMatch = inside.match(/(?:[\s\[\{\(<])([\w]*)$/); + const fragment = fragMatch ? fragMatch[1] : inside; + if (!fragment || fragment.length === 0) return null; + const soundNames = Object.keys(soundMap.get()).sort(); + const filteredSounds = soundNames.filter((name) => name.startsWith(fragment)); + let options = filteredSounds.map((name) => ({ label: name, type: 'sound' })); + const from = soundContext.to - fragment.length; + return { + from, + options, + }; + } + + let bankMatch = context.matchBefore(/bank\(\s*(['"])?([\w]*)$/); + if (bankMatch) { + let banks = bankCompletions(); + console.log('[autocomplete] Bank context detected:', bankMatch.text); + console.log('[autocomplete] soundMap keys:', Object.keys(soundMap.get())); + console.log('[autocomplete] bankCompletions:', banks); + // Extract quote and fragment using regex groups on match.text + const groups = bankMatch.text.match(/(['"])?([\w]*)$/); + const quote = groups ? groups[1] : undefined; + const fragment = groups ? groups[2] || '' : ''; + let from; + if (quote) { + from = bankMatch.from + bankMatch.text.indexOf(quote) + 1; + } else { + from = bankMatch.to - fragment.length; + } + const filteredBanks = banks.filter((b) => b.label.startsWith(fragment)); + let options; + if (!quote) { + options = filteredBanks.map((b) => ({ ...b, apply: '"' + b.label + '"' })); + } else { + const afterCursor = context.state.sliceDoc(bankMatch.to, bankMatch.to + 1); + options = filteredBanks.map((b) => { + if (afterCursor !== quote) { + return { ...b, apply: b.label + quote }; + } + return b; + }); + } + return { + from, + options, + }; + } + + // 3. Check for scale context: .scale("..."), only after colon + let scaleContext = context.matchBefore(/\.scale\(\s*['"][^'"]*:[^'"]*$/); + if (scaleContext) { + // Find the last colon in the text + const text = scaleContext.text; + const colonIdx = text.lastIndexOf(':'); + if (colonIdx === -1) return null; + // Get the fragment after the colon + const fragment = text.slice(colonIdx + 1); + // Filter scale completions by fragment + const filteredScales = scaleCompletions.filter((s) => s.label.startsWith(fragment)); + // Insert colon-form (replace spaces with colons) for completions + const options = filteredScales.map((s) => ({ + ...s, + apply: s.label.replace(/\s+/g, ':') + })); + const from = scaleContext.from + colonIdx + 1; + return { + from, + options, + }; + } + + // fallback: original logic + const word = context.matchBefore(/\w*/); + if (word && word.from === word.to && !context.explicit) return null; + + if (word) { + console.log('[autocomplete] Default context:', word.text); + return { + from: word.from, + options: jsdocCompletions, + }; + } + return null; }; export const isAutoCompletionEnabled = (enabled) => From 0b67473bd3a7de3df71982b4bdc50d98bc41d3d6 Mon Sep 17 00:00:00 2001 From: drdozer Date: Thu, 11 Sep 2025 18:59:26 +0100 Subject: [PATCH 144/335] refactor: modularize autocomplete context handlers using strategy array --- packages/codemirror/autocomplete.mjs | 68 ++++++++++++++++------------ 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/packages/codemirror/autocomplete.mjs b/packages/codemirror/autocomplete.mjs index c1c7bb14e..591552cc7 100644 --- a/packages/codemirror/autocomplete.mjs +++ b/packages/codemirror/autocomplete.mjs @@ -114,23 +114,18 @@ const jsdocCompletions = jsdoc.docs type: 'function', // https://codemirror.net/docs/ref/#autocomplete.Completion.type })); -export const strudelAutocomplete = (context) => { - // --- Pitch names for scale key completion --- - // Ideally, these should be imported from packages/tonal/tonleiter.mjs - // but are duplicated here as they are not exported. - const pitchNames = [ - 'C', 'C#', 'Db', 'D', 'D#', 'Eb', 'E', 'Fb', 'F', 'F#', 'Gb', - 'G', 'G#', 'Ab', 'A', 'A#', 'Bb', 'B', 'Cb' - ]; - - // Block fallback completions inside .scale("..."), even before the colon + +// --- Handler functions for each context --- +const pitchNames = [ + 'C', 'C#', 'Db', 'D', 'D#', 'Eb', 'E', 'Fb', 'F', 'F#', 'Gb', + 'G', 'G#', 'Ab', 'A', 'A#', 'Bb', 'B', 'Cb' +]; + +function scalePreColonHandler(context) { let scalePreColonContext = context.matchBefore(/\.scale\(\s*['"][^'"]*$/); if (scalePreColonContext) { - // Only yield completions if a colon is present (handled below) if (!scalePreColonContext.text.includes(':')) { if (context.explicit) { - // Provide pitch completions on explicit request - // (Union of sharps and flats from tonleiter.mjs) const text = scalePreColonContext.text; const match = text.match(/([A-Ga-g][#b]*)?$/); const fragment = match ? match[0] : ''; @@ -139,19 +134,17 @@ export const strudelAutocomplete = (context) => { const options = filtered.map((p) => ({ label: p, type: 'pitch' })); return { from, options }; } else { - // Block fallback completions return { from: scalePreColonContext.to, options: [] }; } } - - // (second block removed, handled above) if (!scalePreColonContext.text.includes(':')) { return { from: scalePreColonContext.to, options: [] }; } } - - // 1. Check for sound context: s("..."), sound("...") - // Trigger after at least one letter is typed after whitespace or bracket inside the quotes + return null; +} + +function soundHandler(context) { let soundContext = context.matchBefore(/(s|sound)\(\s*['"][^'"]*$/); if (soundContext) { const text = soundContext.text; @@ -170,13 +163,13 @@ export const strudelAutocomplete = (context) => { options, }; } + return null; +} +function bankHandler(context) { let bankMatch = context.matchBefore(/bank\(\s*(['"])?([\w]*)$/); if (bankMatch) { let banks = bankCompletions(); - console.log('[autocomplete] Bank context detected:', bankMatch.text); - console.log('[autocomplete] soundMap keys:', Object.keys(soundMap.get())); - console.log('[autocomplete] bankCompletions:', banks); // Extract quote and fragment using regex groups on match.text const groups = bankMatch.text.match(/(['"])?([\w]*)$/); const quote = groups ? groups[1] : undefined; @@ -205,19 +198,17 @@ export const strudelAutocomplete = (context) => { options, }; } + return null; +} - // 3. Check for scale context: .scale("..."), only after colon +function scaleAfterColonHandler(context) { let scaleContext = context.matchBefore(/\.scale\(\s*['"][^'"]*:[^'"]*$/); if (scaleContext) { - // Find the last colon in the text const text = scaleContext.text; const colonIdx = text.lastIndexOf(':'); if (colonIdx === -1) return null; - // Get the fragment after the colon const fragment = text.slice(colonIdx + 1); - // Filter scale completions by fragment const filteredScales = scaleCompletions.filter((s) => s.label.startsWith(fragment)); - // Insert colon-form (replace spaces with colons) for completions const options = filteredScales.map((s) => ({ ...s, apply: s.label.replace(/\s+/g, ':') @@ -228,19 +219,36 @@ export const strudelAutocomplete = (context) => { options, }; } + return null; +} - // fallback: original logic +function fallbackHandler(context) { const word = context.matchBefore(/\w*/); if (word && word.from === word.to && !context.explicit) return null; - if (word) { - console.log('[autocomplete] Default context:', word.text); return { from: word.from, options: jsdocCompletions, }; } return null; +} + +const handlers = [ + scalePreColonHandler, + soundHandler, + bankHandler, + scaleAfterColonHandler, + // this handler *must* be last + fallbackHandler +]; + +export const strudelAutocomplete = (context) => { + for (const handler of handlers) { + const result = handler(context); + if (result) return result; + } + return null; }; export const isAutoCompletionEnabled = (enabled) => From 6b6d4b86a6a09d24484013a2f23b38f7269d1436 Mon Sep 17 00:00:00 2001 From: drdozer Date: Thu, 11 Sep 2025 18:59:50 +0100 Subject: [PATCH 145/335] refactor: modularize autocomplete context handlers using strategy array From 90614612e24673bab8ea0dd4eef00381c47c1a10 Mon Sep 17 00:00:00 2001 From: drdozer Date: Thu, 11 Sep 2025 19:00:05 +0100 Subject: [PATCH 146/335] feat: add E# and B# to pitchNames for complete enharmonic coverage --- packages/codemirror/autocomplete.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/codemirror/autocomplete.mjs b/packages/codemirror/autocomplete.mjs index 591552cc7..5d6c7233d 100644 --- a/packages/codemirror/autocomplete.mjs +++ b/packages/codemirror/autocomplete.mjs @@ -117,8 +117,8 @@ const jsdocCompletions = jsdoc.docs // --- Handler functions for each context --- const pitchNames = [ - 'C', 'C#', 'Db', 'D', 'D#', 'Eb', 'E', 'Fb', 'F', 'F#', 'Gb', - 'G', 'G#', 'Ab', 'A', 'A#', 'Bb', 'B', 'Cb' + 'C', 'C#', 'Db', 'D', 'D#', 'Eb', 'E', 'E#', 'Fb', 'F', 'F#', 'Gb', + 'G', 'G#', 'Ab', 'A', 'A#', 'Bb', 'B', 'B#', 'Cb' ]; function scalePreColonHandler(context) { From ed182d4b3f2e118d4d56df2a141b6200043020dd Mon Sep 17 00:00:00 2001 From: drdozer Date: Thu, 11 Sep 2025 19:01:22 +0100 Subject: [PATCH 147/335] Updated the codemirror packages to be able to access additional imports. --- packages/codemirror/package.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/codemirror/package.json b/packages/codemirror/package.json index 803b33f3d..bb1059f11 100644 --- a/packages/codemirror/package.json +++ b/packages/codemirror/package.json @@ -47,6 +47,8 @@ "@strudel/core": "workspace:*", "@strudel/draw": "workspace:*", "@strudel/transpiler": "workspace:*", + "@tonaljs/tonal": "^4.10.0", + "superdough": "workspace:*", "nanostores": "^0.11.3" }, "devDependencies": { From cd659ac2a1eeccfc65ccd82d8a8c5a51129404c2 Mon Sep 17 00:00:00 2001 From: drdozer Date: Thu, 11 Sep 2025 21:37:35 +0100 Subject: [PATCH 148/335] feat: sound autocomplete matches anywhere in name using includes() --- packages/codemirror/autocomplete.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/codemirror/autocomplete.mjs b/packages/codemirror/autocomplete.mjs index 5d6c7233d..110a9165a 100644 --- a/packages/codemirror/autocomplete.mjs +++ b/packages/codemirror/autocomplete.mjs @@ -155,7 +155,7 @@ function soundHandler(context) { const fragment = fragMatch ? fragMatch[1] : inside; if (!fragment || fragment.length === 0) return null; const soundNames = Object.keys(soundMap.get()).sort(); - const filteredSounds = soundNames.filter((name) => name.startsWith(fragment)); + const filteredSounds = soundNames.filter((name) => name.includes(fragment)); let options = filteredSounds.map((name) => ({ label: name, type: 'sound' })); const from = soundContext.to - fragment.length; return { From 39460eb1005529dbc2d81d2eec92c92cb0a9b364 Mon Sep 17 00:00:00 2001 From: drdozer Date: Fri, 12 Sep 2025 12:11:36 +0100 Subject: [PATCH 149/335] Commiting lockfile. --- pnpm-lock.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c225057f3..d67f42d28 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -215,9 +215,15 @@ importers: '@strudel/transpiler': specifier: workspace:* version: link:../transpiler + '@tonaljs/tonal': + specifier: ^4.10.0 + version: 4.10.0 nanostores: specifier: ^0.11.3 version: 0.11.3 + superdough: + specifier: workspace:* + version: link:../superdough devDependencies: vite: specifier: ^6.0.11 From 1670aebad80a5dc398317e0f70d5a20b37d27049 Mon Sep 17 00:00:00 2001 From: drdozer Date: Sat, 13 Sep 2025 21:35:28 +0100 Subject: [PATCH 150/335] Updated the gitignore rules for vscode. --- .gitignore | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.gitignore b/.gitignore index 2be3ee698..7532adaf0 100644 --- a/.gitignore +++ b/.gitignore @@ -45,6 +45,20 @@ tidal-drum-machines webaudiofontdata src-tauri/target + + +### BEGIN Visual Studio Code ### +# Blanket, recursive exclude for .vscode directory and files +.vscode/**/* +# Unexclude specific files and directories within .vscode +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +### END Visual Studio Code ### + + + # BEGIN JetBrains -> END JetBrains # for JetBrains IDE users, e.g. WebStorm. Source: https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore From 709b654ed39927f1c5f5ea8ae7bbde54f22e0f11 Mon Sep 17 00:00:00 2001 From: Aria Date: Sat, 13 Sep 2025 16:21:09 -0500 Subject: [PATCH 151/335] Add synonyms to autocomplete --- packages/codemirror/autocomplete.mjs | 26 ++++++++++++++++--- packages/codemirror/tooltip.mjs | 9 ++++--- packages/core/pattern.mjs | 12 +++++---- website/src/repl/Repl.css | 7 +++++ .../src/repl/components/panel/Reference.jsx | 3 +-- 5 files changed, 42 insertions(+), 15 deletions(-) diff --git a/packages/codemirror/autocomplete.mjs b/packages/codemirror/autocomplete.mjs index b56cab826..69aa3bc59 100644 --- a/packages/codemirror/autocomplete.mjs +++ b/packages/codemirror/autocomplete.mjs @@ -54,11 +54,12 @@ const buildExamples = (examples) => ` : ''; -export const Autocomplete = ({ doc, label }) => +export const Autocomplete = (doc) => h`
-

${label || getDocLabel(doc)}

+

${getDocLabel(doc)}

+ ${doc.synonyms_text ? `
Synonyms: ${doc.synonyms_text}
` : ''} ${doc.description ? `
${doc.description}
` : ''} ${buildParamsList(doc.params)} ${buildExamples(doc.examples)} @@ -74,19 +75,36 @@ const isValidDoc = (doc) => { const hasExcludedTags = (doc) => ['superdirtOnly', 'noAutocomplete'].some((tag) => doc.tags?.find((t) => t.originalTitle === tag)); +export const getSynonymDoc = (doc, synonym) => { + const synonyms = doc.synonyms || []; + const docLabel = getDocLabel(doc); + // Swap `doc.name` in for `s` in the list of synonyms + const synonymsWithDoc = [docLabel, ...synonyms].filter((x) => x && x !== synonym); + return { + ...doc, + name: synonym, + longname: synonym, + synonyms: synonymsWithDoc, + synonyms_text: synonymsWithDoc.join(', '), + }; +}; + const jsdocCompletions = (() => { const seen = new Set(); // avoid repetition const completions = []; for (const doc of jsdoc.docs) { if (!isValidDoc(doc) || hasExcludedTags(doc)) continue; - let labels = [getDocLabel(doc), ...(doc.synonyms || [])]; + const docLabel = getDocLabel(doc); + // Remove duplicates + const synonyms = doc.synonyms || []; + let labels = [docLabel, ...synonyms]; for (const label of labels) { // https://codemirror.net/docs/ref/#autocomplete.Completion if (label && !seen.has(label)) { seen.add(label); completions.push({ label, - info: () => Autocomplete({ doc, label }), + info: () => Autocomplete(getSynonymDoc(doc, label)), type: 'function', // https://codemirror.net/docs/ref/#autocomplete.Completion.type }); } diff --git a/packages/codemirror/tooltip.mjs b/packages/codemirror/tooltip.mjs index f67e6d14a..d1d0479b2 100644 --- a/packages/codemirror/tooltip.mjs +++ b/packages/codemirror/tooltip.mjs @@ -1,6 +1,6 @@ import { hoverTooltip } from '@codemirror/view'; import jsdoc from '../../doc.json'; -import { Autocomplete } from './autocomplete.mjs'; +import { Autocomplete, getSynonymDoc } from './autocomplete.mjs'; const getDocLabel = (doc) => doc.name || doc.longname; @@ -52,10 +52,11 @@ export const strudelTooltip = hoverTooltip( let entry = jsdoc.docs.filter((doc) => getDocLabel(doc) === word)[0]; if (!entry) { // Try for synonyms - entry = jsdoc.docs.filter((doc) => doc.synonyms && doc.synonyms.includes(word))[0]; - if (!entry) { + const doc = jsdoc.docs.filter((doc) => doc.synonyms && doc.synonyms.includes(word))[0]; + if (!doc) { return null; } + entry = getSynonymDoc(doc, word); } return { @@ -66,7 +67,7 @@ export const strudelTooltip = hoverTooltip( create(view) { let dom = document.createElement('div'); dom.className = 'strudel-tooltip'; - const ac = Autocomplete({ doc: entry, label: word }); + const ac = Autocomplete(entry); dom.appendChild(ac); return { dom }; }, diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index addc301d5..39790f8a0 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -1246,7 +1246,8 @@ export const silence = gap(1); /* Like silence, but with a 'steps' (relative duration) of 0 */ export const nothing = gap(0); -/** A discrete value that repeats once per cycle. +/** + * A discrete value that repeats once per cycle. * * @returns {Pattern} * @example @@ -1299,7 +1300,8 @@ export function sequenceP(pats) { return result; } -/** The given items are played at the same time at the same length. +/** + * The given items are played at the same time at the same length. * * @return {Pattern} * @synonyms polyrhythm, pr @@ -1382,11 +1384,11 @@ export function stackBy(by, ...pats) { .setSteps(steps); } -/** Concatenation: combines a list of patterns, switching between them successively, one per cycle: - * - * synonyms: `cat` +/** + * Concatenation: combines a list of patterns, switching between them successively, one per cycle. * * @return {Pattern} + * @synonyms cat * @example * slowcat("e5", "b4", ["d5", "c5"]) * diff --git a/website/src/repl/Repl.css b/website/src/repl/Repl.css index 498679090..9cf51ff85 100644 --- a/website/src/repl/Repl.css +++ b/website/src/repl/Repl.css @@ -112,6 +112,13 @@ margin: 0 0 8px 0; } +.autocomplete-info-function-synonyms { + margin: 0 0 12px 0; + color: var(--foreground); + line-height: 1.5; + opacity: 0.8; +} + .autocomplete-info-function-description { margin: 0 0 12px 0; color: var(--foreground); diff --git a/website/src/repl/components/panel/Reference.jsx b/website/src/repl/components/panel/Reference.jsx index 81826aca2..6007667fa 100644 --- a/website/src/repl/components/panel/Reference.jsx +++ b/website/src/repl/components/panel/Reference.jsx @@ -16,8 +16,7 @@ const availableFunctions = (() => { if (!s || seen.has(s)) continue; seen.add(s); // Swap `doc.name` in for `s` in the list of synonyms - const notS = synonyms.filter((x) => x && x !== s); - const synonymsWithDoc = Array.from(new Set([doc.name, ...notS])); + const synonymsWithDoc = [doc.name, ...synonyms].filter((x) => x && x !== s); functions.push({ ...doc, name: s, // update names for the synonym From a9f7d825c8456641b46451e48411d479d4b3e938 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 14 Sep 2025 00:40:54 +0200 Subject: [PATCH 152/335] hotfix: format --- website/src/pages/learn/xen.mdx | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/website/src/pages/learn/xen.mdx b/website/src/pages/learn/xen.mdx index 32e2c0b43..b8b27ac7f 100644 --- a/website/src/pages/learn/xen.mdx +++ b/website/src/pages/learn/xen.mdx @@ -16,10 +16,7 @@ These functions allow the use of scales other than your typical chromatic 12 bas Here's an example of how to configure a basic hexany scale: - + Try other scales like `hexany1`, `iraq`, `gumbeng`, `gunkali`, or `tranh3` @@ -67,6 +64,7 @@ Another helpful trick when exploring new tunings is to strum them. Many have a much more enchanting sound that was chosen over many generations of musicians for being strummed. Take the `sanza` tuning: + + This quality is often due to how the tunings were formed with instruments that were played differently than a piano. As such, some tunings are much better strummed, with the subtle clash of the detuned notes actually making the sound much more magical: From 2d2b238da9a3246a5af994584fc585a74890213c Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 14 Sep 2025 01:03:14 +0200 Subject: [PATCH 153/335] fix: use template element for string to html --- packages/codemirror/html.mjs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/codemirror/html.mjs b/packages/codemirror/html.mjs index 527275ef6..f240059d3 100644 --- a/packages/codemirror/html.mjs +++ b/packages/codemirror/html.mjs @@ -1,6 +1,7 @@ -const parser = typeof DOMParser !== 'undefined' ? new DOMParser() : null; export let html = (string) => { - return parser?.parseFromString(string, 'text/html').querySelectorAll('*'); + const template = document.createElement('template'); + template.innerHTML = string.trim(); + return template.content.childNodes; }; let parseChunk = (chunk) => { if (Array.isArray(chunk)) return chunk.flat().join(''); From 9782795761648595fc05deacf863a7bf1a0348ab Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 14 Sep 2025 01:04:48 +0200 Subject: [PATCH 154/335] fix: autocomplete container style --- website/src/repl/Repl.css | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/website/src/repl/Repl.css b/website/src/repl/Repl.css index 9cf51ff85..b5cd34d81 100644 --- a/website/src/repl/Repl.css +++ b/website/src/repl/Repl.css @@ -80,6 +80,8 @@ min-width: 300px !important; max-height: 400px !important; background-color: var(--lineHighlight) !important; + overflow: auto; + background: var(--background) !important; } /* Main tooltip container */ @@ -91,7 +93,7 @@ font-size: var(--font-size, 13px); line-height: 1.4; max-width: 600px; - max-height: 400px; + height: 100%; min-width: 400px; white-space: normal !important; overflow-y: auto !important; From d6254294b087af1008efc1943a110a36cc2afdb3 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 14 Sep 2025 01:09:30 +0200 Subject: [PATCH 155/335] fix: bring back tests on external PRs (push doesn't cut it for forks) --- .forgejo/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.forgejo/workflows/test.yml b/.forgejo/workflows/test.yml index 90cb7e258..6b3759571 100644 --- a/.forgejo/workflows/test.yml +++ b/.forgejo/workflows/test.yml @@ -1,6 +1,6 @@ name: Strudel tests -on: [push] +on: [push, pull_request] jobs: build: @@ -19,7 +19,7 @@ jobs: - uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - cache: 'pnpm' + cache: "pnpm" - run: pnpm install - run: pnpm run format-check - run: pnpm run lint From 9da027d377e278b5b2bb173139c03dc2de7b72f8 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 14 Sep 2025 01:11:34 +0200 Subject: [PATCH 156/335] hotfix: format --- website/src/pages/workshop/first-sounds.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/pages/workshop/first-sounds.mdx b/website/src/pages/workshop/first-sounds.mdx index f120f332a..1d659972b 100644 --- a/website/src/pages/workshop/first-sounds.mdx +++ b/website/src/pages/workshop/first-sounds.mdx @@ -260,7 +260,7 @@ It is quite common that there are many ways to express the same idea. punchcard /> -**selecting sample numbers separately** +**selecting sample numbers separately** Instead of selecting sample numbers one by one: From f5c4373f996c5e8a699b4c850baa310d16666021 Mon Sep 17 00:00:00 2001 From: Dsm0 Date: Sat, 13 Sep 2025 17:21:19 -0700 Subject: [PATCH 157/335] added plyWith/plyWithClassic functions --- packages/core/pattern.mjs | 50 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index 39790f8a0..a88a1eaea 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -2399,6 +2399,56 @@ export const stut = register('stut', function (times, feedback, time, pat) { return pat._echoWith(times, time, (pat, i) => pat.gain(Math.pow(feedback, i))); }); +export const applyN = register('applyN', function (n, func, p) { + let result = p; + for (let i = 0; i < n; i++) { + result = func(result); + } + return result; +}); + +/** + * The plyWithClassic function repeats each event the given number of times, applying the given function to each event.\n + * Here the function does not take the iteration index as an argument. + * @name plyWithClassic + * @param {number} factor how many times to repeat + * @param {function} func function to apply, given the pattern + * @example + * "<0 [2 4]>" + * .plyWith(4, (p) => p.add(2)) + * .scale("C:minor").note() + */ +export const plyWithClassic = register('plyWithClassic', function (factor, func, pat) { + const result = pat + .fmap((x) => cat(...listRange(0, factor - 1).map((i) => applyN(i, func, x)))._fast(factor)) + .squeezeJoin(); + if (__steps) { + result._steps = Fraction(factor).mulmaybe(pat._steps); + } + return result; +}); + +/** + * The plyWith function repeats each event the given number of times, applying the given function to each event. + * @name plyWith + * @synonyms plywith + * @param {number} factor how many times to repeat + * @param {function} func function to apply, given the pattern and the iteration index + * @example + * "<0 [2 4]>" + * .plyWith(4, (p,n) => p.add(n*2)) + * .scale("C:minor").note() + */ +export const plyWith = register(['plyWith', 'plywith'], function (factor, func, pat) { + const result = pat + .fmap((x) => cat(cat(pure(x), ...listRange(1, factor - 1).map((i) => func(pure(x), i))))._fast(factor)) + .squeezeJoin(); + if (__steps) { + result._steps = Fraction(factor).mulmaybe(pat._steps); + } + return result; +}); + /** * Divides a pattern into a given number of subdivisions, plays the subdivisions in order, but increments the starting subdivision each cycle. The pattern wraps to the first subdivision after the last subdivision is played. * @name iter From addb6db1c76ed9de1246c8f3f617f6d8220d0892 Mon Sep 17 00:00:00 2001 From: Dsm0 Date: Sun, 14 Sep 2025 02:21:25 -0700 Subject: [PATCH 158/335] updated names + snapshot --- packages/core/pattern.mjs | 19 ++++---- test/__snapshots__/examples.test.mjs.snap | 58 +++++++++++++++++++++++ 2 files changed, 68 insertions(+), 9 deletions(-) diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index a88a1eaea..262b92bb3 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -2408,9 +2408,9 @@ export const applyN = register('applyN', function (n, func, p) { }); /** - * The plyWithClassic function repeats each event the given number of times, applying the given function to each event.\n - * Here the function does not take the iteration index as an argument. - * @name plyWithClassic + * The plyWith function repeats each event the given number of times, applying the given function to each event.\n + * @name plyWith + * @synonyms plywith * @param {number} factor how many times to repeat * @param {function} func function to apply, given the pattern * @example @@ -2418,7 +2418,7 @@ export const applyN = register('applyN', function (n, func, p) { * .plyWith(4, (p) => p.add(2)) * .scale("C:minor").note() */ -export const plyWithClassic = register('plyWithClassic', function (factor, func, pat) { +export const plyWith = register(['plyWith', 'plywith'], function (factor, func, pat) { const result = pat .fmap((x) => cat(...listRange(0, factor - 1).map((i) => applyN(i, func, x)))._fast(factor)) .squeezeJoin(); @@ -2429,17 +2429,18 @@ export const plyWithClassic = register('plyWithClassic', function (factor, func, }); /** - * The plyWith function repeats each event the given number of times, applying the given function to each event. - * @name plyWith - * @synonyms plywith + * The plyForEach function repeats each event the given number of times, applying the given function to each event. + * This version of ply uses the iteration index as an argument to the function, similar to echoWith. + * @name plyForEach + * @synonyms plyforeach * @param {number} factor how many times to repeat * @param {function} func function to apply, given the pattern and the iteration index * @example * "<0 [2 4]>" - * .plyWith(4, (p,n) => p.add(n*2)) + * .plyForEach(4, (p,n) => p.add(n*2)) * .scale("C:minor").note() */ -export const plyWith = register(['plyWith', 'plywith'], function (factor, func, pat) { +export const plyForEach = register(['plyForEach', 'plyforeach'], function (factor, func, pat) { const result = pat .fmap((x) => cat(cat(pure(x), ...listRange(1, factor - 1).map((i) => func(pure(x), i))))._fast(factor)) .squeezeJoin(); diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index ecbc33eac..46359b620 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -7365,6 +7365,64 @@ exports[`runs examples > example "ply" example index 0 1`] = ` ] `; +exports[`runs examples > example "plyForEach" example index 0 1`] = ` +[ + "[ 0/1 → 1/4 | note:C3 ]", + "[ 1/4 → 1/2 | note:Eb3 ]", + "[ 1/2 → 3/4 | note:G3 ]", + "[ 3/4 → 1/1 | note:Bb3 ]", + "[ 1/1 → 9/8 | note:Eb3 ]", + "[ 9/8 → 5/4 | note:G3 ]", + "[ 5/4 → 11/8 | note:Bb3 ]", + "[ 11/8 → 3/2 | note:D4 ]", + "[ 3/2 → 13/8 | note:G3 ]", + "[ 13/8 → 7/4 | note:Bb3 ]", + "[ 7/4 → 15/8 | note:D4 ]", + "[ 15/8 → 2/1 | note:F4 ]", + "[ 2/1 → 9/4 | note:C3 ]", + "[ 9/4 → 5/2 | note:Eb3 ]", + "[ 5/2 → 11/4 | note:G3 ]", + "[ 11/4 → 3/1 | note:Bb3 ]", + "[ 3/1 → 25/8 | note:Eb3 ]", + "[ 25/8 → 13/4 | note:G3 ]", + "[ 13/4 → 27/8 | note:Bb3 ]", + "[ 27/8 → 7/2 | note:D4 ]", + "[ 7/2 → 29/8 | note:G3 ]", + "[ 29/8 → 15/4 | note:Bb3 ]", + "[ 15/4 → 31/8 | note:D4 ]", + "[ 31/8 → 4/1 | note:F4 ]", +] +`; + +exports[`runs examples > example "plyWith" example index 0 1`] = ` +[ + "[ 0/1 → 1/4 | note:C3 ]", + "[ 1/4 → 1/2 | note:Eb3 ]", + "[ 1/2 → 3/4 | note:G3 ]", + "[ 3/4 → 1/1 | note:Bb3 ]", + "[ 1/1 → 9/8 | note:Eb3 ]", + "[ 9/8 → 5/4 | note:G3 ]", + "[ 5/4 → 11/8 | note:Bb3 ]", + "[ 11/8 → 3/2 | note:D4 ]", + "[ 3/2 → 13/8 | note:G3 ]", + "[ 13/8 → 7/4 | note:Bb3 ]", + "[ 7/4 → 15/8 | note:D4 ]", + "[ 15/8 → 2/1 | note:F4 ]", + "[ 2/1 → 9/4 | note:C3 ]", + "[ 9/4 → 5/2 | note:Eb3 ]", + "[ 5/2 → 11/4 | note:G3 ]", + "[ 11/4 → 3/1 | note:Bb3 ]", + "[ 3/1 → 25/8 | note:Eb3 ]", + "[ 25/8 → 13/4 | note:G3 ]", + "[ 13/4 → 27/8 | note:Bb3 ]", + "[ 27/8 → 7/2 | note:D4 ]", + "[ 7/2 → 29/8 | note:G3 ]", + "[ 29/8 → 15/4 | note:Bb3 ]", + "[ 15/4 → 31/8 | note:D4 ]", + "[ 31/8 → 4/1 | note:F4 ]", +] +`; + exports[`runs examples > example "polymeter" example index 0 1`] = ` [ "[ 0/1 → 1/6 | note:c ]", From df1934f87b41e722fb8567ee051902b95e31b2b9 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 14 Sep 2025 23:54:51 +0200 Subject: [PATCH 159/335] add some typechecking + fix delay --- packages/supradough/dough.mjs | 190 +++++++++++++++++++++++++++++----- 1 file changed, 165 insertions(+), 25 deletions(-) diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index 711922b63..1cb9241ad 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -1,4 +1,6 @@ // this is dough, the superdough without dependencies +// @ts-check +// @ts-ignore ignore next line because sampleRate is unknown const SAMPLE_RATE = typeof sampleRate !== 'undefined' ? sampleRate : 48000; const PI_DIV_SR = Math.PI / SAMPLE_RATE; const ISR = 1 / SAMPLE_RATE; @@ -641,8 +643,8 @@ const note2midi = (note, defaultOctave = 3) => { } const chroma = chromas[pc.toLowerCase()]; const offset = acc?.split('').reduce((o, char) => o + accs[char], 0) || 0; - oct = Number(oct || defaultOctave); - return (oct + 1) * 12 + chroma + offset; + const octave = Number(oct || defaultOctave); + return (octave + 1) * 12 + chroma + offset; }; const midi2freq = (midi) => Math.pow(2, (midi - 69) / 12) * 440; const note2freq = (note) => { @@ -654,9 +656,152 @@ const note2freq = (note) => { }; export class DoughVoice { + /** @type {number} */ + id = 0; + /** @type {number[]} */ out = [0, 0]; + + /** @type {number | undefined} */ + attack; + /** @type {number | undefined} */ + decay; + /** @type {number | undefined} */ + sustain; + /** @type {number} */ + release; + /** @type {number} */ + _begin; + /** @type {number} */ + _duration; + + /** @type {any} */ + _sound; + /** @type {number} */ + _channels = 1; + /** @type {BufferPlayer[] | undefined} */ + _buffers; + /** @type {string | undefined} */ + unit; + + /** @type {ADSR | undefined} */ + _penv; + /** @type {number | undefined} */ + penv; + /** @type {number | undefined} */ + pattack; + /** @type {number | undefined} */ + pdecay; + /** @type {number | undefined} */ + psustain; + /** @type {number | undefined} */ + prelease; + + /** @type {number | undefined} */ + vib; + + _vib; + /** @type {number | undefined} */ + vibmod; + + /** @type {SineOsc | undefined} */ + _fm; + /** @type {number | undefined} */ + fmh; + /** @type {number | undefined} */ + fmi; + + /** @type {ADSR | undefined} */ + _fmenv; + /** @type {number | undefined} */ + fmattack; + /** @type {number | undefined} */ + fmdecay; + /** @type {number | undefined} */ + fmsustain; + /** @type {number | undefined} */ + fmrelease; + + /** @type {ADSR | undefined} */ + _lpenv; + lpenv; + /** @type {number | undefined} */ + lpattack; + /** @type {number | undefined} */ + lpdecay; + /** @type {number | undefined} */ + lpsustain; + /** @type {number | undefined} */ + lprelease; + + /** @type {ADSR | undefined} */ + _hpenv; + /** @type {number | undefined} */ + hpenv; + /** @type {number | undefined} */ + hpattack; + /** @type {number | undefined} */ + hpdecay; + /** @type {number | undefined} */ + hpsustain; + /** @type {number | undefined} */ + hprelease; + + /** @type {ADSR | undefined} */ + _bpenv; + /** @type {number | undefined} */ + bpenv; + /** @type {number | undefined} */ + bpattack; + /** @type {number | undefined} */ + bpdecay; + /** @type {number | undefined} */ + bpsustain; + /** @type {number | undefined} */ + bprelease; + + /** @type {number | undefined} */ + cutoff; + /** @type {number | undefined} */ + hcutoff; + /** @type {number | undefined} */ + bandf; + /** @type {number | undefined} */ + coarse; + /** @type {number | undefined} */ + crush; + /** @type {number | undefined} */ + distort; + + /** @type {number} */ + freq; + /** @type {string | undefined} */ + note; + + /** @type {TwoPoleFilter[] | null | undefined} */ + _lpf; + /** @type {TwoPoleFilter[] | null | undefined} */ + _hpf; + /** @type {TwoPoleFilter[] | null | undefined} */ + _bpf; + /** @type {Chorus[] | null | undefined} */ + _chorus; + /** @type {Coarse[] | null | undefined} */ + _coarse; + /** @type {Crush[] | null | undefined} */ + _crush; + /** @type {Distort[] | null | undefined} */ + _distort; + + /** + * @param {DoughVoice} value + */ constructor(value) { - value.freq ??= note2freq(value.note); + // mandatory controls + this.freq ??= note2freq(value.note); + this._begin = value._begin; + this._duration = value._duration; + this.release = value.release ?? 0; + // the rest.. we use $ for readability let $ = this; Object.assign($, value); $.s = $.s ?? getDefaultValue('s'); @@ -773,7 +918,7 @@ export class DoughVoice { let freq = this.freq * this.speed; // frequency modulation - if (this._fm) { + if (this._fm && this.fmh !== undefined && this.fmi !== undefined) { let fmi = this.fmi; if (this._fmenv) { const env = this._fmenv.update(t, gate, this.fmattack, this.fmdecay, this.fmsustain, this.fmrelease); @@ -785,37 +930,31 @@ export class DoughVoice { } // vibrato - if (this._vib) { + if (this._vib && this.vibmod !== undefined) { freq = freq * 2 ** ((this._vib.update(this.vib) * this.vibmod) / 12); } // pitch envelope - if (this._penv) { + if (this._penv && this.penv !== undefined) { const env = this._penv.update(t, gate, this.pattack, this.pdecay, this.psustain, this.prelease); freq = freq + env * this.penv; } // filters let lpf = this.cutoff; - if (this._lpf) { - if (this._lpenv) { - const env = this._lpenv.update(t, gate, this.lpattack, this.lpdecay, this.lpsustain, this.lprelease); - lpf = this.lpenv * env * lpf + lpf; - } + if (lpf !== undefined && this._lpenv) { + const env = this._lpenv.update(t, gate, this.lpattack, this.lpdecay, this.lpsustain, this.lprelease); + lpf = this.lpenv * env * lpf + lpf; } let hpf = this.hcutoff; - if (this._hpf) { - if (this._hpenv) { - const env = this._hpenv.update(t, gate, this.hpattack, this.hpdecay, this.hpsustain, this.hprelease); - hpf = 2 ** this.hpenv * env * hpf + hpf; - } + if (hpf !== undefined && this._hpenv && this.hpenv !== undefined) { + const env = this._hpenv.update(t, gate, this.hpattack, this.hpdecay, this.hpsustain, this.hprelease); + hpf = 2 ** this.hpenv * env * hpf + hpf; } let bpf = this.bandf; - if (this._bpf) { - if (this._bpenv) { - const env = this._bpenv.update(t, gate, this.bpattack, this.bpdecay, this.bpsustain, this.bprelease); - bpf = 2 ** this.bpenv * env * bpf + bpf; - } + if (bpf !== undefined && this._bpenv && this.bpenv !== undefined) { + const env = this._bpenv.update(t, gate, this.bpattack, this.bpdecay, this.bpsustain, this.bprelease); + bpf = 2 ** this.bpenv * env * bpf + bpf; } // gain envelope const env = this._adsr.update(t, gate, this.attack, this.decay, this.sustain, this.release); @@ -891,8 +1030,8 @@ export class Dough { this.sampleRate = sampleRate; this.t = Math.floor(currentTime * sampleRate); // samples // console.log('init dough', this.sampleRate, this.t); - this._delayL = new PitchDelay(); - this._delayR = new PitchDelay(); + this._delayL = new Delay(); + this._delayR = new Delay(); } loadSample(name, channels, sampleRate) { BufferPlayer.samples.set(name, { channels, sampleRate }); @@ -965,8 +1104,9 @@ export class Dough { } } // todo: how to change delaytime / delayfeedback from a voice? - const delayL = this._delayL.update(this.delaysend[0], this.delaytime, this.delayspeed); - const delayR = this._delayR.update(this.delaysend[1], this.delaytime, this.delayspeed); + const delayL = this._delayL.update(this.delaysend[0], this.delaytime); + const delayR = this._delayR.update(this.delaysend[1], this.delaytime); + this.delaysend[0] = delayL * this.delayfeedback; this.delaysend[1] = delayR * this.delayfeedback; this.out[0] += delayL; From 92b2013cf6efa9f29372060ab6a052081633cb23 Mon Sep 17 00:00:00 2001 From: Aria Date: Sun, 14 Sep 2025 17:04:39 -0500 Subject: [PATCH 160/335] Correctly handle silences for non-notes --- packages/tonal/test/tonal.test.mjs | 2 +- packages/tonal/tonal.mjs | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/tonal/test/tonal.test.mjs b/packages/tonal/test/tonal.test.mjs index cb856fa99..5f61b05a9 100644 --- a/packages/tonal/test/tonal.test.mjs +++ b/packages/tonal/test/tonal.test.mjs @@ -66,7 +66,7 @@ describe('tonal', () => { n(seq('0b#', '1#b', '2#b#')) .scale('C major') .firstCycleValues.map((h) => h.note), - ).toEqual(['', '', '']); + ).toEqual([]); }); it('snaps notes (upwards) to scale', () => { const inputNotes = ['Cb', 'Eb', 'G', 'A#', 'Bb']; diff --git a/packages/tonal/tonal.mjs b/packages/tonal/tonal.mjs index 4f189e3d6..ae75ab690 100644 --- a/packages/tonal/tonal.mjs +++ b/packages/tonal/tonal.mjs @@ -189,8 +189,7 @@ function _convertStepToNumberAndOffset(step) { const match = /^(-?\d+)(#+|b+)?$/.exec(step); if (!match) { - logger(`[tonal] invalid scale step "${step}", expected number or integer with optional # b suffixes`, 'error'); - return [silence, 0]; + throw new Error(`invalid scale step "${step}", expected number or integer with optional # b suffixes`); } asNumber = Number(match[1]); // These decorations will determine the semitone offset based on the number of @@ -275,8 +274,8 @@ export const scale = register( // legacy.. return pure(step); } - const [number, offset] = _convertStepToNumberAndOffset(step); try { + const [number, offset] = _convertStepToNumberAndOffset(step); let note; if (isObject && value.anchor) { note = stepInNamedScale(number, scale, value.anchor); @@ -287,7 +286,7 @@ export const scale = register( value = pure(isObject ? { ...value, note } : note); } catch (err) { logger(`[tonal] ${err.message}`, 'error'); - value = silence; + return silence; } return value; } From c8875b29c1ca1ff55d4bb74cc304a3a435e83112 Mon Sep 17 00:00:00 2001 From: drdozer Date: Mon, 15 Sep 2025 14:27:59 +0100 Subject: [PATCH 161/335] Improve autocompletion behavior - Refactored handlers to use consistent early return pattern for better readability - Added blocking behavior for unquoted contexts (sound(, scale(, bank()) to guide users toward correct syntax instead of showing irrelevant fallback completions - Fixed soundHandler to show all sounds when fragment is empty (e.g., sound("")) - Simplified bankHandler by removing complex quote handling logic in favor of consistent blocking pattern - Made scale handler regex patterns consistent (removed leading dots) - All handlers now follow same structure: block unquoted contexts, provide completions for quoted contexts --- packages/codemirror/autocomplete.mjs | 176 +++++++++++++++------------ 1 file changed, 99 insertions(+), 77 deletions(-) diff --git a/packages/codemirror/autocomplete.mjs b/packages/codemirror/autocomplete.mjs index 2d53fe613..b5fb2f1fe 100644 --- a/packages/codemirror/autocomplete.mjs +++ b/packages/codemirror/autocomplete.mjs @@ -1,12 +1,9 @@ - import jsdoc from '../../doc.json'; import { autocompletion } from '@codemirror/autocomplete'; import { h } from './html'; import { Scale } from '@tonaljs/tonal'; import { soundMap } from 'superdough'; - - const escapeHtml = (str) => { const div = document.createElement('div'); div.innerText = str; @@ -80,7 +77,6 @@ const isValidDoc = (doc) => { const hasExcludedTags = (doc) => ['superdirtOnly', 'noAutocomplete'].some((tag) => doc.tags?.find((t) => t.originalTitle === tag)); - export function bankCompletions() { const soundDict = soundMap.get(); const banks = new Set(); @@ -88,10 +84,11 @@ export function bankCompletions() { const [bank, suffix] = key.split('_'); if (suffix && bank) banks.add(bank); } - return Array.from(banks).sort().map((name) => ({ label: name, type: 'bank' })); + return Array.from(banks) + .sort() + .map((name) => ({ label: name, type: 'bank' })); } - // Attempt to get all scale names from Tonal let scaleCompletions = []; try { @@ -138,15 +135,43 @@ const jsdocCompletions = (() => { return completions; })(); - // --- Handler functions for each context --- const pitchNames = [ - 'C', 'C#', 'Db', 'D', 'D#', 'Eb', 'E', 'E#', 'Fb', 'F', 'F#', 'Gb', - 'G', 'G#', 'Ab', 'A', 'A#', 'Bb', 'B', 'B#', 'Cb' + 'C', + 'C#', + 'Db', + 'D', + 'D#', + 'Eb', + 'E', + 'E#', + 'Fb', + 'F', + 'F#', + 'Gb', + 'G', + 'G#', + 'Ab', + 'A', + 'A#', + 'Bb', + 'B', + 'B#', + 'Cb', ]; function scalePreColonHandler(context) { - let scalePreColonContext = context.matchBefore(/\.scale\(\s*['"][^'"]*$/); + // First check for scale context without quotes - block with empty completions + let scaleNoQuotesContext = context.matchBefore(/scale\(\s*$/); + if (scaleNoQuotesContext) { + return { + from: scaleNoQuotesContext.to, + options: [], + }; + } + + // Then check for scale context with quotes - provide completions + let scalePreColonContext = context.matchBefore(/scale\(\s*['"][^'"]*$/); if (scalePreColonContext) { if (!scalePreColonContext.text.includes(':')) { if (context.explicit) { @@ -161,89 +186,86 @@ function scalePreColonHandler(context) { return { from: scalePreColonContext.to, options: [] }; } } - if (!scalePreColonContext.text.includes(':')) { - return { from: scalePreColonContext.to, options: [] }; - } } return null; } function soundHandler(context) { - let soundContext = context.matchBefore(/(s|sound)\(\s*['"][^'"]*$/); - if (soundContext) { - const text = soundContext.text; - const quoteIdx = Math.max(text.lastIndexOf('"'), text.lastIndexOf("'")); - if (quoteIdx === -1) return null; - const inside = text.slice(quoteIdx + 1); - const fragMatch = inside.match(/(?:[\s\[\{\(<])([\w]*)$/); - const fragment = fragMatch ? fragMatch[1] : inside; - if (!fragment || fragment.length === 0) return null; - const soundNames = Object.keys(soundMap.get()).sort(); - const filteredSounds = soundNames.filter((name) => name.includes(fragment)); - let options = filteredSounds.map((name) => ({ label: name, type: 'sound' })); - const from = soundContext.to - fragment.length; + // First check for sound context without quotes - block with empty completions + let soundNoQuotesContext = context.matchBefore(/(s|sound)\(\s*$/); + if (soundNoQuotesContext) { return { - from, - options, + from: soundNoQuotesContext.to, + options: [], }; } - return null; + + // Then check for sound context with quotes - provide completions + let soundContext = context.matchBefore(/(s|sound)\(\s*['"][^'"]*$/); + if (!soundContext) return null; + + const text = soundContext.text; + const quoteIdx = Math.max(text.lastIndexOf('"'), text.lastIndexOf("'")); + if (quoteIdx === -1) return null; + const inside = text.slice(quoteIdx + 1); + const fragMatch = inside.match(/(?:[\s\[\{\(<])([\w]*)$/); + const fragment = fragMatch ? fragMatch[1] : inside; + const soundNames = Object.keys(soundMap.get()).sort(); + const filteredSounds = soundNames.filter((name) => name.includes(fragment)); + let options = filteredSounds.map((name) => ({ label: name, type: 'sound' })); + const from = soundContext.to - fragment.length; + return { + from, + options, + }; } function bankHandler(context) { - let bankMatch = context.matchBefore(/bank\(\s*(['"])?([\w]*)$/); - if (bankMatch) { - let banks = bankCompletions(); - // Extract quote and fragment using regex groups on match.text - const groups = bankMatch.text.match(/(['"])?([\w]*)$/); - const quote = groups ? groups[1] : undefined; - const fragment = groups ? groups[2] || '' : ''; - let from; - if (quote) { - from = bankMatch.from + bankMatch.text.indexOf(quote) + 1; - } else { - from = bankMatch.to - fragment.length; - } - const filteredBanks = banks.filter((b) => b.label.startsWith(fragment)); - let options; - if (!quote) { - options = filteredBanks.map((b) => ({ ...b, apply: '"' + b.label + '"' })); - } else { - const afterCursor = context.state.sliceDoc(bankMatch.to, bankMatch.to + 1); - options = filteredBanks.map((b) => { - if (afterCursor !== quote) { - return { ...b, apply: b.label + quote }; - } - return b; - }); - } + // First check for bank context without quotes - block with empty completions + let bankNoQuotesContext = context.matchBefore(/bank\(\s*$/); + if (bankNoQuotesContext) { return { - from, - options, + from: bankNoQuotesContext.to, + options: [], }; } - return null; + + // Then check for bank context with quotes - provide completions + let bankMatch = context.matchBefore(/bank\(\s*['"][^'"]*$/); + if (!bankMatch) return null; + + const text = bankMatch.text; + const quoteIdx = Math.max(text.lastIndexOf('"'), text.lastIndexOf("'")); + if (quoteIdx === -1) return null; + const inside = text.slice(quoteIdx + 1); + const fragment = inside; + let banks = bankCompletions(); + const filteredBanks = banks.filter((b) => b.label.startsWith(fragment)); + const from = bankMatch.to - fragment.length; + return { + from, + options: filteredBanks, + }; } function scaleAfterColonHandler(context) { - let scaleContext = context.matchBefore(/\.scale\(\s*['"][^'"]*:[^'"]*$/); - if (scaleContext) { - const text = scaleContext.text; - const colonIdx = text.lastIndexOf(':'); - if (colonIdx === -1) return null; - const fragment = text.slice(colonIdx + 1); - const filteredScales = scaleCompletions.filter((s) => s.label.startsWith(fragment)); - const options = filteredScales.map((s) => ({ - ...s, - apply: s.label.replace(/\s+/g, ':') - })); - const from = scaleContext.from + colonIdx + 1; - return { - from, - options, - }; - } - return null; + let scaleContext = context.matchBefore(/scale\(\s*['"][^'"]*:[^'"]*$/); + if (!scaleContext) return null; + + const text = scaleContext.text; + const colonIdx = text.lastIndexOf(':'); + if (colonIdx === -1) return null; + const fragment = text.slice(colonIdx + 1); + const filteredScales = scaleCompletions.filter((s) => s.label.startsWith(fragment)); + const options = filteredScales.map((s) => ({ + ...s, + apply: s.label.replace(/\s+/g, ':'), + })); + const from = scaleContext.from + colonIdx + 1; + return { + from, + options, + }; } function fallbackHandler(context) { @@ -264,7 +286,7 @@ const handlers = [ bankHandler, scaleAfterColonHandler, // this handler *must* be last - fallbackHandler + fallbackHandler, ]; export const strudelAutocomplete = (context) => { From cb011c8bb0b4187938aa03f264fccc4569ddffdc Mon Sep 17 00:00:00 2001 From: Matthew Pocock Date: Mon, 15 Sep 2025 18:44:30 +0100 Subject: [PATCH 162/335] Add autocomplete for mode function - Added modePreColonHandler for autocomplete of mode values (below, above, duck, root) - Added modeAfterColonHandler for pitch name completion after colon in mode:anchor syntax - Follows same pattern as sound/bank/scale handlers for complex expressions - Supports expressions like '' with proper fragment matching - Uses regex pattern (?:[\s\[\{\()<])([\w:]*)$ to handle delimited expressions --- packages/codemirror/autocomplete.mjs | 57 ++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/packages/codemirror/autocomplete.mjs b/packages/codemirror/autocomplete.mjs index b5fb2f1fe..71b371e6c 100644 --- a/packages/codemirror/autocomplete.mjs +++ b/packages/codemirror/autocomplete.mjs @@ -97,6 +97,14 @@ try { console.warn('[autocomplete] Could not load scale names from Tonal:', e); } +// Valid mode values for voicing +const modeCompletions = [ + { label: 'below', type: 'mode' }, + { label: 'above', type: 'mode' }, + { label: 'duck', type: 'mode' }, + { label: 'root', type: 'mode' }, +]; + export const getSynonymDoc = (doc, synonym) => { const synonyms = doc.synonyms || []; const docLabel = getDocLabel(doc); @@ -248,6 +256,53 @@ function bankHandler(context) { }; } +function modePreColonHandler(context) { + // First check for mode context without quotes - block with empty completions + let modeNoQuotesContext = context.matchBefore(/mode\(\s*$/); + if (modeNoQuotesContext) { + return { + from: modeNoQuotesContext.to, + options: [], + }; + } + + // Then check for mode context with quotes - provide completions + let modeContext = context.matchBefore(/mode\(\s*['"][^'"]*$/); + if (!modeContext) return null; + + const text = modeContext.text; + const quoteIdx = Math.max(text.lastIndexOf('"'), text.lastIndexOf("'")); + if (quoteIdx === -1) return null; + const inside = text.slice(quoteIdx + 1); + const fragMatch = inside.match(/(?:[\s\[\{\(<])([\w:]*)$/); + const fragment = fragMatch ? fragMatch[1] : inside; + const filteredModes = modeCompletions.filter((m) => m.label.startsWith(fragment)); + const from = modeContext.to - fragment.length; + return { + from, + options: filteredModes, + }; +} + +function modeAfterColonHandler(context) { + let modeContext = context.matchBefore(/mode\(\s*['"][^'"]*:[^'"]*$/); + if (!modeContext) return null; + + const text = modeContext.text; + const colonIdx = text.lastIndexOf(':'); + if (colonIdx === -1) return null; + const fragment = text.slice(colonIdx + 1); + + // For anchor after colon, we can suggest pitch names + const filtered = pitchNames.filter((p) => p.toLowerCase().startsWith(fragment.toLowerCase())); + const options = filtered.map((p) => ({ label: p, type: 'pitch' })); + const from = modeContext.from + colonIdx + 1; + return { + from, + options, + }; +} + function scaleAfterColonHandler(context) { let scaleContext = context.matchBefore(/scale\(\s*['"][^'"]*:[^'"]*$/); if (!scaleContext) return null; @@ -284,7 +339,9 @@ const handlers = [ scalePreColonHandler, soundHandler, bankHandler, + modePreColonHandler, scaleAfterColonHandler, + modeAfterColonHandler, // this handler *must* be last fallbackHandler, ]; From a7e485992e6bba4dd62a30787565e18408152137 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 15 Sep 2025 20:54:39 +0200 Subject: [PATCH 163/335] add tic80 font --- website/public/fonts/tic80/license.txt | 5 +++++ website/public/fonts/tic80/readme.txt | 16 ++++++++++++++++ website/public/fonts/tic80/tic-80-wide-font.otf | Bin 0 -> 10020 bytes .../src/repl/components/panel/SettingsTab.jsx | 1 + website/src/styles/index.css | 5 +++++ 5 files changed, 27 insertions(+) create mode 100644 website/public/fonts/tic80/license.txt create mode 100644 website/public/fonts/tic80/readme.txt create mode 100644 website/public/fonts/tic80/tic-80-wide-font.otf diff --git a/website/public/fonts/tic80/license.txt b/website/public/fonts/tic80/license.txt new file mode 100644 index 000000000..e42ba4eb9 --- /dev/null +++ b/website/public/fonts/tic80/license.txt @@ -0,0 +1,5 @@ +The FontStruction “TIC-80 wide font” +(https://fontstruct.com/fontstructions/show/1388526) by “nesbox” is licensed +under a Creative Commons CC0 Public Domain Dedication license +(http://creativecommons.org/publicdomain/zero/1.0/). +[ancestry] \ No newline at end of file diff --git a/website/public/fonts/tic80/readme.txt b/website/public/fonts/tic80/readme.txt new file mode 100644 index 000000000..b3aaff55c --- /dev/null +++ b/website/public/fonts/tic80/readme.txt @@ -0,0 +1,16 @@ +The font file in this archive was created using Fontstruct the free, online +font-building tool. +This font was created by “nesbox”. +This font has a homepage where this archive and other versions may be found: +https://fontstruct.com/fontstructions/show/1388526 +[ancestry] +Try Fontstruct at https://fontstruct.com +It’s easy and it’s fun. + +Fontstruct is copyright ©2017-2025 Rob Meek + +LEGAL NOTICE: +In using this font you must comply with the licensing terms described in the +file “license.txt” included with this archive. +If you redistribute the font file in this archive, it must be accompanied by all +the other files from this archive, including this one. diff --git a/website/public/fonts/tic80/tic-80-wide-font.otf b/website/public/fonts/tic80/tic-80-wide-font.otf new file mode 100644 index 0000000000000000000000000000000000000000..ba1c1caf4c74de8484950313ad046f5cd7c56ace GIT binary patch literal 10020 zcmeHMZERa-6+YJ=*G}SmHA^U)TP|o~V>EV}u1!0rXqOV&!Dwl_ZYpENN!-M39cQ+) zrjt9S!6qOurU`}wV-iSwYT6$pgeEpV1{>-In#K=4eoS*1(-0E;n1*9#NqNpW@4dcu z+^+ix%u(!f-}|0(o^#G~&b{{CfB5izYNxv?NY3cknDeKn#(zQ-4iWYLb}(-;X}w|FrLs^(X~ILv(Z}zgsuj_n387(ieOH z2i_?V`Mvc3g((z#H3$@lO+Fz{VjZs#zv+wdc(1WThY!*&a-0oyUyfy+|J`}yb1Qrj zBB02AMICwGx>5h#WB1ct=TBbqAG>Srx~p@c&t_fs_(J>r>waJU^;UALz3y78Pj{`A zEqBeo$1l6*FZGjk1K(JiM_#vXL{$R#X98b_cU07hp~Oo#j^dBc-Q~Q~*>E0JL~YkQ z@$=`;mtWfZ(irdkAA9|u#%)mulftsP5APct+&*+VGnqb~n`f|)(=vi1;S9zkl^5?bT8wUOTtE*k4(UESGIwEZdcGq*k(*%aN4?Z>T2h z<;6$`c0d7AWif;u*oPe*)g-U3;JrM+a+&20i!7U_iP}b}M0EWI+Ra@;8KTn|o;+B@z2ipJG zaYe_cI_~OtwBzO26|q!oA@)q{mCntb2Ra|>{9)(0&eyxH>AI=w-mYJERl0|}k99xT zeXb|cb5+ko&qB{{dX{?=y|?t<-}~#{SJ!P^chkCu);-r3=-bq{tM5eLclsXdd%W-I zz8B(={qgV>H${bOOHq5;YSAIk+F!Jt@4(YiP{aiDPH@$ ztxI29{Yrm4@_Zz22kiLLP^1e7{9h?o%3Pdkl2gButS0+WBpjhIdOjZB+W(#nEZ0i4 zQa?(ALZURwiz`V}RxOvF;WA2zxtLN$ub5iiWnGtdmW3Ef56J8X9sz^ZWK+C)wwhp1 zObOn-3KW8vJuWhxu#qi@91m|3Zb?AOA_c7K>|jA-)`ePWfNcvBaJ2%ix}GcLIuluT zA;fFXnr)H^w&1F0&ipwAaqIT0XZ?!Rq$r9J6`Q$piTk2Fz z`n6Y*aOrhptyB-mk5%JG>uHOk`YTDTwiZFsW~#C#=%xz!GrC$rwa~a;oxCRYN`rXV zdX>3{n7o}{y1kv?lVVJ= z*9Y2jc=xQ?pXF?*9W5fuYNxT4D`jnEzyNrpn^P~%1n{6jv$n|`U;#Chz?nF_0VxjP zfhW4#5Otr;ZGF+}f@eiDpw|dDdkoK=F+iYzO%DB0n?WUGqh2u9kmN2enzOX;Gp*rp4*$&TjQ8@EahWvR4a17|Dci&B5BLao#=3ljeE zgUNu|?`Fe4;0)8H(K&IIvhq%$ua-1#8m68%UL=!#ZGSJVBpR^rT=KlL6?blFu~!lv z*O8(X^a*#!wmPT%junc|Wp9F27U2)+0|lY0*qIVq2%)$c7ffi_HmuT}ARf*F3-{_G zdib1aYi4B23sn=Js%OC`^o85ks;9lt%<87zXtLyErUvJQ13O?&y*tznZ_<0O>RH@- zHDYMkFM%_}we71A>ovakR&VZViIHXxsktDd5!5xnYm0&8hW4&)rF}i;)w7&)6aZkF zJRm@L(9#+YIDkFwZ7q-6j-EFjN&>7tD|j?RuU=3?QCX5pC*VQ}s>@~nZ3q-ic@?y~ zM@a)jjokJ{$S&8W)w81gj!UWuof+$93`qTqMd6^PQ7NkpS5+BpqoL#7s3|}6k_8zT zN!7qHoocF~dEKs-42XIkvMRVbWO#E29yrKHI@UU$wK zR$y{yZa7aUt86v(mWhLXYk0)n?w>EP3&iY-tEc^jF~@7L$!q=r=3xOtp<)7;A_^3L z&REYS2RMX`!=T2{TvDEaQc{CnbLh{S`HG|+h7)k^FQLf(ntPzJ7oZg`Lnxc62k4EQ zV{hK2*Bi?^J+KqVkSgUX-s?1%USx6slAh*Pm0`>vn&{BjczWG%+fc7sGQHugaVMK{ zyB=xu1_aj)Jt4U^ceR4jf9KBk{=z3F33Etp+XW#2=%q@O{7!^p+8EU&f~bE@@qh{C z#52mSw^u8ChiLBIu%dNkQ!edb$!tc$C%84u7}xA6|9B=Qe6!yT90l<1;tW1`;H}aL zmjDGDK_Oq#TA9|`aV4_ zYDCzs*feDx1f?m?a&XEe)E?My0?8Yw6VFQ>&iD(7z1|RkS!7FTuv$V2d6erMl;jzj z2sQM(89;fh&RxK*4xgeYe6Qo;29hbhyvR&+c?^^dmlJhYzwEj9MzD_fq&7T=>Jr{yp=3(Qx8WXv zTrTo1oaeDEBvuP}*PZM@6UCERd(s5YdoYS53Pp|;M5i)h^x9yJ0do}*x2y7-0+gVt znS>1IcxUIZ;}+EG91c{#s$ujBL(`oMQ}gK#R;VdqRgFyxNwCw)4QE3y=eWoq43xgP z!I5xy&{}b}#1CwkHgJD4;Kt`V)PI|4{Nm#OL5ICo%3z)O>1C~~Kb`41Wd5OkOW=g} zd;K+@WZ|iddlaB9y1|^m^Dw%_$RQe{c_W8ufPP?Po8t7Okt1}3{$k`PZL)@p+(t3$ zRwK95Q42qx%BzF!vwmgd7|jOu8o85>27YSfE*cN6Gjbmt3>Hx1#54%`_0Zf zP4`h~1aSDRxQJXlV+PkDV9Nv7gv6GC4F?DvSxrd{SwVafYdJ*YP%F&@ z^mCMz3>A^F0$oQ*{JGu=J}>TGUml%!1J)M#b2h;9X&_;Iu+Fx4OQsz2z(&&;{hytGDqesWooMo-EO5OfU@Z^UC&7rimr0+GB;6^@%}Gv~vq|tPLyCDE(iCvq4($|BoD^KV z!dkPy!kx*{oPbT`Ll$ew6z zc}LRuLMAuk;F+Orai2iepA9;hf|GKJ`P5`Oo64Vba>soS4igi(>~yg>TevQn+rT@F*AXurh^Q6klnwjiCo^Z zFtTIo$hAp@Ihs$WikUmo&S);1g%@XZbjUd{H-0KJ;q1v}Q<)iOPkJ&lflav?c7kvx zj1FRDl|(K-m7EooNzq8&na<~uNNjS9EstlWoZIJ86DKn>Q_h{~+37R+f^#B=XR+Bc z$jQ7jo}S!&I=B1yk@@V+yLavc-`}3)Z_jd_f6a6B?OC40d~LjD{8!C#+_mZJx0v^> IUluR_2cfFLr2qf` literal 0 HcmV?d00001 diff --git a/website/src/repl/components/panel/SettingsTab.jsx b/website/src/repl/components/panel/SettingsTab.jsx index 26c9ae287..80daef018 100644 --- a/website/src/repl/components/panel/SettingsTab.jsx +++ b/website/src/repl/components/panel/SettingsTab.jsx @@ -74,6 +74,7 @@ const fontFamilyOptions = { FiraCode: 'FiraCode', 'FiraCode-SemiBold': 'FiraCode SemiBold', teletext: 'teletext', + tic80: 'tic80', mode7: 'mode7', BigBlueTerminal: 'BigBlueTerminal', x3270: 'x3270', diff --git a/website/src/styles/index.css b/website/src/styles/index.css index 7fa4b2df8..41b282ff4 100644 --- a/website/src/styles/index.css +++ b/website/src/styles/index.css @@ -50,6 +50,11 @@ src: url('/fonts/teletext/EuropeanTeletext.ttf'); size-adjust: 90%; } +@font-face { + font-family: 'tic80'; + src: url('/fonts/tic80/tic-80-wide-font.otf'); + size-adjust: 60%; +} @font-face { font-family: 'mode7'; src: url('/fonts/mode7/MODE7GX3.TTF'); From 6ebe84e09629bae580ecafa595ea171f34be9cf1 Mon Sep 17 00:00:00 2001 From: Matthew Pocock Date: Mon, 15 Sep 2025 21:34:15 +0100 Subject: [PATCH 164/335] Added completion for chord. --- packages/codemirror/autocomplete.mjs | 81 ++++++++++++++++++++++++++-- 1 file changed, 78 insertions(+), 3 deletions(-) diff --git a/packages/codemirror/autocomplete.mjs b/packages/codemirror/autocomplete.mjs index 71b371e6c..142c5f267 100644 --- a/packages/codemirror/autocomplete.mjs +++ b/packages/codemirror/autocomplete.mjs @@ -3,6 +3,7 @@ import { autocompletion } from '@codemirror/autocomplete'; import { h } from './html'; import { Scale } from '@tonaljs/tonal'; import { soundMap } from 'superdough'; +import { complex } from '../tonal/ireal.mjs'; const escapeHtml = (str) => { const div = document.createElement('div'); @@ -105,6 +106,23 @@ const modeCompletions = [ { label: 'root', type: 'mode' }, ]; +// Valid chord symbols from ireal dictionary plus empty string for major triads +const chordSymbols = ['', ...Object.keys(complex)].sort(); +const chordSymbolCompletions = chordSymbols.map((symbol) => { + if (symbol === '') { + return { + label: 'major', + apply: '', + type: 'chord-symbol', + }; + } + return { + label: symbol, + apply: symbol, + type: 'chord-symbol', + }; +}); + export const getSynonymDoc = (doc, synonym) => { const synonyms = doc.synonyms || []; const docLabel = getDocLabel(doc); @@ -216,7 +234,7 @@ function soundHandler(context) { const quoteIdx = Math.max(text.lastIndexOf('"'), text.lastIndexOf("'")); if (quoteIdx === -1) return null; const inside = text.slice(quoteIdx + 1); - const fragMatch = inside.match(/(?:[\s\[\{\(<])([\w]*)$/); + const fragMatch = inside.match(/(?:[\s[{(<])([\w]*)$/); const fragment = fragMatch ? fragMatch[1] : inside; const soundNames = Object.keys(soundMap.get()).sort(); const filteredSounds = soundNames.filter((name) => name.includes(fragment)); @@ -274,7 +292,7 @@ function modePreColonHandler(context) { const quoteIdx = Math.max(text.lastIndexOf('"'), text.lastIndexOf("'")); if (quoteIdx === -1) return null; const inside = text.slice(quoteIdx + 1); - const fragMatch = inside.match(/(?:[\s\[\{\(<])([\w:]*)$/); + const fragMatch = inside.match(/(?:[\s[{(<])([\w:]*)$/); const fragment = fragMatch ? fragMatch[1] : inside; const filteredModes = modeCompletions.filter((m) => m.label.startsWith(fragment)); const from = modeContext.to - fragment.length; @@ -303,6 +321,60 @@ function modeAfterColonHandler(context) { }; } +function chordHandler(context) { + // First check for chord context without quotes - block with empty completions + let chordNoQuotesContext = context.matchBefore(/chord\(\s*$/); + if (chordNoQuotesContext) { + return { + from: chordNoQuotesContext.to, + options: [], + }; + } + + // Then check for chord context with quotes - provide completions + let chordContext = context.matchBefore(/chord\(\s*['"][^'"]*$/); + if (!chordContext) return null; + + const text = chordContext.text; + const quoteIdx = Math.max(text.lastIndexOf('"'), text.lastIndexOf("'")); + if (quoteIdx === -1) return null; + const inside = text.slice(quoteIdx + 1); + + // Use same fragment matching as sound/mode for expressions like "" + const fragMatch = inside.match(/(?:[\s[{(<])([\w#b+^:-]*)$/); + const fragment = fragMatch ? fragMatch[1] : inside; + + // Check if fragment contains any pitch name at start (for root + symbol) + let rootMatch = null; + let symbolFragment = fragment; + for (const pitch of pitchNames) { + if (fragment.toLowerCase().startsWith(pitch.toLowerCase())) { + rootMatch = pitch; + symbolFragment = fragment.slice(pitch.length); + break; + } + } + + if (rootMatch) { + // We have a root, now complete chord symbols + const filteredSymbols = chordSymbolCompletions.filter((s) => + s.label.toLowerCase().startsWith(symbolFragment.toLowerCase()), + ); + + // Create completions that replace the entire chord, not just the symbol part + const options = filteredSymbols; + + const from = chordContext.to - symbolFragment.length; + return { from, options }; + } else { + // No root yet, complete with pitch names + const filteredPitches = pitchNames.filter((p) => p.toLowerCase().startsWith(fragment.toLowerCase())); + const options = filteredPitches.map((p) => ({ label: p, type: 'pitch' })); + const from = chordContext.to - fragment.length; + return { from, options }; + } +} + function scaleAfterColonHandler(context) { let scaleContext = context.matchBefore(/scale\(\s*['"][^'"]*:[^'"]*$/); if (!scaleContext) return null; @@ -339,6 +411,7 @@ const handlers = [ scalePreColonHandler, soundHandler, bankHandler, + chordHandler, modePreColonHandler, scaleAfterColonHandler, modeAfterColonHandler, @@ -349,7 +422,9 @@ const handlers = [ export const strudelAutocomplete = (context) => { for (const handler of handlers) { const result = handler(context); - if (result) return result; + if (result) { + return result; + } } return null; }; From 2cba1dcb317fea1046a8a95f673ad888e1960723 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Mon, 15 Sep 2025 21:46:37 -0400 Subject: [PATCH 165/335] working --- packages/core/signal.mjs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs index 6bd6fde67..f736ce71f 100644 --- a/packages/core/signal.mjs +++ b/packages/core/signal.mjs @@ -16,7 +16,7 @@ export function steady(value) { } export const signal = (func) => { - const query = (state) => [new Hap(undefined, state.span, func(state.span.begin))]; + const query = (state) => [new Hap(undefined, state.span, func(state.span.begin.valueOf()))]; return new Pattern(query); }; @@ -152,7 +152,10 @@ export const itri2 = fastcat(isaw2, saw2); * * @return {Pattern} */ -export const time = signal(id); +export const time = signal((x) => { + console.info(typeof x) +return x +}); /** * The mouse's x position value ranges from 0 to 1. From 7dfd7dbcdc4500cf69d4a7767ba74f0adc42ffa7 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Mon, 15 Sep 2025 21:47:40 -0400 Subject: [PATCH 166/335] rmconsole --- packages/core/signal.mjs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs index f736ce71f..2646ccf7c 100644 --- a/packages/core/signal.mjs +++ b/packages/core/signal.mjs @@ -152,10 +152,7 @@ export const itri2 = fastcat(isaw2, saw2); * * @return {Pattern} */ -export const time = signal((x) => { - console.info(typeof x) -return x -}); +export const time = signal(id); /** * The mouse's x position value ranges from 0 to 1. From 74e27ca94f977b2586616ccb023a6a6f96edbedb Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Mon, 15 Sep 2025 21:57:56 -0400 Subject: [PATCH 167/335] coerce in correct place --- packages/core/signal.mjs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs index 2646ccf7c..b246cb9e3 100644 --- a/packages/core/signal.mjs +++ b/packages/core/signal.mjs @@ -16,7 +16,7 @@ export function steady(value) { } export const signal = (func) => { - const query = (state) => [new Hap(undefined, state.span, func(state.span.begin.valueOf()))]; + const query = (state) => [new Hap(undefined, state.span, func(state.span.begin))]; return new Pattern(query); }; @@ -152,7 +152,9 @@ export const itri2 = fastcat(isaw2, saw2); * * @return {Pattern} */ -export const time = signal(id); +export const time = signal(x => { + return x.valueOf() +}); /** * The mouse's x position value ranges from 0 to 1. From 4cc453c640bda94df291b3cb562f5d4d9b75f576 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Mon, 15 Sep 2025 22:09:05 -0400 Subject: [PATCH 168/335] fix test --- packages/core/signal.mjs | 4 ++-- packages/core/test/pattern.test.mjs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs index b246cb9e3..79e45da7d 100644 --- a/packages/core/signal.mjs +++ b/packages/core/signal.mjs @@ -152,8 +152,8 @@ export const itri2 = fastcat(isaw2, saw2); * * @return {Pattern} */ -export const time = signal(x => { - return x.valueOf() +export const time = signal((x) => { + return x.valueOf(); }); /** diff --git a/packages/core/test/pattern.test.mjs b/packages/core/test/pattern.test.mjs index 1df5c8776..3b6619b56 100644 --- a/packages/core/test/pattern.test.mjs +++ b/packages/core/test/pattern.test.mjs @@ -877,7 +877,7 @@ describe('Pattern', () => { .squeezeJoin() .queryArc(3, 4) .map((x) => x.value), - ).toStrictEqual([Fraction(3)]); + ).toStrictEqual([3]); }); }); describe('ply', () => { From 3eb40ee7d3b5c1b1404a0d00e131bca018ca3e2e Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Tue, 16 Sep 2025 01:44:01 -0400 Subject: [PATCH 169/335] working in dev --- packages/core/logger.mjs | 5 +++-- packages/superdough/logger.mjs | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/core/logger.mjs b/packages/core/logger.mjs index 4f2002319..6727c2422 100644 --- a/packages/core/logger.mjs +++ b/packages/core/logger.mjs @@ -5,8 +5,9 @@ let debounce = 1000, lastTime; export function errorLogger(e, origin = 'cyclist') { - //TODO: add some kind of debug flag that enables this while in dev mode - // console.error(e); + if (process.env.NODE_ENV === 'development') { + console.error(e); + } logger(`[${origin}] error: ${e.message}`); } diff --git a/packages/superdough/logger.mjs b/packages/superdough/logger.mjs index b3c9c34f3..912db1738 100644 --- a/packages/superdough/logger.mjs +++ b/packages/superdough/logger.mjs @@ -1,8 +1,10 @@ let log = (msg) => console.log(msg); -export function errorLogger(e, origin = 'cyclist') { +export function errorLogger(e, origin = 'superdough') { //TODO: add some kind of debug flag that enables this while in dev mode - // console.error(e); + if (process.env.NODE_ENV === 'development') { + console.error(e); + } logger(`[${origin}] error: ${e.message}`); } From 9a8f8a051c35b9f8ced51b3e2549ff0dcc0ebfb0 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Tue, 16 Sep 2025 01:48:37 -0400 Subject: [PATCH 170/335] rm comment --- packages/superdough/logger.mjs | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/superdough/logger.mjs b/packages/superdough/logger.mjs index 912db1738..99fd0cf39 100644 --- a/packages/superdough/logger.mjs +++ b/packages/superdough/logger.mjs @@ -1,7 +1,6 @@ let log = (msg) => console.log(msg); export function errorLogger(e, origin = 'superdough') { - //TODO: add some kind of debug flag that enables this while in dev mode if (process.env.NODE_ENV === 'development') { console.error(e); } From edb6c0db2e0c9088db7f3b3c1240f63c07962127 Mon Sep 17 00:00:00 2001 From: Matthew Pocock Date: Tue, 16 Sep 2025 14:45:22 +0100 Subject: [PATCH 171/335] Reordered handlers to be a bit more organised. --- packages/codemirror/autocomplete.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/codemirror/autocomplete.mjs b/packages/codemirror/autocomplete.mjs index 142c5f267..8b3111b51 100644 --- a/packages/codemirror/autocomplete.mjs +++ b/packages/codemirror/autocomplete.mjs @@ -408,12 +408,12 @@ function fallbackHandler(context) { } const handlers = [ - scalePreColonHandler, soundHandler, bankHandler, chordHandler, - modePreColonHandler, + scalePreColonHandler, scaleAfterColonHandler, + modePreColonHandler, modeAfterColonHandler, // this handler *must* be last fallbackHandler, From 9cdba1a50ee806bd56215d2635ec1cad1338a204 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Tue, 16 Sep 2025 11:36:21 -0400 Subject: [PATCH 172/335] Working --- packages/core/pattern.mjs | 4 +++- packages/core/signal.mjs | 4 +--- packages/superdough/superdough.mjs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index 262b92bb3..2991cffea 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -6,6 +6,7 @@ This program is free software: you can redistribute it and/or modify it under th import TimeSpan from './timespan.mjs'; import Fraction, { lcm } from './fraction.mjs'; +import FractionClass from 'fraction.js'; import Hap from './hap.mjs'; import State from './state.mjs'; import { unionWithObj } from './value.mjs'; @@ -26,6 +27,7 @@ import { } from './util.mjs'; import drawLine from './drawLine.mjs'; import { logger } from './logger.mjs'; +import fraction from './fraction.mjs'; let stringParser; @@ -999,7 +1001,7 @@ addToPrototype('weaveWith', function (t, ...funcs) { // compose matrix functions function _nonArrayObject(x) { - return !Array.isArray(x) && typeof x === 'object'; + return !Array.isArray(x) && typeof x === 'object' && !(x instanceof FractionClass); } function _composeOp(a, b, func) { if (_nonArrayObject(a) || _nonArrayObject(b)) { diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs index 79e45da7d..6bd6fde67 100644 --- a/packages/core/signal.mjs +++ b/packages/core/signal.mjs @@ -152,9 +152,7 @@ export const itri2 = fastcat(isaw2, saw2); * * @return {Pattern} */ -export const time = signal((x) => { - return x.valueOf(); -}); +export const time = signal(id); /** * The mouse's x position value ranges from 0 to 1. diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index f1f308a7d..b1df93916 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -465,7 +465,7 @@ function duckOrbit(audioContext, targetOrbit, t, onsettime = 0, attacktime = 0.1 gainParam.cancelScheduledValues(now); gainParam.setValueAtTime(currVal, now); - const t0 = Math.max(t, now); // guard against now > t + const t0 = now; // guard against now > t const duckedVal = clamp(1 - Math.sqrt(depth), 0.01, currVal); gainParam.exponentialRampToValueAtTime(duckedVal, t0 + onset); gainParam.exponentialRampToValueAtTime(1, t0 + onset + attack); From 89b7eac789e221097a55d5ee20904d5c14b7c3ab Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Tue, 16 Sep 2025 11:52:36 -0400 Subject: [PATCH 173/335] fix test --- packages/core/fraction.mjs | 2 ++ packages/core/pattern.mjs | 6 ++---- packages/core/test/pattern.test.mjs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/core/fraction.mjs b/packages/core/fraction.mjs index 2e3bc68ea..076fbadf6 100644 --- a/packages/core/fraction.mjs +++ b/packages/core/fraction.mjs @@ -126,6 +126,8 @@ export const lcm = (...fractions) => { ); }; +export const isFraction = (x) => x instanceof Fraction; + fraction._original = Fraction; export default fraction; diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index 2991cffea..196248eba 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -5,8 +5,7 @@ This program is free software: you can redistribute it and/or modify it under th */ import TimeSpan from './timespan.mjs'; -import Fraction, { lcm } from './fraction.mjs'; -import FractionClass from 'fraction.js'; +import Fraction, {isFraction, lcm } from './fraction.mjs'; import Hap from './hap.mjs'; import State from './state.mjs'; import { unionWithObj } from './value.mjs'; @@ -27,7 +26,6 @@ import { } from './util.mjs'; import drawLine from './drawLine.mjs'; import { logger } from './logger.mjs'; -import fraction from './fraction.mjs'; let stringParser; @@ -1001,7 +999,7 @@ addToPrototype('weaveWith', function (t, ...funcs) { // compose matrix functions function _nonArrayObject(x) { - return !Array.isArray(x) && typeof x === 'object' && !(x instanceof FractionClass); + return !Array.isArray(x) && typeof x === 'object' && !isFraction(x); } function _composeOp(a, b, func) { if (_nonArrayObject(a) || _nonArrayObject(b)) { diff --git a/packages/core/test/pattern.test.mjs b/packages/core/test/pattern.test.mjs index 3b6619b56..1df5c8776 100644 --- a/packages/core/test/pattern.test.mjs +++ b/packages/core/test/pattern.test.mjs @@ -877,7 +877,7 @@ describe('Pattern', () => { .squeezeJoin() .queryArc(3, 4) .map((x) => x.value), - ).toStrictEqual([3]); + ).toStrictEqual([Fraction(3)]); }); }); describe('ply', () => { From f2b2f9f9591e5c37667be04b15a35f593aff3cf1 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Tue, 16 Sep 2025 11:53:19 -0400 Subject: [PATCH 174/335] format --- packages/core/pattern.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index 196248eba..d0be3f599 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -5,7 +5,7 @@ This program is free software: you can redistribute it and/or modify it under th */ import TimeSpan from './timespan.mjs'; -import Fraction, {isFraction, lcm } from './fraction.mjs'; +import Fraction, { isFraction, lcm } from './fraction.mjs'; import Hap from './hap.mjs'; import State from './state.mjs'; import { unionWithObj } from './value.mjs'; From a68c7847531ff94faf0a9f0e048643117703d606 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Tue, 16 Sep 2025 11:55:31 -0400 Subject: [PATCH 175/335] rm unessecary change --- packages/superdough/superdough.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index b1df93916..f1f308a7d 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -465,7 +465,7 @@ function duckOrbit(audioContext, targetOrbit, t, onsettime = 0, attacktime = 0.1 gainParam.cancelScheduledValues(now); gainParam.setValueAtTime(currVal, now); - const t0 = now; // guard against now > t + const t0 = Math.max(t, now); // guard against now > t const duckedVal = clamp(1 - Math.sqrt(depth), 0.01, currVal); gainParam.exponentialRampToValueAtTime(duckedVal, t0 + onset); gainParam.exponentialRampToValueAtTime(1, t0 + onset + attack); From 5445f0812fe1b7147aeb4866d15114afe56f809c Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Wed, 17 Sep 2025 12:41:46 +0200 Subject: [PATCH 176/335] configurable port for osc bridge + add bin field --- packages/osc/package.json | 1 + packages/osc/server.js | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/osc/package.json b/packages/osc/package.json index d5a272328..6e8a3394a 100644 --- a/packages/osc/package.json +++ b/packages/osc/package.json @@ -3,6 +3,7 @@ "version": "1.2.4", "description": "OSC messaging for strudel", "main": "osc.mjs", + "bin": "./server.mjs", "type": "module", "publishConfig": { "main": "dist/index.mjs" diff --git a/packages/osc/server.js b/packages/osc/server.js index 75fc5b1c0..c727e65f7 100644 --- a/packages/osc/server.js +++ b/packages/osc/server.js @@ -6,6 +6,19 @@ This program is free software: you can redistribute it and/or modify it under th import OSC from 'osc-js'; +const args = process.argv.slice(2); +function getArgValue(flag) { + const i = args.indexOf(flag); + if (i !== -1) { + const nextIsFlag = args[i + 1]?.startsWith('--') ?? true; + if (nextIsFlag) return true; + return args[i + 1]; + } +} + +let udpClientPort = Number(getArgValue('--port')) || 57120; +// dirt = 7771 + const config = { receiver: 'ws', // @param {string} Where messages sent via 'send' method will be delivered to, 'ws' for Websocket clients, 'udp' for udp client udpServer: { @@ -17,7 +30,7 @@ const config = { }, udpClient: { host: 'localhost', // @param {string} Hostname of udp client for messaging - port: 57120, // @param {number} Port of udp client for messaging + port: udpClientPort, // @param {number} Port of udp client for messaging }, wsServer: { host: 'localhost', // @param {string} Hostname of WebSocket server From 820744dc27a80e70a14fab0110c5219ff3c22cc7 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Wed, 17 Sep 2025 12:42:11 +0200 Subject: [PATCH 177/335] bump osc to 1.2.5 --- packages/osc/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/osc/package.json b/packages/osc/package.json index 6e8a3394a..bf7fb474d 100644 --- a/packages/osc/package.json +++ b/packages/osc/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/osc", - "version": "1.2.4", + "version": "1.2.5", "description": "OSC messaging for strudel", "main": "osc.mjs", "bin": "./server.mjs", From 5d7c6c3e4b29e22ded1ecb07ce52bd03a994920c Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Wed, 17 Sep 2025 12:47:41 +0200 Subject: [PATCH 178/335] fix: add node shebang + bump osc to 1.2.6 --- packages/osc/package.json | 2 +- packages/osc/server.js | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/osc/package.json b/packages/osc/package.json index bf7fb474d..ad0d383ff 100644 --- a/packages/osc/package.json +++ b/packages/osc/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/osc", - "version": "1.2.5", + "version": "1.2.6", "description": "OSC messaging for strudel", "main": "osc.mjs", "bin": "./server.mjs", diff --git a/packages/osc/server.js b/packages/osc/server.js index c727e65f7..4d87862ca 100644 --- a/packages/osc/server.js +++ b/packages/osc/server.js @@ -1,3 +1,5 @@ +#!/usr/bin/env node + /* server.js - Copyright (C) 2022 Strudel contributors - see From aba594b72ab9c1591167b4f73088c4539f40bfd8 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Wed, 17 Sep 2025 12:52:42 +0200 Subject: [PATCH 179/335] fix: bin field --- packages/osc/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/osc/package.json b/packages/osc/package.json index ad0d383ff..239acda19 100644 --- a/packages/osc/package.json +++ b/packages/osc/package.json @@ -1,9 +1,9 @@ { "name": "@strudel/osc", - "version": "1.2.6", + "version": "1.2.7", "description": "OSC messaging for strudel", "main": "osc.mjs", - "bin": "./server.mjs", + "bin": "./server.js", "type": "module", "publishConfig": { "main": "dist/index.mjs" From 28d7e0e489440beec0fedfbbf1a676d78bd63a73 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Wed, 17 Sep 2025 13:39:28 +0200 Subject: [PATCH 180/335] export osc function to be able to do all(osc) --- packages/osc/osc.mjs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/osc/osc.mjs b/packages/osc/osc.mjs index 8262e5569..fe0691522 100644 --- a/packages/osc/osc.mjs +++ b/packages/osc/osc.mjs @@ -6,7 +6,7 @@ This program is free software: you can redistribute it and/or modify it under th import OSC from 'osc-js'; -import { logger, parseNumeral, Pattern, isNote, noteToMidi, ClockCollator } from '@strudel/core'; +import { logger, parseNumeral, register, isNote, noteToMidi, ClockCollator } from '@strudel/core'; let connection; // Promise function connect() { @@ -81,6 +81,4 @@ export async function oscTrigger(hap, currentTime, cps = 1, targetTime) { * @memberof Pattern * @returns Pattern */ -Pattern.prototype.osc = function () { - return this.onTrigger(oscTrigger); -}; +export const osc = register('osc', (pat) => pat.onTrigger(oscTrigger)); From cdb623cb66484843915e35fc2a7de2e3e029c71e Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Wed, 17 Sep 2025 13:39:35 +0200 Subject: [PATCH 181/335] overhaul osc readme --- packages/osc/README.md | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/packages/osc/README.md b/packages/osc/README.md index 3dc65e16e..d5ee60fbc 100644 --- a/packages/osc/README.md +++ b/packages/osc/README.md @@ -4,36 +4,35 @@ OSC output for strudel patterns! Currently only tested with super collider / sup ## Usage -OSC will only work if you run the REPL locally + the OSC server besides it: +Assuming you have [node.js](https://nodejs.org/) installed, you can run the osc bridge server via: -From the project root: - -```js -npm run repl +```sh +npx @strudel/osc ``` -and in a seperate shell: - -```js -npm run osc -``` - -This should give you +You should see something like: ```log osc client running on port 57120 -osc server running on port 57121 +osc server running on port 7771 websocket server running on port 8080 ``` -Now open Supercollider (with the super dirt startup file) +By default it will use port 57120 for the osc client, which is what [superdirt](https://github.com/musikinformatik/SuperDirt) uses. You can change it via the `--port` option: -Now open the REPL and type: - -```js -s(" hh").osc() +```sh +npx @strudel/osc --port 7771 # classic dirt ``` -or just [click here](https://strudel.cc/#cygiPGJkIHNkPiBoaCIpLm9zYygp)... +To test it in strudel, you have can use `all(osc)` to send all events through osc: + +```js +$: s("bd*4") + +all(osc) +``` + + +[open in repl](hhttps://strudel.cc/#JDogcygiYmQqNCIpCgphbGwob3NjKQ%3D%3D) You can read more about [how to use Superdirt with Strudel the Tutorial](https://strudel.cc/learn/input-output/#superdirt-api) From 663229ecde6e6cff0a9aa71386e2fa3e6fe10a51 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Wed, 17 Sep 2025 13:50:02 +0200 Subject: [PATCH 182/335] bump osc to 1.2.8 --- packages/osc/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/osc/package.json b/packages/osc/package.json index 239acda19..4244c2c61 100644 --- a/packages/osc/package.json +++ b/packages/osc/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/osc", - "version": "1.2.7", + "version": "1.2.8", "description": "OSC messaging for strudel", "main": "osc.mjs", "bin": "./server.js", From 82c90471954d41f90d39c3b4c108a4ee0f24c766 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 18 Sep 2025 10:47:23 +0200 Subject: [PATCH 183/335] fix: unstable filter --- packages/supradough/dough.mjs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index 1cb9241ad..ea572224b 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -1,5 +1,5 @@ // this is dough, the superdough without dependencies -// @ts-check +// @ts-nocheck // @ts-ignore ignore next line because sampleRate is unknown const SAMPLE_RATE = typeof sampleRate !== 'undefined' ? sampleRate : 48000; const PI_DIV_SR = Math.PI / SAMPLE_RATE; @@ -151,7 +151,8 @@ export class TwoPoleFilter { resonance = Math.max(resonance, 0); cutoff = Math.min(cutoff, 20000); - const c = 2 * Math.sin(cutoff * PI_DIV_SR); + let c = 2 * Math.sin(cutoff * PI_DIV_SR); + c = clamp(c, 0, 1.14); // this line prevents instability TODO: test const r = Math.pow(0.5, (resonance + 0.125) / 0.125); const mrc = 1 - r * c; From a0c2edad30485e27fdbc787d6a58588724ad63a8 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 18 Sep 2025 10:54:41 +0200 Subject: [PATCH 184/335] fix: add clamp function --- packages/supradough/dough.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index ea572224b..7231792c9 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -6,6 +6,7 @@ const PI_DIV_SR = Math.PI / SAMPLE_RATE; const ISR = 1 / SAMPLE_RATE; let gainCurveFunc = (val) => Math.pow(val, 2); +const clamp = (num, min, max) => Math.min(Math.max(num, min), max); function applyGainCurve(val) { return gainCurveFunc(val); From 91ad3d729fb60f04e6dcc58f1286236e398cf331 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 18 Sep 2025 20:36:40 +0200 Subject: [PATCH 185/335] feat: osc add --debug flag to log messages + log errors --- packages/osc/server.js | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/packages/osc/server.js b/packages/osc/server.js index 4d87862ca..2571c49d6 100644 --- a/packages/osc/server.js +++ b/packages/osc/server.js @@ -19,7 +19,7 @@ function getArgValue(flag) { } let udpClientPort = Number(getArgValue('--port')) || 57120; -// dirt = 7771 +let debug = Number(getArgValue('--debug')) || 0; const config = { receiver: 'ws', // @param {string} Where messages sent via 'send' method will be delivered to, 'ws' for Websocket clients, 'udp' for udp client @@ -42,8 +42,34 @@ const config = { const osc = new OSC({ plugin: new OSC.BridgePlugin(config) }); -osc.open(); // start a WebSocket server on port 8080 +if (debug) { + osc.on('*', (message) => { + const { address, args } = message; + let str = ''; + for (let i = 0; i < args.length; i += 2) { + str += `${args[i]}: ${args[i + 1]} `; + } + console.log(`${address} ${str}`); + }); +} + +osc.on('error', (message) => { + if (message.toString().includes('EADDRINUSE')) { + console.log(`------ ERROR ------- +osc server already running! to stop it: +1. run "lsof -ti :57121 | xargs kill -9" (macos / linux) +2. re-run the osc server +`); + } else { + console.log(message); + } +}); + +osc.open(); console.log('osc client running on port', config.udpClient.port); console.log('osc server running on port', config.udpServer.port); console.log('websocket server running on port', config.wsServer.port); +if (debug) { + console.log('debug logs enabled. incoming messages will appear below'); +} From a25f7637968c0036e527254973fec59edc1cb52d Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 18 Sep 2025 20:37:19 +0200 Subject: [PATCH 186/335] docs: add --debug flag to readme --- packages/osc/README.md | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/packages/osc/README.md b/packages/osc/README.md index d5ee60fbc..0a7bfedcf 100644 --- a/packages/osc/README.md +++ b/packages/osc/README.md @@ -14,16 +14,28 @@ You should see something like: ```log osc client running on port 57120 -osc server running on port 7771 +osc server running on port 57121 websocket server running on port 8080 ``` +### --port + By default it will use port 57120 for the osc client, which is what [superdirt](https://github.com/musikinformatik/SuperDirt) uses. You can change it via the `--port` option: ```sh npx @strudel/osc --port 7771 # classic dirt ``` +### --debug + +To log all incoming osc messages, add the `--debug` flag: + +```sh +npx @strudel/osc --debug +``` + +## Usage in Strudel + To test it in strudel, you have can use `all(osc)` to send all events through osc: ```js @@ -32,7 +44,6 @@ $: s("bd*4") all(osc) ``` - -[open in repl](hhttps://strudel.cc/#JDogcygiYmQqNCIpCgphbGwob3NjKQ%3D%3D) +[open in repl](https://strudel.cc/#JDogcygiYmQqNCIpCgphbGwob3NjKQ%3D%3D) You can read more about [how to use Superdirt with Strudel the Tutorial](https://strudel.cc/learn/input-output/#superdirt-api) From c54fa7d2665569006b71aff9019ea17aac9dd725 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 18 Sep 2025 20:39:05 +0200 Subject: [PATCH 187/335] chore: bump osc to 1.2.8 --- packages/osc/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/osc/package.json b/packages/osc/package.json index 4244c2c61..92aa30bf3 100644 --- a/packages/osc/package.json +++ b/packages/osc/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/osc", - "version": "1.2.8", + "version": "1.2.9", "description": "OSC messaging for strudel", "main": "osc.mjs", "bin": "./server.js", From 1c3e07afd3c4fac5367b5afd18dfe4242a72c18c Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 18 Sep 2025 20:40:25 +0200 Subject: [PATCH 188/335] fix: rephrase error message + bump to 1.2.10 --- packages/osc/package.json | 2 +- packages/osc/server.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/osc/package.json b/packages/osc/package.json index 92aa30bf3..bc828d798 100644 --- a/packages/osc/package.json +++ b/packages/osc/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/osc", - "version": "1.2.9", + "version": "1.2.10", "description": "OSC messaging for strudel", "main": "osc.mjs", "bin": "./server.js", diff --git a/packages/osc/server.js b/packages/osc/server.js index 2571c49d6..d7ec21c4b 100644 --- a/packages/osc/server.js +++ b/packages/osc/server.js @@ -56,7 +56,7 @@ if (debug) { osc.on('error', (message) => { if (message.toString().includes('EADDRINUSE')) { console.log(`------ ERROR ------- -osc server already running! to stop it: +a server is already running on port 57121! to stop it: 1. run "lsof -ti :57121 | xargs kill -9" (macos / linux) 2. re-run the osc server `); From 7080490c68839226705b9df0acc14aebb1f8f4e8 Mon Sep 17 00:00:00 2001 From: Matthew Pocock Date: Thu, 18 Sep 2025 21:52:40 +0100 Subject: [PATCH 189/335] Merge handlers and cache regexes in autocomplete - Merged scalePreColonHandler and scaleAfterColonHandler into single scaleHandler - Merged modePreColonHandler and modeAfterColonHandler into single modeHandler - Cached all regex patterns as constants above their respective handler functions - Eliminated regex compilation overhead on every keystroke/navigation event - Improved code maintainability by reducing duplication between similar handlers - Preserved exact same functionality while improving performance Each handler now follows a consistent pattern of checking after-colon context first (more specific) then pre-colon context, with all regex patterns pre-compiled for better performance during intensive autocomplete sessions. --- packages/codemirror/autocomplete.mjs | 147 ++++++++++++++++----------- 1 file changed, 87 insertions(+), 60 deletions(-) diff --git a/packages/codemirror/autocomplete.mjs b/packages/codemirror/autocomplete.mjs index 8b3111b51..022c3bbaf 100644 --- a/packages/codemirror/autocomplete.mjs +++ b/packages/codemirror/autocomplete.mjs @@ -186,9 +186,16 @@ const pitchNames = [ 'Cb', ]; -function scalePreColonHandler(context) { +// Cached regex patterns for scaleHandler +const SCALE_NO_QUOTES_REGEX = /scale\(\s*$/; +const SCALE_AFTER_COLON_REGEX = /scale\(\s*['"][^'"]*:[^'"]*$/; +const SCALE_PRE_COLON_REGEX = /scale\(\s*['"][^'"]*$/; +const SCALE_PITCH_MATCH_REGEX = /([A-Ga-g][#b]*)?$/; +const SCALE_SPACES_TO_COLON_REGEX = /\s+/g; + +function scaleHandler(context) { // First check for scale context without quotes - block with empty completions - let scaleNoQuotesContext = context.matchBefore(/scale\(\s*$/); + let scaleNoQuotesContext = context.matchBefore(SCALE_NO_QUOTES_REGEX); if (scaleNoQuotesContext) { return { from: scaleNoQuotesContext.to, @@ -196,13 +203,33 @@ function scalePreColonHandler(context) { }; } - // Then check for scale context with quotes - provide completions - let scalePreColonContext = context.matchBefore(/scale\(\s*['"][^'"]*$/); + // Check for after-colon context first (more specific) + let scaleAfterColonContext = context.matchBefore(SCALE_AFTER_COLON_REGEX); + if (scaleAfterColonContext) { + const text = scaleAfterColonContext.text; + const colonIdx = text.lastIndexOf(':'); + if (colonIdx !== -1) { + const fragment = text.slice(colonIdx + 1); + const filteredScales = scaleCompletions.filter((s) => s.label.startsWith(fragment)); + const options = filteredScales.map((s) => ({ + ...s, + apply: s.label.replace(SCALE_SPACES_TO_COLON_REGEX, ':'), + })); + const from = scaleAfterColonContext.from + colonIdx + 1; + return { + from, + options, + }; + } + } + + // Then check for pre-colon context + let scalePreColonContext = context.matchBefore(SCALE_PRE_COLON_REGEX); if (scalePreColonContext) { if (!scalePreColonContext.text.includes(':')) { if (context.explicit) { const text = scalePreColonContext.text; - const match = text.match(/([A-Ga-g][#b]*)?$/); + const match = text.match(SCALE_PITCH_MATCH_REGEX); const fragment = match ? match[0] : ''; const filtered = pitchNames.filter((p) => p.toLowerCase().startsWith(fragment.toLowerCase())); const from = scalePreColonContext.to - fragment.length; @@ -216,9 +243,14 @@ function scalePreColonHandler(context) { return null; } +// Cached regex patterns for soundHandler +const SOUND_NO_QUOTES_REGEX = /(s|sound)\(\s*$/; +const SOUND_WITH_QUOTES_REGEX = /(s|sound)\(\s*['"][^'"]*$/; +const SOUND_FRAGMENT_MATCH_REGEX = /(?:[\s[{(<])([\w]*)$/; + function soundHandler(context) { // First check for sound context without quotes - block with empty completions - let soundNoQuotesContext = context.matchBefore(/(s|sound)\(\s*$/); + let soundNoQuotesContext = context.matchBefore(SOUND_NO_QUOTES_REGEX); if (soundNoQuotesContext) { return { from: soundNoQuotesContext.to, @@ -227,14 +259,14 @@ function soundHandler(context) { } // Then check for sound context with quotes - provide completions - let soundContext = context.matchBefore(/(s|sound)\(\s*['"][^'"]*$/); + let soundContext = context.matchBefore(SOUND_WITH_QUOTES_REGEX); if (!soundContext) return null; const text = soundContext.text; const quoteIdx = Math.max(text.lastIndexOf('"'), text.lastIndexOf("'")); if (quoteIdx === -1) return null; const inside = text.slice(quoteIdx + 1); - const fragMatch = inside.match(/(?:[\s[{(<])([\w]*)$/); + const fragMatch = inside.match(SOUND_FRAGMENT_MATCH_REGEX); const fragment = fragMatch ? fragMatch[1] : inside; const soundNames = Object.keys(soundMap.get()).sort(); const filteredSounds = soundNames.filter((name) => name.includes(fragment)); @@ -246,9 +278,13 @@ function soundHandler(context) { }; } +// Cached regex patterns for bankHandler +const BANK_NO_QUOTES_REGEX = /bank\(\s*$/; +const BANK_WITH_QUOTES_REGEX = /bank\(\s*['"][^'"]*$/; + function bankHandler(context) { // First check for bank context without quotes - block with empty completions - let bankNoQuotesContext = context.matchBefore(/bank\(\s*$/); + let bankNoQuotesContext = context.matchBefore(BANK_NO_QUOTES_REGEX); if (bankNoQuotesContext) { return { from: bankNoQuotesContext.to, @@ -257,7 +293,7 @@ function bankHandler(context) { } // Then check for bank context with quotes - provide completions - let bankMatch = context.matchBefore(/bank\(\s*['"][^'"]*$/); + let bankMatch = context.matchBefore(BANK_WITH_QUOTES_REGEX); if (!bankMatch) return null; const text = bankMatch.text; @@ -274,9 +310,15 @@ function bankHandler(context) { }; } -function modePreColonHandler(context) { +// Cached regex patterns for modeHandler +const MODE_NO_QUOTES_REGEX = /mode\(\s*$/; +const MODE_AFTER_COLON_REGEX = /mode\(\s*['"][^'"]*:[^'"]*$/; +const MODE_PRE_COLON_REGEX = /mode\(\s*['"][^'"]*$/; +const MODE_FRAGMENT_MATCH_REGEX = /(?:[\s[{(<])([\w:]*)$/; + +function modeHandler(context) { // First check for mode context without quotes - block with empty completions - let modeNoQuotesContext = context.matchBefore(/mode\(\s*$/); + let modeNoQuotesContext = context.matchBefore(MODE_NO_QUOTES_REGEX); if (modeNoQuotesContext) { return { from: modeNoQuotesContext.to, @@ -284,15 +326,33 @@ function modePreColonHandler(context) { }; } - // Then check for mode context with quotes - provide completions - let modeContext = context.matchBefore(/mode\(\s*['"][^'"]*$/); + // Check for after-colon context first (more specific) + let modeAfterColonContext = context.matchBefore(MODE_AFTER_COLON_REGEX); + if (modeAfterColonContext) { + const text = modeAfterColonContext.text; + const colonIdx = text.lastIndexOf(':'); + if (colonIdx !== -1) { + const fragment = text.slice(colonIdx + 1); + // For anchor after colon, we can suggest pitch names + const filtered = pitchNames.filter((p) => p.toLowerCase().startsWith(fragment.toLowerCase())); + const options = filtered.map((p) => ({ label: p, type: 'pitch' })); + const from = modeAfterColonContext.from + colonIdx + 1; + return { + from, + options, + }; + } + } + + // Then check for pre-colon context + let modeContext = context.matchBefore(MODE_PRE_COLON_REGEX); if (!modeContext) return null; const text = modeContext.text; const quoteIdx = Math.max(text.lastIndexOf('"'), text.lastIndexOf("'")); if (quoteIdx === -1) return null; const inside = text.slice(quoteIdx + 1); - const fragMatch = inside.match(/(?:[\s[{(<])([\w:]*)$/); + const fragMatch = inside.match(MODE_FRAGMENT_MATCH_REGEX); const fragment = fragMatch ? fragMatch[1] : inside; const filteredModes = modeCompletions.filter((m) => m.label.startsWith(fragment)); const from = modeContext.to - fragment.length; @@ -302,28 +362,14 @@ function modePreColonHandler(context) { }; } -function modeAfterColonHandler(context) { - let modeContext = context.matchBefore(/mode\(\s*['"][^'"]*:[^'"]*$/); - if (!modeContext) return null; - - const text = modeContext.text; - const colonIdx = text.lastIndexOf(':'); - if (colonIdx === -1) return null; - const fragment = text.slice(colonIdx + 1); - - // For anchor after colon, we can suggest pitch names - const filtered = pitchNames.filter((p) => p.toLowerCase().startsWith(fragment.toLowerCase())); - const options = filtered.map((p) => ({ label: p, type: 'pitch' })); - const from = modeContext.from + colonIdx + 1; - return { - from, - options, - }; -} +// Cached regex patterns for chordHandler +const CHORD_NO_QUOTES_REGEX = /chord\(\s*$/; +const CHORD_WITH_QUOTES_REGEX = /chord\(\s*['"][^'"]*$/; +const CHORD_FRAGMENT_MATCH_REGEX = /(?:[\s[{(<])([\w#b+^:-]*)$/; function chordHandler(context) { // First check for chord context without quotes - block with empty completions - let chordNoQuotesContext = context.matchBefore(/chord\(\s*$/); + let chordNoQuotesContext = context.matchBefore(CHORD_NO_QUOTES_REGEX); if (chordNoQuotesContext) { return { from: chordNoQuotesContext.to, @@ -332,7 +378,7 @@ function chordHandler(context) { } // Then check for chord context with quotes - provide completions - let chordContext = context.matchBefore(/chord\(\s*['"][^'"]*$/); + let chordContext = context.matchBefore(CHORD_WITH_QUOTES_REGEX); if (!chordContext) return null; const text = chordContext.text; @@ -341,7 +387,7 @@ function chordHandler(context) { const inside = text.slice(quoteIdx + 1); // Use same fragment matching as sound/mode for expressions like "" - const fragMatch = inside.match(/(?:[\s[{(<])([\w#b+^:-]*)$/); + const fragMatch = inside.match(CHORD_FRAGMENT_MATCH_REGEX); const fragment = fragMatch ? fragMatch[1] : inside; // Check if fragment contains any pitch name at start (for root + symbol) @@ -375,28 +421,11 @@ function chordHandler(context) { } } -function scaleAfterColonHandler(context) { - let scaleContext = context.matchBefore(/scale\(\s*['"][^'"]*:[^'"]*$/); - if (!scaleContext) return null; - - const text = scaleContext.text; - const colonIdx = text.lastIndexOf(':'); - if (colonIdx === -1) return null; - const fragment = text.slice(colonIdx + 1); - const filteredScales = scaleCompletions.filter((s) => s.label.startsWith(fragment)); - const options = filteredScales.map((s) => ({ - ...s, - apply: s.label.replace(/\s+/g, ':'), - })); - const from = scaleContext.from + colonIdx + 1; - return { - from, - options, - }; -} +// Cached regex patterns for fallbackHandler +const FALLBACK_WORD_REGEX = /\w*/; function fallbackHandler(context) { - const word = context.matchBefore(/\w*/); + const word = context.matchBefore(FALLBACK_WORD_REGEX); if (word && word.from === word.to && !context.explicit) return null; if (word) { return { @@ -411,10 +440,8 @@ const handlers = [ soundHandler, bankHandler, chordHandler, - scalePreColonHandler, - scaleAfterColonHandler, - modePreColonHandler, - modeAfterColonHandler, + scaleHandler, + modeHandler, // this handler *must* be last fallbackHandler, ]; From 8833d623f71f89df51b79a4f8467456f72daa278 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 21 Sep 2025 16:06:28 +0200 Subject: [PATCH 190/335] fix: all function in mondo --- packages/mondough/mondough.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mondough/mondough.mjs b/packages/mondough/mondough.mjs index e409d5a3b..669183279 100644 --- a/packages/mondough/mondough.mjs +++ b/packages/mondough/mondough.mjs @@ -85,7 +85,7 @@ function evaluator(node, scope) { let pat; if (type === 'plain' && typeof variable !== 'undefined') { // some function names are not patternable, so we skip reification here - if (['!', 'extend', '@', 'expand', 'square', 'angle'].includes(value)) { + if (['!', 'extend', '@', 'expand', 'square', 'angle', 'all'].includes(value)) { return variable; } pat = reify(variable); From 86248328cc2be957da71566aeb671f69a10ccabe Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 21 Sep 2025 16:09:10 +0200 Subject: [PATCH 191/335] fix: mondo setcps / setcpm --- packages/core/repl.mjs | 17 +++++++++++++++-- packages/mondough/mondough.mjs | 2 +- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/packages/core/repl.mjs b/packages/core/repl.mjs index 47231af4d..23c5b25e0 100644 --- a/packages/core/repl.mjs +++ b/packages/core/repl.mjs @@ -85,7 +85,17 @@ export function repl({ const start = () => scheduler.start(); const pause = () => scheduler.pause(); const toggle = () => scheduler.toggle(); - const setCps = (cps) => scheduler.setCps(cps); + const setCps = (cps) => { + scheduler.setCps(unpure(cps)); + return silence; + }; + + function unpure(pat) { + if (pat._Pattern) { + return pat.__pure; + } + return pat; + } /** * Changes the global tempo to the given cycles per minute @@ -97,7 +107,10 @@ export function repl({ * setcpm(140/4) // =140 bpm in 4/4 * $: s("bd*4,[- sd]*2").bank('tr707') */ - const setCpm = (cpm) => scheduler.setCps(cpm / 60); + const setCpm = (cpm) => { + scheduler.setCps(unpure(cpm) / 60); + return silence; + }; // TODO - not documented as jsdoc examples as the test framework doesn't simulate enough context for `each` and `all`.. diff --git a/packages/mondough/mondough.mjs b/packages/mondough/mondough.mjs index 669183279..b7ee83787 100644 --- a/packages/mondough/mondough.mjs +++ b/packages/mondough/mondough.mjs @@ -85,7 +85,7 @@ function evaluator(node, scope) { let pat; if (type === 'plain' && typeof variable !== 'undefined') { // some function names are not patternable, so we skip reification here - if (['!', 'extend', '@', 'expand', 'square', 'angle', 'all'].includes(value)) { + if (['!', 'extend', '@', 'expand', 'square', 'angle', 'all', 'setcpm', 'setcps'].includes(value)) { return variable; } pat = reify(variable); From 452827630b2ea1949674e645835a960bb1ae1be1 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 21 Sep 2025 16:13:09 +0200 Subject: [PATCH 192/335] move unpure up --- packages/core/repl.mjs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/core/repl.mjs b/packages/core/repl.mjs index 23c5b25e0..53562f216 100644 --- a/packages/core/repl.mjs +++ b/packages/core/repl.mjs @@ -74,6 +74,14 @@ export function repl({ return silence; }; + // helper to get a patternified pure value out + function unpure(pat) { + if (pat._Pattern) { + return pat.__pure; + } + return pat; + } + const setPattern = async (pattern, autostart = true) => { pattern = editPattern?.(pattern) || pattern; await scheduler.setPattern(pattern, autostart); @@ -90,13 +98,6 @@ export function repl({ return silence; }; - function unpure(pat) { - if (pat._Pattern) { - return pat.__pure; - } - return pat; - } - /** * Changes the global tempo to the given cycles per minute * From c64aa3bf01b1af8a01f26064ce9a4542fe1ffcd4 Mon Sep 17 00:00:00 2001 From: Kissaki Date: Sun, 21 Sep 2025 18:27:05 +0200 Subject: [PATCH 193/335] Fix link syntax in `project-start` --- website/src/pages/technical-manual/project-start.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/pages/technical-manual/project-start.mdx b/website/src/pages/technical-manual/project-start.mdx index 4e6e37636..d5612736a 100644 --- a/website/src/pages/technical-manual/project-start.mdx +++ b/website/src/pages/technical-manual/project-start.mdx @@ -118,7 +118,7 @@ If you'd rather use your own UI, you can use the `@strudel/web` package: ``` -For more info on this package, see the [@strudel/web README]https://codeberg.org/uzu/strudel/src/branch/main/packages/web#strudel-web). +For more info on this package, see the [@strudel/web README](https://codeberg.org/uzu/strudel/src/branch/main/packages/web#strudel-web). ## Via npm From 4d39f36868c4240f242443e5492861820c24288a Mon Sep 17 00:00:00 2001 From: Kissaki Date: Sun, 21 Sep 2025 18:31:59 +0200 Subject: [PATCH 194/335] Fix web README sample code Looks like the code was copied, and then the wrong string was replaced when creating this code sample. --- packages/web/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web/README.md b/packages/web/README.md index 659c82713..e86600cd7 100644 --- a/packages/web/README.md +++ b/packages/web/README.md @@ -62,7 +62,7 @@ initStrudel(); document.getElementById('play').addEventListener('click', () => evaluate('note("c a f e").jux(rev)') ); -document.getElementById('play').addEventListener('stop', +document.getElementById('stop').addEventListener('click', () => hush() ); ``` From c5bd2a7487a8da8ee61bbaedfd0d278e29eba75e Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sun, 21 Sep 2025 23:54:04 -0400 Subject: [PATCH 195/335] working --- packages/core/controls.mjs | 12 ++ packages/superdough/feedbackdelay.mjs | 3 + packages/superdough/helpers.mjs | 7 + packages/superdough/superdough.mjs | 199 +++-------------------- packages/superdough/superdoughoutput.mjs | 192 ++++++++++++++++++++++ 5 files changed, 238 insertions(+), 175 deletions(-) create mode 100644 packages/superdough/superdoughoutput.mjs diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 044cfa96d..f961e4fa4 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -402,6 +402,18 @@ export const { bandq, bpq } = registerControl('bandq', 'bpq'); * */ export const { begin } = registerControl('begin'); +/** + * A pattern of numbers from 0 to 1. Skips the beginning of each sample, e.g. `0.25` to cut off the first quarter from each sample. + * + * @memberof Pattern + * @name bufferHold + * @param {number | Pattern} amount between 0 and 1, where 1 is the length of the sample + * @example + * samples({ rave: 'rave/AREUREADY.wav' }, 'github:tidalcycles/dirt-samples') + * s("rave").begin("<0 .25 .5 .75>").fast(2) + * + */ +export const { bufferHold } = registerControl('bufferHold'); /** * The same as .begin, but cuts off the end off each sample. * diff --git a/packages/superdough/feedbackdelay.mjs b/packages/superdough/feedbackdelay.mjs index c182d6558..13beeb1cf 100644 --- a/packages/superdough/feedbackdelay.mjs +++ b/packages/superdough/feedbackdelay.mjs @@ -23,6 +23,9 @@ if (typeof DelayNode !== 'undefined') { start(t) { this.delayGain.gain.setValueAtTime(this.delayGain.gain.value, t + this.delayTime.value); } + stop(t) { + this.delayGain.gain.setValueAtTime(0, t); + } } AudioContext.prototype.createFeedbackDelay = function (wet, time, feedback) { diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index 69e7e8560..5b2fa1a40 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -10,6 +10,13 @@ export function gainNode(value) { return node; } +export function effectSend(input, effect, wet) { + const send = gainNode(wet); + input.connect(send); + send.connect(effect); + return send; +} + const getSlope = (y1, y2, x1, x2) => { const denom = x2 - x1; if (denom === 0) { diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index f1f308a7d..0d1845b91 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -7,12 +7,13 @@ This program is free software: you can redistribute it and/or modify it under th import './feedbackdelay.mjs'; import './reverb.mjs'; import './vowel.mjs'; -import { clamp, nanFallback, _mod, cycleToSeconds, secondsToCycle } from './util.mjs'; +import { nanFallback, _mod, cycleToSeconds } from './util.mjs'; import workletsUrl from './worklets.mjs?audioworklet'; -import { createFilter, gainNode, getCompressor, getWorklet, webAudioTimeout } from './helpers.mjs'; +import { createFilter, gainNode, getCompressor, getWorklet, effectSend } from './helpers.mjs'; import { map } from 'nanostores'; -import { logger, errorLogger } from './logger.mjs'; +import { logger } from './logger.mjs'; import { loadBuffer } from './sampler.mjs'; +import { SuperdoughAudioController } from './superdoughoutput.mjs'; export const DEFAULT_MAX_POLYPHONY = 128; const DEFAULT_AUDIO_DEVICE_NAME = 'System Standard'; @@ -301,65 +302,16 @@ export async function initAudioOnFirstClick(options) { return audioReady; } -const maxfeedback = 0.98; - -let channelMerger, destinationGain; -//update the output channel configuration to match user's audio device -export function initializeAudioOutput() { - const audioContext = getAudioContext(); - const maxChannelCount = audioContext.destination.maxChannelCount; - audioContext.destination.channelCount = maxChannelCount; - channelMerger = new ChannelMergerNode(audioContext, { numberOfInputs: audioContext.destination.channelCount }); - destinationGain = new GainNode(audioContext); - channelMerger.connect(destinationGain); - destinationGain.connect(audioContext.destination); +let controller; +function getSuperdoughAudioController() { + if (controller == null) { + controller = new SuperdoughAudioController(getAudioContext()); + } + return controller; } - -// input: AudioNode, channels: ?Array -export const connectToDestination = (input, channels = [0, 1]) => { - const ctx = getAudioContext(); - if (channelMerger == null) { - initializeAudioOutput(); - } - //This upmix can be removed if correct channel counts are set throughout the app, - // and then strudel could theoretically support surround sound audio files - const stereoMix = new StereoPannerNode(ctx); - input.connect(stereoMix); - - const splitter = new ChannelSplitterNode(ctx, { - numberOfOutputs: stereoMix.channelCount, - }); - stereoMix.connect(splitter); - channels.forEach((ch, i) => { - splitter.connect(channelMerger, i % stereoMix.channelCount, ch % ctx.destination.channelCount); - }); -}; - -export const panic = () => { - if (destinationGain == null) { - return; - } - destinationGain.gain.linearRampToValueAtTime(0, getAudioContext().currentTime + 0.01); - destinationGain = null; - channelMerger == null; -}; - -function getDelay(orbit, delaytime, delayfeedback, t) { - if (delayfeedback > maxfeedback) { - //logger(`delayfeedback was clamped to ${maxfeedback} to save your ears`); - } - delayfeedback = clamp(delayfeedback, 0, 0.98); - let delayNode = orbits[orbit].delayNode; - if (delayNode === undefined) { - const ac = getAudioContext(); - delayNode = ac.createFeedbackDelay(1, delaytime, delayfeedback); - delayNode.start?.(t); // for some reason, this throws when audion extension is installed.. - connectToOrbit(delayNode, orbit); - orbits[orbit].delayNode = delayNode; - } - delayNode.delayTime.value !== delaytime && delayNode.delayTime.setValueAtTime(delaytime, t); - delayNode.feedback.value !== delayfeedback && delayNode.feedback.setValueAtTime(delayfeedback, t); - return delayNode; +export function connectToDestination(input, channels) { + const controller = getSuperdoughAudioController(); + controller.output.connectToDestination(input, channels); } export function getLfo(audioContext, begin, end, properties = {}) { @@ -415,97 +367,6 @@ function getFilterType(ftype) { return typeof ftype === 'number' ? filterTypes[Math.floor(_mod(ftype, filterTypes.length))] : ftype; } -// type orbit { -// output: GainNode, -// reverbNode: ConvolverNode -// delayNode: FeedbackDelayNode -// } -let orbits = {}; -function connectToOrbit(node, orbit) { - if (orbits[orbit] == null) { - errorLogger(new Error('target orbit does not exist'), 'superdough'); - } - node.connect(orbits[orbit].output); -} - -function setOrbit(audioContext, orbit, channels) { - if (orbits[orbit] == null) { - orbits[orbit] = { - // Setup output node through which all audio filters prior to hitting - // the destination (and thus allows for global volume automation) - output: new GainNode(audioContext, { gain: 1, channelCount: 2, channelCountMode: 'explicit' }), - }; - connectToDestination(orbits[orbit].output, channels); - } -} - -function duckOrbit(audioContext, targetOrbit, t, onsettime = 0, attacktime = 0.1, duckdepth = 1) { - const targetArr = [targetOrbit].flat(); - const onsetArr = [onsettime].flat(); - const attackArr = [attacktime].flat(); - const depthArr = [duckdepth].flat(); - - targetArr.forEach((target, idx) => { - if (orbits[target] == null) { - errorLogger(new Error(`duck target orbit ${target} does not exist`), 'superdough'); - return; - } - const onset = onsetArr[idx] ?? onsetArr[0]; - const attack = Math.max(attackArr[idx] ?? attackArr[0], 0.002); - const depth = depthArr[idx] ?? depthArr[0]; - const gainParam = orbits[target].output.gain; - webAudioTimeout( - audioContext, - () => { - const now = audioContext.currentTime; - - // cancelScheduledValues and setValueAtTime together emulate cancelAndHoldAtTime - // on browsers which lack that method - const currVal = gainParam.value; - gainParam.cancelScheduledValues(now); - gainParam.setValueAtTime(currVal, now); - - const t0 = Math.max(t, now); // guard against now > t - const duckedVal = clamp(1 - Math.sqrt(depth), 0.01, currVal); - gainParam.exponentialRampToValueAtTime(duckedVal, t0 + onset); - gainParam.exponentialRampToValueAtTime(1, t0 + onset + attack); - }, - 0, - t - 0.01, - ); - }); -} - -let hasChanged = (now, before) => now !== undefined && now !== before; -function getReverb(orbit, duration, fade, lp, dim, ir, irspeed, irbegin) { - // If no reverb has been created for a given orbit, create one - let reverbNode = orbits[orbit].reverbNode; - if (reverbNode === undefined) { - const ac = getAudioContext(); - reverbNode = ac.createReverb(duration, fade, lp, dim, ir, irspeed, irbegin); - connectToOrbit(reverbNode, orbit); - orbits[orbit].reverbNode = reverbNode; - } - - if ( - hasChanged(duration, reverbNode.duration) || - hasChanged(fade, reverbNode.fade) || - hasChanged(lp, reverbNode.lp) || - hasChanged(dim, reverbNode.dim) || - hasChanged(irspeed, reverbNode.irspeed) || - hasChanged(irbegin, reverbNode.irbegin) || - reverbNode.ir !== ir - ) { - // only regenerate when something has changed - // avoids endless regeneration on things like - // stack(s("a"), s("b").rsize(8)).room(.5) - // this only works when args may stay undefined until here - // setting default values breaks this - reverbNode.generate(duration, fade, lp, dim, ir, irspeed, irbegin); - } - return reverbNode; -} - export let analysers = {}, analysersData = {}; @@ -538,15 +399,8 @@ export function getAnalyzerData(type = 'time', id = 1) { return analysersData[id]; } -function effectSend(input, effect, wet) { - const send = gainNode(wet); - input.connect(send); - send.connect(effect); - return send; -} - export function resetGlobalEffects() { - orbits = {}; + controller.reset(); analysers = {}; analysersData = {}; } @@ -561,6 +415,7 @@ function mapChannelNumbers(channels) { export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) => { // new: t is always expected to be the absolute target onset time const ac = getAudioContext(); + const audioController = getSuperdoughAudioController(); let { stretch } = value; if (stretch != null) { @@ -679,10 +534,9 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) ); const channels = value.channels != null ? mapChannelNumbers(value.channels) : orbitChannels; - setOrbit(ac, orbit, channels, t, cycle, cps); - + const orbitBus = audioController.getOrbit(orbit, channels); if (duckorbit != null) { - duckOrbit(ac, duckorbit, t, duckonset, duckattack, duckdepth); + orbitBus.duck(duckorbit, t, duckonset, duckattack, duckdepth); } gain = applyGainCurve(nanFallback(gain, 1)); @@ -872,14 +726,11 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) chain.push(post); // delay - let delaySend; if (delay > 0 && delaytime > 0 && delayfeedback > 0) { - const delayNode = getDelay(orbit, delaytime, delayfeedback, t); - delaySend = effectSend(post, delayNode, delay); - audioNodes.push(delaySend); + orbitBus.getDelay(delaytime, delayfeedback, t); + orbitBus.sendDelay(post, delay); } // reverb - let reverbSend; if (room > 0) { let roomIR; if (ir !== undefined) { @@ -892,25 +743,23 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) } roomIR = await loadBuffer(url, ac, ir, 0); } - const reverbNode = getReverb(orbit, roomsize, roomfade, roomlp, roomdim, roomIR, irspeed, irbegin); - reverbSend = effectSend(post, reverbNode, room); - audioNodes.push(reverbSend); + orbitBus.getReverb(roomsize, roomfade, roomlp, roomdim, roomIR, irspeed, irbegin); + orbitBus.sendReverb(post, room); } // analyser - let analyserSend; if (analyze) { const analyserNode = getAnalyserById(analyze, 2 ** (fft + 5)); - analyserSend = effectSend(post, analyserNode, 1); + const analyserSend = effectSend(post, analyserNode, 1); audioNodes.push(analyserSend); } if (dry != null) { dry = applyGainCurve(dry); const dryGain = new GainNode(ac, { gain: dry }); chain.push(dryGain); - connectToOrbit(dryGain, orbit); + orbitBus.connectToOutput(dryGain); } else { - connectToOrbit(post, orbit); + orbitBus.connectToOutput(post); } // connect chain elements together diff --git a/packages/superdough/superdoughoutput.mjs b/packages/superdough/superdoughoutput.mjs new file mode 100644 index 000000000..cb391ead7 --- /dev/null +++ b/packages/superdough/superdoughoutput.mjs @@ -0,0 +1,192 @@ +import { effectSend, webAudioTimeout } from './helpers.mjs'; +import { errorLogger } from './logger.mjs'; + +let hasChanged = (now, before) => now !== undefined && now !== before; + +export class Orbit { + reverbNode; + delayNode; + output; + summingNode; + audioContext; + constructor(audioContext) { + this.audioContext = audioContext; + this.output = new GainNode(audioContext, { gain: 1, channelCount: 2, channelCountMode: 'explicit' }); + this.summingNode = new GainNode(audioContext, { gain: 1, channelCount: 2, channelCountMode: 'explicit' }); + this.summingNode.connect(this.output); + } + + disconnect() { + this.output.disconnect(); + this.summingNode.disconnect(); + this.delayNode?.disconnect(); + this.reverbNode?.disconnect(); + } + + getDelay(delaytime = 0, feedback = 0.5, t) { + const maxfeedback = 0.98; + if (feedback > maxfeedback) { + //logger(`feedback was clamped to ${maxfeedback} to save your ears`); + } + feedback = clamp(feedback, 0, 0.98); + if (this.delayNode == null) { + this.delayNode = this.audioContext.createFeedbackDelay(1, delaytime, feedback); + this.delayNode.connect(this.summingNode); + this.delayNode.start?.(t); // for some reason, this throws when audion extension is installed.. + } + this.delayNode.delayTime.value !== delaytime && this.delayNode.delayTime.setValueAtTime(delaytime, t); + this.delayNode.feedback.value !== feedback && this.delayNode.feedback.setValueAtTime(feedback, t); + return this.delayNode; + } + + getReverb(duration, fade, lp, dim, ir, irspeed, irbegin) { + // If no reverb has been created for a given orbit, create one + if (this.reverbNode == null) { + this.reverbNode = this.audioContext.createReverb(duration, fade, lp, dim, ir, irspeed, irbegin); + this.reverbNode.connect(this.summingNode); + } + + if ( + hasChanged(duration, this.reverbNode.duration) || + hasChanged(fade, this.reverbNode.fade) || + hasChanged(lp, this.reverbNode.lp) || + hasChanged(dim, this.reverbNode.dim) || + hasChanged(irspeed, this.reverbNode.irspeed) || + hasChanged(irbegin, this.reverbNode.irbegin) || + this.reverbNode.ir !== ir + ) { + // only regenerate when something has changed + // avoids endless regeneration on things like + // stack(s("a"), s("b").rsize(8)).room(.5) + // this only works when args may stay undefined until here + // setting default values breaks this + this.reverbNode.generate(duration, fade, lp, dim, ir, irspeed, irbegin); + } + return this.reverbNode; + } + sendReverb(node, amount) { + effectSend(node, this.reverbNode, amount); + } + + sendDelay(node, amount) { + effectSend(node, this.delayNode, amount); + } + + duck(t, onsettime = 0, attacktime = 0.1, depth = 1) { + const onset = onsettime; + const attack = Math.max(attacktime, 0.002); + const gainParam = this.output.gain; + webAudioTimeout( + this.audioContext, + () => { + const now = this.audioContext.currentTime; + + // cancelScheduledValues and setValueAtTime together emulate cancelAndHoldAtTime + // on browsers which lack that method + const currVal = gainParam.value; + gainParam.cancelScheduledValues(now); + gainParam.setValueAtTime(currVal, now); + + const t0 = Math.max(t, now); // guard against now > t + const duckedVal = clamp(1 - Math.sqrt(depth), 0.01, currVal); + gainParam.exponentialRampToValueAtTime(duckedVal, t0 + onset); + gainParam.exponentialRampToValueAtTime(1, t0 + onset + attack); + }, + 0, + t - 0.01, + ); + } + + connectToOutput(node) { + node.connect(this.summingNode); + } +} + +export class SuperdoughOutput { + channelMerger; + destinationGain; + + constructor(audioContext) { + this.audioContext = audioContext; + this.initializeAudio(); + } + + initializeAudio() { + const audioContext = this.audioContext; + const maxChannelCount = audioContext.destination.maxChannelCount; + this.audioContext.destination.channelCount = maxChannelCount; + this.channelMerger = new ChannelMergerNode(audioContext, { numberOfInputs: audioContext.destination.channelCount }); + this.destinationGain = new GainNode(audioContext); + this.channelMerger.connect(this.destinationGain); + this.destinationGain.connect(audioContext.destination); + } + + reset() { + this.channelMerger.disconnect(); + this.destinationGain.disconnect(); + this.destinationGain = null; + this.channelMerger = null; + this.nodes = {}; + this.initializeAudio(); + } + connectToDestination = (input, channels = [0, 1]) => { + //This upmix can be removed if correct channel counts are set throughout the app, + // and then strudel could theoretically support surround sound audio files + const stereoMix = new StereoPannerNode(this.audioContext); + input.connect(stereoMix); + + const splitter = new ChannelSplitterNode(this.audioContext, { + numberOfOutputs: stereoMix.channelCount, + }); + stereoMix.connect(splitter); + channels.forEach((ch, i) => { + splitter.connect(this.channelMerger, i % stereoMix.channelCount, ch % this.audioContext.destination.channelCount); + }); + }; +} + +export class SuperdoughAudioController { + audioContext; + output; + nodes = {}; + + constructor(audioContext) { + this.audioContext = audioContext; + this.output = new SuperdoughOutput(audioContext); + } + + reset() { + Array.from(this.nodes).forEach((node) => { + node.disconnect(); + }); + this.output.reset(); + } + + duck(targetOrbits, t, onsettime = 0, attacktime = 0.1, depth = 1) { + const targetArr = [targetOrbits].flat(); + const onsetArr = [onsettime].flat(); + const attackArr = [attacktime].flat(); + const depthArr = [depth].flat(); + + targetArr.forEach((target, idx) => { + const orbit = this.nodes[target]; + + if (orbit == null) { + errorLogger(new Error(`duck target orbit ${target} does not exist`), 'superdough'); + return; + } + const onset = onsetArr[idx] ?? onsetArr[0]; + const attack = Math.max(attackArr[idx] ?? attackArr[0], 0.002); + const depth = depthArr[idx] ?? depthArr[0]; + orbit.duck({ t, onsettime: onset, attacktime: attack, depth }); + }); + } + + getOrbit(orbitNum, channels) { + if (this.nodes[orbitNum] == null) { + this.nodes[orbitNum] = new Orbit(this.audioContext); + this.output.connectToDestination(this.nodes[orbitNum].output, channels); + } + return this.nodes[orbitNum]; + } +} From beafd9c7001c5976ae936fc669f3f522b547c435 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Mon, 22 Sep 2025 00:07:06 -0400 Subject: [PATCH 196/335] format --- packages/superdough/superdough.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 0d1845b91..922fbbe43 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -400,7 +400,7 @@ export function getAnalyzerData(type = 'time', id = 1) { } export function resetGlobalEffects() { - controller.reset(); + controller?.reset(); analysers = {}; analysersData = {}; } From 82893ffc226bb47df9269d270845f206391109ba Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Mon, 22 Sep 2025 00:11:02 -0400 Subject: [PATCH 197/335] fix import --- packages/superdough/superdoughoutput.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/superdough/superdoughoutput.mjs b/packages/superdough/superdoughoutput.mjs index cb391ead7..df1a29ab2 100644 --- a/packages/superdough/superdoughoutput.mjs +++ b/packages/superdough/superdoughoutput.mjs @@ -1,5 +1,6 @@ import { effectSend, webAudioTimeout } from './helpers.mjs'; import { errorLogger } from './logger.mjs'; +import {clamp} from './util.mjs' let hasChanged = (now, before) => now !== undefined && now !== before; From da926805b37dc28a2cce4185b890f77350b7e2ac Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Mon, 22 Sep 2025 00:12:48 -0400 Subject: [PATCH 198/335] rm dead code --- packages/core/controls.mjs | 12 ------------ packages/superdough/superdough.mjs | 1 - packages/superdough/superdoughoutput.mjs | 2 +- 3 files changed, 1 insertion(+), 14 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index f961e4fa4..044cfa96d 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -402,18 +402,6 @@ export const { bandq, bpq } = registerControl('bandq', 'bpq'); * */ export const { begin } = registerControl('begin'); -/** - * A pattern of numbers from 0 to 1. Skips the beginning of each sample, e.g. `0.25` to cut off the first quarter from each sample. - * - * @memberof Pattern - * @name bufferHold - * @param {number | Pattern} amount between 0 and 1, where 1 is the length of the sample - * @example - * samples({ rave: 'rave/AREUREADY.wav' }, 'github:tidalcycles/dirt-samples') - * s("rave").begin("<0 .25 .5 .75>").fast(2) - * - */ -export const { bufferHold } = registerControl('bufferHold'); /** * The same as .begin, but cuts off the end off each sample. * diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 922fbbe43..72c167adf 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -727,7 +727,6 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) // delay if (delay > 0 && delaytime > 0 && delayfeedback > 0) { - orbitBus.getDelay(delaytime, delayfeedback, t); orbitBus.sendDelay(post, delay); } // reverb diff --git a/packages/superdough/superdoughoutput.mjs b/packages/superdough/superdoughoutput.mjs index df1a29ab2..29113e469 100644 --- a/packages/superdough/superdoughoutput.mjs +++ b/packages/superdough/superdoughoutput.mjs @@ -1,6 +1,6 @@ import { effectSend, webAudioTimeout } from './helpers.mjs'; import { errorLogger } from './logger.mjs'; -import {clamp} from './util.mjs' +import { clamp } from './util.mjs'; let hasChanged = (now, before) => now !== undefined && now !== before; From fdcdc3aaa0e82ff1c6c69a4604cf7091fc463a10 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Mon, 22 Sep 2025 00:13:59 -0400 Subject: [PATCH 199/335] rm deadcode --- packages/superdough/feedbackdelay.mjs | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/superdough/feedbackdelay.mjs b/packages/superdough/feedbackdelay.mjs index 13beeb1cf..c182d6558 100644 --- a/packages/superdough/feedbackdelay.mjs +++ b/packages/superdough/feedbackdelay.mjs @@ -23,9 +23,6 @@ if (typeof DelayNode !== 'undefined') { start(t) { this.delayGain.gain.setValueAtTime(this.delayGain.gain.value, t + this.delayTime.value); } - stop(t) { - this.delayGain.gain.setValueAtTime(0, t); - } } AudioContext.prototype.createFeedbackDelay = function (wet, time, feedback) { From 1eb9dc73fa6259c29aafbfb4d39972a8fbf72c97 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Mon, 22 Sep 2025 00:34:57 -0400 Subject: [PATCH 200/335] fix duck --- packages/superdough/superdough.mjs | 3 ++- packages/superdough/superdoughoutput.mjs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 72c167adf..f22e82d7b 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -536,7 +536,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) const channels = value.channels != null ? mapChannelNumbers(value.channels) : orbitChannels; const orbitBus = audioController.getOrbit(orbit, channels); if (duckorbit != null) { - orbitBus.duck(duckorbit, t, duckonset, duckattack, duckdepth); + audioController.duck(duckorbit, t, duckonset, duckattack, duckdepth); } gain = applyGainCurve(nanFallback(gain, 1)); @@ -727,6 +727,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) // delay if (delay > 0 && delaytime > 0 && delayfeedback > 0) { + orbitBus.getDelay(delaytime, delayfeedback, t); orbitBus.sendDelay(post, delay); } // reverb diff --git a/packages/superdough/superdoughoutput.mjs b/packages/superdough/superdoughoutput.mjs index 29113e469..57c2e8563 100644 --- a/packages/superdough/superdoughoutput.mjs +++ b/packages/superdough/superdoughoutput.mjs @@ -179,7 +179,8 @@ export class SuperdoughAudioController { const onset = onsetArr[idx] ?? onsetArr[0]; const attack = Math.max(attackArr[idx] ?? attackArr[0], 0.002); const depth = depthArr[idx] ?? depthArr[0]; - orbit.duck({ t, onsettime: onset, attacktime: attack, depth }); + + orbit.duck(t, onset, attack, depth); }); } From 0633954e2498cacb28fb69a6770d0854f589a0a8 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Wed, 24 Sep 2025 00:23:05 -0700 Subject: [PATCH 201/335] working --- packages/superdough/superdough.mjs | 5 + packages/superdough/superdoughoutput.mjs | 346 ++++++++++++----------- packages/superdough/worklets.mjs | 75 +++++ 3 files changed, 259 insertions(+), 167 deletions(-) diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index f22e82d7b..1d3028e80 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -458,6 +458,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) duckonset, duckattack, duckdepth, + djf, // filters fanchor = getDefaultValue('fanchor'), drive = 0.69, @@ -747,6 +748,10 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) orbitBus.sendReverb(post, room); } + if (djf != null) { + orbitBus.getDjf(djf, t) + } + // analyser if (analyze) { const analyserNode = getAnalyserById(analyze, 2 ** (fft + 5)); diff --git a/packages/superdough/superdoughoutput.mjs b/packages/superdough/superdoughoutput.mjs index 57c2e8563..38760d041 100644 --- a/packages/superdough/superdoughoutput.mjs +++ b/packages/superdough/superdoughoutput.mjs @@ -1,194 +1,206 @@ -import { effectSend, webAudioTimeout } from './helpers.mjs'; +import { effectSend, getWorklet, webAudioTimeout } from './helpers.mjs'; import { errorLogger } from './logger.mjs'; import { clamp } from './util.mjs'; let hasChanged = (now, before) => now !== undefined && now !== before; export class Orbit { - reverbNode; - delayNode; - output; - summingNode; - audioContext; - constructor(audioContext) { - this.audioContext = audioContext; - this.output = new GainNode(audioContext, { gain: 1, channelCount: 2, channelCountMode: 'explicit' }); - this.summingNode = new GainNode(audioContext, { gain: 1, channelCount: 2, channelCountMode: 'explicit' }); - this.summingNode.connect(this.output); - } - - disconnect() { - this.output.disconnect(); - this.summingNode.disconnect(); - this.delayNode?.disconnect(); - this.reverbNode?.disconnect(); - } - - getDelay(delaytime = 0, feedback = 0.5, t) { - const maxfeedback = 0.98; - if (feedback > maxfeedback) { - //logger(`feedback was clamped to ${maxfeedback} to save your ears`); - } - feedback = clamp(feedback, 0, 0.98); - if (this.delayNode == null) { - this.delayNode = this.audioContext.createFeedbackDelay(1, delaytime, feedback); - this.delayNode.connect(this.summingNode); - this.delayNode.start?.(t); // for some reason, this throws when audion extension is installed.. - } - this.delayNode.delayTime.value !== delaytime && this.delayNode.delayTime.setValueAtTime(delaytime, t); - this.delayNode.feedback.value !== feedback && this.delayNode.feedback.setValueAtTime(feedback, t); - return this.delayNode; - } - - getReverb(duration, fade, lp, dim, ir, irspeed, irbegin) { - // If no reverb has been created for a given orbit, create one - if (this.reverbNode == null) { - this.reverbNode = this.audioContext.createReverb(duration, fade, lp, dim, ir, irspeed, irbegin); - this.reverbNode.connect(this.summingNode); + reverbNode; + delayNode; + output; + summingNode; + djfNode; + audioContext; + constructor(audioContext) { + this.audioContext = audioContext; + this.output = new GainNode(audioContext, { gain: 1, channelCount: 2, channelCountMode: 'explicit' }); + this.summingNode = new GainNode(audioContext, { gain: 1, channelCount: 2, channelCountMode: 'explicit' }); + this.summingNode.connect(this.output); } - if ( - hasChanged(duration, this.reverbNode.duration) || - hasChanged(fade, this.reverbNode.fade) || - hasChanged(lp, this.reverbNode.lp) || - hasChanged(dim, this.reverbNode.dim) || - hasChanged(irspeed, this.reverbNode.irspeed) || - hasChanged(irbegin, this.reverbNode.irbegin) || - this.reverbNode.ir !== ir - ) { - // only regenerate when something has changed - // avoids endless regeneration on things like - // stack(s("a"), s("b").rsize(8)).room(.5) - // this only works when args may stay undefined until here - // setting default values breaks this - this.reverbNode.generate(duration, fade, lp, dim, ir, irspeed, irbegin); + disconnect() { + this.output.disconnect(); + this.summingNode.disconnect(); + this.delayNode?.disconnect(); + this.reverbNode?.disconnect(); } - return this.reverbNode; - } - sendReverb(node, amount) { - effectSend(node, this.reverbNode, amount); - } - sendDelay(node, amount) { - effectSend(node, this.delayNode, amount); - } + getDjf(value, t = 0) { + if (this.djfNode == null){ + this.djfNode = getWorklet(this.audioContext, 'djf-processor', {value}) + this.summingNode.disconnect() + this.summingNode.connect(this.djfNode) + this.djfNode.connect(this.output) + } + const val = this.djfNode.parameters.get('value') + val.setValueAtTime(value, t) + } + + getDelay(delaytime = 0, feedback = 0.5, t) { + const maxfeedback = 0.98; + if (feedback > maxfeedback) { + //logger(`feedback was clamped to ${maxfeedback} to save your ears`); + } + feedback = clamp(feedback, 0, 0.98); + if (this.delayNode == null) { + this.delayNode = this.audioContext.createFeedbackDelay(1, delaytime, feedback); + this.delayNode.connect(this.summingNode); + this.delayNode.start?.(t); // for some reason, this throws when audion extension is installed.. + } + this.delayNode.delayTime.value !== delaytime && this.delayNode.delayTime.setValueAtTime(delaytime, t); + this.delayNode.feedback.value !== feedback && this.delayNode.feedback.setValueAtTime(feedback, t); + return this.delayNode; + } - duck(t, onsettime = 0, attacktime = 0.1, depth = 1) { - const onset = onsettime; - const attack = Math.max(attacktime, 0.002); - const gainParam = this.output.gain; - webAudioTimeout( - this.audioContext, - () => { - const now = this.audioContext.currentTime; + getReverb(duration, fade, lp, dim, ir, irspeed, irbegin) { + // If no reverb has been created for a given orbit, create one + if (this.reverbNode == null) { + this.reverbNode = this.audioContext.createReverb(duration, fade, lp, dim, ir, irspeed, irbegin); + this.reverbNode.connect(this.summingNode); + } - // cancelScheduledValues and setValueAtTime together emulate cancelAndHoldAtTime - // on browsers which lack that method - const currVal = gainParam.value; - gainParam.cancelScheduledValues(now); - gainParam.setValueAtTime(currVal, now); + if ( + hasChanged(duration, this.reverbNode.duration) || + hasChanged(fade, this.reverbNode.fade) || + hasChanged(lp, this.reverbNode.lp) || + hasChanged(dim, this.reverbNode.dim) || + hasChanged(irspeed, this.reverbNode.irspeed) || + hasChanged(irbegin, this.reverbNode.irbegin) || + this.reverbNode.ir !== ir + ) { + // only regenerate when something has changed + // avoids endless regeneration on things like + // stack(s("a"), s("b").rsize(8)).room(.5) + // this only works when args may stay undefined until here + // setting default values breaks this + this.reverbNode.generate(duration, fade, lp, dim, ir, irspeed, irbegin); + } + return this.reverbNode; + } + sendReverb(node, amount) { + effectSend(node, this.reverbNode, amount); + } - const t0 = Math.max(t, now); // guard against now > t - const duckedVal = clamp(1 - Math.sqrt(depth), 0.01, currVal); - gainParam.exponentialRampToValueAtTime(duckedVal, t0 + onset); - gainParam.exponentialRampToValueAtTime(1, t0 + onset + attack); - }, - 0, - t - 0.01, - ); - } + sendDelay(node, amount) { + effectSend(node, this.delayNode, amount); + } - connectToOutput(node) { - node.connect(this.summingNode); - } + duck(t, onsettime = 0, attacktime = 0.1, depth = 1) { + const onset = onsettime; + const attack = Math.max(attacktime, 0.002); + const gainParam = this.output.gain; + webAudioTimeout( + this.audioContext, + () => { + const now = this.audioContext.currentTime; + + // cancelScheduledValues and setValueAtTime together emulate cancelAndHoldAtTime + // on browsers which lack that method + const currVal = gainParam.value; + gainParam.cancelScheduledValues(now); + gainParam.setValueAtTime(currVal, now); + + const t0 = Math.max(t, now); // guard against now > t + const duckedVal = clamp(1 - Math.sqrt(depth), 0.01, currVal); + gainParam.exponentialRampToValueAtTime(duckedVal, t0 + onset); + gainParam.exponentialRampToValueAtTime(1, t0 + onset + attack); + }, + 0, + t - 0.01, + ); + } + + connectToOutput(node) { + node.connect(this.summingNode); + } } export class SuperdoughOutput { - channelMerger; - destinationGain; + channelMerger; + destinationGain; - constructor(audioContext) { - this.audioContext = audioContext; - this.initializeAudio(); - } + constructor(audioContext) { + this.audioContext = audioContext; + this.initializeAudio(); + } - initializeAudio() { - const audioContext = this.audioContext; - const maxChannelCount = audioContext.destination.maxChannelCount; - this.audioContext.destination.channelCount = maxChannelCount; - this.channelMerger = new ChannelMergerNode(audioContext, { numberOfInputs: audioContext.destination.channelCount }); - this.destinationGain = new GainNode(audioContext); - this.channelMerger.connect(this.destinationGain); - this.destinationGain.connect(audioContext.destination); - } + initializeAudio() { + const audioContext = this.audioContext; + const maxChannelCount = audioContext.destination.maxChannelCount; + this.audioContext.destination.channelCount = maxChannelCount; + this.channelMerger = new ChannelMergerNode(audioContext, { numberOfInputs: audioContext.destination.channelCount }); + this.destinationGain = new GainNode(audioContext); + this.channelMerger.connect(this.destinationGain); + this.destinationGain.connect(audioContext.destination); + } - reset() { - this.channelMerger.disconnect(); - this.destinationGain.disconnect(); - this.destinationGain = null; - this.channelMerger = null; - this.nodes = {}; - this.initializeAudio(); - } - connectToDestination = (input, channels = [0, 1]) => { - //This upmix can be removed if correct channel counts are set throughout the app, - // and then strudel could theoretically support surround sound audio files - const stereoMix = new StereoPannerNode(this.audioContext); - input.connect(stereoMix); + reset() { + this.channelMerger.disconnect(); + this.destinationGain.disconnect(); + this.destinationGain = null; + this.channelMerger = null; + this.nodes = {}; + this.initializeAudio(); + } + connectToDestination = (input, channels = [0, 1]) => { + //This upmix can be removed if correct channel counts are set throughout the app, + // and then strudel could theoretically support surround sound audio files + const stereoMix = new StereoPannerNode(this.audioContext); + input.connect(stereoMix); - const splitter = new ChannelSplitterNode(this.audioContext, { - numberOfOutputs: stereoMix.channelCount, - }); - stereoMix.connect(splitter); - channels.forEach((ch, i) => { - splitter.connect(this.channelMerger, i % stereoMix.channelCount, ch % this.audioContext.destination.channelCount); - }); - }; + const splitter = new ChannelSplitterNode(this.audioContext, { + numberOfOutputs: stereoMix.channelCount, + }); + stereoMix.connect(splitter); + channels.forEach((ch, i) => { + splitter.connect(this.channelMerger, i % stereoMix.channelCount, ch % this.audioContext.destination.channelCount); + }); + }; } export class SuperdoughAudioController { - audioContext; - output; - nodes = {}; + audioContext; + output; + nodes = {}; - constructor(audioContext) { - this.audioContext = audioContext; - this.output = new SuperdoughOutput(audioContext); - } - - reset() { - Array.from(this.nodes).forEach((node) => { - node.disconnect(); - }); - this.output.reset(); - } - - duck(targetOrbits, t, onsettime = 0, attacktime = 0.1, depth = 1) { - const targetArr = [targetOrbits].flat(); - const onsetArr = [onsettime].flat(); - const attackArr = [attacktime].flat(); - const depthArr = [depth].flat(); - - targetArr.forEach((target, idx) => { - const orbit = this.nodes[target]; - - if (orbit == null) { - errorLogger(new Error(`duck target orbit ${target} does not exist`), 'superdough'); - return; - } - const onset = onsetArr[idx] ?? onsetArr[0]; - const attack = Math.max(attackArr[idx] ?? attackArr[0], 0.002); - const depth = depthArr[idx] ?? depthArr[0]; - - orbit.duck(t, onset, attack, depth); - }); - } - - getOrbit(orbitNum, channels) { - if (this.nodes[orbitNum] == null) { - this.nodes[orbitNum] = new Orbit(this.audioContext); - this.output.connectToDestination(this.nodes[orbitNum].output, channels); + constructor(audioContext) { + this.audioContext = audioContext; + this.output = new SuperdoughOutput(audioContext); + } + + reset() { + Array.from(this.nodes).forEach((node) => { + node.disconnect(); + }); + this.output.reset(); + } + + duck(targetOrbits, t, onsettime = 0, attacktime = 0.1, depth = 1) { + const targetArr = [targetOrbits].flat(); + const onsetArr = [onsettime].flat(); + const attackArr = [attacktime].flat(); + const depthArr = [depth].flat(); + + targetArr.forEach((target, idx) => { + const orbit = this.nodes[target]; + + if (orbit == null) { + errorLogger(new Error(`duck target orbit ${target} does not exist`), 'superdough'); + return; + } + const onset = onsetArr[idx] ?? onsetArr[0]; + const attack = Math.max(attackArr[idx] ?? attackArr[0], 0.002); + const depth = depthArr[idx] ?? depthArr[0]; + + orbit.duck(t, onset, attack, depth); + }); + } + + getOrbit(orbitNum, channels) { + if (this.nodes[orbitNum] == null) { + this.nodes[orbitNum] = new Orbit(this.audioContext); + this.output.connectToDestination(this.nodes[orbitNum].output, channels); + } + return this.nodes[orbitNum]; } - return this.nodes[orbitNum]; - } } diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 2406d56dc..06e81f38c 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -271,6 +271,81 @@ class ShapeProcessor extends AudioWorkletProcessor { } registerProcessor('shape-processor', ShapeProcessor); +class TwoPoleFilter { + s0 = 0; + s1 = 0; + update(s, cutoff, resonance = 0) { + // Out of bound values can produce NaNs + resonance = clamp(resonance, 0, 1) + cutoff = clamp(cutoff, 0, sampleRate / 2 - 1) + const c = clamp(2 * Math.sin(cutoff * (_PI / sampleRate)), 0, 1.14); + const r = Math.pow(0.5, (resonance + 0.125) / 0.125); + const mrc = 1 - r * c; + this.s0 = mrc * this.s0 - c * this.s1 + c * s; // bpf + this.s1 = mrc * this.s1 + c * this.s0; // lpf + return this.s1; // return lpf by default + } +} + +class DJFProcessor extends AudioWorkletProcessor { + static get parameterDescriptors() { + return [ + { name: 'value', defaultValue: 0.5 }, + ]; + } + + constructor() { + super(); + this.filters = [new TwoPoleFilter(), new TwoPoleFilter()] + } + + process(inputs, outputs, parameters) { + const input = inputs[0]; + const output = outputs[0]; + + const hasInput = !(input[0] === undefined); + this.started = hasInput; + + const value = clamp(parameters.value[0], 0, 1); + let filterType = 'none' + let cutoff + let v = 1; + if (value > 0.5) { + filterType = 'hipass' + v = (value - .5) * 2 + } else if (value < 0.5) { + filterType = 'lopass' + v = value * 2 + } + cutoff = Math.pow((v * 11), 4) + + // let cutoff = parameters.frequency[0]; + + for (let i = 0; i < input.length; i++) { + for (let n = 0; n < blockSize; n++) { + if (filterType == 'none') { + output[i][n] = input[i][n] + } else { + this.filters[i].update(input[i][n], cutoff, 0.2) + if (filterType === 'lopass') { + output[i][n] = this.filters[i].s1 + } else if (filterType === 'hipass') { + output[i][n] = input[i][n] - this.filters[i].s1 + } else { + output[i][n] = input[i][n] + } + } + + + + + } + } + return true; + } +} +registerProcessor('djf-processor', DJFProcessor); + function fast_tanh(x) { const x2 = x * x; return (x * (27.0 + x2)) / (27.0 + 9.0 * x2); From 28c94efaa9d036fd361e3cc8708e1465e39a1432 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Wed, 24 Sep 2025 00:24:25 -0700 Subject: [PATCH 202/335] format --- packages/superdough/superdough.mjs | 2 +- packages/superdough/superdoughoutput.mjs | 356 +++++++++++------------ packages/superdough/worklets.mjs | 38 +-- 3 files changed, 195 insertions(+), 201 deletions(-) diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 1d3028e80..63ed7d30b 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -749,7 +749,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) } if (djf != null) { - orbitBus.getDjf(djf, t) + orbitBus.getDjf(djf, t); } // analyser diff --git a/packages/superdough/superdoughoutput.mjs b/packages/superdough/superdoughoutput.mjs index 38760d041..9ef7bcbf3 100644 --- a/packages/superdough/superdoughoutput.mjs +++ b/packages/superdough/superdoughoutput.mjs @@ -5,202 +5,202 @@ import { clamp } from './util.mjs'; let hasChanged = (now, before) => now !== undefined && now !== before; export class Orbit { - reverbNode; - delayNode; - output; - summingNode; - djfNode; - audioContext; - constructor(audioContext) { - this.audioContext = audioContext; - this.output = new GainNode(audioContext, { gain: 1, channelCount: 2, channelCountMode: 'explicit' }); - this.summingNode = new GainNode(audioContext, { gain: 1, channelCount: 2, channelCountMode: 'explicit' }); - this.summingNode.connect(this.output); + reverbNode; + delayNode; + output; + summingNode; + djfNode; + audioContext; + constructor(audioContext) { + this.audioContext = audioContext; + this.output = new GainNode(audioContext, { gain: 1, channelCount: 2, channelCountMode: 'explicit' }); + this.summingNode = new GainNode(audioContext, { gain: 1, channelCount: 2, channelCountMode: 'explicit' }); + this.summingNode.connect(this.output); + } + + disconnect() { + this.output.disconnect(); + this.summingNode.disconnect(); + this.delayNode?.disconnect(); + this.reverbNode?.disconnect(); + } + + getDjf(value, t = 0) { + if (this.djfNode == null) { + this.djfNode = getWorklet(this.audioContext, 'djf-processor', { value }); + this.summingNode.disconnect(); + this.summingNode.connect(this.djfNode); + this.djfNode.connect(this.output); + } + const val = this.djfNode.parameters.get('value'); + val.setValueAtTime(value, t); + } + + getDelay(delaytime = 0, feedback = 0.5, t) { + const maxfeedback = 0.98; + if (feedback > maxfeedback) { + //logger(`feedback was clamped to ${maxfeedback} to save your ears`); + } + feedback = clamp(feedback, 0, 0.98); + if (this.delayNode == null) { + this.delayNode = this.audioContext.createFeedbackDelay(1, delaytime, feedback); + this.delayNode.connect(this.summingNode); + this.delayNode.start?.(t); // for some reason, this throws when audion extension is installed.. + } + this.delayNode.delayTime.value !== delaytime && this.delayNode.delayTime.setValueAtTime(delaytime, t); + this.delayNode.feedback.value !== feedback && this.delayNode.feedback.setValueAtTime(feedback, t); + return this.delayNode; + } + + getReverb(duration, fade, lp, dim, ir, irspeed, irbegin) { + // If no reverb has been created for a given orbit, create one + if (this.reverbNode == null) { + this.reverbNode = this.audioContext.createReverb(duration, fade, lp, dim, ir, irspeed, irbegin); + this.reverbNode.connect(this.summingNode); } - disconnect() { - this.output.disconnect(); - this.summingNode.disconnect(); - this.delayNode?.disconnect(); - this.reverbNode?.disconnect(); + if ( + hasChanged(duration, this.reverbNode.duration) || + hasChanged(fade, this.reverbNode.fade) || + hasChanged(lp, this.reverbNode.lp) || + hasChanged(dim, this.reverbNode.dim) || + hasChanged(irspeed, this.reverbNode.irspeed) || + hasChanged(irbegin, this.reverbNode.irbegin) || + this.reverbNode.ir !== ir + ) { + // only regenerate when something has changed + // avoids endless regeneration on things like + // stack(s("a"), s("b").rsize(8)).room(.5) + // this only works when args may stay undefined until here + // setting default values breaks this + this.reverbNode.generate(duration, fade, lp, dim, ir, irspeed, irbegin); } + return this.reverbNode; + } + sendReverb(node, amount) { + effectSend(node, this.reverbNode, amount); + } - getDjf(value, t = 0) { - if (this.djfNode == null){ - this.djfNode = getWorklet(this.audioContext, 'djf-processor', {value}) - this.summingNode.disconnect() - this.summingNode.connect(this.djfNode) - this.djfNode.connect(this.output) - } - const val = this.djfNode.parameters.get('value') - val.setValueAtTime(value, t) - } - - getDelay(delaytime = 0, feedback = 0.5, t) { - const maxfeedback = 0.98; - if (feedback > maxfeedback) { - //logger(`feedback was clamped to ${maxfeedback} to save your ears`); - } - feedback = clamp(feedback, 0, 0.98); - if (this.delayNode == null) { - this.delayNode = this.audioContext.createFeedbackDelay(1, delaytime, feedback); - this.delayNode.connect(this.summingNode); - this.delayNode.start?.(t); // for some reason, this throws when audion extension is installed.. - } - this.delayNode.delayTime.value !== delaytime && this.delayNode.delayTime.setValueAtTime(delaytime, t); - this.delayNode.feedback.value !== feedback && this.delayNode.feedback.setValueAtTime(feedback, t); - return this.delayNode; - } + sendDelay(node, amount) { + effectSend(node, this.delayNode, amount); + } - getReverb(duration, fade, lp, dim, ir, irspeed, irbegin) { - // If no reverb has been created for a given orbit, create one - if (this.reverbNode == null) { - this.reverbNode = this.audioContext.createReverb(duration, fade, lp, dim, ir, irspeed, irbegin); - this.reverbNode.connect(this.summingNode); - } + duck(t, onsettime = 0, attacktime = 0.1, depth = 1) { + const onset = onsettime; + const attack = Math.max(attacktime, 0.002); + const gainParam = this.output.gain; + webAudioTimeout( + this.audioContext, + () => { + const now = this.audioContext.currentTime; - if ( - hasChanged(duration, this.reverbNode.duration) || - hasChanged(fade, this.reverbNode.fade) || - hasChanged(lp, this.reverbNode.lp) || - hasChanged(dim, this.reverbNode.dim) || - hasChanged(irspeed, this.reverbNode.irspeed) || - hasChanged(irbegin, this.reverbNode.irbegin) || - this.reverbNode.ir !== ir - ) { - // only regenerate when something has changed - // avoids endless regeneration on things like - // stack(s("a"), s("b").rsize(8)).room(.5) - // this only works when args may stay undefined until here - // setting default values breaks this - this.reverbNode.generate(duration, fade, lp, dim, ir, irspeed, irbegin); - } - return this.reverbNode; - } - sendReverb(node, amount) { - effectSend(node, this.reverbNode, amount); - } + // cancelScheduledValues and setValueAtTime together emulate cancelAndHoldAtTime + // on browsers which lack that method + const currVal = gainParam.value; + gainParam.cancelScheduledValues(now); + gainParam.setValueAtTime(currVal, now); - sendDelay(node, amount) { - effectSend(node, this.delayNode, amount); - } + const t0 = Math.max(t, now); // guard against now > t + const duckedVal = clamp(1 - Math.sqrt(depth), 0.01, currVal); + gainParam.exponentialRampToValueAtTime(duckedVal, t0 + onset); + gainParam.exponentialRampToValueAtTime(1, t0 + onset + attack); + }, + 0, + t - 0.01, + ); + } - duck(t, onsettime = 0, attacktime = 0.1, depth = 1) { - const onset = onsettime; - const attack = Math.max(attacktime, 0.002); - const gainParam = this.output.gain; - webAudioTimeout( - this.audioContext, - () => { - const now = this.audioContext.currentTime; - - // cancelScheduledValues and setValueAtTime together emulate cancelAndHoldAtTime - // on browsers which lack that method - const currVal = gainParam.value; - gainParam.cancelScheduledValues(now); - gainParam.setValueAtTime(currVal, now); - - const t0 = Math.max(t, now); // guard against now > t - const duckedVal = clamp(1 - Math.sqrt(depth), 0.01, currVal); - gainParam.exponentialRampToValueAtTime(duckedVal, t0 + onset); - gainParam.exponentialRampToValueAtTime(1, t0 + onset + attack); - }, - 0, - t - 0.01, - ); - } - - connectToOutput(node) { - node.connect(this.summingNode); - } + connectToOutput(node) { + node.connect(this.summingNode); + } } export class SuperdoughOutput { - channelMerger; - destinationGain; + channelMerger; + destinationGain; - constructor(audioContext) { - this.audioContext = audioContext; - this.initializeAudio(); - } + constructor(audioContext) { + this.audioContext = audioContext; + this.initializeAudio(); + } - initializeAudio() { - const audioContext = this.audioContext; - const maxChannelCount = audioContext.destination.maxChannelCount; - this.audioContext.destination.channelCount = maxChannelCount; - this.channelMerger = new ChannelMergerNode(audioContext, { numberOfInputs: audioContext.destination.channelCount }); - this.destinationGain = new GainNode(audioContext); - this.channelMerger.connect(this.destinationGain); - this.destinationGain.connect(audioContext.destination); - } + initializeAudio() { + const audioContext = this.audioContext; + const maxChannelCount = audioContext.destination.maxChannelCount; + this.audioContext.destination.channelCount = maxChannelCount; + this.channelMerger = new ChannelMergerNode(audioContext, { numberOfInputs: audioContext.destination.channelCount }); + this.destinationGain = new GainNode(audioContext); + this.channelMerger.connect(this.destinationGain); + this.destinationGain.connect(audioContext.destination); + } - reset() { - this.channelMerger.disconnect(); - this.destinationGain.disconnect(); - this.destinationGain = null; - this.channelMerger = null; - this.nodes = {}; - this.initializeAudio(); - } - connectToDestination = (input, channels = [0, 1]) => { - //This upmix can be removed if correct channel counts are set throughout the app, - // and then strudel could theoretically support surround sound audio files - const stereoMix = new StereoPannerNode(this.audioContext); - input.connect(stereoMix); + reset() { + this.channelMerger.disconnect(); + this.destinationGain.disconnect(); + this.destinationGain = null; + this.channelMerger = null; + this.nodes = {}; + this.initializeAudio(); + } + connectToDestination = (input, channels = [0, 1]) => { + //This upmix can be removed if correct channel counts are set throughout the app, + // and then strudel could theoretically support surround sound audio files + const stereoMix = new StereoPannerNode(this.audioContext); + input.connect(stereoMix); - const splitter = new ChannelSplitterNode(this.audioContext, { - numberOfOutputs: stereoMix.channelCount, - }); - stereoMix.connect(splitter); - channels.forEach((ch, i) => { - splitter.connect(this.channelMerger, i % stereoMix.channelCount, ch % this.audioContext.destination.channelCount); - }); - }; + const splitter = new ChannelSplitterNode(this.audioContext, { + numberOfOutputs: stereoMix.channelCount, + }); + stereoMix.connect(splitter); + channels.forEach((ch, i) => { + splitter.connect(this.channelMerger, i % stereoMix.channelCount, ch % this.audioContext.destination.channelCount); + }); + }; } export class SuperdoughAudioController { - audioContext; - output; - nodes = {}; + audioContext; + output; + nodes = {}; - constructor(audioContext) { - this.audioContext = audioContext; - this.output = new SuperdoughOutput(audioContext); - } - - reset() { - Array.from(this.nodes).forEach((node) => { - node.disconnect(); - }); - this.output.reset(); - } - - duck(targetOrbits, t, onsettime = 0, attacktime = 0.1, depth = 1) { - const targetArr = [targetOrbits].flat(); - const onsetArr = [onsettime].flat(); - const attackArr = [attacktime].flat(); - const depthArr = [depth].flat(); - - targetArr.forEach((target, idx) => { - const orbit = this.nodes[target]; - - if (orbit == null) { - errorLogger(new Error(`duck target orbit ${target} does not exist`), 'superdough'); - return; - } - const onset = onsetArr[idx] ?? onsetArr[0]; - const attack = Math.max(attackArr[idx] ?? attackArr[0], 0.002); - const depth = depthArr[idx] ?? depthArr[0]; - - orbit.duck(t, onset, attack, depth); - }); - } - - getOrbit(orbitNum, channels) { - if (this.nodes[orbitNum] == null) { - this.nodes[orbitNum] = new Orbit(this.audioContext); - this.output.connectToDestination(this.nodes[orbitNum].output, channels); - } - return this.nodes[orbitNum]; + constructor(audioContext) { + this.audioContext = audioContext; + this.output = new SuperdoughOutput(audioContext); + } + + reset() { + Array.from(this.nodes).forEach((node) => { + node.disconnect(); + }); + this.output.reset(); + } + + duck(targetOrbits, t, onsettime = 0, attacktime = 0.1, depth = 1) { + const targetArr = [targetOrbits].flat(); + const onsetArr = [onsettime].flat(); + const attackArr = [attacktime].flat(); + const depthArr = [depth].flat(); + + targetArr.forEach((target, idx) => { + const orbit = this.nodes[target]; + + if (orbit == null) { + errorLogger(new Error(`duck target orbit ${target} does not exist`), 'superdough'); + return; + } + const onset = onsetArr[idx] ?? onsetArr[0]; + const attack = Math.max(attackArr[idx] ?? attackArr[0], 0.002); + const depth = depthArr[idx] ?? depthArr[0]; + + orbit.duck(t, onset, attack, depth); + }); + } + + getOrbit(orbitNum, channels) { + if (this.nodes[orbitNum] == null) { + this.nodes[orbitNum] = new Orbit(this.audioContext); + this.output.connectToDestination(this.nodes[orbitNum].output, channels); } + return this.nodes[orbitNum]; + } } diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 06e81f38c..4d25617fb 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -276,8 +276,8 @@ class TwoPoleFilter { s1 = 0; update(s, cutoff, resonance = 0) { // Out of bound values can produce NaNs - resonance = clamp(resonance, 0, 1) - cutoff = clamp(cutoff, 0, sampleRate / 2 - 1) + resonance = clamp(resonance, 0, 1); + cutoff = clamp(cutoff, 0, sampleRate / 2 - 1); const c = clamp(2 * Math.sin(cutoff * (_PI / sampleRate)), 0, 1.14); const r = Math.pow(0.5, (resonance + 0.125) / 0.125); const mrc = 1 - r * c; @@ -289,14 +289,12 @@ class TwoPoleFilter { class DJFProcessor extends AudioWorkletProcessor { static get parameterDescriptors() { - return [ - { name: 'value', defaultValue: 0.5 }, - ]; + return [{ name: 'value', defaultValue: 0.5 }]; } constructor() { super(); - this.filters = [new TwoPoleFilter(), new TwoPoleFilter()] + this.filters = [new TwoPoleFilter(), new TwoPoleFilter()]; } process(inputs, outputs, parameters) { @@ -307,38 +305,34 @@ class DJFProcessor extends AudioWorkletProcessor { this.started = hasInput; const value = clamp(parameters.value[0], 0, 1); - let filterType = 'none' - let cutoff + let filterType = 'none'; + let cutoff; let v = 1; if (value > 0.5) { - filterType = 'hipass' - v = (value - .5) * 2 + filterType = 'hipass'; + v = (value - 0.5) * 2; } else if (value < 0.5) { - filterType = 'lopass' - v = value * 2 + filterType = 'lopass'; + v = value * 2; } - cutoff = Math.pow((v * 11), 4) + cutoff = Math.pow(v * 11, 4); // let cutoff = parameters.frequency[0]; for (let i = 0; i < input.length; i++) { for (let n = 0; n < blockSize; n++) { if (filterType == 'none') { - output[i][n] = input[i][n] + output[i][n] = input[i][n]; } else { - this.filters[i].update(input[i][n], cutoff, 0.2) + this.filters[i].update(input[i][n], cutoff, 0.2); if (filterType === 'lopass') { - output[i][n] = this.filters[i].s1 + output[i][n] = this.filters[i].s1; } else if (filterType === 'hipass') { - output[i][n] = input[i][n] - this.filters[i].s1 + output[i][n] = input[i][n] - this.filters[i].s1; } else { - output[i][n] = input[i][n] + output[i][n] = input[i][n]; } } - - - - } } return true; From f0669ce3bad299bf52de86b49f0eee1a146e96a1 Mon Sep 17 00:00:00 2001 From: Aria Date: Wed, 24 Sep 2025 17:32:03 -0700 Subject: [PATCH 203/335] Move algorithm into constructor --- packages/superdough/helpers.mjs | 9 +++++++-- packages/superdough/worklets.mjs | 7 +++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index 9ee660ae2..8b92bd4e4 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -403,6 +403,11 @@ export const getDistortionAlgorithm = (algo) => { }; export const getDistortion = (distort, postgain, algorithm) => { - const { _algorithm, index } = getDistortionAlgorithm(algorithm); - return getWorklet(getAudioContext(), 'distort-processor', { distort, postgain, algorithm: index }); + const { index } = getDistortionAlgorithm(algorithm); + return getWorklet( + getAudioContext(), + 'distort-processor', + { distort, postgain }, + { processorOptions: { algorithm: index } }, + ); }; diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index e593db17e..f1d95e449 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -348,13 +348,13 @@ class DistortProcessor extends AudioWorkletProcessor { return [ { name: 'distort', defaultValue: 0 }, { name: 'postgain', defaultValue: 1 }, - { name: 'algorithm', defaultValue: 0, min: 0 }, ]; } - constructor() { + constructor({ processorOptions }) { super(); this.started = false; + this.algorithm = getDistortionAlgorithm(processorOptions.algorithm).algorithm; } process(inputs, outputs, parameters) { @@ -366,13 +366,12 @@ class DistortProcessor extends AudioWorkletProcessor { return false; } this.started = hasInput; - const { algorithm } = getDistortionAlgorithm(pv(parameters.algorithm, 0)); // do not allow audio rate algo changes for (let n = 0; n < blockSize; n++) { const postgain = clamp(pv(parameters.postgain, n), 0.001, 1); const shape = Math.expm1(pv(parameters.distort, n)); for (let ch = 0; ch < input.length; ch++) { const x = input[ch][n]; - output[ch][n] = postgain * algorithm(x, shape); + output[ch][n] = postgain * this.algorithm(x, shape); } } return true; From da81ba00fb056f77c23ceccab29e92ad78892fd6 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Wed, 24 Sep 2025 20:32:45 -0700 Subject: [PATCH 204/335] adjust control range --- packages/superdough/worklets.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 4d25617fb..fa0fa5345 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -308,10 +308,10 @@ class DJFProcessor extends AudioWorkletProcessor { let filterType = 'none'; let cutoff; let v = 1; - if (value > 0.5) { + if (value > 0.52) { filterType = 'hipass'; v = (value - 0.5) * 2; - } else if (value < 0.5) { + } else if (value < 0.48) { filterType = 'lopass'; v = value * 2; } From c474b8c92e882ca739fa95d7004aaacf8816e435 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Wed, 24 Sep 2025 20:33:51 -0700 Subject: [PATCH 205/335] rm comment --- packages/superdough/worklets.mjs | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index fa0fa5345..2a675bba1 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -317,8 +317,6 @@ class DJFProcessor extends AudioWorkletProcessor { } cutoff = Math.pow(v * 11, 4); - // let cutoff = parameters.frequency[0]; - for (let i = 0; i < input.length; i++) { for (let n = 0; n < blockSize; n++) { if (filterType == 'none') { From d3d9f23c3c2a0ae5ab2d4f1e3c479a83f11f40de Mon Sep 17 00:00:00 2001 From: Aria Date: Wed, 24 Sep 2025 22:06:53 -0700 Subject: [PATCH 206/335] Remove unnecessary defaulting --- packages/superdough/wavetable.mjs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index 9b9e325f7..ccf319201 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -186,13 +186,11 @@ async function onTriggerSynth(t, value, onended, bank, frameLen) { const ac = getAudioContext(); let [attack, decay, sustain, release] = getADSRValues([value.attack, value.decay, value.sustain, value.release]); let sourceDesc, holdEnd, envEnd; - let { unison = 5, spread = 0.6, detune, wtPos, wtWarp, wtWarpMode } = value; + let { unison, spread, detune, wtPos, wtWarp, wtWarpMode } = value; if (typeof wtWarpMode === 'string') { wtWarpMode = WarpMode[wtWarpMode.toUpperCase()] ?? WarpMode.NONE; } - detune = detune ?? 0.18; const frequency = getFrequencyFromValue(value); - const voices = clamp(unison, 1, 100); let { tableUrl, label } = getTableInfo(value, bank); const payload = await loadWavetableFrames(tableUrl, label, frameLen); holdEnd = t + duration; @@ -208,7 +206,7 @@ async function onTriggerSynth(t, value, onended, bank, frameLen) { position: wtPos, warp: wtWarp, warpMode: wtWarpMode, - voices, + voices: unison, spread, }, { outputChannelCount: [2] }, From b3537a9acb6cbf3480de7afbf93c7921969dfd25 Mon Sep 17 00:00:00 2001 From: Aria Date: Wed, 24 Sep 2025 22:17:30 -0700 Subject: [PATCH 207/335] Some cleanup --- packages/superdough/helpers.mjs | 11 ++--------- packages/superdough/worklets.mjs | 2 +- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index 8b92bd4e4..5ef132d00 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -398,16 +398,9 @@ export const getDistortionAlgorithm = (algo) => { } } const name = _algoNames[index % _algoNames.length]; // allow for wrapping if algo was a number - const algorithm = distortionAlgorithms[name]; - return { algorithm, index }; + return distortionAlgorithms[name]; }; export const getDistortion = (distort, postgain, algorithm) => { - const { index } = getDistortionAlgorithm(algorithm); - return getWorklet( - getAudioContext(), - 'distort-processor', - { distort, postgain }, - { processorOptions: { algorithm: index } }, - ); + return getWorklet(getAudioContext(), 'distort-processor', { distort, postgain }, { processorOptions: { algorithm } }); }; diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index f1d95e449..5ab326226 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -354,7 +354,7 @@ class DistortProcessor extends AudioWorkletProcessor { constructor({ processorOptions }) { super(); this.started = false; - this.algorithm = getDistortionAlgorithm(processorOptions.algorithm).algorithm; + this.algorithm = getDistortionAlgorithm(processorOptions.algorithm); } process(inputs, outputs, parameters) { From e3741ae8faad7f1b9c160a6949c71a0ff3b03ee2 Mon Sep 17 00:00:00 2001 From: Aria Date: Thu, 25 Sep 2025 00:05:50 -0700 Subject: [PATCH 208/335] Add control over phase randomization and fix a bug with supersaw --- packages/core/controls.mjs | 10 ++++++++++ packages/superdough/superdough.mjs | 1 - packages/superdough/wavetable.mjs | 13 +++++++------ packages/superdough/worklets.mjs | 8 +++++--- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 7bf554577..89583b475 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -120,6 +120,16 @@ export const { wtWarp, wavetableWarp } = registerControl('wtWarp', 'wavetableWar */ export const { wtWarpMode, wavetableWarpMode } = registerControl('wtWarpMode', 'wavetableWarpMode'); +/** + * Amount of randomness of the initial phase of the wavetable oscillator. + * + * @name wtPhaseRand + * @param {number | Pattern} mode Warp mode: an integer + * @synonyms wavetableWarpMode + * + */ +export const { wtPhaseRand, wavetablePhaseRand } = registerControl('wtPhaseRand', 'wavetablePhaseRand'); + /** * Define a custom webaudio node to use as a sound source. * diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index b2b5c8d67..f1f308a7d 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -594,7 +594,6 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) tremolophase = 0, tremoloshape, s = getDefaultValue('s'), - wt, bank, source, gain = getDefaultValue('gain'), diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index ccf319201..044b651e7 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -186,7 +186,7 @@ async function onTriggerSynth(t, value, onended, bank, frameLen) { const ac = getAudioContext(); let [attack, decay, sustain, release] = getADSRValues([value.attack, value.decay, value.sustain, value.release]); let sourceDesc, holdEnd, envEnd; - let { unison, spread, detune, wtPos, wtWarp, wtWarpMode } = value; + let { wtWarpMode } = value; if (typeof wtWarpMode === 'string') { wtWarpMode = WarpMode[wtWarpMode.toUpperCase()] ?? WarpMode.NONE; } @@ -202,12 +202,13 @@ async function onTriggerSynth(t, value, onended, bank, frameLen) { begin: t, end: envEnd, frequency, - detune, - position: wtPos, - warp: wtWarp, + detune: value.detune, + position: value.wtPos, + warp: value.wtWarp, warpMode: wtWarpMode, - voices: unison, - spread, + voices: value.unison, + spread: value.spread, + phaserand: value.wtPhaseRand, }, { outputChannelCount: [2] }, ); diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index b0c0e8e2d..44b82f624 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -474,10 +474,10 @@ class SuperSawOscillatorProcessor extends AudioWorkletProcessor { gainR = gain1; } // Individual voice detuning - freq = applySemitoneDetuneToFrequency(freq, getUnisonDetune(voices, freqspread, n)); + const voiceFreq = applySemitoneDetuneToFrequency(freq, getUnisonDetune(voices, freqspread, n)); // We must wrap this here because it is passed into sawblep below which // has domain [0, 1] - const dt = mod(freq / sampleRate, 1); + const dt = mod(voiceFreq / sampleRate, 1); this.phase[n] = this.phase[n] ?? Math.random(); const v = waveshapes.sawblep(this.phase[n], dt); @@ -988,6 +988,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { { name: 'warpMode', defaultValue: 0 }, { name: 'voices', defaultValue: 1, minValue: 1, maxValue: 32 }, { name: 'spread', defaultValue: 0, minValue: 0, maxValue: 1 }, + { name: 'phaserand', defaultValue: 1, minValue: 0, maxValue: 1 }, ]; } @@ -1188,6 +1189,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { const warpAmount = pv(parameters.warp, i); const warpMode = pv(parameters.warpMode, i); const voices = pv(parameters.voices, i); + const phaseRand = pv(parameters.phaserand, i); const gain1 = Math.sqrt(1 - spread); const gain2 = Math.sqrt(spread); let f = pv(parameters.frequency, i); @@ -1207,7 +1209,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { const bank = this.tables[level]; // warp phase then sample - this.phase[n] = this.phase[n] ?? Math.random(); + this.phase[n] = this.phase[n] ?? Math.random() * phaseRand; let ph = this._warpPhase(this.phase[n], warpAmount, warpMode); const s0 = this._sampleFrame(bank[fIdx], ph); const s1 = this._sampleFrame(bank[Math.min(this.numFrames - 1, fIdx + 1)], ph); From bd8d207a3d7271fde88f578f36f1901e8bef0008 Mon Sep 17 00:00:00 2001 From: Aria Date: Thu, 25 Sep 2025 00:17:13 -0700 Subject: [PATCH 209/335] Typo --- packages/core/controls.mjs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 89583b475..989097d69 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -114,7 +114,7 @@ export const { wtWarp, wavetableWarp } = registerControl('wtWarp', 'wavetableWar * spin, chaos, primes, binary, brownian, reciprocal, wormhole, logistic, sigmoid, fractal, flip * * @name wtWarpMode - * @param {number | Pattern} mode Warp mode: an integer + * @param {number | Pattern} mode Warp mode * @synonyms wavetableWarpMode * */ @@ -124,8 +124,8 @@ export const { wtWarpMode, wavetableWarpMode } = registerControl('wtWarpMode', ' * Amount of randomness of the initial phase of the wavetable oscillator. * * @name wtPhaseRand - * @param {number | Pattern} mode Warp mode: an integer - * @synonyms wavetableWarpMode + * @param {number | Pattern} amount Randomness of the initial phase. Between 0 (not random) and 1 (fully random) + * @synonyms wavetablePhaseRand * */ export const { wtPhaseRand, wavetablePhaseRand } = registerControl('wtPhaseRand', 'wavetablePhaseRand'); From 96981c3c1d8ddc1e837c48ee8e4c3c883e6066e7 Mon Sep 17 00:00:00 2001 From: Aria Date: Thu, 25 Sep 2025 00:36:28 -0700 Subject: [PATCH 210/335] A bit more cleanup --- packages/core/controls.mjs | 2 +- packages/superdough/wavetable.mjs | 31 ++++++++++--------------------- 2 files changed, 11 insertions(+), 22 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 989097d69..9b5519704 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -114,7 +114,7 @@ export const { wtWarp, wavetableWarp } = registerControl('wtWarp', 'wavetableWar * spin, chaos, primes, binary, brownian, reciprocal, wormhole, logistic, sigmoid, fractal, flip * * @name wtWarpMode - * @param {number | Pattern} mode Warp mode + * @param {number | string | Pattern} mode Warp mode * @synonyms wavetableWarpMode * */ diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index 044b651e7..feb5098b0 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -182,20 +182,19 @@ export const tables = async (url, frameLen, json) => { }; async function onTriggerSynth(t, value, onended, bank, frameLen) { - let { s, n = 0, duration } = value; + const { s, n = 0, duration } = value; const ac = getAudioContext(); - let [attack, decay, sustain, release] = getADSRValues([value.attack, value.decay, value.sustain, value.release]); - let sourceDesc, holdEnd, envEnd; + const [attack, decay, sustain, release] = getADSRValues([value.attack, value.decay, value.sustain, value.release]); let { wtWarpMode } = value; if (typeof wtWarpMode === 'string') { wtWarpMode = WarpMode[wtWarpMode.toUpperCase()] ?? WarpMode.NONE; } const frequency = getFrequencyFromValue(value); - let { tableUrl, label } = getTableInfo(value, bank); + const { tableUrl, label } = getTableInfo(value, bank); const payload = await loadWavetableFrames(tableUrl, label, frameLen); - holdEnd = t + duration; - envEnd = holdEnd + release + 0.01; - const worklet = getWorklet( + const holdEnd = t + duration; + const envEnd = holdEnd + release; + const source = getWorklet( ac, 'wavetable-oscillator-processor', { @@ -212,34 +211,24 @@ async function onTriggerSynth(t, value, onended, bank, frameLen) { }, { outputChannelCount: [2] }, ); - worklet.port.postMessage({ type: 'tables', payload }); - sourceDesc = { source: worklet }; - const { source } = sourceDesc; + source.port.postMessage({ type: 'tables', payload }); if (ac.currentTime > t) { logger(`[wavetable] still loading sound "${s}:${n}"`, 'highlight'); return; } - if (!source) { - logger(`[wavetable] could not load "${s}:${n}"`, 'error'); - return; - } - let vibratoOscillator = getVibratoOscillator(source.detune, value, t); + const vibratoOscillator = getVibratoOscillator(source.detune, value, t); const envGain = ac.createGain(); const node = source.connect(envGain); getParamADSR(node.gain, attack, decay, sustain, release, 0, 1, t, holdEnd, 'linear'); getPitchEnvelope(source.detune, value, t, holdEnd); - - const out = ac.createGain(); // we need a separate gain for the cutgroups because firefox... - node.connect(out); - let handle = { node: out, bufferSource: source, oscillator: worklet }; - let timeoutNode = webAudioTimeout( + const handle = { node, source }; + const timeoutNode = webAudioTimeout( ac, () => { source.disconnect(); destroyAudioWorkletNode(source); vibratoOscillator?.stop(); node.disconnect(); - out.disconnect(); onended(); }, t, From f8f42565ae36839b63b37e85d2a7be5a1d7b322c Mon Sep 17 00:00:00 2001 From: Aria Date: Thu, 25 Sep 2025 00:40:25 -0700 Subject: [PATCH 211/335] Typo - add back slight delay in cleanup --- packages/superdough/wavetable.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index feb5098b0..5805685d7 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -193,7 +193,7 @@ async function onTriggerSynth(t, value, onended, bank, frameLen) { const { tableUrl, label } = getTableInfo(value, bank); const payload = await loadWavetableFrames(tableUrl, label, frameLen); const holdEnd = t + duration; - const envEnd = holdEnd + release; + const envEnd = holdEnd + release + 0.01; const source = getWorklet( ac, 'wavetable-oscillator-processor', From 8b2c35b7a3217a57fdc954ba3eca5d4592720520 Mon Sep 17 00:00:00 2001 From: Aria Date: Thu, 25 Sep 2025 01:10:41 -0700 Subject: [PATCH 212/335] Cleanup --- packages/superdough/wavetable.mjs | 22 ++++++++++------------ packages/superdough/worklets.mjs | 8 ++++---- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index 5805685d7..c628549e7 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -1,5 +1,5 @@ import { getAudioContext, registerSound } from './index.mjs'; -import { clamp, getSoundIndex, valueToMidi } from './util.mjs'; +import { getSoundIndex, valueToMidi } from './util.mjs'; import { destroyAudioWorkletNode, getADSRValues, @@ -86,28 +86,27 @@ function humanFileSize(bytes, si) { return bytes.toFixed(1) + ' ' + units[u]; } -export function getTableInfo(hapValue, bank) { - const { wt, n = 0 } = hapValue; +export function getTableInfo(hapValue, tableUrls) { + const { s, n = 0 } = hapValue; let midi = valueToMidi(hapValue, 36); let transpose = midi - 36; // C3 is middle C; - const index = getSoundIndex(n, bank.length); - const tableUrl = bank[index]; - const label = `${wt}:${index}`; + const index = getSoundIndex(n, tableUrls.length); + const tableUrl = tableUrls[index]; + const label = `${s}:${index}`; return { transpose, tableUrl, index, midi, label }; } -const loadBuffer = (url, ac, wt, n = 0) => { - const label = wt ? `table "${wt}:${n}"` : 'table'; +const loadBuffer = (url, ac, label) => { url = url.replace('#', '%23'); if (!loadCache[url]) { - logger(`[wavetable] load ${label}..`, 'load-table', { url }); + logger(`[wavetable] load table ${label}..`, 'load-table', { url }); const timestamp = Date.now(); loadCache[url] = fetch(url) .then((res) => res.arrayBuffer()) .then(async (res) => { const took = Date.now() - timestamp; const size = humanFileSize(res.byteLength); - logger(`[wavetable] load ${label}... done! loaded ${size} in ${took}ms`, 'loaded-table', { url }); + logger(`[wavetable] load table ${label}... done! loaded ${size} in ${took}ms`, 'loaded-table', { url }); const decoded = await ac.decodeAudioData(res); return decoded; }); @@ -151,7 +150,7 @@ const _processTables = (json, baseUrl, frameLen) => { }; /** - * Loads a collection of wavetables to use with `wt` + * Loads a collection of wavetables to use with `s` * * @name tables */ @@ -167,7 +166,6 @@ export const tables = async (url, frameLen, json) => { // not a browser return; } - const base = url.split('/').slice(0, -1).join('/'); if (typeof fetch === 'undefined') { // skip fetch when in node / testing return; diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 44b82f624..daf19e537 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -474,10 +474,10 @@ class SuperSawOscillatorProcessor extends AudioWorkletProcessor { gainR = gain1; } // Individual voice detuning - const voiceFreq = applySemitoneDetuneToFrequency(freq, getUnisonDetune(voices, freqspread, n)); + const freqVoice = applySemitoneDetuneToFrequency(freq, getUnisonDetune(voices, freqspread, n)); // We must wrap this here because it is passed into sawblep below which // has domain [0, 1] - const dt = mod(voiceFreq / sampleRate, 1); + const dt = mod(freqVoice / sampleRate, 1); this.phase[n] = this.phase[n] ?? Math.random(); const v = waveshapes.sawblep(this.phase[n], dt); @@ -1203,14 +1203,14 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { gainL = gain2; gainR = gain1; } - let fVoice = applySemitoneDetuneToFrequency(f, getUnisonDetune(voices, detune, n)); // voice detune + const fVoice = applySemitoneDetuneToFrequency(f, getUnisonDetune(voices, detune, n)); // voice detune const dPhase = fVoice / sampleRate; const level = this._chooseMip(dPhase); const bank = this.tables[level]; // warp phase then sample this.phase[n] = this.phase[n] ?? Math.random() * phaseRand; - let ph = this._warpPhase(this.phase[n], warpAmount, warpMode); + const ph = this._warpPhase(this.phase[n], warpAmount, warpMode); const s0 = this._sampleFrame(bank[fIdx], ph); const s1 = this._sampleFrame(bank[Math.min(this.numFrames - 1, fIdx + 1)], ph); let s = s0 + (s1 - s0) * frac; From dfc4a0818c551b8978fa537da05557a4edfc4f43 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Thu, 25 Sep 2025 23:39:08 -0700 Subject: [PATCH 213/335] res adjust --- packages/superdough/worklets.mjs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 9592dd7df..af8a4a633 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -322,10 +322,10 @@ class DJFProcessor extends AudioWorkletProcessor { let filterType = 'none'; let cutoff; let v = 1; - if (value > 0.52) { + if (value > 0.51) { filterType = 'hipass'; v = (value - 0.5) * 2; - } else if (value < 0.48) { + } else if (value < 0.49) { filterType = 'lopass'; v = value * 2; } @@ -336,7 +336,7 @@ class DJFProcessor extends AudioWorkletProcessor { if (filterType == 'none') { output[i][n] = input[i][n]; } else { - this.filters[i].update(input[i][n], cutoff, 0.2); + this.filters[i].update(input[i][n], cutoff, 0.1); if (filterType === 'lopass') { output[i][n] = this.filters[i].s1; } else if (filterType === 'hipass') { From 266cb614a87a6fbe7b7d8e32c211adcf6923339c Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Thu, 25 Sep 2025 23:44:32 -0700 Subject: [PATCH 214/335] add better example --- packages/core/controls.mjs | 2 +- test/__snapshots__/examples.test.mjs.snap | 52 ++++++++++++++--------- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 9b5519704..2565b73bb 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -1171,7 +1171,7 @@ export const { resonance, lpq } = registerControl('resonance', 'lpq'); * @name djf * @param {number | Pattern} cutoff below 0.5 is low pass filter, above is high pass filter * @example - * n("0 3 7 [10,24]").s('superzow').octave(3).djf("<.5 .25 .5 .75>").osc() + * n(irand(16).seg(8)).scale("d:phrygian").s("supersaw").djf("<.5 .3 .2 .75>") * */ export const { djf } = registerControl('djf'); diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index f91503ca2..a05975580 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -2831,26 +2831,38 @@ exports[`runs examples > example "distort" example index 1 1`] = ` exports[`runs examples > example "djf" example index 0 1`] = ` [ - "[ 0/1 → 1/4 | n:0 s:superzow octave:3 djf:0.5 ]", - "[ 1/4 → 1/2 | n:3 s:superzow octave:3 djf:0.5 ]", - "[ 1/2 → 3/4 | n:7 s:superzow octave:3 djf:0.5 ]", - "[ 3/4 → 1/1 | n:10 s:superzow octave:3 djf:0.5 ]", - "[ 3/4 → 1/1 | n:24 s:superzow octave:3 djf:0.5 ]", - "[ 1/1 → 5/4 | n:0 s:superzow octave:3 djf:0.25 ]", - "[ 5/4 → 3/2 | n:3 s:superzow octave:3 djf:0.25 ]", - "[ 3/2 → 7/4 | n:7 s:superzow octave:3 djf:0.25 ]", - "[ 7/4 → 2/1 | n:10 s:superzow octave:3 djf:0.25 ]", - "[ 7/4 → 2/1 | n:24 s:superzow octave:3 djf:0.25 ]", - "[ 2/1 → 9/4 | n:0 s:superzow octave:3 djf:0.5 ]", - "[ 9/4 → 5/2 | n:3 s:superzow octave:3 djf:0.5 ]", - "[ 5/2 → 11/4 | n:7 s:superzow octave:3 djf:0.5 ]", - "[ 11/4 → 3/1 | n:10 s:superzow octave:3 djf:0.5 ]", - "[ 11/4 → 3/1 | n:24 s:superzow octave:3 djf:0.5 ]", - "[ 3/1 → 13/4 | n:0 s:superzow octave:3 djf:0.75 ]", - "[ 13/4 → 7/2 | n:3 s:superzow octave:3 djf:0.75 ]", - "[ 7/2 → 15/4 | n:7 s:superzow octave:3 djf:0.75 ]", - "[ 15/4 → 4/1 | n:10 s:superzow octave:3 djf:0.75 ]", - "[ 15/4 → 4/1 | n:24 s:superzow octave:3 djf:0.75 ]", + "[ 0/1 → 1/8 | note:D3 s:supersaw djf:0.5 ]", + "[ 1/8 → 1/4 | note:G4 s:supersaw djf:0.5 ]", + "[ 1/4 → 3/8 | note:Bb3 s:supersaw djf:0.5 ]", + "[ 3/8 → 1/2 | note:C4 s:supersaw djf:0.5 ]", + "[ 1/2 → 5/8 | note:A3 s:supersaw djf:0.5 ]", + "[ 5/8 → 3/4 | note:F3 s:supersaw djf:0.5 ]", + "[ 3/4 → 7/8 | note:G3 s:supersaw djf:0.5 ]", + "[ 7/8 → 1/1 | note:C4 s:supersaw djf:0.5 ]", + "[ 1/1 → 9/8 | note:Eb4 s:supersaw djf:0.3 ]", + "[ 9/8 → 5/4 | note:G4 s:supersaw djf:0.3 ]", + "[ 5/4 → 11/8 | note:A4 s:supersaw djf:0.3 ]", + "[ 11/8 → 3/2 | note:F3 s:supersaw djf:0.3 ]", + "[ 3/2 → 13/8 | note:F4 s:supersaw djf:0.3 ]", + "[ 13/8 → 7/4 | note:D4 s:supersaw djf:0.3 ]", + "[ 7/4 → 15/8 | note:G3 s:supersaw djf:0.3 ]", + "[ 15/8 → 2/1 | note:F4 s:supersaw djf:0.3 ]", + "[ 2/1 → 17/8 | note:Eb5 s:supersaw djf:0.2 ]", + "[ 17/8 → 9/4 | note:D5 s:supersaw djf:0.2 ]", + "[ 9/4 → 19/8 | note:Bb3 s:supersaw djf:0.2 ]", + "[ 19/8 → 5/2 | note:C5 s:supersaw djf:0.2 ]", + "[ 5/2 → 21/8 | note:D4 s:supersaw djf:0.2 ]", + "[ 21/8 → 11/4 | note:F3 s:supersaw djf:0.2 ]", + "[ 11/4 → 23/8 | note:G4 s:supersaw djf:0.2 ]", + "[ 23/8 → 3/1 | note:D3 s:supersaw djf:0.2 ]", + "[ 3/1 → 25/8 | note:G3 s:supersaw djf:0.75 ]", + "[ 25/8 → 13/4 | note:Bb3 s:supersaw djf:0.75 ]", + "[ 13/4 → 27/8 | note:Eb5 s:supersaw djf:0.75 ]", + "[ 27/8 → 7/2 | note:C4 s:supersaw djf:0.75 ]", + "[ 7/2 → 29/8 | note:C4 s:supersaw djf:0.75 ]", + "[ 29/8 → 15/4 | note:Eb5 s:supersaw djf:0.75 ]", + "[ 15/4 → 31/8 | note:Bb4 s:supersaw djf:0.75 ]", + "[ 31/8 → 4/1 | note:A4 s:supersaw djf:0.75 ]", ] `; From 2b3b6389431f9b38f0d26da37f0eac202c38f39f Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Fri, 26 Sep 2025 21:47:45 -0500 Subject: [PATCH 215/335] sample source for WT --- packages/superdough/sampler.mjs | 38 ++++++++++++++++++++++--------- packages/superdough/util.mjs | 1 + packages/superdough/wavetable.mjs | 17 ++++++++------ packages/superdough/worklets.mjs | 5 ++-- website/src/repl/idbutils.mjs | 11 +++------ 5 files changed, 44 insertions(+), 28 deletions(-) diff --git a/packages/superdough/sampler.mjs b/packages/superdough/sampler.mjs index 9188c17c3..0e9633d4d 100644 --- a/packages/superdough/sampler.mjs +++ b/packages/superdough/sampler.mjs @@ -1,5 +1,5 @@ import { noteToMidi, valueToMidi, getSoundIndex } from './util.mjs'; -import { getAudioContext, registerSound } from './index.mjs'; +import { getAudioContext, registerSound, registerWaveTable } from './index.mjs'; import { getADSRValues, getParamADSR, getPitchEnvelope, getVibratoOscillator } from './helpers.mjs'; import { logger } from './logger.mjs'; @@ -79,14 +79,14 @@ export const getSampleBufferSource = async (hapValue, bank, resolveUrl) => { bufferSource.buffer = buffer; bufferSource.playbackRate.value = playbackRate; - const { s, loopBegin = 0, loopEnd = 1, begin = 0, end = 1 } = hapValue; + const { loopBegin = 0, loopEnd = 1, begin = 0, end = 1 } = hapValue; // "The computation of the offset into the sound is performed using the sound buffer's natural sample rate, // rather than the current playback rate, so even if the sound is playing at twice its normal speed, // the midway point through a 10-second audio buffer is still 5." const offset = begin * bufferSource.buffer.duration; - const loop = s.startsWith('wt_') ? 1 : hapValue.loop; + const loop = hapValue.loop; if (loop) { bufferSource.loop = true; bufferSource.loopStart = loopBegin * bufferSource.buffer.duration - offset; @@ -267,16 +267,13 @@ export const samples = async (sampleMap, baseUrl = sampleMap._base || '', option return samples(json, baseUrl || base, options); } const { prebake, tag } = options; + + processSampleMap( sampleMap, - (key, bank) => - registerSound(key, (t, hapValue, onended) => onTriggerSample(t, hapValue, onended, bank), { - type: 'sample', - samples: bank, - baseUrl, - prebake, - tag, - }), + (key, bank) => { + registerSample(key, bank, { baseUrl, prebake, tag }) + }, baseUrl, ); }; @@ -366,3 +363,22 @@ export async function onTriggerSample(t, value, onended, bank, resolveUrl) { return handle; } + + +function registerSample(key, bank, params) { + registerSound(key, (t, hapValue, onended) => onTriggerSample(t, hapValue, onended, bank), { + type: 'sample', + samples: bank, + ...params + }) +} + +export function registerSampleSource(key, bank, params) { + const isWavetable = key.startsWith('wt_'); + if (isWavetable) { + registerWaveTable(key,bank, params) + } else { + registerSample(key, bank, params) + } + +} \ No newline at end of file diff --git a/packages/superdough/util.mjs b/packages/superdough/util.mjs index 764ebb43e..80dd31a9d 100644 --- a/packages/superdough/util.mjs +++ b/packages/superdough/util.mjs @@ -76,3 +76,4 @@ export function cycleToSeconds(cycle, cps) { export function secondsToCycle(t, cps) { return t * cps; } + diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index c628549e7..067656045 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -140,15 +140,18 @@ const _processTables = (json, baseUrl, frameLen) => { baseUrl = githubPath(baseUrl, ''); } value = value.map((v) => baseUrl + v); - registerSound(key, (t, hapValue, onended) => onTriggerSynth(t, hapValue, onended, value, frameLen), { - type: 'wavetable', - tables: value, - baseUrl, - frameLen, - }); + registerWaveTable(key,value, {baseUrl, frameLen}) }); }; +export function registerWaveTable(key, bank, params) { + registerSound(key, (t, hapValue, onended) => onTriggerSynth(t, hapValue, onended, bank, params?.frameLen ?? 2048), { + type: 'wavetable', + tables: bank, + ...params + }); +} + /** * Loads a collection of wavetables to use with `s` * @@ -179,7 +182,7 @@ export const tables = async (url, frameLen, json) => { }); }; -async function onTriggerSynth(t, value, onended, bank, frameLen) { +export async function onTriggerSynth(t, value, onended, bank, frameLen) { const { s, n = 0, duration } = value; const ac = getAudioContext(); const [attack, decay, sustain, release] = getADSRValues([value.attack, value.decay, value.sustain, value.release]); diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index af8a4a633..14093d098 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -1239,6 +1239,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { } const outL = outputs[0][0]; const outR = outputs[0][1] || outputs[0][0]; + const gainAdjustment = .15; if (!this.tables) { outL.fill(0); @@ -1284,8 +1285,8 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { if (warpMode === WarpMode.FLIP && this.phase[n] < warpAmount) { s = -s; } - outL[i] += (s * gainL) / Math.sqrt(voices); - outR[i] += (s * gainR) / Math.sqrt(voices); + outL[i] += ((s * gainL) / Math.sqrt(voices)) * gainAdjustment; + outR[i] += ((s * gainR) / Math.sqrt(voices)) * gainAdjustment; this.phase[n] = wrapPhase(this.phase[n] + dPhase); } } diff --git a/website/src/repl/idbutils.mjs b/website/src/repl/idbutils.mjs index f26ee0479..5ac604559 100644 --- a/website/src/repl/idbutils.mjs +++ b/website/src/repl/idbutils.mjs @@ -1,4 +1,4 @@ -import { registerSound, onTriggerSample } from '@strudel/webaudio'; +import { registerSampleSource } from '@strudel/webaudio'; import { isAudioFile } from './files.mjs'; import { logger } from '@strudel/core'; @@ -76,13 +76,8 @@ export function registerSamplesFromDB(config = userSamplesDBConfig, onComplete = }) .map((title) => titlePathMap.get(title)); - registerSound(key, (t, hapValue, onended) => onTriggerSample(t, hapValue, onended, value), { - type: 'sample', - samples: value, - baseUrl: undefined, - prebake: false, - tag: undefined, - }); + registerSampleSource(key,value, {prebake: false}) + }); logger('imported sounds registered!', 'success'); From 97beaec25ae69d5ec146df1dfa77eaddd0d4fbed Mon Sep 17 00:00:00 2001 From: Aria Date: Fri, 26 Sep 2025 20:46:10 -0700 Subject: [PATCH 216/335] Added examples, fixed samplerate issue on import, added to settings tab, fixed spread, added default wavetables, change default phaserand to 0 --- packages/core/controls.mjs | 10 +- packages/superdough/wavetable.mjs | 90 +++++++--- packages/superdough/worklets.mjs | 23 +-- test/__snapshots__/examples.test.mjs.snap | 159 ++++++++++++++++++ website/public/uzu-wavetables.json | 54 ++++++ .../src/repl/components/panel/SoundsTab.jsx | 6 +- website/src/repl/prebake.mjs | 6 +- website/src/settings.mjs | 1 + 8 files changed, 311 insertions(+), 38 deletions(-) create mode 100644 website/public/uzu-wavetables.json diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 9b5519704..3e5e9e63c 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -93,7 +93,8 @@ export const { s, sound } = registerControl(['s', 'n', 'gain'], 'sound'); * @name wtPos * @param {number | Pattern} position Position in the wavetable from 0 to 1 * @synonyms wavetablePosition - * + * @example + * s("squelch").seg(8).note("F1").wtPos("0 0.25 0.5 0.75 1") */ export const { wtPos, wavetablePosition } = registerControl('wtPos', 'wavetablePosition'); @@ -103,7 +104,9 @@ export const { wtPos, wavetablePosition } = registerControl('wtPos', 'wavetableP * @name wtWarp * @param {number | Pattern} amount Warp of the wavetable from 0 to 1 * @synonyms wavetableWarp - * + * @example + * s("basique").seg(8).note("F1").wtWarp("0 0.25 0.5 0.75 1") + * .wtWarpMode("spin") */ export const { wtWarp, wavetableWarp } = registerControl('wtWarp', 'wavetableWarp'); @@ -116,6 +119,9 @@ export const { wtWarp, wavetableWarp } = registerControl('wtWarp', 'wavetableWar * @name wtWarpMode * @param {number | string | Pattern} mode Warp mode * @synonyms wavetableWarpMode + * @example + * s("morgana").seg(8).note("F1").wtWarp("0 0.25 0.5 0.75 1") + * .wtWarpMode("*2") * */ export const { wtWarpMode, wavetableWarpMode } = registerControl('wtWarpMode', 'wavetableWarpMode'); diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index c628549e7..14706f925 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -39,8 +39,7 @@ export const WarpMode = Object.freeze({ }); async function loadWavetableFrames(url, label, frameLen = 256) { - const ac = getAudioContext(); - const buf = await loadBuffer(url, ac, label); + const buf = await loadBuffer(url, label); const ch0 = buf.getChannelData(0); const total = ch0.length; const numFrames = Math.floor(total / frameLen); @@ -96,7 +95,37 @@ export function getTableInfo(hapValue, tableUrls) { return { transpose, tableUrl, index, midi, label }; } -const loadBuffer = (url, ac, label) => { +// Extract the sample rate of a .wav file +function parseWavSampleRate(arrBuf) { + const dv = new DataView(arrBuf); + // Header is "RIFFWAVE", so 12 bytes + let p = 12; + // Look through chunks for the format header + // (they will always have an 8 byte header (id and size) followed by a payload) + while (p + 8 <= dv.byteLength) { + // Parse id + const id = String.fromCharCode(dv.getUint8(p), dv.getUint8(p + 1), dv.getUint8(p + 2), dv.getUint8(p + 3)); + // Parse chunk size + const size = dv.getUint32(p + 4, true); + if (id === 'fmt ') { + // The format chunk contains the sample rate after + // 8 bytes of header, 2 bytes of format tag, 2 bytes of num channels + // (for a total of 12) + return dv.getUint32(p + 12, true); + } + // Advance to next chunk + p += 8 + size + (size & 1); + } + return null; +} + +async function decodeAtNativeRate(arr) { + const sr = parseWavSampleRate(arr) || 44100; + const tempAC = new OfflineAudioContext(1, 1, sr); + return await tempAC.decodeAudioData(arr); +} + +const loadBuffer = (url, label) => { url = url.replace('#', '%23'); if (!loadCache[url]) { logger(`[wavetable] load table ${label}..`, 'load-table', { url }); @@ -107,7 +136,7 @@ const loadBuffer = (url, ac, label) => { const took = Date.now() - timestamp; const size = humanFileSize(res.byteLength); logger(`[wavetable] load table ${label}... done! loaded ${size} in ${took}ms`, 'loaded-table', { url }); - const decoded = await ac.decodeAudioData(res); + const decoded = await decodeAtNativeRate(res); return decoded; }); } @@ -127,25 +156,40 @@ function githubPath(base, subpath = '') { return `https://raw.githubusercontent.com/${path}/${subpath}`; } -const _processTables = (json, baseUrl, frameLen) => { - return Object.entries(json).forEach(([key, value]) => { - if (typeof value === 'string') { - value = [value]; +const _processTables = (json, baseUrl, frameLen, options = {}) => { + baseUrl = json._base || baseUrl; + return Object.entries(json).forEach(([key, tables]) => { + if (key === '_base') return false; + if (typeof tables === 'string') { + tables = [tables]; } - if (typeof value !== 'object') { + if (typeof tables !== 'object') { throw new Error('wrong json format for ' + key); } - baseUrl = value._base || baseUrl; - if (baseUrl.startsWith('github:')) { - baseUrl = githubPath(baseUrl, ''); + let resolvedUrl = baseUrl; + if (resolvedUrl.startsWith('github:')) { + resolvedUrl = githubPath(resolvedUrl, ''); + } + tables = tables + .map((t) => resolvedUrl + t) + .filter((t) => { + if (!t.toLowerCase().endsWith('.wav')) { + logger(`[wavetable] skipping ${t} -- wavetables must be ".wav" format`); + return false; + } + return true; + }); + if (tables.length) { + const { prebake, tag } = options; + registerSound(key, (t, hapValue, onended) => onTriggerSynth(t, hapValue, onended, tables, frameLen), { + type: 'wavetable', + tables, + baseUrl, + frameLen, + prebake, + tag, + }); } - value = value.map((v) => baseUrl + v); - registerSound(key, (t, hapValue, onended) => onTriggerSynth(t, hapValue, onended, value, frameLen), { - type: 'wavetable', - tables: value, - baseUrl, - frameLen, - }); }); }; @@ -154,7 +198,7 @@ const _processTables = (json, baseUrl, frameLen) => { * * @name tables */ -export const tables = async (url, frameLen, json) => { +export const tables = async (url, frameLen, json, options = {}) => { if (json !== undefined) return _processTables(json, url, frameLen); if (url.startsWith('github:')) { url = githubPath(url, 'strudel.json'); @@ -172,14 +216,14 @@ export const tables = async (url, frameLen, json) => { } return fetch(url) .then((res) => res.json()) - .then((json) => _processTables(json, url, frameLen)) + .then((json) => _processTables(json, url, frameLen, options)) .catch((error) => { console.error(error); throw new Error(`error loading "${url}"`); }); }; -async function onTriggerSynth(t, value, onended, bank, frameLen) { +async function onTriggerSynth(t, value, onended, tables, frameLen) { const { s, n = 0, duration } = value; const ac = getAudioContext(); const [attack, decay, sustain, release] = getADSRValues([value.attack, value.decay, value.sustain, value.release]); @@ -188,7 +232,7 @@ async function onTriggerSynth(t, value, onended, bank, frameLen) { wtWarpMode = WarpMode[wtWarpMode.toUpperCase()] ?? WarpMode.NONE; } const frequency = getFrequencyFromValue(value); - const { tableUrl, label } = getTableInfo(value, bank); + const { tableUrl, label } = getTableInfo(value, tables); const payload = await loadWavetableFrames(tableUrl, label, frameLen); const holdEnd = t + duration; const envEnd = holdEnd + release + 0.01; diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index daf19e537..dbfb78f81 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -988,7 +988,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { { name: 'warpMode', defaultValue: 0 }, { name: 'voices', defaultValue: 1, minValue: 1, maxValue: 32 }, { name: 'spread', defaultValue: 0, minValue: 0, maxValue: 1 }, - { name: 'phaserand', defaultValue: 1, minValue: 0, maxValue: 1 }, + { name: 'phaserand', defaultValue: 0, minValue: 0, maxValue: 1 }, ]; } @@ -1155,10 +1155,10 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { } _sampleFrame(frame, phase) { - const pos = phase * (frame.length - 1); + const pos = phase * frame.length; const i = pos | 0; const frac = pos - i; - const a = frame[i]; + const a = frame[i % frame.length]; const b = frame[(i + 1) % frame.length]; return a + (b - a) * frac; } @@ -1181,7 +1181,6 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { for (let i = 0; i < outL.length; i++) { const detune = pv(parameters.detune, i); - const spread = pv(parameters.spread, i) * 0.5 + 0.5; const tablePos = pv(parameters.position, i); const idx = tablePos * (this.numFrames - 1); const fIdx = idx | 0; @@ -1189,11 +1188,13 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { const warpAmount = pv(parameters.warp, i); const warpMode = pv(parameters.warpMode, i); const voices = pv(parameters.voices, i); + const spread = voices > 1 ? pv(parameters.spread, i) : 0; const phaseRand = pv(parameters.phaserand, i); - const gain1 = Math.sqrt(1 - spread); - const gain2 = Math.sqrt(spread); + const gain1 = Math.sqrt(0.5 - 0.5 * spread); + const gain2 = Math.sqrt(0.5 + 0.5 * spread); let f = pv(parameters.frequency, i); f = applySemitoneDetuneToFrequency(f, detune / 100); // overall detune + const normalizer = 0.3 / Math.sqrt(voices); for (let n = 0; n < voices; n++) { const isOdd = (n & 1) == 1; let gainL = gain1; @@ -1206,19 +1207,19 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { const fVoice = applySemitoneDetuneToFrequency(f, getUnisonDetune(voices, detune, n)); // voice detune const dPhase = fVoice / sampleRate; const level = this._chooseMip(dPhase); - const bank = this.tables[level]; + const table = this.tables[level]; // warp phase then sample this.phase[n] = this.phase[n] ?? Math.random() * phaseRand; const ph = this._warpPhase(this.phase[n], warpAmount, warpMode); - const s0 = this._sampleFrame(bank[fIdx], ph); - const s1 = this._sampleFrame(bank[Math.min(this.numFrames - 1, fIdx + 1)], ph); + const s0 = this._sampleFrame(table[fIdx], ph); + const s1 = this._sampleFrame(table[Math.min(this.numFrames - 1, fIdx + 1)], ph); let s = s0 + (s1 - s0) * frac; if (warpMode === WarpMode.FLIP && this.phase[n] < warpAmount) { s = -s; } - outL[i] += (s * gainL) / Math.sqrt(voices); - outR[i] += (s * gainR) / Math.sqrt(voices); + outL[i] += s * gainL * normalizer; + outR[i] += s * gainR * normalizer; this.phase[n] = wrapPhase(this.phase[n] + dPhase); } } diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index f91503ca2..3305def11 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -11981,6 +11981,165 @@ exports[`runs examples > example "withValue" example index 0 1`] = ` ] `; +exports[`runs examples > example "wtPos" example index 0 1`] = ` +[ + "[ 0/1 → 1/8 | s:squelch note:F1 wtPos:0 ]", + "[ (1/8 → 1/5) ⇝ 1/4 | s:squelch note:F1 wtPos:0 ]", + "[ 1/8 ⇜ (1/5 → 1/4) | s:squelch note:F1 wtPos:0.25 ]", + "[ 1/4 → 3/8 | s:squelch note:F1 wtPos:0.25 ]", + "[ (3/8 → 2/5) ⇝ 1/2 | s:squelch note:F1 wtPos:0.25 ]", + "[ 3/8 ⇜ (2/5 → 1/2) | s:squelch note:F1 wtPos:0.5 ]", + "[ (1/2 → 3/5) ⇝ 5/8 | s:squelch note:F1 wtPos:0.5 ]", + "[ 1/2 ⇜ (3/5 → 5/8) | s:squelch note:F1 wtPos:0.75 ]", + "[ 5/8 → 3/4 | s:squelch note:F1 wtPos:0.75 ]", + "[ (3/4 → 4/5) ⇝ 7/8 | s:squelch note:F1 wtPos:0.75 ]", + "[ 3/4 ⇜ (4/5 → 7/8) | s:squelch note:F1 wtPos:1 ]", + "[ 7/8 → 1/1 | s:squelch note:F1 wtPos:1 ]", + "[ 1/1 → 9/8 | s:squelch note:F1 wtPos:0 ]", + "[ (9/8 → 6/5) ⇝ 5/4 | s:squelch note:F1 wtPos:0 ]", + "[ 9/8 ⇜ (6/5 → 5/4) | s:squelch note:F1 wtPos:0.25 ]", + "[ 5/4 → 11/8 | s:squelch note:F1 wtPos:0.25 ]", + "[ (11/8 → 7/5) ⇝ 3/2 | s:squelch note:F1 wtPos:0.25 ]", + "[ 11/8 ⇜ (7/5 → 3/2) | s:squelch note:F1 wtPos:0.5 ]", + "[ (3/2 → 8/5) ⇝ 13/8 | s:squelch note:F1 wtPos:0.5 ]", + "[ 3/2 ⇜ (8/5 → 13/8) | s:squelch note:F1 wtPos:0.75 ]", + "[ 13/8 → 7/4 | s:squelch note:F1 wtPos:0.75 ]", + "[ (7/4 → 9/5) ⇝ 15/8 | s:squelch note:F1 wtPos:0.75 ]", + "[ 7/4 ⇜ (9/5 → 15/8) | s:squelch note:F1 wtPos:1 ]", + "[ 15/8 → 2/1 | s:squelch note:F1 wtPos:1 ]", + "[ 2/1 → 17/8 | s:squelch note:F1 wtPos:0 ]", + "[ (17/8 → 11/5) ⇝ 9/4 | s:squelch note:F1 wtPos:0 ]", + "[ 17/8 ⇜ (11/5 → 9/4) | s:squelch note:F1 wtPos:0.25 ]", + "[ 9/4 → 19/8 | s:squelch note:F1 wtPos:0.25 ]", + "[ (19/8 → 12/5) ⇝ 5/2 | s:squelch note:F1 wtPos:0.25 ]", + "[ 19/8 ⇜ (12/5 → 5/2) | s:squelch note:F1 wtPos:0.5 ]", + "[ (5/2 → 13/5) ⇝ 21/8 | s:squelch note:F1 wtPos:0.5 ]", + "[ 5/2 ⇜ (13/5 → 21/8) | s:squelch note:F1 wtPos:0.75 ]", + "[ 21/8 → 11/4 | s:squelch note:F1 wtPos:0.75 ]", + "[ (11/4 → 14/5) ⇝ 23/8 | s:squelch note:F1 wtPos:0.75 ]", + "[ 11/4 ⇜ (14/5 → 23/8) | s:squelch note:F1 wtPos:1 ]", + "[ 23/8 → 3/1 | s:squelch note:F1 wtPos:1 ]", + "[ 3/1 → 25/8 | s:squelch note:F1 wtPos:0 ]", + "[ (25/8 → 16/5) ⇝ 13/4 | s:squelch note:F1 wtPos:0 ]", + "[ 25/8 ⇜ (16/5 → 13/4) | s:squelch note:F1 wtPos:0.25 ]", + "[ 13/4 → 27/8 | s:squelch note:F1 wtPos:0.25 ]", + "[ (27/8 → 17/5) ⇝ 7/2 | s:squelch note:F1 wtPos:0.25 ]", + "[ 27/8 ⇜ (17/5 → 7/2) | s:squelch note:F1 wtPos:0.5 ]", + "[ (7/2 → 18/5) ⇝ 29/8 | s:squelch note:F1 wtPos:0.5 ]", + "[ 7/2 ⇜ (18/5 → 29/8) | s:squelch note:F1 wtPos:0.75 ]", + "[ 29/8 → 15/4 | s:squelch note:F1 wtPos:0.75 ]", + "[ (15/4 → 19/5) ⇝ 31/8 | s:squelch note:F1 wtPos:0.75 ]", + "[ 15/4 ⇜ (19/5 → 31/8) | s:squelch note:F1 wtPos:1 ]", + "[ 31/8 → 4/1 | s:squelch note:F1 wtPos:1 ]", +] +`; + +exports[`runs examples > example "wtWarp" example index 0 1`] = ` +[ + "[ 0/1 → 1/8 | s:basique note:F1 wtWarp:0 wtWarpMode:spin ]", + "[ (1/8 → 1/5) ⇝ 1/4 | s:basique note:F1 wtWarp:0 wtWarpMode:spin ]", + "[ 1/8 ⇜ (1/5 → 1/4) | s:basique note:F1 wtWarp:0.25 wtWarpMode:spin ]", + "[ 1/4 → 3/8 | s:basique note:F1 wtWarp:0.25 wtWarpMode:spin ]", + "[ (3/8 → 2/5) ⇝ 1/2 | s:basique note:F1 wtWarp:0.25 wtWarpMode:spin ]", + "[ 3/8 ⇜ (2/5 → 1/2) | s:basique note:F1 wtWarp:0.5 wtWarpMode:spin ]", + "[ (1/2 → 3/5) ⇝ 5/8 | s:basique note:F1 wtWarp:0.5 wtWarpMode:spin ]", + "[ 1/2 ⇜ (3/5 → 5/8) | s:basique note:F1 wtWarp:0.75 wtWarpMode:spin ]", + "[ 5/8 → 3/4 | s:basique note:F1 wtWarp:0.75 wtWarpMode:spin ]", + "[ (3/4 → 4/5) ⇝ 7/8 | s:basique note:F1 wtWarp:0.75 wtWarpMode:spin ]", + "[ 3/4 ⇜ (4/5 → 7/8) | s:basique note:F1 wtWarp:1 wtWarpMode:spin ]", + "[ 7/8 → 1/1 | s:basique note:F1 wtWarp:1 wtWarpMode:spin ]", + "[ 1/1 → 9/8 | s:basique note:F1 wtWarp:0 wtWarpMode:spin ]", + "[ (9/8 → 6/5) ⇝ 5/4 | s:basique note:F1 wtWarp:0 wtWarpMode:spin ]", + "[ 9/8 ⇜ (6/5 → 5/4) | s:basique note:F1 wtWarp:0.25 wtWarpMode:spin ]", + "[ 5/4 → 11/8 | s:basique note:F1 wtWarp:0.25 wtWarpMode:spin ]", + "[ (11/8 → 7/5) ⇝ 3/2 | s:basique note:F1 wtWarp:0.25 wtWarpMode:spin ]", + "[ 11/8 ⇜ (7/5 → 3/2) | s:basique note:F1 wtWarp:0.5 wtWarpMode:spin ]", + "[ (3/2 → 8/5) ⇝ 13/8 | s:basique note:F1 wtWarp:0.5 wtWarpMode:spin ]", + "[ 3/2 ⇜ (8/5 → 13/8) | s:basique note:F1 wtWarp:0.75 wtWarpMode:spin ]", + "[ 13/8 → 7/4 | s:basique note:F1 wtWarp:0.75 wtWarpMode:spin ]", + "[ (7/4 → 9/5) ⇝ 15/8 | s:basique note:F1 wtWarp:0.75 wtWarpMode:spin ]", + "[ 7/4 ⇜ (9/5 → 15/8) | s:basique note:F1 wtWarp:1 wtWarpMode:spin ]", + "[ 15/8 → 2/1 | s:basique note:F1 wtWarp:1 wtWarpMode:spin ]", + "[ 2/1 → 17/8 | s:basique note:F1 wtWarp:0 wtWarpMode:spin ]", + "[ (17/8 → 11/5) ⇝ 9/4 | s:basique note:F1 wtWarp:0 wtWarpMode:spin ]", + "[ 17/8 ⇜ (11/5 → 9/4) | s:basique note:F1 wtWarp:0.25 wtWarpMode:spin ]", + "[ 9/4 → 19/8 | s:basique note:F1 wtWarp:0.25 wtWarpMode:spin ]", + "[ (19/8 → 12/5) ⇝ 5/2 | s:basique note:F1 wtWarp:0.25 wtWarpMode:spin ]", + "[ 19/8 ⇜ (12/5 → 5/2) | s:basique note:F1 wtWarp:0.5 wtWarpMode:spin ]", + "[ (5/2 → 13/5) ⇝ 21/8 | s:basique note:F1 wtWarp:0.5 wtWarpMode:spin ]", + "[ 5/2 ⇜ (13/5 → 21/8) | s:basique note:F1 wtWarp:0.75 wtWarpMode:spin ]", + "[ 21/8 → 11/4 | s:basique note:F1 wtWarp:0.75 wtWarpMode:spin ]", + "[ (11/4 → 14/5) ⇝ 23/8 | s:basique note:F1 wtWarp:0.75 wtWarpMode:spin ]", + "[ 11/4 ⇜ (14/5 → 23/8) | s:basique note:F1 wtWarp:1 wtWarpMode:spin ]", + "[ 23/8 → 3/1 | s:basique note:F1 wtWarp:1 wtWarpMode:spin ]", + "[ 3/1 → 25/8 | s:basique note:F1 wtWarp:0 wtWarpMode:spin ]", + "[ (25/8 → 16/5) ⇝ 13/4 | s:basique note:F1 wtWarp:0 wtWarpMode:spin ]", + "[ 25/8 ⇜ (16/5 → 13/4) | s:basique note:F1 wtWarp:0.25 wtWarpMode:spin ]", + "[ 13/4 → 27/8 | s:basique note:F1 wtWarp:0.25 wtWarpMode:spin ]", + "[ (27/8 → 17/5) ⇝ 7/2 | s:basique note:F1 wtWarp:0.25 wtWarpMode:spin ]", + "[ 27/8 ⇜ (17/5 → 7/2) | s:basique note:F1 wtWarp:0.5 wtWarpMode:spin ]", + "[ (7/2 → 18/5) ⇝ 29/8 | s:basique note:F1 wtWarp:0.5 wtWarpMode:spin ]", + "[ 7/2 ⇜ (18/5 → 29/8) | s:basique note:F1 wtWarp:0.75 wtWarpMode:spin ]", + "[ 29/8 → 15/4 | s:basique note:F1 wtWarp:0.75 wtWarpMode:spin ]", + "[ (15/4 → 19/5) ⇝ 31/8 | s:basique note:F1 wtWarp:0.75 wtWarpMode:spin ]", + "[ 15/4 ⇜ (19/5 → 31/8) | s:basique note:F1 wtWarp:1 wtWarpMode:spin ]", + "[ 31/8 → 4/1 | s:basique note:F1 wtWarp:1 wtWarpMode:spin ]", +] +`; + +exports[`runs examples > example "wtWarpMode" example index 0 1`] = ` +[ + "[ 0/1 → 1/8 | s:morgana note:F1 wtWarp:0 wtWarpMode:asym ]", + "[ (1/8 → 1/5) ⇝ 1/4 | s:morgana note:F1 wtWarp:0 wtWarpMode:asym ]", + "[ 1/8 ⇜ (1/5 → 1/4) | s:morgana note:F1 wtWarp:0.25 wtWarpMode:asym ]", + "[ 1/4 → 3/8 | s:morgana note:F1 wtWarp:0.25 wtWarpMode:asym ]", + "[ (3/8 → 2/5) ⇝ 1/2 | s:morgana note:F1 wtWarp:0.25 wtWarpMode:asym ]", + "[ 3/8 ⇜ (2/5 → 1/2) | s:morgana note:F1 wtWarp:0.5 wtWarpMode:asym ]", + "[ (1/2 → 3/5) ⇝ 5/8 | s:morgana note:F1 wtWarp:0.5 wtWarpMode:bendp ]", + "[ 1/2 ⇜ (3/5 → 5/8) | s:morgana note:F1 wtWarp:0.75 wtWarpMode:bendp ]", + "[ 5/8 → 3/4 | s:morgana note:F1 wtWarp:0.75 wtWarpMode:bendp ]", + "[ (3/4 → 4/5) ⇝ 7/8 | s:morgana note:F1 wtWarp:0.75 wtWarpMode:bendp ]", + "[ 3/4 ⇜ (4/5 → 7/8) | s:morgana note:F1 wtWarp:1 wtWarpMode:bendp ]", + "[ 7/8 → 1/1 | s:morgana note:F1 wtWarp:1 wtWarpMode:bendp ]", + "[ 1/1 → 9/8 | s:morgana note:F1 wtWarp:0 wtWarpMode:spin ]", + "[ (9/8 → 6/5) ⇝ 5/4 | s:morgana note:F1 wtWarp:0 wtWarpMode:spin ]", + "[ 9/8 ⇜ (6/5 → 5/4) | s:morgana note:F1 wtWarp:0.25 wtWarpMode:spin ]", + "[ 5/4 → 11/8 | s:morgana note:F1 wtWarp:0.25 wtWarpMode:spin ]", + "[ (11/8 → 7/5) ⇝ 3/2 | s:morgana note:F1 wtWarp:0.25 wtWarpMode:spin ]", + "[ 11/8 ⇜ (7/5 → 3/2) | s:morgana note:F1 wtWarp:0.5 wtWarpMode:spin ]", + "[ (3/2 → 8/5) ⇝ 13/8 | s:morgana note:F1 wtWarp:0.5 wtWarpMode:logistic ]", + "[ 3/2 ⇜ (8/5 → 13/8) | s:morgana note:F1 wtWarp:0.75 wtWarpMode:logistic ]", + "[ 13/8 → 7/4 | s:morgana note:F1 wtWarp:0.75 wtWarpMode:logistic ]", + "[ (7/4 → 9/5) ⇝ 15/8 | s:morgana note:F1 wtWarp:0.75 wtWarpMode:logistic ]", + "[ 7/4 ⇜ (9/5 → 15/8) | s:morgana note:F1 wtWarp:1 wtWarpMode:logistic ]", + "[ 15/8 → 2/1 | s:morgana note:F1 wtWarp:1 wtWarpMode:logistic ]", + "[ 2/1 → 17/8 | s:morgana note:F1 wtWarp:0 wtWarpMode:sync ]", + "[ (17/8 → 11/5) ⇝ 9/4 | s:morgana note:F1 wtWarp:0 wtWarpMode:sync ]", + "[ 17/8 ⇜ (11/5 → 9/4) | s:morgana note:F1 wtWarp:0.25 wtWarpMode:sync ]", + "[ 9/4 → 19/8 | s:morgana note:F1 wtWarp:0.25 wtWarpMode:sync ]", + "[ (19/8 → 12/5) ⇝ 5/2 | s:morgana note:F1 wtWarp:0.25 wtWarpMode:sync ]", + "[ 19/8 ⇜ (12/5 → 5/2) | s:morgana note:F1 wtWarp:0.5 wtWarpMode:sync ]", + "[ (5/2 → 13/5) ⇝ 21/8 | s:morgana note:F1 wtWarp:0.5 wtWarpMode:wormhole ]", + "[ 5/2 ⇜ (13/5 → 21/8) | s:morgana note:F1 wtWarp:0.75 wtWarpMode:wormhole ]", + "[ 21/8 → 11/4 | s:morgana note:F1 wtWarp:0.75 wtWarpMode:wormhole ]", + "[ (11/4 → 14/5) ⇝ 23/8 | s:morgana note:F1 wtWarp:0.75 wtWarpMode:wormhole ]", + "[ 11/4 ⇜ (14/5 → 23/8) | s:morgana note:F1 wtWarp:1 wtWarpMode:wormhole ]", + "[ 23/8 → 3/1 | s:morgana note:F1 wtWarp:1 wtWarpMode:wormhole ]", + "[ 3/1 → 25/8 | s:morgana note:F1 wtWarp:0 wtWarpMode:brownian ]", + "[ (25/8 → 16/5) ⇝ 13/4 | s:morgana note:F1 wtWarp:0 wtWarpMode:brownian ]", + "[ 25/8 ⇜ (16/5 → 13/4) | s:morgana note:F1 wtWarp:0.25 wtWarpMode:brownian ]", + "[ 13/4 → 27/8 | s:morgana note:F1 wtWarp:0.25 wtWarpMode:brownian ]", + "[ (27/8 → 17/5) ⇝ 7/2 | s:morgana note:F1 wtWarp:0.25 wtWarpMode:brownian ]", + "[ 27/8 ⇜ (17/5 → 7/2) | s:morgana note:F1 wtWarp:0.5 wtWarpMode:brownian ]", + "[ (7/2 → 18/5) ⇝ 29/8 | s:morgana note:F1 wtWarp:0.5 wtWarpMode:asym ]", + "[ 7/2 ⇜ (18/5 → 29/8) | s:morgana note:F1 wtWarp:0.75 wtWarpMode:asym ]", + "[ 29/8 → 15/4 | s:morgana note:F1 wtWarp:0.75 wtWarpMode:asym ]", + "[ (15/4 → 19/5) ⇝ 31/8 | s:morgana note:F1 wtWarp:0.75 wtWarpMode:asym ]", + "[ 15/4 ⇜ (19/5 → 31/8) | s:morgana note:F1 wtWarp:1 wtWarpMode:asym ]", + "[ 31/8 → 4/1 | s:morgana note:F1 wtWarp:1 wtWarpMode:asym ]", +] +`; + exports[`runs examples > example "xfade" example index 0 1`] = ` [ "[ 0/1 → 1/8 | s:hh gain:0 ]", diff --git a/website/public/uzu-wavetables.json b/website/public/uzu-wavetables.json new file mode 100644 index 000000000..4497791f0 --- /dev/null +++ b/website/public/uzu-wavetables.json @@ -0,0 +1,54 @@ +{ + "_base": "http://localhost:5432", + "Bad Day": [ + "/Bad Day.wav" + ], + "Basique": [ + "/Basique.wav" + ], + "Crickets": [ + "/Crickets.wav" + ], + "Curses": [ + "/Curses.wav" + ], + "Earl Grey": [ + "/Earl Grey.wav" + ], + "Echoes": [ + "/Echoes.wav" + ], + "Glimmer": [ + "/Glimmer.wav" + ], + "Majick": [ + "/Majick.wav" + ], + "Meditation": [ + "/Meditation.wav" + ], + "Morgana": [ + "/Morgana.wav" + ], + "Red Alert": [ + "/Red Alert.wav" + ], + "Sad Piano": [ + "/Sad Piano.wav" + ], + "Shook": [ + "/Shook.wav" + ], + "Sludge": [ + "/Sludge.wav" + ], + "Squelch": [ + "/Squelch.wav" + ], + "Summers Day": [ + "/Summers Day.wav" + ], + "Wasp": [ + "/Wasp.wav" + ] +} \ No newline at end of file diff --git a/website/src/repl/components/panel/SoundsTab.jsx b/website/src/repl/components/panel/SoundsTab.jsx index 0484da02d..ff64fc18e 100644 --- a/website/src/repl/components/panel/SoundsTab.jsx +++ b/website/src/repl/components/panel/SoundsTab.jsx @@ -44,6 +44,9 @@ export function SoundsTab() { if (soundsFilter === soundFilterType.SYNTHS) { return filtered.filter(([_, { data }]) => ['synth', 'soundfont'].includes(data.type)); } + if (soundsFilter === soundFilterType.WAVETABLES) { + return filtered.filter(([_, { data }]) => data.type === 'wavetable'); + } //TODO: tidy this up, it does not need to be saved in settings if (soundsFilter === 'importSounds') { return []; @@ -74,6 +77,7 @@ export function SoundsTab() { samples: 'samples', drums: 'drum-machines', synths: 'Synths', + wavetables: 'Wavetables', user: 'User', importSounds: 'import-sounds', }} @@ -125,7 +129,7 @@ export function SoundsTab() { > {' '} {name} - {data?.type === 'sample' ? `(${getSamples(data.samples)})` : ''} + {data?.type === 'sample' || data?.type === 'wavetable' ? `(${getSamples(data.samples)})` : ''} {data?.type === 'soundfont' ? `(${data.fonts.length})` : ''} ); diff --git a/website/src/repl/prebake.mjs b/website/src/repl/prebake.mjs index fac6f5bb6..855798fdd 100644 --- a/website/src/repl/prebake.mjs +++ b/website/src/repl/prebake.mjs @@ -1,5 +1,5 @@ import { Pattern, noteToMidi, valueToMidi } from '@strudel/core'; -import { aliasBank, registerSynthSounds, registerZZFXSounds, samples } from '@strudel/webaudio'; +import { aliasBank, registerSynthSounds, registerZZFXSounds, samples, tables } from '@strudel/webaudio'; import { registerSamplesFromDB } from './idbutils.mjs'; import './piano.mjs'; import './files.mjs'; @@ -32,6 +32,10 @@ export async function prebake() { prebake: true, tag: 'drum-machines', }), + tables(`${baseNoTrailing}/uzu-wavetables.json`, 2048, undefined, { + prebake: true, + tag: 'wavetables', + }), samples(`${baseNoTrailing}/mridangam.json`, undefined, { prebake: true, tag: 'drum-machines' }), samples( { diff --git a/website/src/settings.mjs b/website/src/settings.mjs index 9c3d78146..9365a6db5 100644 --- a/website/src/settings.mjs +++ b/website/src/settings.mjs @@ -13,6 +13,7 @@ export const soundFilterType = { DRUMS: 'drums', SAMPLES: 'samples', SYNTHS: 'synths', + WAVETABLES: 'wavetables', ALL: 'all', }; From 4bd103e61200fe888196807b7c43a9ff206cb38c Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sat, 27 Sep 2025 11:31:43 -0400 Subject: [PATCH 217/335] gain adj --- packages/superdough/worklets.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 14093d098..826e96104 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -1049,7 +1049,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { { name: 'begin', defaultValue: 0, min: 0, max: Number.POSITIVE_INFINITY }, { name: 'end', defaultValue: 0, min: 0, max: Number.POSITIVE_INFINITY }, { name: 'frequency', defaultValue: 220, minValue: 0.01, maxValue: 20000 }, - { name: 'detune', defaultValue: 0 }, + { name: 'detune', defaultValue: .18 }, { name: 'position', defaultValue: 0, minValue: 0, maxValue: 1 }, { name: 'warp', defaultValue: 0, minValue: 0, maxValue: 1 }, { name: 'warpMode', defaultValue: 0 }, From a9957b45e5ce101fe3142d9dbeb6112cacc188a8 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sat, 27 Sep 2025 13:22:21 -0400 Subject: [PATCH 218/335] suppoert existing wt_ api --- packages/superdough/sampler.mjs | 2 +- website/public/uzu-wavetables.json | 22 ++++++++++++++++++++++ website/src/repl/prebake.mjs | 3 +++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 website/public/uzu-wavetables.json diff --git a/packages/superdough/sampler.mjs b/packages/superdough/sampler.mjs index 0e9633d4d..ef4bdc542 100644 --- a/packages/superdough/sampler.mjs +++ b/packages/superdough/sampler.mjs @@ -272,7 +272,7 @@ export const samples = async (sampleMap, baseUrl = sampleMap._base || '', option processSampleMap( sampleMap, (key, bank) => { - registerSample(key, bank, { baseUrl, prebake, tag }) + registerSampleSource(key, bank, { baseUrl, prebake, tag }) }, baseUrl, ); diff --git a/website/public/uzu-wavetables.json b/website/public/uzu-wavetables.json new file mode 100644 index 000000000..be8a4e16e --- /dev/null +++ b/website/public/uzu-wavetables.json @@ -0,0 +1,22 @@ +{ + "_base": "https://raw.githubusercontent.com/tidalcycles/uzu-wavetables/main/", + "wt_digital": [ + "wt_digital/wt_bad_day.wav", + "wt_digital/wt_basique.wav", + "wt_digital/wt_crickets.wav", + "wt_digital/wt_curses.wav", + "wt_digital/wt_earl_grey.wav", + "wt_digital/wt_echoes.wav", + "wt_digital/wt_glimmer.wav", + "wt_digital/wt_majick.wav", + "wt_digital/wt_meditation.wav", + "wt_digital/wt_morgana.wav", + "wt_digital/wt_red_alert.wav", + "wt_digital/wt_sad_piano.wav", + "wt_digital/wt_shook.wav", + "wt_digital/wt_sludge.wav", + "wt_digital/wt_squelch.wav", + "wt_digital/wt_summer.wav", + "wt_digital/wt_wasp.wav" + ] +} \ No newline at end of file diff --git a/website/src/repl/prebake.mjs b/website/src/repl/prebake.mjs index fac6f5bb6..0b552b871 100644 --- a/website/src/repl/prebake.mjs +++ b/website/src/repl/prebake.mjs @@ -32,6 +32,9 @@ export async function prebake() { prebake: true, tag: 'drum-machines', }), + samples(`${baseNoTrailing}/uzu-wavetables.json`, undefined, { + prebake: true, + }), samples(`${baseNoTrailing}/mridangam.json`, undefined, { prebake: true, tag: 'drum-machines' }), samples( { From a8918d55fb35cb66279c64f1721c7b8a5d0d693b Mon Sep 17 00:00:00 2001 From: Aria Date: Sat, 27 Sep 2025 10:45:30 -0700 Subject: [PATCH 219/335] Actually update normalizer --- packages/superdough/worklets.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 8c40c2763..dc0cf8077 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -1261,7 +1261,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { const gain2 = Math.sqrt(0.5 + 0.5 * spread); let f = pv(parameters.frequency, i); f = applySemitoneDetuneToFrequency(f, detune / 100); // overall detune - const normalizer = 0.3 / Math.sqrt(voices); + const normalizer = 0.3 / voices; for (let n = 0; n < voices; n++) { const isOdd = (n & 1) == 1; let gainL = gain1; From c5c05ebadc749824de9d77a9ad5640f519ac161f Mon Sep 17 00:00:00 2001 From: Aria Date: Sat, 27 Sep 2025 11:02:57 -0700 Subject: [PATCH 220/335] Clean up to align with other PR --- packages/core/controls.mjs | 8 +- packages/superdough/worklets.mjs | 2 +- test/__snapshots__/examples.test.mjs.snap | 159 ---------------------- website/public/uzu-wavetables.json | 54 -------- website/src/repl/prebake.mjs | 4 - 5 files changed, 6 insertions(+), 221 deletions(-) delete mode 100644 website/public/uzu-wavetables.json diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 73e44473e..fef0e45e6 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -94,7 +94,7 @@ export const { s, sound } = registerControl(['s', 'n', 'gain'], 'sound'); * @param {number | Pattern} position Position in the wavetable from 0 to 1 * @synonyms wavetablePosition * @example - * s("squelch").seg(8).note("F1").wtPos("0 0.25 0.5 0.75 1") + * s("squelch").bank("wt_digital").seg(8).note("F1").wtPos("0 0.25 0.5 0.75 1") */ export const { wtPos, wavetablePosition } = registerControl('wtPos', 'wavetablePosition'); @@ -105,7 +105,7 @@ export const { wtPos, wavetablePosition } = registerControl('wtPos', 'wavetableP * @param {number | Pattern} amount Warp of the wavetable from 0 to 1 * @synonyms wavetableWarp * @example - * s("basique").seg(8).note("F1").wtWarp("0 0.25 0.5 0.75 1") + * s("basique").bank("wt_digital").seg(8).note("F1").wtWarp("0 0.25 0.5 0.75 1") * .wtWarpMode("spin") */ export const { wtWarp, wavetableWarp } = registerControl('wtWarp', 'wavetableWarp'); @@ -120,7 +120,7 @@ export const { wtWarp, wavetableWarp } = registerControl('wtWarp', 'wavetableWar * @param {number | string | Pattern} mode Warp mode * @synonyms wavetableWarpMode * @example - * s("morgana").seg(8).note("F1").wtWarp("0 0.25 0.5 0.75 1") + * s("morgana").bank("wt_digital").seg(8).note("F1").wtWarp("0 0.25 0.5 0.75 1") * .wtWarpMode("*2") * */ @@ -132,6 +132,8 @@ export const { wtWarpMode, wavetableWarpMode } = registerControl('wtWarpMode', ' * @name wtPhaseRand * @param {number | Pattern} amount Randomness of the initial phase. Between 0 (not random) and 1 (fully random) * @synonyms wavetablePhaseRand + * @example + * s("basique").bank("wt_digital").seg(16).wtPhaseRand("<0 1>") * */ export const { wtPhaseRand, wavetablePhaseRand } = registerControl('wtPhaseRand', 'wavetablePhaseRand'); diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index dc0cf8077..a83ad9e4f 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -1054,7 +1054,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { { name: 'warp', defaultValue: 0, minValue: 0, maxValue: 1 }, { name: 'warpMode', defaultValue: 0 }, { name: 'voices', defaultValue: 1, minValue: 1, maxValue: 32 }, - { name: 'spread', defaultValue: 0, minValue: 0, maxValue: 1 }, + { name: 'spread', defaultValue: 0.18, minValue: 0, maxValue: 1 }, { name: 'phaserand', defaultValue: 0, minValue: 0, maxValue: 1 }, ]; } diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index c2135e108..a05975580 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -11993,165 +11993,6 @@ exports[`runs examples > example "withValue" example index 0 1`] = ` ] `; -exports[`runs examples > example "wtPos" example index 0 1`] = ` -[ - "[ 0/1 → 1/8 | s:squelch note:F1 wtPos:0 ]", - "[ (1/8 → 1/5) ⇝ 1/4 | s:squelch note:F1 wtPos:0 ]", - "[ 1/8 ⇜ (1/5 → 1/4) | s:squelch note:F1 wtPos:0.25 ]", - "[ 1/4 → 3/8 | s:squelch note:F1 wtPos:0.25 ]", - "[ (3/8 → 2/5) ⇝ 1/2 | s:squelch note:F1 wtPos:0.25 ]", - "[ 3/8 ⇜ (2/5 → 1/2) | s:squelch note:F1 wtPos:0.5 ]", - "[ (1/2 → 3/5) ⇝ 5/8 | s:squelch note:F1 wtPos:0.5 ]", - "[ 1/2 ⇜ (3/5 → 5/8) | s:squelch note:F1 wtPos:0.75 ]", - "[ 5/8 → 3/4 | s:squelch note:F1 wtPos:0.75 ]", - "[ (3/4 → 4/5) ⇝ 7/8 | s:squelch note:F1 wtPos:0.75 ]", - "[ 3/4 ⇜ (4/5 → 7/8) | s:squelch note:F1 wtPos:1 ]", - "[ 7/8 → 1/1 | s:squelch note:F1 wtPos:1 ]", - "[ 1/1 → 9/8 | s:squelch note:F1 wtPos:0 ]", - "[ (9/8 → 6/5) ⇝ 5/4 | s:squelch note:F1 wtPos:0 ]", - "[ 9/8 ⇜ (6/5 → 5/4) | s:squelch note:F1 wtPos:0.25 ]", - "[ 5/4 → 11/8 | s:squelch note:F1 wtPos:0.25 ]", - "[ (11/8 → 7/5) ⇝ 3/2 | s:squelch note:F1 wtPos:0.25 ]", - "[ 11/8 ⇜ (7/5 → 3/2) | s:squelch note:F1 wtPos:0.5 ]", - "[ (3/2 → 8/5) ⇝ 13/8 | s:squelch note:F1 wtPos:0.5 ]", - "[ 3/2 ⇜ (8/5 → 13/8) | s:squelch note:F1 wtPos:0.75 ]", - "[ 13/8 → 7/4 | s:squelch note:F1 wtPos:0.75 ]", - "[ (7/4 → 9/5) ⇝ 15/8 | s:squelch note:F1 wtPos:0.75 ]", - "[ 7/4 ⇜ (9/5 → 15/8) | s:squelch note:F1 wtPos:1 ]", - "[ 15/8 → 2/1 | s:squelch note:F1 wtPos:1 ]", - "[ 2/1 → 17/8 | s:squelch note:F1 wtPos:0 ]", - "[ (17/8 → 11/5) ⇝ 9/4 | s:squelch note:F1 wtPos:0 ]", - "[ 17/8 ⇜ (11/5 → 9/4) | s:squelch note:F1 wtPos:0.25 ]", - "[ 9/4 → 19/8 | s:squelch note:F1 wtPos:0.25 ]", - "[ (19/8 → 12/5) ⇝ 5/2 | s:squelch note:F1 wtPos:0.25 ]", - "[ 19/8 ⇜ (12/5 → 5/2) | s:squelch note:F1 wtPos:0.5 ]", - "[ (5/2 → 13/5) ⇝ 21/8 | s:squelch note:F1 wtPos:0.5 ]", - "[ 5/2 ⇜ (13/5 → 21/8) | s:squelch note:F1 wtPos:0.75 ]", - "[ 21/8 → 11/4 | s:squelch note:F1 wtPos:0.75 ]", - "[ (11/4 → 14/5) ⇝ 23/8 | s:squelch note:F1 wtPos:0.75 ]", - "[ 11/4 ⇜ (14/5 → 23/8) | s:squelch note:F1 wtPos:1 ]", - "[ 23/8 → 3/1 | s:squelch note:F1 wtPos:1 ]", - "[ 3/1 → 25/8 | s:squelch note:F1 wtPos:0 ]", - "[ (25/8 → 16/5) ⇝ 13/4 | s:squelch note:F1 wtPos:0 ]", - "[ 25/8 ⇜ (16/5 → 13/4) | s:squelch note:F1 wtPos:0.25 ]", - "[ 13/4 → 27/8 | s:squelch note:F1 wtPos:0.25 ]", - "[ (27/8 → 17/5) ⇝ 7/2 | s:squelch note:F1 wtPos:0.25 ]", - "[ 27/8 ⇜ (17/5 → 7/2) | s:squelch note:F1 wtPos:0.5 ]", - "[ (7/2 → 18/5) ⇝ 29/8 | s:squelch note:F1 wtPos:0.5 ]", - "[ 7/2 ⇜ (18/5 → 29/8) | s:squelch note:F1 wtPos:0.75 ]", - "[ 29/8 → 15/4 | s:squelch note:F1 wtPos:0.75 ]", - "[ (15/4 → 19/5) ⇝ 31/8 | s:squelch note:F1 wtPos:0.75 ]", - "[ 15/4 ⇜ (19/5 → 31/8) | s:squelch note:F1 wtPos:1 ]", - "[ 31/8 → 4/1 | s:squelch note:F1 wtPos:1 ]", -] -`; - -exports[`runs examples > example "wtWarp" example index 0 1`] = ` -[ - "[ 0/1 → 1/8 | s:basique note:F1 wtWarp:0 wtWarpMode:spin ]", - "[ (1/8 → 1/5) ⇝ 1/4 | s:basique note:F1 wtWarp:0 wtWarpMode:spin ]", - "[ 1/8 ⇜ (1/5 → 1/4) | s:basique note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ 1/4 → 3/8 | s:basique note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ (3/8 → 2/5) ⇝ 1/2 | s:basique note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ 3/8 ⇜ (2/5 → 1/2) | s:basique note:F1 wtWarp:0.5 wtWarpMode:spin ]", - "[ (1/2 → 3/5) ⇝ 5/8 | s:basique note:F1 wtWarp:0.5 wtWarpMode:spin ]", - "[ 1/2 ⇜ (3/5 → 5/8) | s:basique note:F1 wtWarp:0.75 wtWarpMode:spin ]", - "[ 5/8 → 3/4 | s:basique note:F1 wtWarp:0.75 wtWarpMode:spin ]", - "[ (3/4 → 4/5) ⇝ 7/8 | s:basique note:F1 wtWarp:0.75 wtWarpMode:spin ]", - "[ 3/4 ⇜ (4/5 → 7/8) | s:basique note:F1 wtWarp:1 wtWarpMode:spin ]", - "[ 7/8 → 1/1 | s:basique note:F1 wtWarp:1 wtWarpMode:spin ]", - "[ 1/1 → 9/8 | s:basique note:F1 wtWarp:0 wtWarpMode:spin ]", - "[ (9/8 → 6/5) ⇝ 5/4 | s:basique note:F1 wtWarp:0 wtWarpMode:spin ]", - "[ 9/8 ⇜ (6/5 → 5/4) | s:basique note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ 5/4 → 11/8 | s:basique note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ (11/8 → 7/5) ⇝ 3/2 | s:basique note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ 11/8 ⇜ (7/5 → 3/2) | s:basique note:F1 wtWarp:0.5 wtWarpMode:spin ]", - "[ (3/2 → 8/5) ⇝ 13/8 | s:basique note:F1 wtWarp:0.5 wtWarpMode:spin ]", - "[ 3/2 ⇜ (8/5 → 13/8) | s:basique note:F1 wtWarp:0.75 wtWarpMode:spin ]", - "[ 13/8 → 7/4 | s:basique note:F1 wtWarp:0.75 wtWarpMode:spin ]", - "[ (7/4 → 9/5) ⇝ 15/8 | s:basique note:F1 wtWarp:0.75 wtWarpMode:spin ]", - "[ 7/4 ⇜ (9/5 → 15/8) | s:basique note:F1 wtWarp:1 wtWarpMode:spin ]", - "[ 15/8 → 2/1 | s:basique note:F1 wtWarp:1 wtWarpMode:spin ]", - "[ 2/1 → 17/8 | s:basique note:F1 wtWarp:0 wtWarpMode:spin ]", - "[ (17/8 → 11/5) ⇝ 9/4 | s:basique note:F1 wtWarp:0 wtWarpMode:spin ]", - "[ 17/8 ⇜ (11/5 → 9/4) | s:basique note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ 9/4 → 19/8 | s:basique note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ (19/8 → 12/5) ⇝ 5/2 | s:basique note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ 19/8 ⇜ (12/5 → 5/2) | s:basique note:F1 wtWarp:0.5 wtWarpMode:spin ]", - "[ (5/2 → 13/5) ⇝ 21/8 | s:basique note:F1 wtWarp:0.5 wtWarpMode:spin ]", - "[ 5/2 ⇜ (13/5 → 21/8) | s:basique note:F1 wtWarp:0.75 wtWarpMode:spin ]", - "[ 21/8 → 11/4 | s:basique note:F1 wtWarp:0.75 wtWarpMode:spin ]", - "[ (11/4 → 14/5) ⇝ 23/8 | s:basique note:F1 wtWarp:0.75 wtWarpMode:spin ]", - "[ 11/4 ⇜ (14/5 → 23/8) | s:basique note:F1 wtWarp:1 wtWarpMode:spin ]", - "[ 23/8 → 3/1 | s:basique note:F1 wtWarp:1 wtWarpMode:spin ]", - "[ 3/1 → 25/8 | s:basique note:F1 wtWarp:0 wtWarpMode:spin ]", - "[ (25/8 → 16/5) ⇝ 13/4 | s:basique note:F1 wtWarp:0 wtWarpMode:spin ]", - "[ 25/8 ⇜ (16/5 → 13/4) | s:basique note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ 13/4 → 27/8 | s:basique note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ (27/8 → 17/5) ⇝ 7/2 | s:basique note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ 27/8 ⇜ (17/5 → 7/2) | s:basique note:F1 wtWarp:0.5 wtWarpMode:spin ]", - "[ (7/2 → 18/5) ⇝ 29/8 | s:basique note:F1 wtWarp:0.5 wtWarpMode:spin ]", - "[ 7/2 ⇜ (18/5 → 29/8) | s:basique note:F1 wtWarp:0.75 wtWarpMode:spin ]", - "[ 29/8 → 15/4 | s:basique note:F1 wtWarp:0.75 wtWarpMode:spin ]", - "[ (15/4 → 19/5) ⇝ 31/8 | s:basique note:F1 wtWarp:0.75 wtWarpMode:spin ]", - "[ 15/4 ⇜ (19/5 → 31/8) | s:basique note:F1 wtWarp:1 wtWarpMode:spin ]", - "[ 31/8 → 4/1 | s:basique note:F1 wtWarp:1 wtWarpMode:spin ]", -] -`; - -exports[`runs examples > example "wtWarpMode" example index 0 1`] = ` -[ - "[ 0/1 → 1/8 | s:morgana note:F1 wtWarp:0 wtWarpMode:asym ]", - "[ (1/8 → 1/5) ⇝ 1/4 | s:morgana note:F1 wtWarp:0 wtWarpMode:asym ]", - "[ 1/8 ⇜ (1/5 → 1/4) | s:morgana note:F1 wtWarp:0.25 wtWarpMode:asym ]", - "[ 1/4 → 3/8 | s:morgana note:F1 wtWarp:0.25 wtWarpMode:asym ]", - "[ (3/8 → 2/5) ⇝ 1/2 | s:morgana note:F1 wtWarp:0.25 wtWarpMode:asym ]", - "[ 3/8 ⇜ (2/5 → 1/2) | s:morgana note:F1 wtWarp:0.5 wtWarpMode:asym ]", - "[ (1/2 → 3/5) ⇝ 5/8 | s:morgana note:F1 wtWarp:0.5 wtWarpMode:bendp ]", - "[ 1/2 ⇜ (3/5 → 5/8) | s:morgana note:F1 wtWarp:0.75 wtWarpMode:bendp ]", - "[ 5/8 → 3/4 | s:morgana note:F1 wtWarp:0.75 wtWarpMode:bendp ]", - "[ (3/4 → 4/5) ⇝ 7/8 | s:morgana note:F1 wtWarp:0.75 wtWarpMode:bendp ]", - "[ 3/4 ⇜ (4/5 → 7/8) | s:morgana note:F1 wtWarp:1 wtWarpMode:bendp ]", - "[ 7/8 → 1/1 | s:morgana note:F1 wtWarp:1 wtWarpMode:bendp ]", - "[ 1/1 → 9/8 | s:morgana note:F1 wtWarp:0 wtWarpMode:spin ]", - "[ (9/8 → 6/5) ⇝ 5/4 | s:morgana note:F1 wtWarp:0 wtWarpMode:spin ]", - "[ 9/8 ⇜ (6/5 → 5/4) | s:morgana note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ 5/4 → 11/8 | s:morgana note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ (11/8 → 7/5) ⇝ 3/2 | s:morgana note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ 11/8 ⇜ (7/5 → 3/2) | s:morgana note:F1 wtWarp:0.5 wtWarpMode:spin ]", - "[ (3/2 → 8/5) ⇝ 13/8 | s:morgana note:F1 wtWarp:0.5 wtWarpMode:logistic ]", - "[ 3/2 ⇜ (8/5 → 13/8) | s:morgana note:F1 wtWarp:0.75 wtWarpMode:logistic ]", - "[ 13/8 → 7/4 | s:morgana note:F1 wtWarp:0.75 wtWarpMode:logistic ]", - "[ (7/4 → 9/5) ⇝ 15/8 | s:morgana note:F1 wtWarp:0.75 wtWarpMode:logistic ]", - "[ 7/4 ⇜ (9/5 → 15/8) | s:morgana note:F1 wtWarp:1 wtWarpMode:logistic ]", - "[ 15/8 → 2/1 | s:morgana note:F1 wtWarp:1 wtWarpMode:logistic ]", - "[ 2/1 → 17/8 | s:morgana note:F1 wtWarp:0 wtWarpMode:sync ]", - "[ (17/8 → 11/5) ⇝ 9/4 | s:morgana note:F1 wtWarp:0 wtWarpMode:sync ]", - "[ 17/8 ⇜ (11/5 → 9/4) | s:morgana note:F1 wtWarp:0.25 wtWarpMode:sync ]", - "[ 9/4 → 19/8 | s:morgana note:F1 wtWarp:0.25 wtWarpMode:sync ]", - "[ (19/8 → 12/5) ⇝ 5/2 | s:morgana note:F1 wtWarp:0.25 wtWarpMode:sync ]", - "[ 19/8 ⇜ (12/5 → 5/2) | s:morgana note:F1 wtWarp:0.5 wtWarpMode:sync ]", - "[ (5/2 → 13/5) ⇝ 21/8 | s:morgana note:F1 wtWarp:0.5 wtWarpMode:wormhole ]", - "[ 5/2 ⇜ (13/5 → 21/8) | s:morgana note:F1 wtWarp:0.75 wtWarpMode:wormhole ]", - "[ 21/8 → 11/4 | s:morgana note:F1 wtWarp:0.75 wtWarpMode:wormhole ]", - "[ (11/4 → 14/5) ⇝ 23/8 | s:morgana note:F1 wtWarp:0.75 wtWarpMode:wormhole ]", - "[ 11/4 ⇜ (14/5 → 23/8) | s:morgana note:F1 wtWarp:1 wtWarpMode:wormhole ]", - "[ 23/8 → 3/1 | s:morgana note:F1 wtWarp:1 wtWarpMode:wormhole ]", - "[ 3/1 → 25/8 | s:morgana note:F1 wtWarp:0 wtWarpMode:brownian ]", - "[ (25/8 → 16/5) ⇝ 13/4 | s:morgana note:F1 wtWarp:0 wtWarpMode:brownian ]", - "[ 25/8 ⇜ (16/5 → 13/4) | s:morgana note:F1 wtWarp:0.25 wtWarpMode:brownian ]", - "[ 13/4 → 27/8 | s:morgana note:F1 wtWarp:0.25 wtWarpMode:brownian ]", - "[ (27/8 → 17/5) ⇝ 7/2 | s:morgana note:F1 wtWarp:0.25 wtWarpMode:brownian ]", - "[ 27/8 ⇜ (17/5 → 7/2) | s:morgana note:F1 wtWarp:0.5 wtWarpMode:brownian ]", - "[ (7/2 → 18/5) ⇝ 29/8 | s:morgana note:F1 wtWarp:0.5 wtWarpMode:asym ]", - "[ 7/2 ⇜ (18/5 → 29/8) | s:morgana note:F1 wtWarp:0.75 wtWarpMode:asym ]", - "[ 29/8 → 15/4 | s:morgana note:F1 wtWarp:0.75 wtWarpMode:asym ]", - "[ (15/4 → 19/5) ⇝ 31/8 | s:morgana note:F1 wtWarp:0.75 wtWarpMode:asym ]", - "[ 15/4 ⇜ (19/5 → 31/8) | s:morgana note:F1 wtWarp:1 wtWarpMode:asym ]", - "[ 31/8 → 4/1 | s:morgana note:F1 wtWarp:1 wtWarpMode:asym ]", -] -`; - exports[`runs examples > example "xfade" example index 0 1`] = ` [ "[ 0/1 → 1/8 | s:hh gain:0 ]", diff --git a/website/public/uzu-wavetables.json b/website/public/uzu-wavetables.json deleted file mode 100644 index 4497791f0..000000000 --- a/website/public/uzu-wavetables.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "_base": "http://localhost:5432", - "Bad Day": [ - "/Bad Day.wav" - ], - "Basique": [ - "/Basique.wav" - ], - "Crickets": [ - "/Crickets.wav" - ], - "Curses": [ - "/Curses.wav" - ], - "Earl Grey": [ - "/Earl Grey.wav" - ], - "Echoes": [ - "/Echoes.wav" - ], - "Glimmer": [ - "/Glimmer.wav" - ], - "Majick": [ - "/Majick.wav" - ], - "Meditation": [ - "/Meditation.wav" - ], - "Morgana": [ - "/Morgana.wav" - ], - "Red Alert": [ - "/Red Alert.wav" - ], - "Sad Piano": [ - "/Sad Piano.wav" - ], - "Shook": [ - "/Shook.wav" - ], - "Sludge": [ - "/Sludge.wav" - ], - "Squelch": [ - "/Squelch.wav" - ], - "Summers Day": [ - "/Summers Day.wav" - ], - "Wasp": [ - "/Wasp.wav" - ] -} \ No newline at end of file diff --git a/website/src/repl/prebake.mjs b/website/src/repl/prebake.mjs index 855798fdd..79f30bfe0 100644 --- a/website/src/repl/prebake.mjs +++ b/website/src/repl/prebake.mjs @@ -32,10 +32,6 @@ export async function prebake() { prebake: true, tag: 'drum-machines', }), - tables(`${baseNoTrailing}/uzu-wavetables.json`, 2048, undefined, { - prebake: true, - tag: 'wavetables', - }), samples(`${baseNoTrailing}/mridangam.json`, undefined, { prebake: true, tag: 'drum-machines' }), samples( { From 8c3ee6db6bb042a2cf234aeea5cd3501fc2eb7e5 Mon Sep 17 00:00:00 2001 From: Aria Date: Sat, 27 Sep 2025 11:07:04 -0700 Subject: [PATCH 221/335] Missed deletion --- website/src/repl/prebake.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/repl/prebake.mjs b/website/src/repl/prebake.mjs index 79f30bfe0..fac6f5bb6 100644 --- a/website/src/repl/prebake.mjs +++ b/website/src/repl/prebake.mjs @@ -1,5 +1,5 @@ import { Pattern, noteToMidi, valueToMidi } from '@strudel/core'; -import { aliasBank, registerSynthSounds, registerZZFXSounds, samples, tables } from '@strudel/webaudio'; +import { aliasBank, registerSynthSounds, registerZZFXSounds, samples } from '@strudel/webaudio'; import { registerSamplesFromDB } from './idbutils.mjs'; import './piano.mjs'; import './files.mjs'; From 626a99ba5bbaa7032bf5ef62fe2c2d9849ed911a Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sat, 27 Sep 2025 15:22:54 -0400 Subject: [PATCH 222/335] supports old documented way of loading wavetables: --- packages/superdough/sampler.mjs | 33 +++++-------------------------- packages/superdough/util.mjs | 29 ++++++++++++++++++++++++++- packages/superdough/wavetable.mjs | 20 +++++++------------ 3 files changed, 40 insertions(+), 42 deletions(-) diff --git a/packages/superdough/sampler.mjs b/packages/superdough/sampler.mjs index ef4bdc542..02e1fb334 100644 --- a/packages/superdough/sampler.mjs +++ b/packages/superdough/sampler.mjs @@ -1,4 +1,4 @@ -import { noteToMidi, valueToMidi, getSoundIndex } from './util.mjs'; +import { noteToMidi, valueToMidi, getSoundIndex, getCommonSampleInfo } from './util.mjs'; import { getAudioContext, registerSound, registerWaveTable } from './index.mjs'; import { getADSRValues, getParamADSR, getPitchEnvelope, getVibratoOscillator } from './helpers.mjs'; import { logger } from './logger.mjs'; @@ -22,39 +22,16 @@ function humanFileSize(bytes, si) { return bytes.toFixed(1) + ' ' + units[u]; } -// deduces relevant info for sample loading from hap.value and sample definition -// it encapsulates the core sampler logic into a pure and synchronous function -// hapValue: Hap.value, bank: sample bank definition for sound "s" (values in strudel.json format) export function getSampleInfo(hapValue, bank) { - const { s, n = 0, speed = 1.0 } = hapValue; - let midi = valueToMidi(hapValue, 36); - let transpose = midi - 36; // C3 is middle C; - let sampleUrl; - let index = 0; - if (Array.isArray(bank)) { - index = getSoundIndex(n, bank.length); - sampleUrl = bank[index]; - } else { - const midiDiff = (noteA) => noteToMidi(noteA) - midi; - // object format will expect keys as notes - const closest = Object.keys(bank) - .filter((k) => !k.startsWith('_')) - .reduce( - (closest, key, j) => (!closest || Math.abs(midiDiff(key)) < Math.abs(midiDiff(closest)) ? key : closest), - null, - ); - transpose = -midiDiff(closest); // semitones to repitch - index = getSoundIndex(n, bank[closest].length); - sampleUrl = bank[closest][index]; - } - const label = `${s}:${index}`; + const { speed = 1.0 } = hapValue; + const {transpose, url, index, midi, label} = getCommonSampleInfo(hapValue, bank) let playbackRate = Math.abs(speed) * Math.pow(2, transpose / 12); - return { transpose, sampleUrl, index, midi, label, playbackRate }; + return { transpose, url, index, midi, label, playbackRate }; } // takes hapValue and returns buffer + playbackRate. export const getSampleBuffer = async (hapValue, bank, resolveUrl) => { - let { sampleUrl, label, playbackRate } = getSampleInfo(hapValue, bank); + let { url: sampleUrl, label, playbackRate } = getSampleInfo(hapValue, bank); if (resolveUrl) { sampleUrl = await resolveUrl(sampleUrl); } diff --git a/packages/superdough/util.mjs b/packages/superdough/util.mjs index 80dd31a9d..1886c55e5 100644 --- a/packages/superdough/util.mjs +++ b/packages/superdough/util.mjs @@ -76,4 +76,31 @@ export function cycleToSeconds(cycle, cps) { export function secondsToCycle(t, cps) { return t * cps; } - +// deduces relevant info for sample loading from hap.value and sample definition +// it encapsulates the core sampler logic into a pure and synchronous function +// hapValue: Hap.value, bank: sample bank definition for sound "s" (values in strudel.json format) +export function getCommonSampleInfo(hapValue, bank) { + const { s, n = 0 } = hapValue; + let midi = valueToMidi(hapValue, 36); + let transpose = midi - 36; // C3 is middle C; + let url; + let index = 0; + if (Array.isArray(bank)) { + index = getSoundIndex(n, bank.length); + url = bank[index]; + } else { + const midiDiff = (noteA) => noteToMidi(noteA) - midi; + // object format will expect keys as notes + const closest = Object.keys(bank) + .filter((k) => !k.startsWith('_')) + .reduce( + (closest, key, j) => (!closest || Math.abs(midiDiff(key)) < Math.abs(midiDiff(closest)) ? key : closest), + null, + ); + transpose = -midiDiff(closest); // semitones to repitch + index = getSoundIndex(n, bank[closest].length); + url = bank[closest][index]; + } + const label = `${s}:${index}`; + return { transpose, url, index, midi, label }; +} \ No newline at end of file diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index 067656045..a7e708043 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -1,5 +1,5 @@ import { getAudioContext, registerSound } from './index.mjs'; -import { getSoundIndex, valueToMidi } from './util.mjs'; +import { getCommonSampleInfo, getSoundIndex, valueToMidi } from './util.mjs'; import { destroyAudioWorkletNode, getADSRValues, @@ -38,12 +38,12 @@ export const WarpMode = Object.freeze({ FLIP: 21, }); -async function loadWavetableFrames(url, label, frameLen = 256) { +async function loadWavetableFrames(url, label, frameLen = 2048) { const ac = getAudioContext(); const buf = await loadBuffer(url, ac, label); const ch0 = buf.getChannelData(0); const total = ch0.length; - const numFrames = Math.floor(total / frameLen); + const numFrames = Math.max(1,Math.floor(total / frameLen)); const frames = new Array(numFrames); for (let i = 0; i < numFrames; i++) { const start = i * frameLen; @@ -86,14 +86,8 @@ function humanFileSize(bytes, si) { return bytes.toFixed(1) + ' ' + units[u]; } -export function getTableInfo(hapValue, tableUrls) { - const { s, n = 0 } = hapValue; - let midi = valueToMidi(hapValue, 36); - let transpose = midi - 36; // C3 is middle C; - const index = getSoundIndex(n, tableUrls.length); - const tableUrl = tableUrls[index]; - const label = `${s}:${index}`; - return { transpose, tableUrl, index, midi, label }; +export function getTableInfo(hapValue, urls) { + return getCommonSampleInfo(hapValue,urls) } const loadBuffer = (url, ac, label) => { @@ -191,8 +185,8 @@ export async function onTriggerSynth(t, value, onended, bank, frameLen) { wtWarpMode = WarpMode[wtWarpMode.toUpperCase()] ?? WarpMode.NONE; } const frequency = getFrequencyFromValue(value); - const { tableUrl, label } = getTableInfo(value, bank); - const payload = await loadWavetableFrames(tableUrl, label, frameLen); + const { url, label } = getTableInfo(value, bank); + const payload = await loadWavetableFrames(url, label, frameLen); const holdEnd = t + duration; const envEnd = holdEnd + release + 0.01; const source = getWorklet( From 774372a339d929d8826187efc90afe5ae7e5e337 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sat, 27 Sep 2025 15:29:55 -0400 Subject: [PATCH 223/335] format --- packages/superdough/sampler.mjs | 19 ++++++++----------- packages/superdough/util.mjs | 4 ++-- packages/superdough/wavetable.mjs | 10 +++++----- packages/superdough/worklets.mjs | 4 ++-- website/src/repl/idbutils.mjs | 3 +-- website/src/repl/prebake.mjs | 2 +- 6 files changed, 19 insertions(+), 23 deletions(-) diff --git a/packages/superdough/sampler.mjs b/packages/superdough/sampler.mjs index 02e1fb334..b195ba79c 100644 --- a/packages/superdough/sampler.mjs +++ b/packages/superdough/sampler.mjs @@ -23,8 +23,8 @@ function humanFileSize(bytes, si) { } export function getSampleInfo(hapValue, bank) { - const { speed = 1.0 } = hapValue; - const {transpose, url, index, midi, label} = getCommonSampleInfo(hapValue, bank) + const { speed = 1.0 } = hapValue; + const { transpose, url, index, midi, label } = getCommonSampleInfo(hapValue, bank); let playbackRate = Math.abs(speed) * Math.pow(2, transpose / 12); return { transpose, url, index, midi, label, playbackRate }; } @@ -245,11 +245,10 @@ export const samples = async (sampleMap, baseUrl = sampleMap._base || '', option } const { prebake, tag } = options; - processSampleMap( sampleMap, (key, bank) => { - registerSampleSource(key, bank, { baseUrl, prebake, tag }) + registerSampleSource(key, bank, { baseUrl, prebake, tag }); }, baseUrl, ); @@ -341,21 +340,19 @@ export async function onTriggerSample(t, value, onended, bank, resolveUrl) { return handle; } - function registerSample(key, bank, params) { registerSound(key, (t, hapValue, onended) => onTriggerSample(t, hapValue, onended, bank), { type: 'sample', samples: bank, - ...params - }) + ...params, + }); } export function registerSampleSource(key, bank, params) { const isWavetable = key.startsWith('wt_'); if (isWavetable) { - registerWaveTable(key,bank, params) + registerWaveTable(key, bank, params); } else { - registerSample(key, bank, params) + registerSample(key, bank, params); } - -} \ No newline at end of file +} diff --git a/packages/superdough/util.mjs b/packages/superdough/util.mjs index 1886c55e5..0ba095175 100644 --- a/packages/superdough/util.mjs +++ b/packages/superdough/util.mjs @@ -100,7 +100,7 @@ export function getCommonSampleInfo(hapValue, bank) { transpose = -midiDiff(closest); // semitones to repitch index = getSoundIndex(n, bank[closest].length); url = bank[closest][index]; - } + } const label = `${s}:${index}`; return { transpose, url, index, midi, label }; -} \ No newline at end of file +} diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index a7e708043..c54f3a888 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -43,7 +43,7 @@ async function loadWavetableFrames(url, label, frameLen = 2048) { const buf = await loadBuffer(url, ac, label); const ch0 = buf.getChannelData(0); const total = ch0.length; - const numFrames = Math.max(1,Math.floor(total / frameLen)); + const numFrames = Math.max(1, Math.floor(total / frameLen)); const frames = new Array(numFrames); for (let i = 0; i < numFrames; i++) { const start = i * frameLen; @@ -87,7 +87,7 @@ function humanFileSize(bytes, si) { } export function getTableInfo(hapValue, urls) { - return getCommonSampleInfo(hapValue,urls) + return getCommonSampleInfo(hapValue, urls); } const loadBuffer = (url, ac, label) => { @@ -134,15 +134,15 @@ const _processTables = (json, baseUrl, frameLen) => { baseUrl = githubPath(baseUrl, ''); } value = value.map((v) => baseUrl + v); - registerWaveTable(key,value, {baseUrl, frameLen}) + registerWaveTable(key, value, { baseUrl, frameLen }); }); }; -export function registerWaveTable(key, bank, params) { +export function registerWaveTable(key, bank, params) { registerSound(key, (t, hapValue, onended) => onTriggerSynth(t, hapValue, onended, bank, params?.frameLen ?? 2048), { type: 'wavetable', tables: bank, - ...params + ...params, }); } diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 826e96104..91eb68634 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -1049,7 +1049,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { { name: 'begin', defaultValue: 0, min: 0, max: Number.POSITIVE_INFINITY }, { name: 'end', defaultValue: 0, min: 0, max: Number.POSITIVE_INFINITY }, { name: 'frequency', defaultValue: 220, minValue: 0.01, maxValue: 20000 }, - { name: 'detune', defaultValue: .18 }, + { name: 'detune', defaultValue: 0.18 }, { name: 'position', defaultValue: 0, minValue: 0, maxValue: 1 }, { name: 'warp', defaultValue: 0, minValue: 0, maxValue: 1 }, { name: 'warpMode', defaultValue: 0 }, @@ -1239,7 +1239,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { } const outL = outputs[0][0]; const outR = outputs[0][1] || outputs[0][0]; - const gainAdjustment = .15; + const gainAdjustment = 0.3; if (!this.tables) { outL.fill(0); diff --git a/website/src/repl/idbutils.mjs b/website/src/repl/idbutils.mjs index 5ac604559..d87d649c2 100644 --- a/website/src/repl/idbutils.mjs +++ b/website/src/repl/idbutils.mjs @@ -76,8 +76,7 @@ export function registerSamplesFromDB(config = userSamplesDBConfig, onComplete = }) .map((title) => titlePathMap.get(title)); - registerSampleSource(key,value, {prebake: false}) - + registerSampleSource(key, value, { prebake: false }); }); logger('imported sounds registered!', 'success'); diff --git a/website/src/repl/prebake.mjs b/website/src/repl/prebake.mjs index 0b552b871..1fbc84021 100644 --- a/website/src/repl/prebake.mjs +++ b/website/src/repl/prebake.mjs @@ -33,7 +33,7 @@ export async function prebake() { tag: 'drum-machines', }), samples(`${baseNoTrailing}/uzu-wavetables.json`, undefined, { - prebake: true, + prebake: true, }), samples(`${baseNoTrailing}/mridangam.json`, undefined, { prebake: true, tag: 'drum-machines' }), samples( From 917d01c47d9ab245fb09ce121af657a184c52c1f Mon Sep 17 00:00:00 2001 From: Aria Date: Sat, 27 Sep 2025 12:48:37 -0700 Subject: [PATCH 224/335] Add LFOs and envelopes --- packages/core/controls.mjs | 172 ++++++++++++++++++++++++++++- packages/superdough/helpers.mjs | 30 +++++ packages/superdough/superdough.mjs | 39 ++----- packages/superdough/synth.mjs | 3 +- packages/superdough/wavetable.mjs | 37 ++++++- 5 files changed, 247 insertions(+), 34 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index fef0e45e6..23a1dfc3b 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -98,6 +98,90 @@ export const { s, sound } = registerControl(['s', 'n', 'gain'], 'sound'); */ export const { wtPos, wavetablePosition } = registerControl('wtPos', 'wavetablePosition'); +/** + * Attack time of the wavetable oscillator's position envelope + * + * @name wtPosAttack + * @synonyms wtPosAtt + * @param {number | Pattern} time attack time in seconds + */ +export const { wtPosAttack, wtPosAtt } = registerControl('wtPosAttack', 'wtPosAtt'); + +/** + * Decay time of the wavetable oscillator's position envelope + * + * @name wtPosDecay + * @synonyms wtPosDec + * @param {number | Pattern} time decay time in seconds + */ +export const { wtPosDecay, wtPosDec } = registerControl('wtPosDecay', 'wtPosDec'); + +/** + * Sustain time of the wavetable oscillator's position envelope + * + * @name wtPosAttack + * @synonyms wtPosSus + * @param {number | Pattern} gain sustain level (0 to 1) + */ +export const { wtPosSustain, wtPosSus } = registerControl('wtPosSustain', 'wtPosSus'); + +/** + * Release time of the wavetable oscillator's position envelope + * + * @name wtPosRelease + * @synonyms wtPosRel + * @param {number | Pattern} time release time in seconds + */ +export const { wtPosRelease, wtPosRel } = registerControl('wtPosRelease', 'wtPosRel'); + +/** + * Rate of the LFO for the wavetable oscillator's position + * + * @name wtPosRate + * @param {number | Pattern} rate rate in hertz + */ +export const { wtPosRate } = registerControl('wtPosRate'); + +/** + * Depth of the LFO for the wavetable oscillator's position + * + * @name wtPosDepth + * @param {number | Pattern} depth depth of modulation + */ +export const { wtPosDepth } = registerControl('wtPosDepth'); + +/** + * Whether to sync the LFO for the wavetable oscillator's position + * + * @name wtPosSynced + * @param {number | Pattern} synced Whether to sync the lfo to CPM. > 0.5 will be synced + */ +export const { wtPosSynced } = registerControl('wtPosSynced'); + +/** + * Shape of the LFO for the wavetable oscillator's position + * + * @name wtPosShape + * @param {number | Pattern} shape Shape of the lfo (0, 1, 2, ..) + */ +export const { wtPosShape } = registerControl('wtPosShape'); + +/** + * DC offset of the LFO for the wavetable oscillator's position + * + * @name wtPosDCOffset + * @param {number | Pattern} dcoffset dc offset. set to 0 for unipolar + */ +export const { wtPosDCOffset } = registerControl('wtPosDCOffset'); + +/** + * Skew of the LFO for the wavetable oscillator's position + * + * @name wtPosSkew + * @param {number | Pattern} skew How much to bend the LFO shape + */ +export const { wtPosSkew } = registerControl('wtPosSkew'); + /** * Amount of warp (alteration of the waveform) to apply to the wavetable oscillator * @@ -108,10 +192,94 @@ export const { wtPos, wavetablePosition } = registerControl('wtPos', 'wavetableP * s("basique").bank("wt_digital").seg(8).note("F1").wtWarp("0 0.25 0.5 0.75 1") * .wtWarpMode("spin") */ -export const { wtWarp, wavetableWarp } = registerControl('wtWarp', 'wavetableWarp'); +export const { wtWarp, wavetableWarp } = registerControl('wtWarp', 'wavetableWarp') /** - * Amount of warp (alteration of the waveform) to apply to the wavetable oscillator. + * Attack time of the wavetable oscillator's warp envelope + * + * @name wtWarpAttack + * @synonyms wtWarpAtt + * @param {number | Pattern} time attack time in seconds + */ +export const { wtWarpAttack, wtWarpAtt } = registerControl('wtWarpAttack', 'wtWarpAtt'); + +/** + * Decay time of the wavetable oscillator's warp envelope + * + * @name wtWarpDecay + * @synonyms wtWarpDec + * @param {number | Pattern} time decay time in seconds + */ +export const { wtWarpDecay, wtWarpDec } = registerControl('wtWarpDecay', 'wtWarpDec'); + +/** + * Sustain time of the wavetable oscillator's warp envelope + * + * @name wtWarpAttack + * @synonyms wtWarpSus + * @param {number | Pattern} gain sustain level (0 to 1) + */ +export const { wtWarpSustain, wtWarpSus } = registerControl('wtWarpSustain', 'wtWarpSus'); + +/** + * Release time of the wavetable oscillator's warp envelope + * + * @name wtWarpRelease + * @synonyms wtWarpRel + * @param {number | Pattern} time release time in seconds + */ +export const { wtWarpRelease, wtWarpRel } = registerControl('wtWarpRelease', 'wtWarpRel'); + +/** + * Rate of the LFO for the wavetable oscillator's warp + * + * @name wtWarpRate + * @param {number | Pattern} rate rate in hertz + */ +export const { wtWarpRate } = registerControl('wtWarpRate'); + +/** + * Depth of the LFO for the wavetable oscillator's warp + * + * @name wtWarpDepth + * @param {number | Pattern} depth depth of modulation + */ +export const { wtWarpDepth } = registerControl('wtWarpDepth'); + +/** + * Whether to sync the LFO for the wavetable oscillator's warp + * + * @name wtWarpSynced + * @param {number | Pattern} synced Whether to sync the lfo to CPM. > 0.5 will be synced + */ +export const { wtWarpSynced } = registerControl('wtWarpSynced'); + +/** + * Shape of the LFO for the wavetable oscillator's warp + * + * @name wtWarpShape + * @param {number | Pattern} shape Shape of the lfo (0, 1, 2, ..) + */ +export const { wtWarpShape } = registerControl('wtWarpShape'); + +/** + * DC offset of the LFO for the wavetable oscillator's warp + * + * @name wtWarpDCOffset + * @param {number | Pattern} dcoffset dc offset. set to 0 for unipolar + */ +export const { wtWarpDCOffset } = registerControl('wtWarpDCOffset'); + +/** + * Skew of the LFO for the wavetable oscillator's warp + * + * @name wtWarpSkew + * @param {number | Pattern} skew How much to bend the LFO shape + */ +export const { wtWarpSkew } = registerControl('wtWarpSkew'); + +/** + * Type of warp (alteration of the waveform) to apply to the wavetable oscillator. * * The current options are: none, asym, bendp, bendm, bendmp, sync, quant, fold, pwm, orbit, * spin, chaos, primes, binary, brownian, reciprocal, wormhole, logistic, sigmoid, fractal, flip diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index 4921d873e..d3b6ca6c7 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -97,6 +97,36 @@ export const getParamADSR = ( param[ramp](min, end + release); }; +function getModulationShapeInput(val) { + if (typeof val === 'number') { + return val % 5; + } + return { tri: 0, triangle: 0, sine: 1, ramp: 2, saw: 3, square: 4 }[val] ?? 0; +} + +export function getLfo(audioContext, begin, end, properties = {}) { + const { shape = 0, ...props } = properties; + const { dcoffset = -0.5, depth = 1 } = properties; + debugger; + const lfoprops = { + frequency: 1, + depth, + skew: 0.5, + phaseoffset: 0, + time: begin, + begin, + end, + shape: getModulationShapeInput(shape), + dcoffset, + min: dcoffset * depth, + max: dcoffset * depth + depth, + curve: 1, + ...props, + }; + + return getWorklet(audioContext, 'lfo-processor', lfoprops); +} + export function getCompressor(ac, threshold, ratio, knee, attack, release) { const options = { threshold: threshold ?? -3, diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 63ed7d30b..48264ec05 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -9,7 +9,7 @@ import './reverb.mjs'; import './vowel.mjs'; import { nanFallback, _mod, cycleToSeconds } from './util.mjs'; import workletsUrl from './worklets.mjs?audioworklet'; -import { createFilter, gainNode, getCompressor, getWorklet, effectSend } from './helpers.mjs'; +import { createFilter, gainNode, getCompressor, getLfo, getWorklet, effectSend } from './helpers.mjs'; import { map } from 'nanostores'; import { logger } from './logger.mjs'; import { loadBuffer } from './sampler.mjs'; @@ -29,13 +29,6 @@ export function setMultiChannelOrbits(bool) { multiChannelOrbits = bool == true; } -function getModulationShapeInput(val) { - if (typeof val === 'number') { - return val % 5; - } - return { tri: 0, triangle: 0, sine: 1, ramp: 2, saw: 3, square: 4 }[val] ?? 0; -} - export const soundMap = map(); export function registerSound(key, onTrigger, data = {}) { @@ -314,28 +307,6 @@ export function connectToDestination(input, channels) { controller.output.connectToDestination(input, channels); } -export function getLfo(audioContext, begin, end, properties = {}) { - const { shape = 0, ...props } = properties; - const { dcoffset = -0.5, depth = 1 } = properties; - const lfoprops = { - frequency: 1, - depth, - skew: 0.5, - phaseoffset: 0, - time: begin, - begin, - end, - shape: getModulationShapeInput(shape), - dcoffset, - min: dcoffset * depth, - max: dcoffset * depth + depth, - curve: 1, - ...props, - }; - - return getWorklet(audioContext, 'lfo-processor', lfoprops); -} - function getPhaser(time, end, frequency = 1, depth = 0.5, centerFrequency = 1000, sweep = 2000) { const ac = getAudioContext(); const lfoGain = getLfo(ac, time, end, { frequency, depth: sweep * 2 }); @@ -682,6 +653,14 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) tremolo = cps * tremolosync; } + if (value.wtPosSynced != null) { + value.wtPosRate /= cps; + } + + if (value.wtWarpSynced != null) { + value.wtWarpRate /= cps; + } + if (tremolo !== undefined) { // Allow clipping of modulator for more dynamic possiblities, and to prevent speaker overload // EX: a triangle waveform will clip like this /-\ when the depth is above 1 diff --git a/packages/superdough/synth.mjs b/packages/superdough/synth.mjs index 5b1b4edf1..5dc5dc08a 100644 --- a/packages/superdough/synth.mjs +++ b/packages/superdough/synth.mjs @@ -1,11 +1,12 @@ import { clamp } from './util.mjs'; -import { registerSound, getAudioContext, soundMap, getLfo } from './superdough.mjs'; +import { registerSound, getAudioContext, soundMap } from './superdough.mjs'; import { applyFM, destroyAudioWorkletNode, gainNode, getADSRValues, getFrequencyFromValue, + getLfo, getParamADSR, getPitchEnvelope, getVibratoOscillator, diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index 14706f925..dede7a2e5 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -4,6 +4,7 @@ import { destroyAudioWorkletNode, getADSRValues, getFrequencyFromValue, + getLfo, getParamADSR, getPitchEnvelope, getVibratoOscillator, @@ -235,7 +236,8 @@ async function onTriggerSynth(t, value, onended, tables, frameLen) { const { tableUrl, label } = getTableInfo(value, tables); const payload = await loadWavetableFrames(tableUrl, label, frameLen); const holdEnd = t + duration; - const envEnd = holdEnd + release + 0.01; + const endWithRelease = holdEnd + release; + const envEnd = endWithRelease + 0.01; const source = getWorklet( ac, 'wavetable-oscillator-processor', @@ -258,6 +260,37 @@ async function onTriggerSynth(t, value, onended, tables, frameLen) { logger(`[wavetable] still loading sound "${s}:${n}"`, 'highlight'); return; } + const posADSRParams = [value.wtPosAttack, value.wtPosDecay, value.wtPosSustain, value.wtPosRelease]; + const warpADSRParams = [value.wtPosAttack, value.wtPosDecay, value.wtPosSustain, value.wtPosRelease]; + const wtParams = source.parameters; + const positionParam = wtParams.get('position'); + const warpParam = wtParams.get('warp'); + if (posADSRParams.some((p) => p !== undefined)) { + const [pAttack, pDecay, pSustain, pRelease] = getADSRValues(posADSRParams); + getParamADSR(positionParam, pAttack, pDecay, pSustain, pRelease, 0, 1, t, holdEnd, 'linear'); + } else { + const posLFO = getLfo(ac, t, endWithRelease, { + frequency: value.wtPosRate, + depth: value.wtPosDepth, + shape: value.wtPosShape, + skew: value.wtPosSkew, + dcoffset: value.wtPosDCOffset ?? 0, + }); + posLFO.connect(positionParam); + } + if (posADSRParams.some((p) => p !== undefined)) { + const [wAttack, wDecay, wSustain, wRelease] = getADSRValues(warpADSRParams); + getParamADSR(warpParam, wAttack, wDecay, wSustain, wRelease, 0, 1, t, holdEnd, 'linear'); + } else { + const warpLFO = getLfo(ac, t, endWithRelease, { + frequency: value.wtWarpRate, + depth: value.wtWarpDepth, + shape: value.wtWarpShape, + skew: value.wtWarpSkew, + dcoffset: value.wtWarpDCOffset ?? 0, + }); + warpLFO.connect(warpParam); + } const vibratoOscillator = getVibratoOscillator(source.detune, value, t); const envGain = ac.createGain(); const node = source.connect(envGain); @@ -271,6 +304,8 @@ async function onTriggerSynth(t, value, onended, tables, frameLen) { destroyAudioWorkletNode(source); vibratoOscillator?.stop(); node.disconnect(); + warpLFO.disconnect(); + posLFO.disconnect(); onended(); }, t, From 23d4bfa9d9ec9b2f3bc7dd6469da113dfc794629 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sun, 28 Sep 2025 09:19:39 -0400 Subject: [PATCH 225/335] rename controls --- packages/core/controls.mjs | 162 ++++++++++++++++------------- packages/superdough/superdough.mjs | 2 +- packages/superdough/wavetable.mjs | 88 ++++++++++------ 3 files changed, 144 insertions(+), 108 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index b58465965..7e3c2a8e2 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -90,193 +90,191 @@ export const { s, sound } = registerControl(['s', 'n', 'gain'], 'sound'); /** * Position in the wavetable of the wavetable oscillator * - * @name wtPos + * @name wt * @param {number | Pattern} position Position in the wavetable from 0 to 1 * @synonyms wavetablePosition * @example - * s("squelch").bank("wt_digital").seg(8).note("F1").wtPos("0 0.25 0.5 0.75 1") + * s("squelch").bank("wt_digital").seg(8).note("F1").wt("0 0.25 0.5 0.75 1") */ -export const { wtPos, wavetablePosition } = registerControl('wtPos', 'wavetablePosition'); +export const { wt, wavetablePosition } = registerControl('wt', 'wavetablePosition'); +/** + * Amount of envelope applied wavetable oscillator's position envelope + * + * @name wtenv + * @param {number | Pattern} amount between 0 and 1 + */ +export const { wtenv } = registerControl('wtenv'); /** * Attack time of the wavetable oscillator's position envelope * - * @name wtPosAttack - * @synonyms wtPosAtt + * @name wtattack + * @synonyms wtatt * @param {number | Pattern} time attack time in seconds */ -export const { wtPosAttack, wtPosAtt } = registerControl('wtPosAttack', 'wtPosAtt'); +export const { wtattack, wtatt } = registerControl('wtattack', 'wtatt'); /** * Decay time of the wavetable oscillator's position envelope * - * @name wtPosDecay - * @synonyms wtPosDec + * @name wtdecay + * @synonyms wtdec * @param {number | Pattern} time decay time in seconds */ -export const { wtPosDecay, wtPosDec } = registerControl('wtPosDecay', 'wtPosDec'); +export const { wtdecay, wtdec } = registerControl('wtdecay', 'wtdec'); /** * Sustain time of the wavetable oscillator's position envelope * - * @name wtPosAttack - * @synonyms wtPosSus + * @name wtsustain + * @synonyms wtsus * @param {number | Pattern} gain sustain level (0 to 1) */ -export const { wtPosSustain, wtPosSus } = registerControl('wtPosSustain', 'wtPosSus'); +export const { wtsustain, wtsus } = registerControl('wtsustain', 'wtsus'); /** * Release time of the wavetable oscillator's position envelope * - * @name wtPosRelease - * @synonyms wtPosRel + * @name wtrelease + * @synonyms wtrel * @param {number | Pattern} time release time in seconds */ -export const { wtPosRelease, wtPosRel } = registerControl('wtPosRelease', 'wtPosRel'); +export const { wtrelease, wtrel } = registerControl('wtrelease', 'wtrel'); /** * Rate of the LFO for the wavetable oscillator's position * - * @name wtPosRate + * @name wtrate * @param {number | Pattern} rate rate in hertz */ -export const { wtPosRate } = registerControl('wtPosRate'); +export const { wtrate } = registerControl('wtrate'); +/** + * cycle synced rate of the LFO for the wavetable oscillator's position + * + * @name wtsync + * @param {number | Pattern} rate rate in cycles + */ +export const { wtsync } = registerControl('wtsync'); /** * Depth of the LFO for the wavetable oscillator's position * - * @name wtPosDepth + * @name wtdepth * @param {number | Pattern} depth depth of modulation */ -export const { wtPosDepth } = registerControl('wtPosDepth'); - -/** - * Whether to sync the LFO for the wavetable oscillator's position - * - * @name wtPosSynced - * @param {number | Pattern} synced Whether to sync the lfo to CPM. > 0.5 will be synced - */ -export const { wtPosSynced } = registerControl('wtPosSynced'); +export const { wtdepth } = registerControl('wtdepth'); /** * Shape of the LFO for the wavetable oscillator's position * - * @name wtPosShape + * @name wtshape * @param {number | Pattern} shape Shape of the lfo (0, 1, 2, ..) */ -export const { wtPosShape } = registerControl('wtPosShape'); +export const { wtshape } = registerControl('wtshape'); /** * DC offset of the LFO for the wavetable oscillator's position * - * @name wtPosDCOffset + * @name wtdc * @param {number | Pattern} dcoffset dc offset. set to 0 for unipolar */ -export const { wtPosDCOffset } = registerControl('wtPosDCOffset'); +export const { wtdc } = registerControl('wtdc'); /** * Skew of the LFO for the wavetable oscillator's position * - * @name wtPosSkew + * @name wtskew * @param {number | Pattern} skew How much to bend the LFO shape */ -export const { wtPosSkew } = registerControl('wtPosSkew'); +export const { wtskew } = registerControl('wtskew'); /** * Amount of warp (alteration of the waveform) to apply to the wavetable oscillator * - * @name wtWarp + * @name warp * @param {number | Pattern} amount Warp of the wavetable from 0 to 1 * @synonyms wavetableWarp * @example - * s("basique").bank("wt_digital").seg(8).note("F1").wtWarp("0 0.25 0.5 0.75 1") - * .wtWarpMode("spin") + * s("basique").bank("wt_digital").seg(8).note("F1").warp("0 0.25 0.5 0.75 1") + * .warpmode("spin") */ -export const { wtWarp, wavetableWarp } = registerControl('wtWarp', 'wavetableWarp'); +export const { warp, wavetableWarp } = registerControl('warp', 'wavetableWarp'); /** * Attack time of the wavetable oscillator's warp envelope * - * @name wtWarpAttack - * @synonyms wtWarpAtt + * @name warpattack + * @synonyms warpatt * @param {number | Pattern} time attack time in seconds */ -export const { wtWarpAttack, wtWarpAtt } = registerControl('wtWarpAttack', 'wtWarpAtt'); +export const { warpattack, warpatt } = registerControl('warpattack', 'warpatt'); /** * Decay time of the wavetable oscillator's warp envelope * - * @name wtWarpDecay - * @synonyms wtWarpDec + * @name warpdecay + * @synonyms warpdec * @param {number | Pattern} time decay time in seconds */ -export const { wtWarpDecay, wtWarpDec } = registerControl('wtWarpDecay', 'wtWarpDec'); +export const { warpdecay, warpdec } = registerControl('warpdecay', 'warpdec'); /** * Sustain time of the wavetable oscillator's warp envelope * - * @name wtWarpAttack - * @synonyms wtWarpSus + * @name warpsustain + * @synonyms warpsus * @param {number | Pattern} gain sustain level (0 to 1) */ -export const { wtWarpSustain, wtWarpSus } = registerControl('wtWarpSustain', 'wtWarpSus'); +export const { warpsustain, warpsus } = registerControl('warpsustain', 'warpsus'); /** * Release time of the wavetable oscillator's warp envelope * - * @name wtWarpRelease - * @synonyms wtWarpRel + * @name warprelease + * @synonyms warprel * @param {number | Pattern} time release time in seconds */ -export const { wtWarpRelease, wtWarpRel } = registerControl('wtWarpRelease', 'wtWarpRel'); +export const { warprelease, warprel } = registerControl('warprelease', 'warprel'); /** * Rate of the LFO for the wavetable oscillator's warp * - * @name wtWarpRate + * @name warprate * @param {number | Pattern} rate rate in hertz */ -export const { wtWarpRate } = registerControl('wtWarpRate'); +export const { warprate } = registerControl('warprate'); /** * Depth of the LFO for the wavetable oscillator's warp * - * @name wtWarpDepth + * @name warpdepth * @param {number | Pattern} depth depth of modulation */ -export const { wtWarpDepth } = registerControl('wtWarpDepth'); - -/** - * Whether to sync the LFO for the wavetable oscillator's warp - * - * @name wtWarpSynced - * @param {number | Pattern} synced Whether to sync the lfo to CPM. > 0.5 will be synced - */ -export const { wtWarpSynced } = registerControl('wtWarpSynced'); +export const { warpdepth } = registerControl('warpdepth'); /** * Shape of the LFO for the wavetable oscillator's warp * - * @name wtWarpShape + * @name warpshape * @param {number | Pattern} shape Shape of the lfo (0, 1, 2, ..) */ -export const { wtWarpShape } = registerControl('wtWarpShape'); +export const { warpshape } = registerControl('warpshape'); /** * DC offset of the LFO for the wavetable oscillator's warp * - * @name wtWarpDCOffset + * @name warpdc * @param {number | Pattern} dcoffset dc offset. set to 0 for unipolar */ -export const { wtWarpDCOffset } = registerControl('wtWarpDCOffset'); +export const { warpdc } = registerControl('warpdc'); /** * Skew of the LFO for the wavetable oscillator's warp * - * @name wtWarpSkew + * @name warpskew * @param {number | Pattern} skew How much to bend the LFO shape */ -export const { wtWarpSkew } = registerControl('wtWarpSkew'); +export const { warpskew } = registerControl('warpskew'); /** * Type of warp (alteration of the waveform) to apply to the wavetable oscillator. @@ -284,27 +282,43 @@ export const { wtWarpSkew } = registerControl('wtWarpSkew'); * The current options are: none, asym, bendp, bendm, bendmp, sync, quant, fold, pwm, orbit, * spin, chaos, primes, binary, brownian, reciprocal, wormhole, logistic, sigmoid, fractal, flip * - * @name wtWarpMode + * @name warpmode * @param {number | string | Pattern} mode Warp mode * @synonyms wavetableWarpMode * @example - * s("morgana").bank("wt_digital").seg(8).note("F1").wtWarp("0 0.25 0.5 0.75 1") - * .wtWarpMode("*2") + * s("morgana").bank("wt_digital").seg(8).note("F1").warp("0 0.25 0.5 0.75 1") + * .warpmode("*2") * */ -export const { wtWarpMode, wavetableWarpMode } = registerControl('wtWarpMode', 'wavetableWarpMode'); +export const { warpmode, wavetableWarpMode } = registerControl('warpmode', 'wavetableWarpMode'); /** * Amount of randomness of the initial phase of the wavetable oscillator. * - * @name wtPhaseRand + * @name wtphaserand * @param {number | Pattern} amount Randomness of the initial phase. Between 0 (not random) and 1 (fully random) * @synonyms wavetablePhaseRand * @example - * s("basique").bank("wt_digital").seg(16).wtPhaseRand("<0 1>") + * s("basique").bank("wt_digital").seg(16).wtphaserand("<0 1>") * */ -export const { wtPhaseRand, wavetablePhaseRand } = registerControl('wtPhaseRand', 'wavetablePhaseRand'); +export const { wtphaserand, wavetablePhaseRand } = registerControl('wtphaserand', 'wavetablePhaseRand'); + +/** + * Amount of envelope applied wavetable oscillator's position envelope + * + * @name warpenv + * @param {number | Pattern} amount between 0 and 1 + */ +export const { warpenv } = registerControl('warpenv'); + +/** + * cycle synced rate of the LFO for the wavetable warp position + * + * @name warpsync + * @param {number | Pattern} rate rate in cycles + */ +export const { warpsync } = registerControl('warpsync'); /** * Define a custom webaudio node to use as a sound source. diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 48264ec05..52ed9bff8 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -555,7 +555,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) audioNodes.forEach((n) => n?.disconnect()); activeSoundSources.delete(chainID); }; - const soundHandle = await onTrigger(t, value, onEnded); + const soundHandle = await onTrigger(t, value, onEnded, cps); if (soundHandle) { sourceNode = soundHandle.node; diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index 095bd079e..eddc2e3e8 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -14,7 +14,7 @@ import { import { logger } from './logger.mjs'; const WT_MAX_MIP_LEVELS = 6; -export const WarpMode = Object.freeze({ +export const Warpmode = Object.freeze({ NONE: 0, ASYM: 1, MIRROR: 2, @@ -177,11 +177,17 @@ const _processTables = (json, baseUrl, frameLen, options = {}) => { }; export function registerWaveTable(key, tables, params) { - registerSound(key, (t, hapValue, onended) => onTriggerSynth(t, hapValue, onended, tables, params?.frameLen ?? 2048), { - type: 'wavetable', - tables, - ...params, - }); + registerSound( + key, + (t, hapValue, onended, cps) => { + return onTriggerSynth(t, hapValue, onended, tables, cps, params?.frameLen ?? 2048); + }, + { + type: 'wavetable', + tables, + ...params, + }, + ); } /** @@ -214,13 +220,13 @@ export const tables = async (url, frameLen, json, options = {}) => { }); }; -export async function onTriggerSynth(t, value, onended, tables, frameLen) { - const { s, n = 0, duration } = value; +export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) { + const { s, n = 0, duration, wtenv } = value; const ac = getAudioContext(); const [attack, decay, sustain, release] = getADSRValues([value.attack, value.decay, value.sustain, value.release]); - let { wtWarpMode } = value; - if (typeof wtWarpMode === 'string') { - wtWarpMode = WarpMode[wtWarpMode.toUpperCase()] ?? WarpMode.NONE; + let { warpmode } = value; + if (typeof warpmode === 'string') { + warpmode = Warpmode[warpmode.toUpperCase()] ?? Warpmode.NONE; } const frequency = getFrequencyFromValue(value); const { url, label } = getCommonSampleInfo(value, tables); @@ -236,12 +242,12 @@ export async function onTriggerSynth(t, value, onended, tables, frameLen) { end: envEnd, frequency, detune: value.detune, - position: value.wtPos, - warp: value.wtWarp, - warpMode: wtWarpMode, + position: value.wt, + warp: value.warp, + warpMode: warpmode, voices: value.unison, spread: value.spread, - phaserand: value.wtPhaseRand, + phaserand: (value.wtphaserand ?? value.unison > 1) ? 1 : 0, }, { outputChannelCount: [2] }, ); @@ -250,36 +256,52 @@ export async function onTriggerSynth(t, value, onended, tables, frameLen) { logger(`[wavetable] still loading sound "${s}:${n}"`, 'highlight'); return; } - const posADSRParams = [value.wtPosAttack, value.wtPosDecay, value.wtPosSustain, value.wtPosRelease]; - const warpADSRParams = [value.wtPosAttack, value.wtPosDecay, value.wtPosSustain, value.wtPosRelease]; + const posADSRParams = [value.wtattack, value.wtdecay, value.wtsustain, value.wtrelease]; + const warpADSRParams = [value.warpattack, value.warpdecay, value.warpsustain, value.warprelease]; const wtParams = source.parameters; const positionParam = wtParams.get('position'); const warpParam = wtParams.get('warp'); let posLFO; - if (posADSRParams.some((p) => p !== undefined)) { - const [pAttack, pDecay, pSustain, pRelease] = getADSRValues(posADSRParams); - getParamADSR(positionParam, pAttack, pDecay, pSustain, pRelease, 0, 1, t, holdEnd, 'linear'); - } else { + if ([wtenv, ...posADSRParams].some((p) => p !== undefined)) { + const [pAttack, pDecay, pSustain, pRelease] = getADSRValues(posADSRParams, 'linear', [0, 0.5, 0, 0.1]); + const min = value.wt ?? 0; + const max = (wtenv ?? 0.5) + min; + getParamADSR(positionParam, pAttack, pDecay, pSustain, pRelease, min, max, t, holdEnd, 'linear'); + } + let wtrate = value.wtrate; + if (value.wtsync != null) { + wtrate = wtrate = cps * value.wtsync; + } + if ([wtrate, value.wtdepth, value.wtshape, value.wtskew, value.wtdc].some((p) => p != null)) { const posLFO = getLfo(ac, t, endWithRelease, { - frequency: value.wtPosRate, - depth: value.wtPosDepth, - shape: value.wtPosShape, - skew: value.wtPosSkew, - dcoffset: value.wtPosDCOffset ?? 0, + frequency: wtrate, + depth: value.wtdepth ?? 0.5, + shape: value.wtshape, + skew: value.wtskew, + dcoffset: value.wtdc ?? 0, }); posLFO.connect(positionParam); } let warpLFO; + if (posADSRParams.some((p) => p !== undefined)) { const [wAttack, wDecay, wSustain, wRelease] = getADSRValues(warpADSRParams); - getParamADSR(warpParam, wAttack, wDecay, wSustain, wRelease, 0, 1, t, holdEnd, 'linear'); - } else { + const min = value.warp ?? 0; + const max = (value.warpenv ?? 0.5) + min; + getParamADSR(warpParam, wAttack, wDecay, wSustain, wRelease, min, max, t, holdEnd, 'linear', [0, 0.5, 0, 0.1]); + } + let warprate = value.warprate; + if (value.warpsync != null) { + console.info(value.warpsync); + warprate = warprate = cps * value.warpsync; + } + if ([warprate, value.warpdepth, value.warpshape, value.warpskew, value.warpdc].some((p) => p != null)) { const warpLFO = getLfo(ac, t, endWithRelease, { - frequency: value.wtWarpRate, - depth: value.wtWarpDepth, - shape: value.wtWarpShape, - skew: value.wtWarpSkew, - dcoffset: value.wtWarpDCOffset ?? 0, + frequency: warprate, + depth: value.warpdepth ?? 0.5, + shape: value.warpshape, + skew: value.warpskew, + dcoffset: value.warpdc ?? 0, }); warpLFO.connect(warpParam); } From c689874bb473a58e1b7031a385227af675c4af08 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sun, 28 Sep 2025 14:57:12 -0400 Subject: [PATCH 226/335] simplify modulators --- packages/superdough/helpers.mjs | 35 +++++++++++++ packages/superdough/wavetable.mjs | 84 ++++++++++++++++--------------- 2 files changed, 78 insertions(+), 41 deletions(-) diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index 859329b20..c6ebd1b89 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -153,6 +153,41 @@ export const getADSRValues = (params, curve = 'linear', defaultValues) => { return [Math.max(a ?? 0, envmin), Math.max(d ?? 0, envmin), Math.min(sustain, envmax), Math.max(r ?? 0, releaseMin)]; }; +// helper utility for applying standard modulators to a parameter +export function applyParameterModulators(audioContext, param, start, end, envelopeValues, lfoValues) { + let { amount,offset,defaultAmount = 1, curve = 'linear', values, holdEnd, defaultValues } = envelopeValues; + + if (amount == null) { + const hasADSRParams = values.some(p => p != null); + amount = hasADSRParams ? defaultAmount : 0; + } + + const min = offset ?? 0; + const max = amount + min + const diff = Math.abs(max - min) + if (diff) { + const [attack, decay, sustain, release] = getADSRValues(values, curve, defaultValues); + getParamADSR(param, attack, decay, sustain, release, min, max, start, holdEnd, curve); + } + let lfo + let {defaultDepth = 1,depth, dcoffset, ...getLfoInputs} = lfoValues + + if (depth == null) { + const hasLFOParams = Object.values(getLfoInputs).some(v => v != null) + depth = hasLFOParams ? defaultDepth : 0; + } + if (depth) { + lfo = getLfo(audioContext, start, end, { + depth, + dcoffset, + ...getLfoInputs + }); + lfo.connect(param); + } + + return { lfo, disconnect: () => lfo?.disconnect() } +} + export function createFilter(context, type, frequency, Q, att, dec, sus, rel, fenv, start, end, fanchor, model, drive) { const curve = 'exponential'; const [attack, decay, sustain, release] = getADSRValues([att, dec, sus, rel], curve, [0.005, 0.14, 0, 0.1]); diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index eddc2e3e8..bcf4ea461 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -1,6 +1,7 @@ import { getAudioContext, registerSound } from './index.mjs'; import { getCommonSampleInfo } from './util.mjs'; import { + applyParameterModulators, destroyAudioWorkletNode, getADSRValues, getFrequencyFromValue, @@ -220,8 +221,10 @@ export const tables = async (url, frameLen, json, options = {}) => { }); }; + + export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) { - const { s, n = 0, duration, wtenv } = value; + const { s, n = 0, duration } = value; const ac = getAudioContext(); const [attack, decay, sustain, release] = getADSRValues([value.attack, value.decay, value.sustain, value.release]); let { warpmode } = value; @@ -245,7 +248,7 @@ export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) { position: value.wt, warp: value.warp, warpMode: warpmode, - voices: value.unison, + voices: Math.max(value.unison ?? 1, 1), spread: value.spread, phaserand: (value.wtphaserand ?? value.unison > 1) ? 1 : 0, }, @@ -261,55 +264,54 @@ export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) { const wtParams = source.parameters; const positionParam = wtParams.get('position'); const warpParam = wtParams.get('warp'); - let posLFO; - if ([wtenv, ...posADSRParams].some((p) => p !== undefined)) { - const [pAttack, pDecay, pSustain, pRelease] = getADSRValues(posADSRParams, 'linear', [0, 0.5, 0, 0.1]); - const min = value.wt ?? 0; - const max = (wtenv ?? 0.5) + min; - getParamADSR(positionParam, pAttack, pDecay, pSustain, pRelease, min, max, t, holdEnd, 'linear'); - } + let wtrate = value.wtrate; if (value.wtsync != null) { - wtrate = wtrate = cps * value.wtsync; + wtrate = cps * value.wtsync; } - if ([wtrate, value.wtdepth, value.wtshape, value.wtskew, value.wtdc].some((p) => p != null)) { - const posLFO = getLfo(ac, t, endWithRelease, { - frequency: wtrate, - depth: value.wtdepth ?? 0.5, - shape: value.wtshape, - skew: value.wtskew, - dcoffset: value.wtdc ?? 0, - }); - posLFO.connect(positionParam); - } - let warpLFO; - if (posADSRParams.some((p) => p !== undefined)) { - const [wAttack, wDecay, wSustain, wRelease] = getADSRValues(warpADSRParams); - const min = value.warp ?? 0; - const max = (value.warpenv ?? 0.5) + min; - getParamADSR(warpParam, wAttack, wDecay, wSustain, wRelease, min, max, t, holdEnd, 'linear', [0, 0.5, 0, 0.1]); - } + const wtPosModulators = applyParameterModulators(ac, positionParam, t, endWithRelease, { + offset: value.wt, + amount: value.wtenv, + defaultAmount: 0.5, + shape: 'linear', + values: posADSRParams, + holdEnd, + defaultValues: [0, 0.5, 0, 0.1], + }, { + frequency: wtrate, + depth: value.wtdepth, + defaultDepth: 0.5, + shape: value.wtshape, + skew: value.wtskew, + dcoffset: value.wtdc ?? 0, + }); + let warprate = value.warprate; if (value.warpsync != null) { - console.info(value.warpsync); warprate = warprate = cps * value.warpsync; } - if ([warprate, value.warpdepth, value.warpshape, value.warpskew, value.warpdc].some((p) => p != null)) { - const warpLFO = getLfo(ac, t, endWithRelease, { - frequency: warprate, - depth: value.warpdepth ?? 0.5, - shape: value.warpshape, - skew: value.warpskew, - dcoffset: value.warpdc ?? 0, - }); - warpLFO.connect(warpParam); - } + const wtWarpModulators = applyParameterModulators(ac, warpParam, t, endWithRelease, { + offset: value.warp, + amount: value.warpenv, + defaultAmount: 0.5, + shape: 'linear', + values: warpADSRParams, + holdEnd, + defaultValues: [0, 0.5, 0, 0.1], + }, { + frequency: warprate, + depth: value.warpdepth, + defaultDepth: 0.5, + shape: value.warpshape, + skew: value.warpskew, + dcoffset: value.warpdc ?? 0, + }); const vibratoOscillator = getVibratoOscillator(source.detune, value, t); const envGain = ac.createGain(); const node = source.connect(envGain); getParamADSR(node.gain, attack, decay, sustain, release, 0, 1, t, holdEnd, 'linear'); - getPitchEnvelope(source.detune, value, t, holdEnd); + getPitchEnvelope(source.parameters.get('detune'), value, t, holdEnd); const handle = { node, source }; const timeoutNode = webAudioTimeout( ac, @@ -318,8 +320,8 @@ export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) { destroyAudioWorkletNode(source); vibratoOscillator?.stop(); node.disconnect(); - posLFO?.disconnect(); - warpLFO?.disconnect(); + wtPosModulators?.disconnect(); + wtWarpModulators?.disconnect(); onended(); }, t, From 54ebc97ddc3531c4d814e800887e22afc6308d09 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sun, 28 Sep 2025 15:07:35 -0400 Subject: [PATCH 227/335] fix tests --- packages/superdough/helpers.mjs | 22 +- packages/superdough/wavetable.mjs | 80 ++-- packages/superdough/worklets.mjs | 2 +- test/__snapshots__/examples.test.mjs.snap | 440 +++++++++++----------- 4 files changed, 278 insertions(+), 266 deletions(-) diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index c6ebd1b89..47bca330d 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -155,37 +155,37 @@ export const getADSRValues = (params, curve = 'linear', defaultValues) => { // helper utility for applying standard modulators to a parameter export function applyParameterModulators(audioContext, param, start, end, envelopeValues, lfoValues) { - let { amount,offset,defaultAmount = 1, curve = 'linear', values, holdEnd, defaultValues } = envelopeValues; - + let { amount, offset, defaultAmount = 1, curve = 'linear', values, holdEnd, defaultValues } = envelopeValues; + if (amount == null) { - const hasADSRParams = values.some(p => p != null); + const hasADSRParams = values.some((p) => p != null); amount = hasADSRParams ? defaultAmount : 0; } const min = offset ?? 0; - const max = amount + min - const diff = Math.abs(max - min) + const max = amount + min; + const diff = Math.abs(max - min); if (diff) { const [attack, decay, sustain, release] = getADSRValues(values, curve, defaultValues); getParamADSR(param, attack, decay, sustain, release, min, max, start, holdEnd, curve); } - let lfo - let {defaultDepth = 1,depth, dcoffset, ...getLfoInputs} = lfoValues - + let lfo; + let { defaultDepth = 1, depth, dcoffset, ...getLfoInputs } = lfoValues; + if (depth == null) { - const hasLFOParams = Object.values(getLfoInputs).some(v => v != null) + const hasLFOParams = Object.values(getLfoInputs).some((v) => v != null); depth = hasLFOParams ? defaultDepth : 0; } if (depth) { lfo = getLfo(audioContext, start, end, { depth, dcoffset, - ...getLfoInputs + ...getLfoInputs, }); lfo.connect(param); } - return { lfo, disconnect: () => lfo?.disconnect() } + return { lfo, disconnect: () => lfo?.disconnect() }; } export function createFilter(context, type, frequency, Q, att, dec, sus, rel, fenv, start, end, fanchor, model, drive) { diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index bcf4ea461..4a21cabe4 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -221,8 +221,6 @@ export const tables = async (url, frameLen, json, options = {}) => { }); }; - - export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) { const { s, n = 0, duration } = value; const ac = getAudioContext(); @@ -270,43 +268,57 @@ export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) { wtrate = cps * value.wtsync; } - const wtPosModulators = applyParameterModulators(ac, positionParam, t, endWithRelease, { - offset: value.wt, - amount: value.wtenv, - defaultAmount: 0.5, - shape: 'linear', - values: posADSRParams, - holdEnd, - defaultValues: [0, 0.5, 0, 0.1], - }, { - frequency: wtrate, - depth: value.wtdepth, - defaultDepth: 0.5, - shape: value.wtshape, - skew: value.wtskew, - dcoffset: value.wtdc ?? 0, - }); + const wtPosModulators = applyParameterModulators( + ac, + positionParam, + t, + endWithRelease, + { + offset: value.wt, + amount: value.wtenv, + defaultAmount: 0.5, + shape: 'linear', + values: posADSRParams, + holdEnd, + defaultValues: [0, 0.5, 0, 0.1], + }, + { + frequency: wtrate, + depth: value.wtdepth, + defaultDepth: 0.5, + shape: value.wtshape, + skew: value.wtskew, + dcoffset: value.wtdc ?? 0, + }, + ); let warprate = value.warprate; if (value.warpsync != null) { warprate = warprate = cps * value.warpsync; } - const wtWarpModulators = applyParameterModulators(ac, warpParam, t, endWithRelease, { - offset: value.warp, - amount: value.warpenv, - defaultAmount: 0.5, - shape: 'linear', - values: warpADSRParams, - holdEnd, - defaultValues: [0, 0.5, 0, 0.1], - }, { - frequency: warprate, - depth: value.warpdepth, - defaultDepth: 0.5, - shape: value.warpshape, - skew: value.warpskew, - dcoffset: value.warpdc ?? 0, - }); + const wtWarpModulators = applyParameterModulators( + ac, + warpParam, + t, + endWithRelease, + { + offset: value.warp, + amount: value.warpenv, + defaultAmount: 0.5, + shape: 'linear', + values: warpADSRParams, + holdEnd, + defaultValues: [0, 0.5, 0, 0.1], + }, + { + frequency: warprate, + depth: value.warpdepth, + defaultDepth: 0.5, + shape: value.warpshape, + skew: value.warpskew, + dcoffset: value.warpdc ?? 0, + }, + ); const vibratoOscillator = getVibratoOscillator(source.detune, value, t); const envGain = ac.createGain(); const node = source.connect(envGain); diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 0a2d40d91..cea5a1ea5 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -1054,7 +1054,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { { name: 'warp', defaultValue: 0, minValue: 0, maxValue: 1 }, { name: 'warpMode', defaultValue: 0 }, { name: 'voices', defaultValue: 1, minValue: 1, maxValue: 32 }, - { name: 'spread', defaultValue: 0.18, minValue: 0, maxValue: 1 }, + { name: 'spread', defaultValue: 0.4, minValue: 0, maxValue: 1 }, { name: 'phaserand', defaultValue: 0, minValue: 0, maxValue: 1 }, ]; } diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index bfa4ae40e..73278947d 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -11789,6 +11789,112 @@ exports[`runs examples > example "vowel" example index 1 1`] = ` ] `; +exports[`runs examples > example "warp" example index 0 1`] = ` +[ + "[ 0/1 → 1/8 | s:basique bank:wt_digital note:F1 warp:0 warpmode:spin ]", + "[ (1/8 → 1/5) ⇝ 1/4 | s:basique bank:wt_digital note:F1 warp:0 warpmode:spin ]", + "[ 1/8 ⇜ (1/5 → 1/4) | s:basique bank:wt_digital note:F1 warp:0.25 warpmode:spin ]", + "[ 1/4 → 3/8 | s:basique bank:wt_digital note:F1 warp:0.25 warpmode:spin ]", + "[ (3/8 → 2/5) ⇝ 1/2 | s:basique bank:wt_digital note:F1 warp:0.25 warpmode:spin ]", + "[ 3/8 ⇜ (2/5 → 1/2) | s:basique bank:wt_digital note:F1 warp:0.5 warpmode:spin ]", + "[ (1/2 → 3/5) ⇝ 5/8 | s:basique bank:wt_digital note:F1 warp:0.5 warpmode:spin ]", + "[ 1/2 ⇜ (3/5 → 5/8) | s:basique bank:wt_digital note:F1 warp:0.75 warpmode:spin ]", + "[ 5/8 → 3/4 | s:basique bank:wt_digital note:F1 warp:0.75 warpmode:spin ]", + "[ (3/4 → 4/5) ⇝ 7/8 | s:basique bank:wt_digital note:F1 warp:0.75 warpmode:spin ]", + "[ 3/4 ⇜ (4/5 → 7/8) | s:basique bank:wt_digital note:F1 warp:1 warpmode:spin ]", + "[ 7/8 → 1/1 | s:basique bank:wt_digital note:F1 warp:1 warpmode:spin ]", + "[ 1/1 → 9/8 | s:basique bank:wt_digital note:F1 warp:0 warpmode:spin ]", + "[ (9/8 → 6/5) ⇝ 5/4 | s:basique bank:wt_digital note:F1 warp:0 warpmode:spin ]", + "[ 9/8 ⇜ (6/5 → 5/4) | s:basique bank:wt_digital note:F1 warp:0.25 warpmode:spin ]", + "[ 5/4 → 11/8 | s:basique bank:wt_digital note:F1 warp:0.25 warpmode:spin ]", + "[ (11/8 → 7/5) ⇝ 3/2 | s:basique bank:wt_digital note:F1 warp:0.25 warpmode:spin ]", + "[ 11/8 ⇜ (7/5 → 3/2) | s:basique bank:wt_digital note:F1 warp:0.5 warpmode:spin ]", + "[ (3/2 → 8/5) ⇝ 13/8 | s:basique bank:wt_digital note:F1 warp:0.5 warpmode:spin ]", + "[ 3/2 ⇜ (8/5 → 13/8) | s:basique bank:wt_digital note:F1 warp:0.75 warpmode:spin ]", + "[ 13/8 → 7/4 | s:basique bank:wt_digital note:F1 warp:0.75 warpmode:spin ]", + "[ (7/4 → 9/5) ⇝ 15/8 | s:basique bank:wt_digital note:F1 warp:0.75 warpmode:spin ]", + "[ 7/4 ⇜ (9/5 → 15/8) | s:basique bank:wt_digital note:F1 warp:1 warpmode:spin ]", + "[ 15/8 → 2/1 | s:basique bank:wt_digital note:F1 warp:1 warpmode:spin ]", + "[ 2/1 → 17/8 | s:basique bank:wt_digital note:F1 warp:0 warpmode:spin ]", + "[ (17/8 → 11/5) ⇝ 9/4 | s:basique bank:wt_digital note:F1 warp:0 warpmode:spin ]", + "[ 17/8 ⇜ (11/5 → 9/4) | s:basique bank:wt_digital note:F1 warp:0.25 warpmode:spin ]", + "[ 9/4 → 19/8 | s:basique bank:wt_digital note:F1 warp:0.25 warpmode:spin ]", + "[ (19/8 → 12/5) ⇝ 5/2 | s:basique bank:wt_digital note:F1 warp:0.25 warpmode:spin ]", + "[ 19/8 ⇜ (12/5 → 5/2) | s:basique bank:wt_digital note:F1 warp:0.5 warpmode:spin ]", + "[ (5/2 → 13/5) ⇝ 21/8 | s:basique bank:wt_digital note:F1 warp:0.5 warpmode:spin ]", + "[ 5/2 ⇜ (13/5 → 21/8) | s:basique bank:wt_digital note:F1 warp:0.75 warpmode:spin ]", + "[ 21/8 → 11/4 | s:basique bank:wt_digital note:F1 warp:0.75 warpmode:spin ]", + "[ (11/4 → 14/5) ⇝ 23/8 | s:basique bank:wt_digital note:F1 warp:0.75 warpmode:spin ]", + "[ 11/4 ⇜ (14/5 → 23/8) | s:basique bank:wt_digital note:F1 warp:1 warpmode:spin ]", + "[ 23/8 → 3/1 | s:basique bank:wt_digital note:F1 warp:1 warpmode:spin ]", + "[ 3/1 → 25/8 | s:basique bank:wt_digital note:F1 warp:0 warpmode:spin ]", + "[ (25/8 → 16/5) ⇝ 13/4 | s:basique bank:wt_digital note:F1 warp:0 warpmode:spin ]", + "[ 25/8 ⇜ (16/5 → 13/4) | s:basique bank:wt_digital note:F1 warp:0.25 warpmode:spin ]", + "[ 13/4 → 27/8 | s:basique bank:wt_digital note:F1 warp:0.25 warpmode:spin ]", + "[ (27/8 → 17/5) ⇝ 7/2 | s:basique bank:wt_digital note:F1 warp:0.25 warpmode:spin ]", + "[ 27/8 ⇜ (17/5 → 7/2) | s:basique bank:wt_digital note:F1 warp:0.5 warpmode:spin ]", + "[ (7/2 → 18/5) ⇝ 29/8 | s:basique bank:wt_digital note:F1 warp:0.5 warpmode:spin ]", + "[ 7/2 ⇜ (18/5 → 29/8) | s:basique bank:wt_digital note:F1 warp:0.75 warpmode:spin ]", + "[ 29/8 → 15/4 | s:basique bank:wt_digital note:F1 warp:0.75 warpmode:spin ]", + "[ (15/4 → 19/5) ⇝ 31/8 | s:basique bank:wt_digital note:F1 warp:0.75 warpmode:spin ]", + "[ 15/4 ⇜ (19/5 → 31/8) | s:basique bank:wt_digital note:F1 warp:1 warpmode:spin ]", + "[ 31/8 → 4/1 | s:basique bank:wt_digital note:F1 warp:1 warpmode:spin ]", +] +`; + +exports[`runs examples > example "warpmode" example index 0 1`] = ` +[ + "[ 0/1 → 1/8 | s:morgana bank:wt_digital note:F1 warp:0 warpmode:asym ]", + "[ (1/8 → 1/5) ⇝ 1/4 | s:morgana bank:wt_digital note:F1 warp:0 warpmode:asym ]", + "[ 1/8 ⇜ (1/5 → 1/4) | s:morgana bank:wt_digital note:F1 warp:0.25 warpmode:asym ]", + "[ 1/4 → 3/8 | s:morgana bank:wt_digital note:F1 warp:0.25 warpmode:asym ]", + "[ (3/8 → 2/5) ⇝ 1/2 | s:morgana bank:wt_digital note:F1 warp:0.25 warpmode:asym ]", + "[ 3/8 ⇜ (2/5 → 1/2) | s:morgana bank:wt_digital note:F1 warp:0.5 warpmode:asym ]", + "[ (1/2 → 3/5) ⇝ 5/8 | s:morgana bank:wt_digital note:F1 warp:0.5 warpmode:bendp ]", + "[ 1/2 ⇜ (3/5 → 5/8) | s:morgana bank:wt_digital note:F1 warp:0.75 warpmode:bendp ]", + "[ 5/8 → 3/4 | s:morgana bank:wt_digital note:F1 warp:0.75 warpmode:bendp ]", + "[ (3/4 → 4/5) ⇝ 7/8 | s:morgana bank:wt_digital note:F1 warp:0.75 warpmode:bendp ]", + "[ 3/4 ⇜ (4/5 → 7/8) | s:morgana bank:wt_digital note:F1 warp:1 warpmode:bendp ]", + "[ 7/8 → 1/1 | s:morgana bank:wt_digital note:F1 warp:1 warpmode:bendp ]", + "[ 1/1 → 9/8 | s:morgana bank:wt_digital note:F1 warp:0 warpmode:spin ]", + "[ (9/8 → 6/5) ⇝ 5/4 | s:morgana bank:wt_digital note:F1 warp:0 warpmode:spin ]", + "[ 9/8 ⇜ (6/5 → 5/4) | s:morgana bank:wt_digital note:F1 warp:0.25 warpmode:spin ]", + "[ 5/4 → 11/8 | s:morgana bank:wt_digital note:F1 warp:0.25 warpmode:spin ]", + "[ (11/8 → 7/5) ⇝ 3/2 | s:morgana bank:wt_digital note:F1 warp:0.25 warpmode:spin ]", + "[ 11/8 ⇜ (7/5 → 3/2) | s:morgana bank:wt_digital note:F1 warp:0.5 warpmode:spin ]", + "[ (3/2 → 8/5) ⇝ 13/8 | s:morgana bank:wt_digital note:F1 warp:0.5 warpmode:logistic ]", + "[ 3/2 ⇜ (8/5 → 13/8) | s:morgana bank:wt_digital note:F1 warp:0.75 warpmode:logistic ]", + "[ 13/8 → 7/4 | s:morgana bank:wt_digital note:F1 warp:0.75 warpmode:logistic ]", + "[ (7/4 → 9/5) ⇝ 15/8 | s:morgana bank:wt_digital note:F1 warp:0.75 warpmode:logistic ]", + "[ 7/4 ⇜ (9/5 → 15/8) | s:morgana bank:wt_digital note:F1 warp:1 warpmode:logistic ]", + "[ 15/8 → 2/1 | s:morgana bank:wt_digital note:F1 warp:1 warpmode:logistic ]", + "[ 2/1 → 17/8 | s:morgana bank:wt_digital note:F1 warp:0 warpmode:sync ]", + "[ (17/8 → 11/5) ⇝ 9/4 | s:morgana bank:wt_digital note:F1 warp:0 warpmode:sync ]", + "[ 17/8 ⇜ (11/5 → 9/4) | s:morgana bank:wt_digital note:F1 warp:0.25 warpmode:sync ]", + "[ 9/4 → 19/8 | s:morgana bank:wt_digital note:F1 warp:0.25 warpmode:sync ]", + "[ (19/8 → 12/5) ⇝ 5/2 | s:morgana bank:wt_digital note:F1 warp:0.25 warpmode:sync ]", + "[ 19/8 ⇜ (12/5 → 5/2) | s:morgana bank:wt_digital note:F1 warp:0.5 warpmode:sync ]", + "[ (5/2 → 13/5) ⇝ 21/8 | s:morgana bank:wt_digital note:F1 warp:0.5 warpmode:wormhole ]", + "[ 5/2 ⇜ (13/5 → 21/8) | s:morgana bank:wt_digital note:F1 warp:0.75 warpmode:wormhole ]", + "[ 21/8 → 11/4 | s:morgana bank:wt_digital note:F1 warp:0.75 warpmode:wormhole ]", + "[ (11/4 → 14/5) ⇝ 23/8 | s:morgana bank:wt_digital note:F1 warp:0.75 warpmode:wormhole ]", + "[ 11/4 ⇜ (14/5 → 23/8) | s:morgana bank:wt_digital note:F1 warp:1 warpmode:wormhole ]", + "[ 23/8 → 3/1 | s:morgana bank:wt_digital note:F1 warp:1 warpmode:wormhole ]", + "[ 3/1 → 25/8 | s:morgana bank:wt_digital note:F1 warp:0 warpmode:brownian ]", + "[ (25/8 → 16/5) ⇝ 13/4 | s:morgana bank:wt_digital note:F1 warp:0 warpmode:brownian ]", + "[ 25/8 ⇜ (16/5 → 13/4) | s:morgana bank:wt_digital note:F1 warp:0.25 warpmode:brownian ]", + "[ 13/4 → 27/8 | s:morgana bank:wt_digital note:F1 warp:0.25 warpmode:brownian ]", + "[ (27/8 → 17/5) ⇝ 7/2 | s:morgana bank:wt_digital note:F1 warp:0.25 warpmode:brownian ]", + "[ 27/8 ⇜ (17/5 → 7/2) | s:morgana bank:wt_digital note:F1 warp:0.5 warpmode:brownian ]", + "[ (7/2 → 18/5) ⇝ 29/8 | s:morgana bank:wt_digital note:F1 warp:0.5 warpmode:asym ]", + "[ 7/2 ⇜ (18/5 → 29/8) | s:morgana bank:wt_digital note:F1 warp:0.75 warpmode:asym ]", + "[ 29/8 → 15/4 | s:morgana bank:wt_digital note:F1 warp:0.75 warpmode:asym ]", + "[ (15/4 → 19/5) ⇝ 31/8 | s:morgana bank:wt_digital note:F1 warp:0.75 warpmode:asym ]", + "[ 15/4 ⇜ (19/5 → 31/8) | s:morgana bank:wt_digital note:F1 warp:1 warpmode:asym ]", + "[ 31/8 → 4/1 | s:morgana bank:wt_digital note:F1 warp:1 warpmode:asym ]", +] +`; + exports[`runs examples > example "wchoose" example index 0 1`] = ` [ "[ 0/1 → 1/5 | note:c2 s:sine ]", @@ -11993,231 +12099,125 @@ exports[`runs examples > example "withValue" example index 0 1`] = ` ] `; -exports[`runs examples > example "wtPhaseRand" example index 0 1`] = ` +exports[`runs examples > example "wt" example index 0 1`] = ` [ - "[ 0/1 → 1/16 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 1/16 → 1/8 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 1/8 → 3/16 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 3/16 → 1/4 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 1/4 → 5/16 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 5/16 → 3/8 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 3/8 → 7/16 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 7/16 → 1/2 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 1/2 → 9/16 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 9/16 → 5/8 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 5/8 → 11/16 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 11/16 → 3/4 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 3/4 → 13/16 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 13/16 → 7/8 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 7/8 → 15/16 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 15/16 → 1/1 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 1/1 → 17/16 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 17/16 → 9/8 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 9/8 → 19/16 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 19/16 → 5/4 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 5/4 → 21/16 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 21/16 → 11/8 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 11/8 → 23/16 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 23/16 → 3/2 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 3/2 → 25/16 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 25/16 → 13/8 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 13/8 → 27/16 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 27/16 → 7/4 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 7/4 → 29/16 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 29/16 → 15/8 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 15/8 → 31/16 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 31/16 → 2/1 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 2/1 → 33/16 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 33/16 → 17/8 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 17/8 → 35/16 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 35/16 → 9/4 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 9/4 → 37/16 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 37/16 → 19/8 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 19/8 → 39/16 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 39/16 → 5/2 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 5/2 → 41/16 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 41/16 → 21/8 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 21/8 → 43/16 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 43/16 → 11/4 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 11/4 → 45/16 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 45/16 → 23/8 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 23/8 → 47/16 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 47/16 → 3/1 | s:basique bank:wt_digital wtPhaseRand:0 ]", - "[ 3/1 → 49/16 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 49/16 → 25/8 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 25/8 → 51/16 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 51/16 → 13/4 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 13/4 → 53/16 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 53/16 → 27/8 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 27/8 → 55/16 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 55/16 → 7/2 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 7/2 → 57/16 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 57/16 → 29/8 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 29/8 → 59/16 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 59/16 → 15/4 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 15/4 → 61/16 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 61/16 → 31/8 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 31/8 → 63/16 | s:basique bank:wt_digital wtPhaseRand:1 ]", - "[ 63/16 → 4/1 | s:basique bank:wt_digital wtPhaseRand:1 ]", + "[ 0/1 → 1/8 | s:squelch bank:wt_digital note:F1 wt:0 ]", + "[ (1/8 → 1/5) ⇝ 1/4 | s:squelch bank:wt_digital note:F1 wt:0 ]", + "[ 1/8 ⇜ (1/5 → 1/4) | s:squelch bank:wt_digital note:F1 wt:0.25 ]", + "[ 1/4 → 3/8 | s:squelch bank:wt_digital note:F1 wt:0.25 ]", + "[ (3/8 → 2/5) ⇝ 1/2 | s:squelch bank:wt_digital note:F1 wt:0.25 ]", + "[ 3/8 ⇜ (2/5 → 1/2) | s:squelch bank:wt_digital note:F1 wt:0.5 ]", + "[ (1/2 → 3/5) ⇝ 5/8 | s:squelch bank:wt_digital note:F1 wt:0.5 ]", + "[ 1/2 ⇜ (3/5 → 5/8) | s:squelch bank:wt_digital note:F1 wt:0.75 ]", + "[ 5/8 → 3/4 | s:squelch bank:wt_digital note:F1 wt:0.75 ]", + "[ (3/4 → 4/5) ⇝ 7/8 | s:squelch bank:wt_digital note:F1 wt:0.75 ]", + "[ 3/4 ⇜ (4/5 → 7/8) | s:squelch bank:wt_digital note:F1 wt:1 ]", + "[ 7/8 → 1/1 | s:squelch bank:wt_digital note:F1 wt:1 ]", + "[ 1/1 → 9/8 | s:squelch bank:wt_digital note:F1 wt:0 ]", + "[ (9/8 → 6/5) ⇝ 5/4 | s:squelch bank:wt_digital note:F1 wt:0 ]", + "[ 9/8 ⇜ (6/5 → 5/4) | s:squelch bank:wt_digital note:F1 wt:0.25 ]", + "[ 5/4 → 11/8 | s:squelch bank:wt_digital note:F1 wt:0.25 ]", + "[ (11/8 → 7/5) ⇝ 3/2 | s:squelch bank:wt_digital note:F1 wt:0.25 ]", + "[ 11/8 ⇜ (7/5 → 3/2) | s:squelch bank:wt_digital note:F1 wt:0.5 ]", + "[ (3/2 → 8/5) ⇝ 13/8 | s:squelch bank:wt_digital note:F1 wt:0.5 ]", + "[ 3/2 ⇜ (8/5 → 13/8) | s:squelch bank:wt_digital note:F1 wt:0.75 ]", + "[ 13/8 → 7/4 | s:squelch bank:wt_digital note:F1 wt:0.75 ]", + "[ (7/4 → 9/5) ⇝ 15/8 | s:squelch bank:wt_digital note:F1 wt:0.75 ]", + "[ 7/4 ⇜ (9/5 → 15/8) | s:squelch bank:wt_digital note:F1 wt:1 ]", + "[ 15/8 → 2/1 | s:squelch bank:wt_digital note:F1 wt:1 ]", + "[ 2/1 → 17/8 | s:squelch bank:wt_digital note:F1 wt:0 ]", + "[ (17/8 → 11/5) ⇝ 9/4 | s:squelch bank:wt_digital note:F1 wt:0 ]", + "[ 17/8 ⇜ (11/5 → 9/4) | s:squelch bank:wt_digital note:F1 wt:0.25 ]", + "[ 9/4 → 19/8 | s:squelch bank:wt_digital note:F1 wt:0.25 ]", + "[ (19/8 → 12/5) ⇝ 5/2 | s:squelch bank:wt_digital note:F1 wt:0.25 ]", + "[ 19/8 ⇜ (12/5 → 5/2) | s:squelch bank:wt_digital note:F1 wt:0.5 ]", + "[ (5/2 → 13/5) ⇝ 21/8 | s:squelch bank:wt_digital note:F1 wt:0.5 ]", + "[ 5/2 ⇜ (13/5 → 21/8) | s:squelch bank:wt_digital note:F1 wt:0.75 ]", + "[ 21/8 → 11/4 | s:squelch bank:wt_digital note:F1 wt:0.75 ]", + "[ (11/4 → 14/5) ⇝ 23/8 | s:squelch bank:wt_digital note:F1 wt:0.75 ]", + "[ 11/4 ⇜ (14/5 → 23/8) | s:squelch bank:wt_digital note:F1 wt:1 ]", + "[ 23/8 → 3/1 | s:squelch bank:wt_digital note:F1 wt:1 ]", + "[ 3/1 → 25/8 | s:squelch bank:wt_digital note:F1 wt:0 ]", + "[ (25/8 → 16/5) ⇝ 13/4 | s:squelch bank:wt_digital note:F1 wt:0 ]", + "[ 25/8 ⇜ (16/5 → 13/4) | s:squelch bank:wt_digital note:F1 wt:0.25 ]", + "[ 13/4 → 27/8 | s:squelch bank:wt_digital note:F1 wt:0.25 ]", + "[ (27/8 → 17/5) ⇝ 7/2 | s:squelch bank:wt_digital note:F1 wt:0.25 ]", + "[ 27/8 ⇜ (17/5 → 7/2) | s:squelch bank:wt_digital note:F1 wt:0.5 ]", + "[ (7/2 → 18/5) ⇝ 29/8 | s:squelch bank:wt_digital note:F1 wt:0.5 ]", + "[ 7/2 ⇜ (18/5 → 29/8) | s:squelch bank:wt_digital note:F1 wt:0.75 ]", + "[ 29/8 → 15/4 | s:squelch bank:wt_digital note:F1 wt:0.75 ]", + "[ (15/4 → 19/5) ⇝ 31/8 | s:squelch bank:wt_digital note:F1 wt:0.75 ]", + "[ 15/4 ⇜ (19/5 → 31/8) | s:squelch bank:wt_digital note:F1 wt:1 ]", + "[ 31/8 → 4/1 | s:squelch bank:wt_digital note:F1 wt:1 ]", ] `; -exports[`runs examples > example "wtPos" example index 0 1`] = ` +exports[`runs examples > example "wtphaserand" example index 0 1`] = ` [ - "[ 0/1 → 1/8 | s:squelch bank:wt_digital note:F1 wtPos:0 ]", - "[ (1/8 → 1/5) ⇝ 1/4 | s:squelch bank:wt_digital note:F1 wtPos:0 ]", - "[ 1/8 ⇜ (1/5 → 1/4) | s:squelch bank:wt_digital note:F1 wtPos:0.25 ]", - "[ 1/4 → 3/8 | s:squelch bank:wt_digital note:F1 wtPos:0.25 ]", - "[ (3/8 → 2/5) ⇝ 1/2 | s:squelch bank:wt_digital note:F1 wtPos:0.25 ]", - "[ 3/8 ⇜ (2/5 → 1/2) | s:squelch bank:wt_digital note:F1 wtPos:0.5 ]", - "[ (1/2 → 3/5) ⇝ 5/8 | s:squelch bank:wt_digital note:F1 wtPos:0.5 ]", - "[ 1/2 ⇜ (3/5 → 5/8) | s:squelch bank:wt_digital note:F1 wtPos:0.75 ]", - "[ 5/8 → 3/4 | s:squelch bank:wt_digital note:F1 wtPos:0.75 ]", - "[ (3/4 → 4/5) ⇝ 7/8 | s:squelch bank:wt_digital note:F1 wtPos:0.75 ]", - "[ 3/4 ⇜ (4/5 → 7/8) | s:squelch bank:wt_digital note:F1 wtPos:1 ]", - "[ 7/8 → 1/1 | s:squelch bank:wt_digital note:F1 wtPos:1 ]", - "[ 1/1 → 9/8 | s:squelch bank:wt_digital note:F1 wtPos:0 ]", - "[ (9/8 → 6/5) ⇝ 5/4 | s:squelch bank:wt_digital note:F1 wtPos:0 ]", - "[ 9/8 ⇜ (6/5 → 5/4) | s:squelch bank:wt_digital note:F1 wtPos:0.25 ]", - "[ 5/4 → 11/8 | s:squelch bank:wt_digital note:F1 wtPos:0.25 ]", - "[ (11/8 → 7/5) ⇝ 3/2 | s:squelch bank:wt_digital note:F1 wtPos:0.25 ]", - "[ 11/8 ⇜ (7/5 → 3/2) | s:squelch bank:wt_digital note:F1 wtPos:0.5 ]", - "[ (3/2 → 8/5) ⇝ 13/8 | s:squelch bank:wt_digital note:F1 wtPos:0.5 ]", - "[ 3/2 ⇜ (8/5 → 13/8) | s:squelch bank:wt_digital note:F1 wtPos:0.75 ]", - "[ 13/8 → 7/4 | s:squelch bank:wt_digital note:F1 wtPos:0.75 ]", - "[ (7/4 → 9/5) ⇝ 15/8 | s:squelch bank:wt_digital note:F1 wtPos:0.75 ]", - "[ 7/4 ⇜ (9/5 → 15/8) | s:squelch bank:wt_digital note:F1 wtPos:1 ]", - "[ 15/8 → 2/1 | s:squelch bank:wt_digital note:F1 wtPos:1 ]", - "[ 2/1 → 17/8 | s:squelch bank:wt_digital note:F1 wtPos:0 ]", - "[ (17/8 → 11/5) ⇝ 9/4 | s:squelch bank:wt_digital note:F1 wtPos:0 ]", - "[ 17/8 ⇜ (11/5 → 9/4) | s:squelch bank:wt_digital note:F1 wtPos:0.25 ]", - "[ 9/4 → 19/8 | s:squelch bank:wt_digital note:F1 wtPos:0.25 ]", - "[ (19/8 → 12/5) ⇝ 5/2 | s:squelch bank:wt_digital note:F1 wtPos:0.25 ]", - "[ 19/8 ⇜ (12/5 → 5/2) | s:squelch bank:wt_digital note:F1 wtPos:0.5 ]", - "[ (5/2 → 13/5) ⇝ 21/8 | s:squelch bank:wt_digital note:F1 wtPos:0.5 ]", - "[ 5/2 ⇜ (13/5 → 21/8) | s:squelch bank:wt_digital note:F1 wtPos:0.75 ]", - "[ 21/8 → 11/4 | s:squelch bank:wt_digital note:F1 wtPos:0.75 ]", - "[ (11/4 → 14/5) ⇝ 23/8 | s:squelch bank:wt_digital note:F1 wtPos:0.75 ]", - "[ 11/4 ⇜ (14/5 → 23/8) | s:squelch bank:wt_digital note:F1 wtPos:1 ]", - "[ 23/8 → 3/1 | s:squelch bank:wt_digital note:F1 wtPos:1 ]", - "[ 3/1 → 25/8 | s:squelch bank:wt_digital note:F1 wtPos:0 ]", - "[ (25/8 → 16/5) ⇝ 13/4 | s:squelch bank:wt_digital note:F1 wtPos:0 ]", - "[ 25/8 ⇜ (16/5 → 13/4) | s:squelch bank:wt_digital note:F1 wtPos:0.25 ]", - "[ 13/4 → 27/8 | s:squelch bank:wt_digital note:F1 wtPos:0.25 ]", - "[ (27/8 → 17/5) ⇝ 7/2 | s:squelch bank:wt_digital note:F1 wtPos:0.25 ]", - "[ 27/8 ⇜ (17/5 → 7/2) | s:squelch bank:wt_digital note:F1 wtPos:0.5 ]", - "[ (7/2 → 18/5) ⇝ 29/8 | s:squelch bank:wt_digital note:F1 wtPos:0.5 ]", - "[ 7/2 ⇜ (18/5 → 29/8) | s:squelch bank:wt_digital note:F1 wtPos:0.75 ]", - "[ 29/8 → 15/4 | s:squelch bank:wt_digital note:F1 wtPos:0.75 ]", - "[ (15/4 → 19/5) ⇝ 31/8 | s:squelch bank:wt_digital note:F1 wtPos:0.75 ]", - "[ 15/4 ⇜ (19/5 → 31/8) | s:squelch bank:wt_digital note:F1 wtPos:1 ]", - "[ 31/8 → 4/1 | s:squelch bank:wt_digital note:F1 wtPos:1 ]", -] -`; - -exports[`runs examples > example "wtWarp" example index 0 1`] = ` -[ - "[ 0/1 → 1/8 | s:basique bank:wt_digital note:F1 wtWarp:0 wtWarpMode:spin ]", - "[ (1/8 → 1/5) ⇝ 1/4 | s:basique bank:wt_digital note:F1 wtWarp:0 wtWarpMode:spin ]", - "[ 1/8 ⇜ (1/5 → 1/4) | s:basique bank:wt_digital note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ 1/4 → 3/8 | s:basique bank:wt_digital note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ (3/8 → 2/5) ⇝ 1/2 | s:basique bank:wt_digital note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ 3/8 ⇜ (2/5 → 1/2) | s:basique bank:wt_digital note:F1 wtWarp:0.5 wtWarpMode:spin ]", - "[ (1/2 → 3/5) ⇝ 5/8 | s:basique bank:wt_digital note:F1 wtWarp:0.5 wtWarpMode:spin ]", - "[ 1/2 ⇜ (3/5 → 5/8) | s:basique bank:wt_digital note:F1 wtWarp:0.75 wtWarpMode:spin ]", - "[ 5/8 → 3/4 | s:basique bank:wt_digital note:F1 wtWarp:0.75 wtWarpMode:spin ]", - "[ (3/4 → 4/5) ⇝ 7/8 | s:basique bank:wt_digital note:F1 wtWarp:0.75 wtWarpMode:spin ]", - "[ 3/4 ⇜ (4/5 → 7/8) | s:basique bank:wt_digital note:F1 wtWarp:1 wtWarpMode:spin ]", - "[ 7/8 → 1/1 | s:basique bank:wt_digital note:F1 wtWarp:1 wtWarpMode:spin ]", - "[ 1/1 → 9/8 | s:basique bank:wt_digital note:F1 wtWarp:0 wtWarpMode:spin ]", - "[ (9/8 → 6/5) ⇝ 5/4 | s:basique bank:wt_digital note:F1 wtWarp:0 wtWarpMode:spin ]", - "[ 9/8 ⇜ (6/5 → 5/4) | s:basique bank:wt_digital note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ 5/4 → 11/8 | s:basique bank:wt_digital note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ (11/8 → 7/5) ⇝ 3/2 | s:basique bank:wt_digital note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ 11/8 ⇜ (7/5 → 3/2) | s:basique bank:wt_digital note:F1 wtWarp:0.5 wtWarpMode:spin ]", - "[ (3/2 → 8/5) ⇝ 13/8 | s:basique bank:wt_digital note:F1 wtWarp:0.5 wtWarpMode:spin ]", - "[ 3/2 ⇜ (8/5 → 13/8) | s:basique bank:wt_digital note:F1 wtWarp:0.75 wtWarpMode:spin ]", - "[ 13/8 → 7/4 | s:basique bank:wt_digital note:F1 wtWarp:0.75 wtWarpMode:spin ]", - "[ (7/4 → 9/5) ⇝ 15/8 | s:basique bank:wt_digital note:F1 wtWarp:0.75 wtWarpMode:spin ]", - "[ 7/4 ⇜ (9/5 → 15/8) | s:basique bank:wt_digital note:F1 wtWarp:1 wtWarpMode:spin ]", - "[ 15/8 → 2/1 | s:basique bank:wt_digital note:F1 wtWarp:1 wtWarpMode:spin ]", - "[ 2/1 → 17/8 | s:basique bank:wt_digital note:F1 wtWarp:0 wtWarpMode:spin ]", - "[ (17/8 → 11/5) ⇝ 9/4 | s:basique bank:wt_digital note:F1 wtWarp:0 wtWarpMode:spin ]", - "[ 17/8 ⇜ (11/5 → 9/4) | s:basique bank:wt_digital note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ 9/4 → 19/8 | s:basique bank:wt_digital note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ (19/8 → 12/5) ⇝ 5/2 | s:basique bank:wt_digital note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ 19/8 ⇜ (12/5 → 5/2) | s:basique bank:wt_digital note:F1 wtWarp:0.5 wtWarpMode:spin ]", - "[ (5/2 → 13/5) ⇝ 21/8 | s:basique bank:wt_digital note:F1 wtWarp:0.5 wtWarpMode:spin ]", - "[ 5/2 ⇜ (13/5 → 21/8) | s:basique bank:wt_digital note:F1 wtWarp:0.75 wtWarpMode:spin ]", - "[ 21/8 → 11/4 | s:basique bank:wt_digital note:F1 wtWarp:0.75 wtWarpMode:spin ]", - "[ (11/4 → 14/5) ⇝ 23/8 | s:basique bank:wt_digital note:F1 wtWarp:0.75 wtWarpMode:spin ]", - "[ 11/4 ⇜ (14/5 → 23/8) | s:basique bank:wt_digital note:F1 wtWarp:1 wtWarpMode:spin ]", - "[ 23/8 → 3/1 | s:basique bank:wt_digital note:F1 wtWarp:1 wtWarpMode:spin ]", - "[ 3/1 → 25/8 | s:basique bank:wt_digital note:F1 wtWarp:0 wtWarpMode:spin ]", - "[ (25/8 → 16/5) ⇝ 13/4 | s:basique bank:wt_digital note:F1 wtWarp:0 wtWarpMode:spin ]", - "[ 25/8 ⇜ (16/5 → 13/4) | s:basique bank:wt_digital note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ 13/4 → 27/8 | s:basique bank:wt_digital note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ (27/8 → 17/5) ⇝ 7/2 | s:basique bank:wt_digital note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ 27/8 ⇜ (17/5 → 7/2) | s:basique bank:wt_digital note:F1 wtWarp:0.5 wtWarpMode:spin ]", - "[ (7/2 → 18/5) ⇝ 29/8 | s:basique bank:wt_digital note:F1 wtWarp:0.5 wtWarpMode:spin ]", - "[ 7/2 ⇜ (18/5 → 29/8) | s:basique bank:wt_digital note:F1 wtWarp:0.75 wtWarpMode:spin ]", - "[ 29/8 → 15/4 | s:basique bank:wt_digital note:F1 wtWarp:0.75 wtWarpMode:spin ]", - "[ (15/4 → 19/5) ⇝ 31/8 | s:basique bank:wt_digital note:F1 wtWarp:0.75 wtWarpMode:spin ]", - "[ 15/4 ⇜ (19/5 → 31/8) | s:basique bank:wt_digital note:F1 wtWarp:1 wtWarpMode:spin ]", - "[ 31/8 → 4/1 | s:basique bank:wt_digital note:F1 wtWarp:1 wtWarpMode:spin ]", -] -`; - -exports[`runs examples > example "wtWarpMode" example index 0 1`] = ` -[ - "[ 0/1 → 1/8 | s:morgana bank:wt_digital note:F1 wtWarp:0 wtWarpMode:asym ]", - "[ (1/8 → 1/5) ⇝ 1/4 | s:morgana bank:wt_digital note:F1 wtWarp:0 wtWarpMode:asym ]", - "[ 1/8 ⇜ (1/5 → 1/4) | s:morgana bank:wt_digital note:F1 wtWarp:0.25 wtWarpMode:asym ]", - "[ 1/4 → 3/8 | s:morgana bank:wt_digital note:F1 wtWarp:0.25 wtWarpMode:asym ]", - "[ (3/8 → 2/5) ⇝ 1/2 | s:morgana bank:wt_digital note:F1 wtWarp:0.25 wtWarpMode:asym ]", - "[ 3/8 ⇜ (2/5 → 1/2) | s:morgana bank:wt_digital note:F1 wtWarp:0.5 wtWarpMode:asym ]", - "[ (1/2 → 3/5) ⇝ 5/8 | s:morgana bank:wt_digital note:F1 wtWarp:0.5 wtWarpMode:bendp ]", - "[ 1/2 ⇜ (3/5 → 5/8) | s:morgana bank:wt_digital note:F1 wtWarp:0.75 wtWarpMode:bendp ]", - "[ 5/8 → 3/4 | s:morgana bank:wt_digital note:F1 wtWarp:0.75 wtWarpMode:bendp ]", - "[ (3/4 → 4/5) ⇝ 7/8 | s:morgana bank:wt_digital note:F1 wtWarp:0.75 wtWarpMode:bendp ]", - "[ 3/4 ⇜ (4/5 → 7/8) | s:morgana bank:wt_digital note:F1 wtWarp:1 wtWarpMode:bendp ]", - "[ 7/8 → 1/1 | s:morgana bank:wt_digital note:F1 wtWarp:1 wtWarpMode:bendp ]", - "[ 1/1 → 9/8 | s:morgana bank:wt_digital note:F1 wtWarp:0 wtWarpMode:spin ]", - "[ (9/8 → 6/5) ⇝ 5/4 | s:morgana bank:wt_digital note:F1 wtWarp:0 wtWarpMode:spin ]", - "[ 9/8 ⇜ (6/5 → 5/4) | s:morgana bank:wt_digital note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ 5/4 → 11/8 | s:morgana bank:wt_digital note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ (11/8 → 7/5) ⇝ 3/2 | s:morgana bank:wt_digital note:F1 wtWarp:0.25 wtWarpMode:spin ]", - "[ 11/8 ⇜ (7/5 → 3/2) | s:morgana bank:wt_digital note:F1 wtWarp:0.5 wtWarpMode:spin ]", - "[ (3/2 → 8/5) ⇝ 13/8 | s:morgana bank:wt_digital note:F1 wtWarp:0.5 wtWarpMode:logistic ]", - "[ 3/2 ⇜ (8/5 → 13/8) | s:morgana bank:wt_digital note:F1 wtWarp:0.75 wtWarpMode:logistic ]", - "[ 13/8 → 7/4 | s:morgana bank:wt_digital note:F1 wtWarp:0.75 wtWarpMode:logistic ]", - "[ (7/4 → 9/5) ⇝ 15/8 | s:morgana bank:wt_digital note:F1 wtWarp:0.75 wtWarpMode:logistic ]", - "[ 7/4 ⇜ (9/5 → 15/8) | s:morgana bank:wt_digital note:F1 wtWarp:1 wtWarpMode:logistic ]", - "[ 15/8 → 2/1 | s:morgana bank:wt_digital note:F1 wtWarp:1 wtWarpMode:logistic ]", - "[ 2/1 → 17/8 | s:morgana bank:wt_digital note:F1 wtWarp:0 wtWarpMode:sync ]", - "[ (17/8 → 11/5) ⇝ 9/4 | s:morgana bank:wt_digital note:F1 wtWarp:0 wtWarpMode:sync ]", - "[ 17/8 ⇜ (11/5 → 9/4) | s:morgana bank:wt_digital note:F1 wtWarp:0.25 wtWarpMode:sync ]", - "[ 9/4 → 19/8 | s:morgana bank:wt_digital note:F1 wtWarp:0.25 wtWarpMode:sync ]", - "[ (19/8 → 12/5) ⇝ 5/2 | s:morgana bank:wt_digital note:F1 wtWarp:0.25 wtWarpMode:sync ]", - "[ 19/8 ⇜ (12/5 → 5/2) | s:morgana bank:wt_digital note:F1 wtWarp:0.5 wtWarpMode:sync ]", - "[ (5/2 → 13/5) ⇝ 21/8 | s:morgana bank:wt_digital note:F1 wtWarp:0.5 wtWarpMode:wormhole ]", - "[ 5/2 ⇜ (13/5 → 21/8) | s:morgana bank:wt_digital note:F1 wtWarp:0.75 wtWarpMode:wormhole ]", - "[ 21/8 → 11/4 | s:morgana bank:wt_digital note:F1 wtWarp:0.75 wtWarpMode:wormhole ]", - "[ (11/4 → 14/5) ⇝ 23/8 | s:morgana bank:wt_digital note:F1 wtWarp:0.75 wtWarpMode:wormhole ]", - "[ 11/4 ⇜ (14/5 → 23/8) | s:morgana bank:wt_digital note:F1 wtWarp:1 wtWarpMode:wormhole ]", - "[ 23/8 → 3/1 | s:morgana bank:wt_digital note:F1 wtWarp:1 wtWarpMode:wormhole ]", - "[ 3/1 → 25/8 | s:morgana bank:wt_digital note:F1 wtWarp:0 wtWarpMode:brownian ]", - "[ (25/8 → 16/5) ⇝ 13/4 | s:morgana bank:wt_digital note:F1 wtWarp:0 wtWarpMode:brownian ]", - "[ 25/8 ⇜ (16/5 → 13/4) | s:morgana bank:wt_digital note:F1 wtWarp:0.25 wtWarpMode:brownian ]", - "[ 13/4 → 27/8 | s:morgana bank:wt_digital note:F1 wtWarp:0.25 wtWarpMode:brownian ]", - "[ (27/8 → 17/5) ⇝ 7/2 | s:morgana bank:wt_digital note:F1 wtWarp:0.25 wtWarpMode:brownian ]", - "[ 27/8 ⇜ (17/5 → 7/2) | s:morgana bank:wt_digital note:F1 wtWarp:0.5 wtWarpMode:brownian ]", - "[ (7/2 → 18/5) ⇝ 29/8 | s:morgana bank:wt_digital note:F1 wtWarp:0.5 wtWarpMode:asym ]", - "[ 7/2 ⇜ (18/5 → 29/8) | s:morgana bank:wt_digital note:F1 wtWarp:0.75 wtWarpMode:asym ]", - "[ 29/8 → 15/4 | s:morgana bank:wt_digital note:F1 wtWarp:0.75 wtWarpMode:asym ]", - "[ (15/4 → 19/5) ⇝ 31/8 | s:morgana bank:wt_digital note:F1 wtWarp:0.75 wtWarpMode:asym ]", - "[ 15/4 ⇜ (19/5 → 31/8) | s:morgana bank:wt_digital note:F1 wtWarp:1 wtWarpMode:asym ]", - "[ 31/8 → 4/1 | s:morgana bank:wt_digital note:F1 wtWarp:1 wtWarpMode:asym ]", + "[ 0/1 → 1/16 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 1/16 → 1/8 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 1/8 → 3/16 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 3/16 → 1/4 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 1/4 → 5/16 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 5/16 → 3/8 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 3/8 → 7/16 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 7/16 → 1/2 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 1/2 → 9/16 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 9/16 → 5/8 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 5/8 → 11/16 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 11/16 → 3/4 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 3/4 → 13/16 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 13/16 → 7/8 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 7/8 → 15/16 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 15/16 → 1/1 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 1/1 → 17/16 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 17/16 → 9/8 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 9/8 → 19/16 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 19/16 → 5/4 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 5/4 → 21/16 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 21/16 → 11/8 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 11/8 → 23/16 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 23/16 → 3/2 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 3/2 → 25/16 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 25/16 → 13/8 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 13/8 → 27/16 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 27/16 → 7/4 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 7/4 → 29/16 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 29/16 → 15/8 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 15/8 → 31/16 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 31/16 → 2/1 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 2/1 → 33/16 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 33/16 → 17/8 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 17/8 → 35/16 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 35/16 → 9/4 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 9/4 → 37/16 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 37/16 → 19/8 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 19/8 → 39/16 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 39/16 → 5/2 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 5/2 → 41/16 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 41/16 → 21/8 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 21/8 → 43/16 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 43/16 → 11/4 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 11/4 → 45/16 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 45/16 → 23/8 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 23/8 → 47/16 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 47/16 → 3/1 | s:basique bank:wt_digital wtphaserand:0 ]", + "[ 3/1 → 49/16 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 49/16 → 25/8 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 25/8 → 51/16 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 51/16 → 13/4 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 13/4 → 53/16 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 53/16 → 27/8 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 27/8 → 55/16 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 55/16 → 7/2 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 7/2 → 57/16 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 57/16 → 29/8 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 29/8 → 59/16 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 59/16 → 15/4 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 15/4 → 61/16 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 61/16 → 31/8 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 31/8 → 63/16 | s:basique bank:wt_digital wtphaserand:1 ]", + "[ 63/16 → 4/1 | s:basique bank:wt_digital wtphaserand:1 ]", ] `; From bf3fe605d9a71543e9922f7983f03e2f89129be9 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sun, 28 Sep 2025 15:21:06 -0400 Subject: [PATCH 228/335] fix unison gain --- packages/superdough/worklets.mjs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index cea5a1ea5..7f5cbcf23 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -1054,7 +1054,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { { name: 'warp', defaultValue: 0, minValue: 0, maxValue: 1 }, { name: 'warpMode', defaultValue: 0 }, { name: 'voices', defaultValue: 1, minValue: 1, maxValue: 32 }, - { name: 'spread', defaultValue: 0.4, minValue: 0, maxValue: 1 }, + { name: 'spread', defaultValue: 0.7, minValue: 0, maxValue: 1 }, { name: 'phaserand', defaultValue: 0, minValue: 0, maxValue: 1 }, ]; } @@ -1239,7 +1239,6 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { } const outL = outputs[0][0]; const outR = outputs[0][1] || outputs[0][0]; - const gainAdjustment = 0.3; if (!this.tables) { outL.fill(0); @@ -1256,13 +1255,13 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { const warpAmount = pv(parameters.warp, i); const warpMode = pv(parameters.warpMode, i); const voices = pv(parameters.voices, i); - const spread = voices > 1 ? pv(parameters.spread, i) : 0; const phaseRand = pv(parameters.phaserand, i); + const spread = voices > 1 ? pv(parameters.spread, i) : 0; const gain1 = Math.sqrt(0.5 - 0.5 * spread); const gain2 = Math.sqrt(0.5 + 0.5 * spread); let f = pv(parameters.frequency, i); f = applySemitoneDetuneToFrequency(f, detune / 100); // overall detune - const normalizer = 0.3 / voices; + const normalizer = 0.3 / Math.sqrt(voices); for (let n = 0; n < voices; n++) { const isOdd = (n & 1) == 1; let gainL = gain1; From d94f145649b3bf3ea77d49fe26246fc075b353e0 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sun, 28 Sep 2025 15:23:58 -0400 Subject: [PATCH 229/335] fix vib --- packages/superdough/wavetable.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index 4a21cabe4..48b7e661c 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -319,7 +319,7 @@ export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) { dcoffset: value.warpdc ?? 0, }, ); - const vibratoOscillator = getVibratoOscillator(source.detune, value, t); + const vibratoOscillator = getVibratoOscillator(source.parameters.get('detune'), value, t); const envGain = ac.createGain(); const node = source.connect(envGain); getParamADSR(node.gain, attack, decay, sustain, release, 0, 1, t, holdEnd, 'linear'); From 8d45016ccf4ca0d63e5d903a63c21e54f85e8785 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sun, 28 Sep 2025 19:11:13 -0400 Subject: [PATCH 230/335] working --- website/public/uzu-wavetables.json | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/website/public/uzu-wavetables.json b/website/public/uzu-wavetables.json index d9e0eeb90..b2d662d5d 100644 --- a/website/public/uzu-wavetables.json +++ b/website/public/uzu-wavetables.json @@ -5,35 +5,11 @@ "wt_digital/wt_basique.wav", "wt_digital/wt_crickets.wav", "wt_digital/wt_curses.wav", - "wt_digital/wt_earl_grey.wav", - "wt_digital/wt_echoes.wav", - "wt_digital/wt_glimmer.wav", - "wt_digital/wt_majick.wav", - "wt_digital/wt_meditation.wav", - "wt_digital/wt_morgana.wav", - "wt_digital/wt_red_alert.wav", - "wt_digital/wt_sad_piano.wav", - "wt_digital/wt_shook.wav", - "wt_digital/wt_sludge.wav", - "wt_digital/wt_squelch.wav", - "wt_digital/wt_summer.wav", - "wt_digital/wt_wasp.wav" + "wt_digital/wt_echoes.wav" ], "wt_digital_bad_day": ["wt_digital/wt_bad_day.wav"], "wt_digital_basique": ["wt_digital/wt_basique.wav"], "wt_digital_crickets": ["wt_digital/wt_crickets.wav"], "wt_digital_curses": ["wt_digital/wt_curses.wav"], - "wt_digital_earl_grey": ["wt_digital/wt_earl_grey.wav"], - "wt_digital_echoes": ["wt_digital/wt_echoes.wav"], - "wt_digital_glimmer": ["wt_digital/wt_glimmer.wav"], - "wt_digital_majick": ["wt_digital/wt_majick.wav"], - "wt_digital_meditation": ["wt_digital/wt_meditation.wav"], - "wt_digital_morgana": ["wt_digital/wt_morgana.wav"], - "wt_digital_red_alert": ["wt_digital/wt_red_alert.wav"], - "wt_digital_sad_piano": ["wt_digital/wt_sad_piano.wav"], - "wt_digital_shook": ["wt_digital/wt_shook.wav"], - "wt_digital_sludge": ["wt_digital/wt_sludge.wav"], - "wt_digital_squelch": ["wt_digital/wt_squelch.wav"], - "wt_digital_summer": ["wt_digital/wt_summer.wav"], - "wt_digital_wasp": ["wt_digital/wt_wasp.wav"] + "wt_digital_echoes": ["wt_digital/wt_echoes.wav"] } \ No newline at end of file From 48718daea8c6e60a5430a639a09159b795cf2e9b Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sun, 28 Sep 2025 19:57:19 -0400 Subject: [PATCH 231/335] add_vgame --- website/public/uzu-wavetables.json | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/website/public/uzu-wavetables.json b/website/public/uzu-wavetables.json index b2d662d5d..375b1fad3 100644 --- a/website/public/uzu-wavetables.json +++ b/website/public/uzu-wavetables.json @@ -11,5 +11,18 @@ "wt_digital_basique": ["wt_digital/wt_basique.wav"], "wt_digital_crickets": ["wt_digital/wt_crickets.wav"], "wt_digital_curses": ["wt_digital/wt_curses.wav"], - "wt_digital_echoes": ["wt_digital/wt_echoes.wav"] + "wt_digital_echoes": ["wt_digital/wt_echoes.wav"], + "wt_vgame": [ + "wt_vgame/wt_vgame10.wav", + "wt_vgame/wt_vgame11.wav", + "wt_vgame/wt_vgame12.wav", + "wt_vgame/wt_vgame13.wav", + "wt_vgame/wt_vgame14.wav", + "wt_vgame/wt_vgame15.wav", + "wt_vgame/wt_vgame16.wav", + "wt_vgame/wt_vgame17.wav", + "wt_vgame/wt_vgame18.wav", + "wt_vgame/wt_vgame19.wav", + "wt_vgame/wt_vgame20.wav" + ] } \ No newline at end of file From 4de0c11f8c0834868ae346125d35e77134bf4d7d Mon Sep 17 00:00:00 2001 From: Aria Date: Mon, 29 Sep 2025 14:15:50 -0700 Subject: [PATCH 232/335] Remove mipmaps, fix clamping of parameters --- packages/superdough/wavetable.mjs | 32 +++++--------------- packages/superdough/worklets.mjs | 49 +++++++++++++------------------ 2 files changed, 27 insertions(+), 54 deletions(-) diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index 48b7e661c..505e6ac38 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -5,7 +5,6 @@ import { destroyAudioWorkletNode, getADSRValues, getFrequencyFromValue, - getLfo, getParamADSR, getPitchEnvelope, getVibratoOscillator, @@ -14,7 +13,6 @@ import { } from './helpers.mjs'; import { logger } from './logger.mjs'; -const WT_MAX_MIP_LEVELS = 6; export const Warpmode = Object.freeze({ NONE: 0, ASYM: 1, @@ -50,25 +48,7 @@ async function loadWavetableFrames(url, label, frameLen = 2048) { const start = i * frameLen; frames[i] = ch0.subarray(start, start + frameLen); } - - // build mipmaps - const mipmaps = [frames]; - let levelFrames = frames; - for (let level = 1; level < WT_MAX_MIP_LEVELS; level++) { - const prevLen = levelFrames[0].length; - if (prevLen <= 32) break; - const nextLen = prevLen >> 1; - const next = levelFrames.map((src) => { - const out = new Float32Array(nextLen); - for (let j = 0; j < nextLen; j++) { - out[j] = (src[2 * j] + src[2 * j + 1]) / 2; - } - return out; - }); - mipmaps.push(next); - levelFrames = next; - } - return { frames, mipmaps, frameLen, numFrames }; + return { frames, frameLen, numFrames }; } const loadCache = {}; @@ -222,7 +202,7 @@ export const tables = async (url, frameLen, json, options = {}) => { }; export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) { - const { s, n = 0, duration } = value; + const { s, n = 0, duration, clip } = value; const ac = getAudioContext(); const [attack, decay, sustain, release] = getADSRValues([value.attack, value.decay, value.sustain, value.release]); let { warpmode } = value; @@ -232,7 +212,10 @@ export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) { const frequency = getFrequencyFromValue(value); const { url, label } = getCommonSampleInfo(value, tables); const payload = await loadWavetableFrames(url, label, frameLen); - const holdEnd = t + duration; + let holdEnd = t + duration; + if (clip !== undefined) { + holdEnd = Math.min(t + clip * duration, holdEnd); + } const endWithRelease = holdEnd + release; const envEnd = endWithRelease + 0.01; const source = getWorklet( @@ -252,7 +235,7 @@ export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) { }, { outputChannelCount: [2] }, ); - source.port.postMessage({ type: 'tables', payload }); + source.port.postMessage({ type: 'table', payload }); if (ac.currentTime > t) { logger(`[wavetable] still loading sound "${s}:${n}"`, 'highlight'); return; @@ -328,7 +311,6 @@ export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) { const timeoutNode = webAudioTimeout( ac, () => { - source.disconnect(); destroyAudioWorkletNode(source); vibratoOscillator?.stop(); node.disconnect(); diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 7f5cbcf23..814c97f41 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -137,7 +137,7 @@ class LFOProcessor extends AudioWorkletProcessor { } } - process(inputs, outputs, parameters) { + process(_inputs, outputs, parameters) { const begin = parameters['begin'][0]; if (currentTime >= parameters.end[0]) { return false; @@ -510,7 +510,7 @@ class SuperSawOscillatorProcessor extends AudioWorkletProcessor { }, ]; } - process(input, outputs, params) { + process(_input, outputs, params) { if (currentTime <= params.begin[0]) { return true; } @@ -1061,7 +1061,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { constructor(options) { super(options); - this.tables = null; + this.frames = null; this.frameLen = 0; this.numFrames = 0; this.phase = []; @@ -1069,23 +1069,14 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { this.port.onmessage = (e) => { const { type, payload } = e.data || {}; - if (type === 'tables') { - this.tables = payload.mipmaps; + if (type === 'table') { + this.frames = payload.frames; this.frameLen = payload.frameLen; - this.numFrames = this.tables[0].length; + this.numFrames = this.frames.length; } }; } - _chooseMip(dphi) { - const approxHarm = Math.min(64, 1 / Math.max(1e-6, dphi)); - let level = 0; - while (level + 1 < (this.tables?.length || 1) && approxHarm < this.tables[level][0].length / 8) { - level++; - } - return level; - } - _mirror(x) { return 1 - Math.abs(2 * x - 1); } @@ -1222,11 +1213,13 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { } _sampleFrame(frame, phase) { - const pos = phase * frame.length; + const len = frame.length; + const pos = phase * len; const i = pos | 0; const frac = pos - i; - const a = frame[i % frame.length]; - const b = frame[(i + 1) % frame.length]; + const a = frame[i]; + const i1 = i + 1 < len ? i + 1 : 0; // fast wrap + const b = frame[i1]; return a + (b - a) * frac; } @@ -1240,23 +1233,23 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { const outL = outputs[0][0]; const outR = outputs[0][1] || outputs[0][0]; - if (!this.tables) { + if (!this.frames) { outL.fill(0); if (outR !== outL) outR.set(outL); return true; } - + const invSR = 1 / sampleRate; for (let i = 0; i < outL.length; i++) { const detune = pv(parameters.detune, i); - const tablePos = pv(parameters.position, i); + const tablePos = clamp(pv(parameters.position, i), 0, 1); const idx = tablePos * (this.numFrames - 1); const fIdx = idx | 0; const frac = idx - fIdx; - const warpAmount = pv(parameters.warp, i); + const warpAmount = clamp(pv(parameters.warp, i), 0, 1); const warpMode = pv(parameters.warpMode, i); const voices = pv(parameters.voices, i); - const phaseRand = pv(parameters.phaserand, i); - const spread = voices > 1 ? pv(parameters.spread, i) : 0; + const phaseRand = clamp(pv(parameters.phaserand, i), 0, 1); + const spread = voices > 1 ? clamp(pv(parameters.spread, i), 0, 1) : 0; const gain1 = Math.sqrt(0.5 - 0.5 * spread); const gain2 = Math.sqrt(0.5 + 0.5 * spread); let f = pv(parameters.frequency, i); @@ -1272,15 +1265,13 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { gainR = gain1; } const fVoice = applySemitoneDetuneToFrequency(f, getUnisonDetune(voices, detune, n)); // voice detune - const dPhase = fVoice / sampleRate; - const level = this._chooseMip(dPhase); - const table = this.tables[level]; + const dPhase = fVoice * invSR; // warp phase then sample this.phase[n] = this.phase[n] ?? Math.random() * phaseRand; const ph = this._warpPhase(this.phase[n], warpAmount, warpMode); - const s0 = this._sampleFrame(table[fIdx], ph); - const s1 = this._sampleFrame(table[Math.min(this.numFrames - 1, fIdx + 1)], ph); + const s0 = this._sampleFrame(this.frames[fIdx], ph); + const s1 = this._sampleFrame(this.frames[Math.min(this.numFrames - 1, fIdx + 1)], ph); let s = s0 + (s1 - s0) * frac; if (warpMode === WarpMode.FLIP && this.phase[n] < warpAmount) { s = -s; From bad498a1e512061c663bd42408968e9d5d348a0d Mon Sep 17 00:00:00 2001 From: Aria Date: Tue, 30 Sep 2025 16:21:28 -0700 Subject: [PATCH 233/335] Remove unused var --- packages/superdough/worklets.mjs | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 814c97f41..aa49ea32a 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -1065,7 +1065,6 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { this.frameLen = 0; this.numFrames = 0; this.phase = []; - this.syncRatio = 1; this.port.onmessage = (e) => { const { type, payload } = e.data || {}; From cdc5e5f3f33d0fcf06d346120124d76c575dd22a Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Tue, 30 Sep 2025 19:45:30 -0400 Subject: [PATCH 234/335] working --- packages/superdough/superdoughoutput.mjs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/superdough/superdoughoutput.mjs b/packages/superdough/superdoughoutput.mjs index 9ef7bcbf3..221f80a26 100644 --- a/packages/superdough/superdoughoutput.mjs +++ b/packages/superdough/superdoughoutput.mjs @@ -135,12 +135,14 @@ export class SuperdoughOutput { } reset() { + this.disconnect() + this.initializeAudio(); + } + disconnect() { this.channelMerger.disconnect(); this.destinationGain.disconnect(); this.destinationGain = null; this.channelMerger = null; - this.nodes = {}; - this.initializeAudio(); } connectToDestination = (input, channels = [0, 1]) => { //This upmix can be removed if correct channel counts are set throughout the app, @@ -172,6 +174,7 @@ export class SuperdoughAudioController { Array.from(this.nodes).forEach((node) => { node.disconnect(); }); + this.nodes = {} this.output.reset(); } From 9f8143e062239658426c483f7ee9433ed839e3cd Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Tue, 30 Sep 2025 19:46:53 -0400 Subject: [PATCH 235/335] format --- packages/superdough/superdoughoutput.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/superdough/superdoughoutput.mjs b/packages/superdough/superdoughoutput.mjs index 221f80a26..afe91e71e 100644 --- a/packages/superdough/superdoughoutput.mjs +++ b/packages/superdough/superdoughoutput.mjs @@ -135,7 +135,7 @@ export class SuperdoughOutput { } reset() { - this.disconnect() + this.disconnect(); this.initializeAudio(); } disconnect() { @@ -174,7 +174,7 @@ export class SuperdoughAudioController { Array.from(this.nodes).forEach((node) => { node.disconnect(); }); - this.nodes = {} + this.nodes = {}; this.output.reset(); } From a2b8407fbb86477ae4e684481c1cb4915f64307b Mon Sep 17 00:00:00 2001 From: Aria Date: Tue, 30 Sep 2025 23:08:28 -0500 Subject: [PATCH 236/335] Add back mipmaps; add caching --- packages/superdough/wavetable.mjs | 33 +++++++++++++---------- packages/superdough/worklets.mjs | 45 +++++++++++++++++++++++++------ 2 files changed, 56 insertions(+), 22 deletions(-) diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index 505e6ac38..44367f786 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -38,21 +38,25 @@ export const Warpmode = Object.freeze({ FLIP: 21, }); -async function loadWavetableFrames(url, label, frameLen = 2048) { - const buf = await loadBuffer(url, label); - const ch0 = buf.getChannelData(0); - const total = ch0.length; - const numFrames = Math.max(1, Math.floor(total / frameLen)); - const frames = new Array(numFrames); - for (let i = 0; i < numFrames; i++) { - const start = i * frameLen; - frames[i] = ch0.subarray(start, start + frameLen); +const seenKeys = new Set(); +async function getPayload(url, label, frameLen = 2048) { + const key = `${url},${frameLen}`; + if (!seenKeys.has(key)) { + const buf = await loadBuffer(url, label); + const ch0 = buf.getChannelData(0); + const total = ch0.length; + const numFrames = Math.max(1, Math.floor(total / frameLen)); + const frames = new Array(numFrames); + for (let i = 0; i < numFrames; i++) { + const start = i * frameLen; + frames[i] = ch0.subarray(start, start + frameLen); + } + seenKeys.add(key); + return { frames, frameLen, numFrames, key }; } - return { frames, frameLen, numFrames }; + return { frameLen, key }; // worklet will use the cached version } -const loadCache = {}; - function humanFileSize(bytes, si) { var thresh = si ? 1000 : 1024; if (bytes < thresh) return bytes + ' B'; @@ -97,6 +101,7 @@ async function decodeAtNativeRate(arr) { return await tempAC.decodeAudioData(arr); } +const loadCache = {}; const loadBuffer = (url, label) => { url = url.replace('#', '%23'); if (!loadCache[url]) { @@ -211,7 +216,7 @@ export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) { } const frequency = getFrequencyFromValue(value); const { url, label } = getCommonSampleInfo(value, tables); - const payload = await loadWavetableFrames(url, label, frameLen); + const payload = await getPayload(url, label, frameLen); let holdEnd = t + duration; if (clip !== undefined) { holdEnd = Math.min(t + clip * duration, holdEnd); @@ -305,7 +310,7 @@ export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) { const vibratoOscillator = getVibratoOscillator(source.parameters.get('detune'), value, t); const envGain = ac.createGain(); const node = source.connect(envGain); - getParamADSR(node.gain, attack, decay, sustain, release, 0, 1, t, holdEnd, 'linear'); + getParamADSR(node.gain, attack, decay, sustain, release, 0, 0.3, t, holdEnd, 'linear'); getPitchEnvelope(source.parameters.get('detune'), value, t, holdEnd); const handle = { node, source }; const timeoutNode = webAudioTimeout( diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index aa49ea32a..9b190a456 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -1043,6 +1043,7 @@ function brownian(x, oct = 4) { return (sum / norm) * 2 - 1; } +const tablesCache = {}; class WavetableOscillatorProcessor extends AudioWorkletProcessor { static get parameterDescriptors() { return [ @@ -1061,7 +1062,6 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { constructor(options) { super(options); - this.frames = null; this.frameLen = 0; this.numFrames = 0; this.phase = []; @@ -1069,9 +1069,28 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { this.port.onmessage = (e) => { const { type, payload } = e.data || {}; if (type === 'table') { - this.frames = payload.frames; + const key = payload.key; this.frameLen = payload.frameLen; - this.numFrames = this.frames.length; + if (!tablesCache[key]) { + const tables = [payload.frames]; + let table = tables[0]; + for (let level = 1; level < 1; level++) { + const nextLen = table.length >> 1; + const nextTable = table.map((frame) => { + const avg = new Float32Array(nextLen); + for (let i = 0; i < nextLen; i++) { + avg[i] = (frame[2 * i] + frame[2 * i + 1]) / 2; + } + return avg; + }); + tables.push(nextTable); + table = nextTable; + if (nextLen <= 32) break; + } + tablesCache[key] = tables; + } + this.tables = tablesCache[key]; + this.numFrames = this.tables[0].length; } }; } @@ -1222,6 +1241,15 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { return a + (b - a) * frac; } + _chooseMip(dphi) { + const approxHarm = clamp(dphi, 1e-6, 64); + let level = 0; + while (level + 1 < (this.tables?.length || 1) && approxHarm < this.tables[level][0].length / 8) { + level++; + } + return level; + } + process(_inputs, outputs, parameters) { if (currentTime >= parameters.end[0]) { return false; @@ -1231,8 +1259,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { } const outL = outputs[0][0]; const outR = outputs[0][1] || outputs[0][0]; - - if (!this.frames) { + if (!this.tables) { outL.fill(0); if (outR !== outL) outR.set(outL); return true; @@ -1253,7 +1280,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { const gain2 = Math.sqrt(0.5 + 0.5 * spread); let f = pv(parameters.frequency, i); f = applySemitoneDetuneToFrequency(f, detune / 100); // overall detune - const normalizer = 0.3 / Math.sqrt(voices); + const normalizer = 1 / Math.sqrt(voices); for (let n = 0; n < voices; n++) { const isOdd = (n & 1) == 1; let gainL = gain1; @@ -1265,12 +1292,14 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { } const fVoice = applySemitoneDetuneToFrequency(f, getUnisonDetune(voices, detune, n)); // voice detune const dPhase = fVoice * invSR; + const level = this._chooseMip(dPhase); + const table = this.tables[level]; // warp phase then sample this.phase[n] = this.phase[n] ?? Math.random() * phaseRand; const ph = this._warpPhase(this.phase[n], warpAmount, warpMode); - const s0 = this._sampleFrame(this.frames[fIdx], ph); - const s1 = this._sampleFrame(this.frames[Math.min(this.numFrames - 1, fIdx + 1)], ph); + const s0 = this._sampleFrame(table[fIdx], ph); + const s1 = this._sampleFrame(table[Math.min(this.numFrames - 1, fIdx + 1)], ph); let s = s0 + (s1 - s0) * frac; if (warpMode === WarpMode.FLIP && this.phase[n] < warpAmount) { s = -s; From 3a7ec18d46f5e051796d9b0e92155e40665ba981 Mon Sep 17 00:00:00 2001 From: Aria Date: Tue, 30 Sep 2025 23:19:55 -0500 Subject: [PATCH 237/335] Move invsr to constructor --- packages/superdough/worklets.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 9b190a456..ccfaf5107 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -1065,6 +1065,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { this.frameLen = 0; this.numFrames = 0; this.phase = []; + this.invSR = 1 / sampleRate; this.port.onmessage = (e) => { const { type, payload } = e.data || {}; @@ -1264,7 +1265,6 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { if (outR !== outL) outR.set(outL); return true; } - const invSR = 1 / sampleRate; for (let i = 0; i < outL.length; i++) { const detune = pv(parameters.detune, i); const tablePos = clamp(pv(parameters.position, i), 0, 1); @@ -1291,7 +1291,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { gainR = gain1; } const fVoice = applySemitoneDetuneToFrequency(f, getUnisonDetune(voices, detune, n)); // voice detune - const dPhase = fVoice * invSR; + const dPhase = fVoice * this.invSR; const level = this._chooseMip(dPhase); const table = this.tables[level]; From c5f1085bd9e8a0a061247eb2e165fde574809ea7 Mon Sep 17 00:00:00 2001 From: Aria Date: Tue, 30 Sep 2025 23:51:59 -0500 Subject: [PATCH 238/335] WIP --- packages/core/pattern.mjs | 18 ++++++++++++++++++ packages/superdough/helpers.mjs | 1 + packages/superdough/sampler.mjs | 4 ++-- packages/superdough/wavetable.mjs | 1 - 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index d0be3f599..dcee7f174 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -3536,3 +3536,21 @@ export const morph = (frompat, topat, bypat) => { bypat = reify(bypat); return frompat.innerBind((from) => topat.innerBind((to) => bypat.innerBind((by) => _morph(from, to, by)))); }; + +/** + * Wavefolding distortion + * + * @name fold + * @param {number | Pattern} distortion + * + */ +export const fold = register('fold', function (amt, vol = 1, pat) { + return pat.withvValue((v) => { + return { + ...v, + distortion: amt, + distortvol: vol, + distorttype: 'fold', + }; + }).innerJoin(); +}); diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index a471da9dd..6db3b04ab 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -475,6 +475,7 @@ export const getDistortionAlgorithm = (algo) => { }; export const getDistortion = (distort, postgain, algorithm) => { + debugger; return getWorklet(getAudioContext(), 'distort-processor', { distort, postgain }, { processorOptions: { algorithm } }); }; diff --git a/packages/superdough/sampler.mjs b/packages/superdough/sampler.mjs index 325b2e2a6..f229cd338 100644 --- a/packages/superdough/sampler.mjs +++ b/packages/superdough/sampler.mjs @@ -1,5 +1,5 @@ -import { noteToMidi, valueToMidi, getSoundIndex, getCommonSampleInfo } from './util.mjs'; -import { registerSound, registerWavetable } from './index.mjs'; +import { getCommonSampleInfo } from './util.mjs'; +import { registerSound, registerWaveTable } from './index.mjs'; import { getAudioContext } from './audioContext.mjs'; import { getADSRValues, getParamADSR, getPitchEnvelope, getVibratoOscillator } from './helpers.mjs'; import { logger } from './logger.mjs'; diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index 48b7e661c..c340efa8c 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -5,7 +5,6 @@ import { destroyAudioWorkletNode, getADSRValues, getFrequencyFromValue, - getLfo, getParamADSR, getPitchEnvelope, getVibratoOscillator, From a14bf4d97bc26a70a637464a0543d6861c5d9b69 Mon Sep 17 00:00:00 2001 From: Aria Date: Wed, 1 Oct 2025 00:36:59 -0500 Subject: [PATCH 239/335] Add aliases for distort types --- packages/core/pattern.mjs | 67 +++++++++++++++++++++++++----- packages/superdough/helpers.mjs | 1 - packages/superdough/superdough.mjs | 3 +- 3 files changed, 59 insertions(+), 12 deletions(-) diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index dcee7f174..96f7d687e 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -3537,6 +3537,41 @@ export const morph = (frompat, topat, bypat) => { return frompat.innerBind((from) => topat.innerBind((to) => bypat.innerBind((by) => _morph(from, to, by)))); }; +/** + * Soft-clipping distortion + * + * @name soft + * @param {number | Pattern} distortion + * + */ +/** + * Hard-clipping distortion + * + * @name hard + * @param {number | Pattern} distortion + * + */ +/** + * Cubic polynomial distortion + * + * @name cubic + * @param {number | Pattern} distortion + * + */ +/** + * Diode-emulating distortion + * + * @name diode + * @param {number | Pattern} distortion + * + */ +/** + * Asymmetrical diode distortion + * + * @name asym + * @param {number | Pattern} distortion + * + */ /** * Wavefolding distortion * @@ -3544,13 +3579,25 @@ export const morph = (frompat, topat, bypat) => { * @param {number | Pattern} distortion * */ -export const fold = register('fold', function (amt, vol = 1, pat) { - return pat.withvValue((v) => { - return { - ...v, - distortion: amt, - distortvol: vol, - distorttype: 'fold', - }; - }).innerJoin(); -}); +/** + * Wavefolding distortion composed with sinusoid + * + * @name sinefold + * @param {number | Pattern} distortion + * + */ +/** + * Distortion via Chebyshev polynomials + * + * @name chebyshev + * @param {number | Pattern} distortion + * + */ + +const algoNames = ['scurve', 'soft', 'hard', 'cubic', 'diode', 'asym', 'fold', 'sinefold', 'chebyshev']; +for (const name of algoNames) { + Pattern.prototype[name] = function (args) { + const argsPat = reify(args).fmap((v) => (Array.isArray(v) ? [...v, name] : [v, 1, name])); + return this.distort(argsPat); + }; +} diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index 6db3b04ab..a471da9dd 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -475,7 +475,6 @@ export const getDistortionAlgorithm = (algo) => { }; export const getDistortion = (distort, postgain, algorithm) => { - debugger; return getWorklet(getAudioContext(), 'distort-processor', { distort, postgain }, { processorOptions: { algorithm } }); }; diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 8240b45b9..a37504b1d 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -155,6 +155,7 @@ let defaultDefaultValues = { phaserdepth: 0.75, shapevol: 1, distortvol: 1, + distorttype: 0, delay: 0, byteBeatExpression: '0', delayfeedback: 0.5, @@ -455,7 +456,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) shapevol = getDefaultValue('shapevol'), distort, distortvol = getDefaultValue('distortvol'), - distorttype, + distorttype = getDefaultValue('distorttype'), pan, vowel, delay = getDefaultValue('delay'), From c885d84785f73a4624d26bd75f608e58baa0206a Mon Sep 17 00:00:00 2001 From: Aria Date: Wed, 1 Oct 2025 00:39:44 -0500 Subject: [PATCH 240/335] Add comment --- packages/core/pattern.mjs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index 96f7d687e..e2e563e4f 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -3594,8 +3594,9 @@ export const morph = (frompat, topat, bypat) => { * */ -const algoNames = ['scurve', 'soft', 'hard', 'cubic', 'diode', 'asym', 'fold', 'sinefold', 'chebyshev']; -for (const name of algoNames) { +const distAlgoNames = ['scurve', 'soft', 'hard', 'cubic', 'diode', 'asym', 'fold', 'sinefold', 'chebyshev']; +for (const name of distAlgoNames) { + // Add aliases for distortion algorithms Pattern.prototype[name] = function (args) { const argsPat = reify(args).fmap((v) => (Array.isArray(v) ? [...v, name] : [v, 1, name])); return this.distort(argsPat); From 72298c5f037f43470d9be6929b1a099a2b3b4228 Mon Sep 17 00:00:00 2001 From: Aria Date: Wed, 1 Oct 2025 00:45:26 -0500 Subject: [PATCH 241/335] Docstring cleanup --- packages/core/controls.mjs | 8 +++++--- packages/core/pattern.mjs | 25 ++++++++++++++++--------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 5148e47e7..3475fc2f4 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -1892,7 +1892,9 @@ export const { shape } = registerControl(['shape', 'shapevol']); * * @name distort * @synonyms dist - * @param {number | Pattern} distortion + * @param {number | Pattern} distortion amount of distortion to apply + * @param {number | Pattern} volume linear postgain of the distortion + * @param {number | string | Pattern} type type of distortion to apply * @example * s("bd sd [~ bd] sd,hh*8").distort("<0 2 3 10:.5>") * @example @@ -1908,7 +1910,7 @@ export const { distort, dist } = registerControl(['distort', 'distortvol', 'dist * * @name distortvol * @synonyms distvol - * @param {number | Pattern} type + * @param {number | Pattern} volume linear postgain of the distortion * @example * s("bd*4").bank("tr909").distort(2).distortvol(0.8) */ @@ -1919,7 +1921,7 @@ export const { distortvol } = registerControl('distortvol', 'distvol'); * * @name distorttype * @synonyms disttype - * @param {number | string | Pattern} type + * @param {number | string | Pattern} type type of distortion to apply * @example * s("bd*4").bank("tr909").distort(2).distorttype("<0 1 2>") * diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index e2e563e4f..a823e7bca 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -3541,59 +3541,66 @@ export const morph = (frompat, topat, bypat) => { * Soft-clipping distortion * * @name soft - * @param {number | Pattern} distortion + * @param {number | Pattern} distortion amount of distortion to apply + * @param {number | Pattern} volume linear postgain of the distortion * */ /** * Hard-clipping distortion * * @name hard - * @param {number | Pattern} distortion + * @param {number | Pattern} distortion amount of distortion to apply + * @param {number | Pattern} volume linear postgain of the distortion * */ /** * Cubic polynomial distortion * * @name cubic - * @param {number | Pattern} distortion + * @param {number | Pattern} distortion amount of distortion to apply + * @param {number | Pattern} volume linear postgain of the distortion * */ /** * Diode-emulating distortion * * @name diode - * @param {number | Pattern} distortion + * @param {number | Pattern} distortion amount of distortion to apply + * @param {number | Pattern} volume linear postgain of the distortion * */ /** * Asymmetrical diode distortion * * @name asym - * @param {number | Pattern} distortion + * @param {number | Pattern} distortion amount of distortion to apply + * @param {number | Pattern} volume linear postgain of the distortion * */ /** * Wavefolding distortion * * @name fold - * @param {number | Pattern} distortion + * @param {number | Pattern} distortion amount of distortion to apply + * @param {number | Pattern} volume linear postgain of the distortion * */ /** * Wavefolding distortion composed with sinusoid * * @name sinefold - * @param {number | Pattern} distortion + * @param {number | Pattern} distortion amount of distortion to apply + * @param {number | Pattern} volume linear postgain of the distortion * */ /** * Distortion via Chebyshev polynomials * * @name chebyshev - * @param {number | Pattern} distortion + * @param {number | Pattern} distortion amount of distortion to apply + * @param {number | Pattern} volume linear postgain of the distortion * */ - const distAlgoNames = ['scurve', 'soft', 'hard', 'cubic', 'diode', 'asym', 'fold', 'sinefold', 'chebyshev']; for (const name of distAlgoNames) { // Add aliases for distortion algorithms From 8cd497abb245361b4ad2cf469e46b8b13d14247c Mon Sep 17 00:00:00 2001 From: yaxu Date: Wed, 1 Oct 2025 12:54:58 +0200 Subject: [PATCH 242/335] Update website/src/pages/technical-manual/project-start.mdx --- .../src/pages/technical-manual/project-start.mdx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/website/src/pages/technical-manual/project-start.mdx b/website/src/pages/technical-manual/project-start.mdx index 4e6e37636..0866d3e43 100644 --- a/website/src/pages/technical-manual/project-start.mdx +++ b/website/src/pages/technical-manual/project-start.mdx @@ -7,6 +7,21 @@ layout: ../../layouts/MainLayout.astro This Guide shows you the different ways to get started with using Strudel in your own project. +## Respect the license + +First, please take a moment to understand Strudel's free/open source license, +[AGPL-3.0](https://www.gnu.org/licenses/agpl-3.0.en.html). + +Here is a lay summary, but check the license for legal definitions and responsibilities. + +* You can distribute modified versions if you keep track of the changes and the date you made them. +* You must license derivative work under the same license. +* Source code must be distributed along with web publication. + +Among other things, it means that when you share your work, the whole application must be shared under the same free/open source license, or one compatible with it. This is because we want Strudel to stay free/open source. In other words, you are not permitted to distribute integrations of Strudel with libraries or other code that does not have a compatible free/open source license. + +This also applies to clones informed by reading Strudel's source code, as legally speaking, that counts as a 'derivative work'. Again, please [read the licence](https://www.gnu.org/licenses/agpl-3.0.en.html) for details. + ## Embedding the Strudel REPL There are 3 quick ways to embed strudel in your website: From 0ecacae71eddeb7f975b4614a58d3a59c0b67264 Mon Sep 17 00:00:00 2001 From: Alex McLean Date: Wed, 1 Oct 2025 12:02:09 +0100 Subject: [PATCH 243/335] format --- website/src/pages/technical-manual/project-start.mdx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/website/src/pages/technical-manual/project-start.mdx b/website/src/pages/technical-manual/project-start.mdx index 0866d3e43..4a269d1b9 100644 --- a/website/src/pages/technical-manual/project-start.mdx +++ b/website/src/pages/technical-manual/project-start.mdx @@ -9,16 +9,16 @@ This Guide shows you the different ways to get started with using Strudel in you ## Respect the license -First, please take a moment to understand Strudel's free/open source license, +First, please take a moment to understand Strudel's free/open source license, [AGPL-3.0](https://www.gnu.org/licenses/agpl-3.0.en.html). Here is a lay summary, but check the license for legal definitions and responsibilities. -* You can distribute modified versions if you keep track of the changes and the date you made them. -* You must license derivative work under the same license. -* Source code must be distributed along with web publication. +- You can distribute modified versions if you keep track of the changes and the date you made them. +- You must license derivative work under the same license. +- Source code must be distributed along with web publication. -Among other things, it means that when you share your work, the whole application must be shared under the same free/open source license, or one compatible with it. This is because we want Strudel to stay free/open source. In other words, you are not permitted to distribute integrations of Strudel with libraries or other code that does not have a compatible free/open source license. +Among other things, it means that when you share your work, the whole application must be shared under the same free/open source license, or one compatible with it. This is because we want Strudel to stay free/open source. In other words, you are not permitted to distribute integrations of Strudel with libraries or other code that does not have a compatible free/open source license. This also applies to clones informed by reading Strudel's source code, as legally speaking, that counts as a 'derivative work'. Again, please [read the licence](https://www.gnu.org/licenses/agpl-3.0.en.html) for details. From b7d98dd3709b3837fba16a517aac565c7e732ea7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Volhejn?= Date: Wed, 1 Oct 2025 21:53:28 +0200 Subject: [PATCH 244/335] Fix case sensitivity for synonym search --- website/src/repl/components/panel/Reference.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/src/repl/components/panel/Reference.jsx b/website/src/repl/components/panel/Reference.jsx index 6007667fa..505cf50d2 100644 --- a/website/src/repl/components/panel/Reference.jsx +++ b/website/src/repl/components/panel/Reference.jsx @@ -44,10 +44,10 @@ export function Reference() { return true; } - const lowCaseSearch = search.toLowerCase(); + const lowerCaseSearch = search.toLowerCase(); return ( - entry.name.toLowerCase().includes(lowCaseSearch) || - (entry.synonyms?.some((s) => s.includes(lowCaseSearch)) ?? false) + entry.name.toLowerCase().includes(lowerCaseSearch) || + (entry.synonyms?.some((s) => s.toLowerCase().includes(lowerCaseSearch)) ?? false) ); }); }, [search]); From ac582b4d40791276f3eda4f2012ab31491981861 Mon Sep 17 00:00:00 2001 From: Aria Date: Thu, 2 Oct 2025 01:06:29 -0500 Subject: [PATCH 245/335] Wrap properly when phase === 1 --- packages/superdough/worklets.mjs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index ccfaf5107..058559885 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -1234,7 +1234,8 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { _sampleFrame(frame, phase) { const len = frame.length; const pos = phase * len; - const i = pos | 0; + let i = pos | 0; + if (i >= len) i = 0; const frac = pos - i; const a = frame[i]; const i1 = i + 1 < len ? i + 1 : 0; // fast wrap From 99e14dae5ca88443c098abc4fcc56b7e1859832e Mon Sep 17 00:00:00 2001 From: Aria Date: Thu, 2 Oct 2025 01:12:42 -0500 Subject: [PATCH 246/335] Consistency --- packages/superdough/worklets.mjs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 058559885..7858871c2 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -1235,10 +1235,11 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { const len = frame.length; const pos = phase * len; let i = pos | 0; - if (i >= len) i = 0; + if (i >= len) i = 0; // fast wrap const frac = pos - i; const a = frame[i]; - const i1 = i + 1 < len ? i + 1 : 0; // fast wrap + let i1 = i + 1; + if (i1 >= len) i1 = 0; const b = frame[i1]; return a + (b - a) * frac; } From f369de13d7116ce24f952251e6e955e193a14126 Mon Sep 17 00:00:00 2001 From: Aria Date: Thu, 2 Oct 2025 22:45:48 -0500 Subject: [PATCH 247/335] Hook up FM to wavetables --- packages/superdough/wavetable.mjs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index 44367f786..220b95896 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -308,6 +308,7 @@ export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) { }, ); const vibratoOscillator = getVibratoOscillator(source.parameters.get('detune'), value, t); + const fm = applyFM(source.parameters.get('frequency'), value, t); const envGain = ac.createGain(); const node = source.connect(envGain); getParamADSR(node.gain, attack, decay, sustain, release, 0, 0.3, t, holdEnd, 'linear'); @@ -318,6 +319,7 @@ export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) { () => { destroyAudioWorkletNode(source); vibratoOscillator?.stop(); + fm?.stop(); node.disconnect(); wtPosModulators?.disconnect(); wtWarpModulators?.disconnect(); From d496919fe507caa6323ce5d33b553e2b2a15d974 Mon Sep 17 00:00:00 2001 From: Aria Date: Thu, 2 Oct 2025 22:48:41 -0500 Subject: [PATCH 248/335] Import --- packages/superdough/wavetable.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index 220b95896..da6abcf76 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -1,6 +1,7 @@ import { getAudioContext, registerSound } from './index.mjs'; import { getCommonSampleInfo } from './util.mjs'; import { + applyFM, applyParameterModulators, destroyAudioWorkletNode, getADSRValues, From 120f89d57fc38a70f082d1bd1b977e2d4bb8d943 Mon Sep 17 00:00:00 2001 From: Aria Date: Sat, 4 Oct 2025 01:37:57 -0500 Subject: [PATCH 249/335] Handle detune in the presence of pitch envelope --- packages/core/test/pattern.test.mjs | 4 ++-- packages/superdough/wavetable.mjs | 4 ++-- packages/superdough/worklets.mjs | 24 +++++++++++++----------- website/src/components/Header/Search.css | 4 ++-- website/src/pages/learn/samples.mdx | 2 +- 5 files changed, 20 insertions(+), 18 deletions(-) diff --git a/packages/core/test/pattern.test.mjs b/packages/core/test/pattern.test.mjs index 1df5c8776..625f40756 100644 --- a/packages/core/test/pattern.test.mjs +++ b/packages/core/test/pattern.test.mjs @@ -796,7 +796,7 @@ describe('Pattern', () => { }); }); describe('apply', () => { - it('Can apply a function', () => { + (it('Can apply a function', () => { expect(sequence('a', 'b').apply(fast(2)).firstCycle()).toStrictEqual(sequence('a', 'b').fast(2).firstCycle()); }), it('Can apply a pattern of functions', () => { @@ -804,7 +804,7 @@ describe('Pattern', () => { expect(sequence('a', 'b').apply(fast(2), fast(3)).firstCycle()).toStrictEqual( sequence('a', 'b').fast(2, 3).firstCycle(), ); - }); + })); }); describe('layer', () => { it('Can layer up multiple functions', () => { diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index 44367f786..3329dd96b 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -230,12 +230,12 @@ export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) { begin: t, end: envEnd, frequency, - detune: value.detune, + freqspread: value.detune, position: value.wt, warp: value.warp, warpMode: warpmode, voices: Math.max(value.unison ?? 1, 1), - spread: value.spread, + panspread: value.spread, phaserand: (value.wtphaserand ?? value.unison > 1) ? 1 : 0, }, { outputChannelCount: [2] }, diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 7858871c2..dc9d93b27 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -1049,14 +1049,15 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { return [ { name: 'begin', defaultValue: 0, min: 0, max: Number.POSITIVE_INFINITY }, { name: 'end', defaultValue: 0, min: 0, max: Number.POSITIVE_INFINITY }, - { name: 'frequency', defaultValue: 220, minValue: 0.01, maxValue: 20000 }, - { name: 'detune', defaultValue: 0.18 }, - { name: 'position', defaultValue: 0, minValue: 0, maxValue: 1 }, - { name: 'warp', defaultValue: 0, minValue: 0, maxValue: 1 }, + { name: 'frequency', defaultValue: 440, min: Number.EPSILON }, + { name: 'detune', defaultValue: 0 }, + { name: 'freqspread', defaultValue: 0.18, min: 0 }, + { name: 'position', defaultValue: 0, min: 0, max: 1 }, + { name: 'warp', defaultValue: 0, min: 0, max: 1 }, { name: 'warpMode', defaultValue: 0 }, - { name: 'voices', defaultValue: 1, minValue: 1, maxValue: 32 }, - { name: 'spread', defaultValue: 0.7, minValue: 0, maxValue: 1 }, - { name: 'phaserand', defaultValue: 0, minValue: 0, maxValue: 1 }, + { name: 'voices', defaultValue: 1, min: 1 }, + { name: 'panspread', defaultValue: 0.7, min: 0, max: 1 }, + { name: 'phaserand', defaultValue: 0, min: 0, max: 1 }, ]; } @@ -1269,6 +1270,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { } for (let i = 0; i < outL.length; i++) { const detune = pv(parameters.detune, i); + const freqspread = pv(parameters.freqspread, i); const tablePos = clamp(pv(parameters.position, i), 0, 1); const idx = tablePos * (this.numFrames - 1); const fIdx = idx | 0; @@ -1277,9 +1279,9 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { const warpMode = pv(parameters.warpMode, i); const voices = pv(parameters.voices, i); const phaseRand = clamp(pv(parameters.phaserand, i), 0, 1); - const spread = voices > 1 ? clamp(pv(parameters.spread, i), 0, 1) : 0; - const gain1 = Math.sqrt(0.5 - 0.5 * spread); - const gain2 = Math.sqrt(0.5 + 0.5 * spread); + const panspread = voices > 1 ? clamp(pv(parameters.panspread, i), 0, 1) : 0; + const gain1 = Math.sqrt(0.5 - 0.5 * panspread); + const gain2 = Math.sqrt(0.5 + 0.5 * panspread); let f = pv(parameters.frequency, i); f = applySemitoneDetuneToFrequency(f, detune / 100); // overall detune const normalizer = 1 / Math.sqrt(voices); @@ -1292,7 +1294,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { gainL = gain2; gainR = gain1; } - const fVoice = applySemitoneDetuneToFrequency(f, getUnisonDetune(voices, detune, n)); // voice detune + const fVoice = applySemitoneDetuneToFrequency(f, getUnisonDetune(voices, freqspread, n)); // voice detune const dPhase = fVoice * this.invSR; const level = this._chooseMip(dPhase); const table = this.tables[level]; diff --git a/website/src/components/Header/Search.css b/website/src/components/Header/Search.css index 456ef9f6b..b14146cbd 100644 --- a/website/src/components/Header/Search.css +++ b/website/src/components/Header/Search.css @@ -18,8 +18,8 @@ --docsearch-modal-background: var(--background); --docsearch-muted-color: color-mix(in srgb, var(--foreground), #fff 30%); --docsearch-key-gradient: var(--foreground); - --docsearch-key-shadow: inset 0 -2px 0 0 var(--gutterForeground), inset 0 0 1px 1px var(--foreground), - 0 1px 2px 1px var(--gutterBackground); + --docsearch-key-shadow: + inset 0 -2px 0 0 var(--gutterForeground), inset 0 0 1px 1px var(--foreground), 0 1px 2px 1px var(--gutterBackground); } .dark { --docsearch-muted-color: color-mix(in srgb, var(--foreground), #000 30%); diff --git a/website/src/pages/learn/samples.mdx b/website/src/pages/learn/samples.mdx index eb79cccf7..201d57dfa 100644 --- a/website/src/pages/learn/samples.mdx +++ b/website/src/pages/learn/samples.mdx @@ -381,7 +381,7 @@ Sampler effects are functions that can be used to change the behaviour of sample ### scrub -{' '} + ### speed From 3ef6c7c921efd79799f3e9d0a2e3462ab748d267 Mon Sep 17 00:00:00 2001 From: Aria Date: Sat, 4 Oct 2025 02:07:35 -0500 Subject: [PATCH 250/335] Handle scale-for-notes when n also supplied --- packages/core/test/pattern.test.mjs | 4 ++-- packages/tonal/tonal.mjs | 21 ++++++++++++--------- website/src/components/Header/Search.css | 4 ++-- website/src/pages/learn/samples.mdx | 2 +- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/packages/core/test/pattern.test.mjs b/packages/core/test/pattern.test.mjs index 1df5c8776..625f40756 100644 --- a/packages/core/test/pattern.test.mjs +++ b/packages/core/test/pattern.test.mjs @@ -796,7 +796,7 @@ describe('Pattern', () => { }); }); describe('apply', () => { - it('Can apply a function', () => { + (it('Can apply a function', () => { expect(sequence('a', 'b').apply(fast(2)).firstCycle()).toStrictEqual(sequence('a', 'b').fast(2).firstCycle()); }), it('Can apply a pattern of functions', () => { @@ -804,7 +804,7 @@ describe('Pattern', () => { expect(sequence('a', 'b').apply(fast(2), fast(3)).firstCycle()).toStrictEqual( sequence('a', 'b').fast(2, 3).firstCycle(), ); - }); + })); }); describe('layer', () => { it('Can layer up multiple functions', () => { diff --git a/packages/tonal/tonal.mjs b/packages/tonal/tonal.mjs index ae75ab690..a24dc7f25 100644 --- a/packages/tonal/tonal.mjs +++ b/packages/tonal/tonal.mjs @@ -266,9 +266,14 @@ export const scale = register( pat .fmap((value) => { const isObject = typeof value === 'object'; - // The case where the note has been defined via `n` or `pure` - if (!isObject || (isObject && ('n' in value || 'value' in value))) { - const step = isObject ? (value.n ?? value.value) : value; + // If value is a pure value, place it on `n` so that we interpret it as a scale + // degree + value = typeof value !== 'object' ? { n: value } : value; + if ('note' in value) { + const note = _getNearestScaleNote(scale, value.note); + return pure({ ...value, note }); + } else if ('n' in value || 'value' in value) { + const step = value.n ?? value.value; delete value.n; // remove n so it won't cause trouble if (isNote(step)) { // legacy.. @@ -277,7 +282,7 @@ export const scale = register( try { const [number, offset] = _convertStepToNumberAndOffset(step); let note; - if (isObject && value.anchor) { + if (value.anchor) { note = stepInNamedScale(number, scale, value.anchor); } else { note = scaleStep(number, scale); @@ -290,11 +295,9 @@ export const scale = register( } return value; } - // The case where the note has been defined via `note` - else { - const note = _getNearestScaleNote(scale, value.note); - return pure(isObject ? { ...value, note } : note); - } + throw new Error( + `Invalid value format for 'scale'. Value must contain 'n' or 'note' but received ${Object.keys(value)}`, + ); }) .outerJoin() // legacy: diff --git a/website/src/components/Header/Search.css b/website/src/components/Header/Search.css index 456ef9f6b..b14146cbd 100644 --- a/website/src/components/Header/Search.css +++ b/website/src/components/Header/Search.css @@ -18,8 +18,8 @@ --docsearch-modal-background: var(--background); --docsearch-muted-color: color-mix(in srgb, var(--foreground), #fff 30%); --docsearch-key-gradient: var(--foreground); - --docsearch-key-shadow: inset 0 -2px 0 0 var(--gutterForeground), inset 0 0 1px 1px var(--foreground), - 0 1px 2px 1px var(--gutterBackground); + --docsearch-key-shadow: + inset 0 -2px 0 0 var(--gutterForeground), inset 0 0 1px 1px var(--foreground), 0 1px 2px 1px var(--gutterBackground); } .dark { --docsearch-muted-color: color-mix(in srgb, var(--foreground), #000 30%); diff --git a/website/src/pages/learn/samples.mdx b/website/src/pages/learn/samples.mdx index eb79cccf7..201d57dfa 100644 --- a/website/src/pages/learn/samples.mdx +++ b/website/src/pages/learn/samples.mdx @@ -381,7 +381,7 @@ Sampler effects are functions that can be used to change the behaviour of sample ### scrub -{' '} + ### speed From 11dd8a318a5f329d8b5f9269192fbfdc6a15839d Mon Sep 17 00:00:00 2001 From: Aria Date: Sat, 4 Oct 2025 02:13:42 -0500 Subject: [PATCH 251/335] Cleanup --- packages/tonal/tonal.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/tonal/tonal.mjs b/packages/tonal/tonal.mjs index a24dc7f25..e745a33a0 100644 --- a/packages/tonal/tonal.mjs +++ b/packages/tonal/tonal.mjs @@ -268,7 +268,7 @@ export const scale = register( const isObject = typeof value === 'object'; // If value is a pure value, place it on `n` so that we interpret it as a scale // degree - value = typeof value !== 'object' ? { n: value } : value; + value = isObject ? value : { n: value }; if ('note' in value) { const note = _getNearestScaleNote(scale, value.note); return pure({ ...value, note }); From 0d0822598351fcb7b0050a2f452f0fada4375fee Mon Sep 17 00:00:00 2001 From: Jieren Chen Date: Sun, 5 Oct 2025 13:53:00 -0400 Subject: [PATCH 252/335] change the trigger handler to match new hap --- packages/mqtt/mqtt.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mqtt/mqtt.mjs b/packages/mqtt/mqtt.mjs index aef01bd93..d74de342d 100644 --- a/packages/mqtt/mqtt.mjs +++ b/packages/mqtt/mqtt.mjs @@ -82,7 +82,7 @@ Pattern.prototype.mqtt = function ( cx.connect(props); } return this.withHap((hap) => { - const onTrigger = (t_deprecate, hap, currentTime, cps, targetTime) => { + const onTrigger = (hap, currentTime, cps, targetTime) => { let msg_topic = topic; if (!cx || !cx.isConnected()) { return; From be9368e8a2d6be6625b1f55eaf62e8f82a5b587c Mon Sep 17 00:00:00 2001 From: dtricks Date: Fri, 3 Oct 2025 17:57:58 +0200 Subject: [PATCH 253/335] feat(codemirror): add Vim :w evaluate, :q stop, and gc/gcc toggle comment via custom events; docs: add Vim shortcuts page and link from REPL manual --- packages/codemirror/codemirror.mjs | 42 +++++- packages/codemirror/keybindings.mjs | 139 +++++++++++++++++--- website/src/pages/technical-manual/repl.mdx | 4 + website/src/pages/technical-manual/vim.mdx | 36 +++++ 4 files changed, 203 insertions(+), 18 deletions(-) create mode 100644 website/src/pages/technical-manual/vim.mdx diff --git a/packages/codemirror/codemirror.mjs b/packages/codemirror/codemirror.mjs index 4dc23996f..6359609ca 100644 --- a/packages/codemirror/codemirror.mjs +++ b/packages/codemirror/codemirror.mjs @@ -1,4 +1,5 @@ import { closeBrackets } from '@codemirror/autocomplete'; +import { toggleLineComment } from '@codemirror/commands'; export { toggleComment, toggleBlockComment, toggleLineComment, toggleBlockCommentByLine } from '@codemirror/commands'; // import { search, highlightSelectionMatches } from '@codemirror/search'; import { indentWithTab } from '@codemirror/commands'; @@ -13,7 +14,7 @@ import { lineNumbers, drawSelection, } from '@codemirror/view'; -import { repl, registerControl } from '@strudel/core'; +import { repl, registerControl, logger } from '@strudel/core'; import { Drawer, cleanupDraw } from '@strudel/draw'; import { isAutoCompletionEnabled } from './autocomplete.mjs'; import { isTooltipEnabled } from './tooltip.mjs'; @@ -245,6 +246,32 @@ export class StrudelMirror { } }; document.addEventListener('start-repl', this.onStartRepl); + + // Handle global evaluation requests (e.g., from Vim :w) + this.onEvaluateRequest = (e) => { + try { + // Evaluate current editor on repl-evaluate + logger('[repl] evaluate via event'); + this.evaluate(); + e?.cancelable && e.preventDefault?.(); + } catch (err) { + console.error('Error handling repl-evaluate event', err); + } + }; + document.addEventListener('repl-evaluate', this.onEvaluateRequest); + document.addEventListener('repl-stop', this.onStopRequest); + + // Toggle comments requested from Vim (gc/gcc) + this.onToggleComment = (e) => { + try { + // Honor selections; toggleLineComment handles both selections and single line + toggleLineComment(this.editor); + e?.cancelable && e.preventDefault?.(); + } catch (err) { + console.error('Error handling repl-toggle-comment event', err); + } + }; + document.addEventListener('repl-toggle-comment', this.onToggleComment); } draw(haps, time, painters) { painters?.forEach((painter) => painter(this.drawContext, time, haps, this.drawTime)); @@ -271,6 +298,16 @@ export class StrudelMirror { async stop() { this.repl.scheduler.stop(); } + + // Listen for global stop requests (e.g., from Vim :q) + onStopRequest = (e) => { + try { + this.stop(); + e?.cancelable && e.preventDefault?.(); + } catch (err) { + console.error('Error handling repl-stop event', err); + } + }; async toggle() { if (this.repl.scheduler.started) { this.repl.stop(); @@ -351,6 +388,9 @@ export class StrudelMirror { } clear() { this.onStartRepl && document.removeEventListener('start-repl', this.onStartRepl); + this.onEvaluateRequest && document.removeEventListener('repl-evaluate', this.onEvaluateRequest); + this.onStopRequest && document.removeEventListener('repl-stop', this.onStopRequest); + this.onToggleComment && document.removeEventListener('repl-toggle-comment', this.onToggleComment); } getCursorLocation() { return this.editor.state.selection.main.head; diff --git a/packages/codemirror/keybindings.mjs b/packages/codemirror/keybindings.mjs index ca5f34f4c..7de2a7238 100644 --- a/packages/codemirror/keybindings.mjs +++ b/packages/codemirror/keybindings.mjs @@ -1,32 +1,137 @@ -import { Prec } from '@codemirror/state'; -import { keymap, ViewPlugin } from '@codemirror/view'; +import {defaultKeymap} from '@codemirror/commands'; +import {Prec} from '@codemirror/state'; +import {keymap, ViewPlugin} from '@codemirror/view'; // import { searchKeymap } from '@codemirror/search'; -import { emacs } from '@replit/codemirror-emacs'; -import { vim } from '@replit/codemirror-vim'; +import {emacs} from '@replit/codemirror-emacs'; +import {vim, Vim} from '@replit/codemirror-vim'; +import { logger } from '@strudel/core'; // import { vim } from './vim_test.mjs'; -import { vscodeKeymap } from '@replit/codemirror-vscode-keymap'; -import { defaultKeymap } from '@codemirror/commands'; +import {vscodeKeymap} from '@replit/codemirror-vscode-keymap'; const vscodePlugin = ViewPlugin.fromClass( - class { - constructor() {} - }, - { - provide: () => { - return Prec.highest(keymap.of([...vscodeKeymap])); + class { + constructor() {} + }, + { + provide : () => { return Prec.highest(keymap.of([...vscodeKeymap ])); }, }, - }, ); const vscodeExtension = (options) => [vscodePlugin].concat(options ?? []); +// Map Vim :w to trigger the same action as evaluation. We dispatch a custom +// event 'repl-evaluate' that the editor listens for, and also simulate +// Ctrl+Enter/Alt+Enter as a fallback. We log to the Strudel logger so it +// appears in the Console panel. +try { + if (Vim && typeof Vim.defineEx === 'function') { + // Map gc/gcc to toggle line comments by dispatching a custom event that our + // CodeMirror integration listens to. This avoids depending on Vim's internal + // actions and works with current selections/visual mode. + try { + Vim.defineAction('strudelToggleComment', (cm) => { + const view = cm?.view || cm; + try { + const ev = new CustomEvent('repl-toggle-comment', { detail: { source: 'vim', view }, cancelable: true }); + document.dispatchEvent(ev); + } catch (e) { + console.error('strudelToggleComment dispatch failed', e); + } + }); + Vim.mapCommand('gc', 'action', 'strudelToggleComment', {}, { context: 'normal' }); + Vim.mapCommand('gc', 'action', 'strudelToggleComment', {}, { context: 'visual' }); + Vim.mapCommand('gcc', 'action', 'strudelToggleComment', {}, { context: 'normal' }); + } catch (e) { + console.error('Vim gc/gcc mapping failed', e); + } + + // :q to pause/stop + // :q to pause/stop + Vim.defineEx('quit', 'q', (cm) => { + try { + const view = cm?.view || cm; + // First try dispatching our custom stop event, then fallback to Alt+. + let handled = false; + try { + const ev = new CustomEvent('repl-stop', { detail: { source: 'vim', view }, cancelable: true }); + handled = document.dispatchEvent(ev) === false; + } catch {} + if (!handled) { + const altDot = new KeyboardEvent('keydown', { + key: '.', + code: 'Period', + altKey: true, + bubbles: true, + cancelable: true, + }); + view?.dom?.dispatchEvent?.(altDot); + } + } catch (e) { + console.error('Error dispatching :q stop event', e); + } + }); + + // :w to evaluate + // :w to evaluate + Vim.defineEx('write', 'w', (cm) => { + const view = + cm?.view || + cm; // CM6 Vim passes either an object with view or the view itself + try { + view?.focus?.(); + // Let the app know this came from Vim :w + try { + logger('[vim] :w — evaluating code'); + } catch {} + // Dispatch a dedicated evaluate event first + let handled = false; + try { + const ev = new CustomEvent('repl-evaluate', { detail: { source: 'vim', view }, cancelable: true }); + handled = document.dispatchEvent(ev) === false; // false means preventDefault was called + } catch {} + if (handled) { + return; + } + // Try Ctrl+Enter first if not handled by custom event + const ctrlEnter = new KeyboardEvent('keydown', { + key : 'Enter', + code : 'Enter', + ctrlKey : true, + bubbles : true, + cancelable : true, + }); + view?.dom?.dispatchEvent?.(ctrlEnter); + // If not handled (no handler called preventDefault), try Alt+Enter as + // fallback + if (!ctrlEnter.defaultPrevented) { + const altEnter = new KeyboardEvent('keydown', { + key : 'Enter', + code : 'Enter', + altKey : true, + bubbles : true, + cancelable : true, + }); + view?.dom?.dispatchEvent?.(altEnter); + } + } catch (e) { + console.error('Error dispatching :w evaluation event', e); + } + }); + } +} catch (e) { + console.error('Vim ex command setup failed (defineEx missing or Vim unavailable)', e); +} + const keymaps = { - vim, + vim, + // Add extra Vim keymap for gc to toggle line comment + // We will include a Vim-specific keymap that calls the CM command + // respecting the current selection. emacs, - codemirror: () => keymap.of(defaultKeymap), - vscode: vscodeExtension, + codemirror : () => keymap.of(defaultKeymap), + vscode : vscodeExtension, }; export function keybindings(name) { const active = keymaps[name]; - return [active ? Prec.high(active()) : []]; + return [ active ? Prec.high(active()) : [] ]; } diff --git a/website/src/pages/technical-manual/repl.mdx b/website/src/pages/technical-manual/repl.mdx index 8c4287af5..f74a4fb8b 100644 --- a/website/src/pages/technical-manual/repl.mdx +++ b/website/src/pages/technical-manual/repl.mdx @@ -117,6 +117,10 @@ Here's an example AST for `c3 [e3 g3]` which translates to `seq(c3, seq(e3, g3))` +## Vim Keybindings + +See the separate page on Vim shortcuts for a quick reference: [/technical-manual/vim](/technical-manual/vim) + ## Scheduling Events After an instance of `Pattern` is obtained from the user code, diff --git a/website/src/pages/technical-manual/vim.mdx b/website/src/pages/technical-manual/vim.mdx new file mode 100644 index 000000000..ec284d0bf --- /dev/null +++ b/website/src/pages/technical-manual/vim.mdx @@ -0,0 +1,36 @@ +--- +title: Vim Shortcuts +layout: ../../layouts/MainLayout.astro +--- + +# Vim Shortcuts in the REPL + +When the REPL editor (CodeMirror) is configured to use Vim keybindings, the following commands are available: + +- :w — Evaluate the current code + - Triggers the same evaluation as Ctrl+Enter / Alt+Enter + - You’ll see messages in the Console panel such as: + - [vim] :w — evaluating code + - [repl] evaluate via event + - [eval] code updated + +- :q — Stop/pause playback + - Triggers the same stop action as Alt+. + - Useful to quickly stop scheduling without leaving Vim mode + +- gc — Toggle line comments for the current selection(s) + - Works in normal and visual mode + - If there’s a selection, all selected lines are toggled + +- gcc — Toggle comment for the current line (normal mode) + +Notes + +- Behavior respects the current language mode in the editor for comment syntax. +- If multiple REPL editors are open, commands target the active editor. The implementation dispatches custom events handled by the editor. +- If you don’t see the Console panel, open the right panel in the REPL UI. + +Troubleshooting + +- If :w logs but evaluation doesn’t apply, ensure Vim keybindings are active and try again. You can also use Ctrl+Enter as a fallback. +- For :q / gc / gcc, ensure focus is inside the editor. If an error occurs, reload the page to reset editor state and try again. From 73a98349596c68031b33b1fe44b830498faea920 Mon Sep 17 00:00:00 2001 From: dtricks Date: Fri, 3 Oct 2025 18:12:47 +0200 Subject: [PATCH 254/335] codeformat --- packages/codemirror/codemirror.mjs | 2 +- packages/codemirror/keybindings.mjs | 56 +++++++++++----------- packages/osc/server.js | 0 website/src/pages/technical-manual/vim.mdx | 3 ++ 4 files changed, 32 insertions(+), 29 deletions(-) mode change 100644 => 100755 packages/osc/server.js diff --git a/packages/codemirror/codemirror.mjs b/packages/codemirror/codemirror.mjs index 6359609ca..f3ab3890e 100644 --- a/packages/codemirror/codemirror.mjs +++ b/packages/codemirror/codemirror.mjs @@ -298,7 +298,7 @@ export class StrudelMirror { async stop() { this.repl.scheduler.stop(); } - + // Listen for global stop requests (e.g., from Vim :q) onStopRequest = (e) => { try { diff --git a/packages/codemirror/keybindings.mjs b/packages/codemirror/keybindings.mjs index 7de2a7238..06aaad523 100644 --- a/packages/codemirror/keybindings.mjs +++ b/packages/codemirror/keybindings.mjs @@ -1,20 +1,22 @@ -import {defaultKeymap} from '@codemirror/commands'; -import {Prec} from '@codemirror/state'; -import {keymap, ViewPlugin} from '@codemirror/view'; +import { defaultKeymap } from '@codemirror/commands'; +import { Prec } from '@codemirror/state'; +import { keymap, ViewPlugin } from '@codemirror/view'; // import { searchKeymap } from '@codemirror/search'; -import {emacs} from '@replit/codemirror-emacs'; -import {vim, Vim} from '@replit/codemirror-vim'; +import { emacs } from '@replit/codemirror-emacs'; +import { vim, Vim } from '@replit/codemirror-vim'; import { logger } from '@strudel/core'; // import { vim } from './vim_test.mjs'; -import {vscodeKeymap} from '@replit/codemirror-vscode-keymap'; +import { vscodeKeymap } from '@replit/codemirror-vscode-keymap'; const vscodePlugin = ViewPlugin.fromClass( - class { - constructor() {} - }, - { - provide : () => { return Prec.highest(keymap.of([...vscodeKeymap ])); }, + class { + constructor() {} + }, + { + provide: () => { + return Prec.highest(keymap.of([...vscodeKeymap])); }, + }, ); const vscodeExtension = (options) => [vscodePlugin].concat(options ?? []); @@ -73,9 +75,7 @@ try { // :w to evaluate // :w to evaluate Vim.defineEx('write', 'w', (cm) => { - const view = - cm?.view || - cm; // CM6 Vim passes either an object with view or the view itself + const view = cm?.view || cm; // CM6 Vim passes either an object with view or the view itself try { view?.focus?.(); // Let the app know this came from Vim :w @@ -93,22 +93,22 @@ try { } // Try Ctrl+Enter first if not handled by custom event const ctrlEnter = new KeyboardEvent('keydown', { - key : 'Enter', - code : 'Enter', - ctrlKey : true, - bubbles : true, - cancelable : true, + key: 'Enter', + code: 'Enter', + ctrlKey: true, + bubbles: true, + cancelable: true, }); view?.dom?.dispatchEvent?.(ctrlEnter); // If not handled (no handler called preventDefault), try Alt+Enter as // fallback if (!ctrlEnter.defaultPrevented) { const altEnter = new KeyboardEvent('keydown', { - key : 'Enter', - code : 'Enter', - altKey : true, - bubbles : true, - cancelable : true, + key: 'Enter', + code: 'Enter', + altKey: true, + bubbles: true, + cancelable: true, }); view?.dom?.dispatchEvent?.(altEnter); } @@ -122,16 +122,16 @@ try { } const keymaps = { - vim, + vim, // Add extra Vim keymap for gc to toggle line comment // We will include a Vim-specific keymap that calls the CM command // respecting the current selection. emacs, - codemirror : () => keymap.of(defaultKeymap), - vscode : vscodeExtension, + codemirror: () => keymap.of(defaultKeymap), + vscode: vscodeExtension, }; export function keybindings(name) { const active = keymaps[name]; - return [ active ? Prec.high(active()) : [] ]; + return [active ? Prec.high(active()) : []]; } diff --git a/packages/osc/server.js b/packages/osc/server.js old mode 100644 new mode 100755 diff --git a/website/src/pages/technical-manual/vim.mdx b/website/src/pages/technical-manual/vim.mdx index ec284d0bf..b18a259ec 100644 --- a/website/src/pages/technical-manual/vim.mdx +++ b/website/src/pages/technical-manual/vim.mdx @@ -8,6 +8,7 @@ layout: ../../layouts/MainLayout.astro When the REPL editor (CodeMirror) is configured to use Vim keybindings, the following commands are available: - :w — Evaluate the current code + - Triggers the same evaluation as Ctrl+Enter / Alt+Enter - You’ll see messages in the Console panel such as: - [vim] :w — evaluating code @@ -15,10 +16,12 @@ When the REPL editor (CodeMirror) is configured to use Vim keybindings, the foll - [eval] code updated - :q — Stop/pause playback + - Triggers the same stop action as Alt+. - Useful to quickly stop scheduling without leaving Vim mode - gc — Toggle line comments for the current selection(s) + - Works in normal and visual mode - If there’s a selection, all selected lines are toggled From 46ba165c7eb7375056625e837fee12ff9cef1aee Mon Sep 17 00:00:00 2001 From: dtricks Date: Fri, 3 Oct 2025 18:16:18 +0200 Subject: [PATCH 255/335] remove gcc --- packages/codemirror/codemirror.mjs | 60 ++++++++++++---------- packages/codemirror/keybindings.mjs | 11 ++-- website/src/pages/technical-manual/vim.mdx | 4 +- 3 files changed, 39 insertions(+), 36 deletions(-) diff --git a/packages/codemirror/codemirror.mjs b/packages/codemirror/codemirror.mjs index f3ab3890e..69fce4b50 100644 --- a/packages/codemirror/codemirror.mjs +++ b/packages/codemirror/codemirror.mjs @@ -1,31 +1,31 @@ import { closeBrackets } from '@codemirror/autocomplete'; -import { toggleLineComment } from '@codemirror/commands'; -export { toggleComment, toggleBlockComment, toggleLineComment, toggleBlockCommentByLine } from '@codemirror/commands'; -// import { search, highlightSelectionMatches } from '@codemirror/search'; -import { indentWithTab } from '@codemirror/commands'; +import { indentWithTab, toggleLineComment } from '@codemirror/commands'; import { javascript, javascriptLanguage } from '@codemirror/lang-javascript'; -import { defaultHighlightStyle, syntaxHighlighting, bracketMatching } from '@codemirror/language'; +import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from '@codemirror/language'; import { Compartment, EditorState, Prec } from '@codemirror/state'; import { + drawSelection, EditorView, - highlightActiveLineGutter, highlightActiveLine, + highlightActiveLineGutter, keymap, lineNumbers, - drawSelection, } from '@codemirror/view'; -import { repl, registerControl, logger } from '@strudel/core'; -import { Drawer, cleanupDraw } from '@strudel/draw'; +import { persistentAtom } from '@nanostores/persistent'; +import { logger, registerControl, repl } from '@strudel/core'; +import { cleanupDraw, Drawer } from '@strudel/draw'; + import { isAutoCompletionEnabled } from './autocomplete.mjs'; -import { isTooltipEnabled } from './tooltip.mjs'; +import { basicSetup } from './basicSetup.mjs'; import { flash, isFlashEnabled } from './flash.mjs'; import { highlightMiniLocations, isPatternHighlightingEnabled, updateMiniLocations } from './highlight.mjs'; import { keybindings } from './keybindings.mjs'; -import { initTheme, activateTheme, theme } from './themes.mjs'; import { sliderPlugin, updateSliderWidgets } from './slider.mjs'; -import { widgetPlugin, updateWidgets } from './widget.mjs'; -import { persistentAtom } from '@nanostores/persistent'; -import { basicSetup } from './basicSetup.mjs'; +import { activateTheme, initTheme, theme } from './themes.mjs'; +import { isTooltipEnabled } from './tooltip.mjs'; +import { updateWidgets, widgetPlugin } from './widget.mjs'; + +export { toggleBlockComment, toggleBlockCommentByLine, toggleComment, toggleLineComment } from '@codemirror/commands'; const extensions = { isLineWrappingEnabled: (on) => (on ? EditorView.lineWrapping : []), @@ -95,8 +95,8 @@ export function initEditor({ initialCode = '', onChange, onEvaluate, onStop, roo }), sliderPlugin, widgetPlugin, - // indentOnInput(), // works without. already brought with javascript extension? - // bracketMatching(), // does not do anything + // indentOnInput(), // works without. already brought with javascript + // extension? bracketMatching(), // does not do anything syntaxHighlighting(defaultHighlightStyle), EditorView.updateListener.of((v) => onChange(v)), drawSelection({ cursorBlinkRate: 0 }), @@ -120,13 +120,13 @@ export function initEditor({ initialCode = '', onChange, onEvaluate, onStop, roo run: () => onStop?.(), }, /* { - key: 'Ctrl-Shift-.', - run: () => (onPanic ? onPanic() : onStop?.()), - }, - { - key: 'Ctrl-Shift-Enter', - run: () => (onReEvaluate ? onReEvaluate() : onEvaluate?.()), - }, */ + key: 'Ctrl-Shift-.', + run: () => (onPanic ? onPanic() : onStop?.()), + }, + { + key: 'Ctrl-Shift-Enter', + run: () => (onReEvaluate ? onReEvaluate() : onEvaluate?.()), + }, */ ]), ), ], @@ -207,7 +207,8 @@ export class StrudelMirror { updateWidgets(this.editor, widgets); updateMiniLocations(this.editor, this.miniLocations); replOptions?.afterEval?.(options); - // if no painters are set (.onPaint was not called), then we only need the present moment (for highlighting) + // if no painters are set (.onPaint was not called), then we only need + // the present moment (for highlighting) const drawTime = options.pattern.getPainters().length ? this.drawTime : [0, 0]; this.drawer.setDrawTime(drawTime); // invalidate drawer after we've set the appropriate drawTime @@ -261,10 +262,11 @@ export class StrudelMirror { document.addEventListener('repl-evaluate', this.onEvaluateRequest); document.addEventListener('repl-stop', this.onStopRequest); - // Toggle comments requested from Vim (gc/gcc) + // Toggle comments requested from Vim (gc) this.onToggleComment = (e) => { try { - // Honor selections; toggleLineComment handles both selections and single line + // Honor selections; toggleLineComment handles both selections and + // single line toggleLineComment(this.editor); e?.cancelable && e.preventDefault?.(); } catch (err) { @@ -383,7 +385,11 @@ export class StrudelMirror { } } setCode(code) { - const changes = { from: 0, to: this.editor.state.doc.length, insert: code }; + const changes = { + from: 0, + to: this.editor.state.doc.length, + insert: code, + }; this.editor.dispatch({ changes }); } clear() { diff --git a/packages/codemirror/keybindings.mjs b/packages/codemirror/keybindings.mjs index 06aaad523..545c9797d 100644 --- a/packages/codemirror/keybindings.mjs +++ b/packages/codemirror/keybindings.mjs @@ -4,9 +4,9 @@ import { keymap, ViewPlugin } from '@codemirror/view'; // import { searchKeymap } from '@codemirror/search'; import { emacs } from '@replit/codemirror-emacs'; import { vim, Vim } from '@replit/codemirror-vim'; -import { logger } from '@strudel/core'; // import { vim } from './vim_test.mjs'; import { vscodeKeymap } from '@replit/codemirror-vscode-keymap'; +import { logger } from '@strudel/core'; const vscodePlugin = ViewPlugin.fromClass( class { @@ -26,9 +26,9 @@ const vscodeExtension = (options) => [vscodePlugin].concat(options ?? []); // appears in the Console panel. try { if (Vim && typeof Vim.defineEx === 'function') { - // Map gc/gcc to toggle line comments by dispatching a custom event that our - // CodeMirror integration listens to. This avoids depending on Vim's internal - // actions and works with current selections/visual mode. + // Map gc to toggle line comments by dispatching a custom event that our + // CodeMirror integration listens to. This avoids depending on Vim's + // internal actions and works with current selections/visual mode. try { Vim.defineAction('strudelToggleComment', (cm) => { const view = cm?.view || cm; @@ -41,9 +41,8 @@ try { }); Vim.mapCommand('gc', 'action', 'strudelToggleComment', {}, { context: 'normal' }); Vim.mapCommand('gc', 'action', 'strudelToggleComment', {}, { context: 'visual' }); - Vim.mapCommand('gcc', 'action', 'strudelToggleComment', {}, { context: 'normal' }); } catch (e) { - console.error('Vim gc/gcc mapping failed', e); + console.error('Vim gc mapping failed', e); } // :q to pause/stop diff --git a/website/src/pages/technical-manual/vim.mdx b/website/src/pages/technical-manual/vim.mdx index b18a259ec..73f5e1a11 100644 --- a/website/src/pages/technical-manual/vim.mdx +++ b/website/src/pages/technical-manual/vim.mdx @@ -25,8 +25,6 @@ When the REPL editor (CodeMirror) is configured to use Vim keybindings, the foll - Works in normal and visual mode - If there’s a selection, all selected lines are toggled -- gcc — Toggle comment for the current line (normal mode) - Notes - Behavior respects the current language mode in the editor for comment syntax. @@ -36,4 +34,4 @@ Notes Troubleshooting - If :w logs but evaluation doesn’t apply, ensure Vim keybindings are active and try again. You can also use Ctrl+Enter as a fallback. -- For :q / gc / gcc, ensure focus is inside the editor. If an error occurs, reload the page to reset editor state and try again. +- For :q / gc, ensure focus is inside the editor. If an error occurs, reload the page to reset editor state and try again. From cfe17fcba56a8d3767deecd08ef86f054c339d7f Mon Sep 17 00:00:00 2001 From: dtricks Date: Fri, 3 Oct 2025 18:19:18 +0200 Subject: [PATCH 256/335] wrong unicode char --- website/src/pages/technical-manual/vim.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/website/src/pages/technical-manual/vim.mdx b/website/src/pages/technical-manual/vim.mdx index 73f5e1a11..fa53aa550 100644 --- a/website/src/pages/technical-manual/vim.mdx +++ b/website/src/pages/technical-manual/vim.mdx @@ -10,7 +10,7 @@ When the REPL editor (CodeMirror) is configured to use Vim keybindings, the foll - :w — Evaluate the current code - Triggers the same evaluation as Ctrl+Enter / Alt+Enter - - You’ll see messages in the Console panel such as: + - You'll see messages in the Console panel such as: - [vim] :w — evaluating code - [repl] evaluate via event - [eval] code updated @@ -23,15 +23,15 @@ When the REPL editor (CodeMirror) is configured to use Vim keybindings, the foll - gc — Toggle line comments for the current selection(s) - Works in normal and visual mode - - If there’s a selection, all selected lines are toggled + - If there's a selection, all selected lines are toggled Notes - Behavior respects the current language mode in the editor for comment syntax. - If multiple REPL editors are open, commands target the active editor. The implementation dispatches custom events handled by the editor. -- If you don’t see the Console panel, open the right panel in the REPL UI. +- If you don't see the Console panel, open the right panel in the REPL UI. Troubleshooting -- If :w logs but evaluation doesn’t apply, ensure Vim keybindings are active and try again. You can also use Ctrl+Enter as a fallback. +- If :w logs but evaluation doesn't apply, ensure Vim keybindings are active and try again. You can also use Ctrl+Enter as a fallback. - For :q / gc, ensure focus is inside the editor. If an error occurs, reload the page to reset editor state and try again. From 30a2e149592659ec9e9262c7d05fc7134ef29729 Mon Sep 17 00:00:00 2001 From: dtricks Date: Fri, 3 Oct 2025 18:29:32 +0200 Subject: [PATCH 257/335] weird permission change --- packages/osc/server.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 packages/osc/server.js diff --git a/packages/osc/server.js b/packages/osc/server.js old mode 100755 new mode 100644 From a79fc3db5b78a31d6944ca5501206c41cbb9b1bd Mon Sep 17 00:00:00 2001 From: dtricks Date: Sat, 4 Oct 2025 14:49:56 +0200 Subject: [PATCH 258/335] remove unnecessary comments --- packages/codemirror/keybindings.mjs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/codemirror/keybindings.mjs b/packages/codemirror/keybindings.mjs index 545c9797d..5cd6a50e4 100644 --- a/packages/codemirror/keybindings.mjs +++ b/packages/codemirror/keybindings.mjs @@ -45,7 +45,6 @@ try { console.error('Vim gc mapping failed', e); } - // :q to pause/stop // :q to pause/stop Vim.defineEx('quit', 'q', (cm) => { try { @@ -71,7 +70,6 @@ try { } }); - // :w to evaluate // :w to evaluate Vim.defineEx('write', 'w', (cm) => { const view = cm?.view || cm; // CM6 Vim passes either an object with view or the view itself @@ -122,9 +120,6 @@ try { const keymaps = { vim, - // Add extra Vim keymap for gc to toggle line comment - // We will include a Vim-specific keymap that calls the CM command - // respecting the current selection. emacs, codemirror: () => keymap.of(defaultKeymap), vscode: vscodeExtension, From f48f8e46e51c1010bb3dc9e0599b5de8dbb2a00d Mon Sep 17 00:00:00 2001 From: dtricks Date: Mon, 6 Oct 2025 11:09:21 +0200 Subject: [PATCH 259/335] fix empty catches --- packages/codemirror/keybindings.mjs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/codemirror/keybindings.mjs b/packages/codemirror/keybindings.mjs index 5cd6a50e4..81dc87a52 100644 --- a/packages/codemirror/keybindings.mjs +++ b/packages/codemirror/keybindings.mjs @@ -54,7 +54,9 @@ try { try { const ev = new CustomEvent('repl-stop', { detail: { source: 'vim', view }, cancelable: true }); handled = document.dispatchEvent(ev) === false; - } catch {} + } catch (e) { + console.error('Error dispatching repl-stop event', e); + } if (!handled) { const altDot = new KeyboardEvent('keydown', { key: '.', @@ -78,13 +80,17 @@ try { // Let the app know this came from Vim :w try { logger('[vim] :w — evaluating code'); - } catch {} + } catch (e) { + console.error('Error logging Vim :w evaluation', e); + } // Dispatch a dedicated evaluate event first let handled = false; try { const ev = new CustomEvent('repl-evaluate', { detail: { source: 'vim', view }, cancelable: true }); handled = document.dispatchEvent(ev) === false; // false means preventDefault was called - } catch {} + } catch (e) { + console.error('Error dispatching repl-evaluate event', e); + } if (handled) { return; } From 3dc9b3524c40f1dba8492940760c2dde081f5928 Mon Sep 17 00:00:00 2001 From: Tristan de Cacqueray Date: Tue, 7 Oct 2025 17:19:02 +0200 Subject: [PATCH 260/335] mondo: add & sugar --- packages/mondo/mondo.mjs | 23 +++++++++++++++++++++++ packages/mondo/test/mondo.test.mjs | 1 + 2 files changed, 24 insertions(+) diff --git a/packages/mondo/mondo.mjs b/packages/mondo/mondo.mjs index b879f24bf..cdd758431 100644 --- a/packages/mondo/mondo.mjs +++ b/packages/mondo/mondo.mjs @@ -22,6 +22,7 @@ export class MondoParser { number: /^-?[0-9]*\.?[0-9]+/, // before pipe! // TODO: better error handling when "-" is used as rest, e.g "s [- bd]" op: /^[*/:!@%?+-]|^\.{2}/, // * / : ! @ % ? .. + and: /^&/, // dollar: /^\$/, pipe: /^#/, stack: /^[,$]/, @@ -150,6 +151,27 @@ export class MondoParser { } return children; } + desugar_ands(children) { + while (true) { + let opIndex = children.findIndex((child) => child.type === 'and'); + if (opIndex === -1) break; + if (opIndex === children.length - 1) { + throw new Error(`cannot use & as last child.`); + } + if (opIndex === 0) { + throw new Error(`cannot use & as first child.`); + } + // convert infix to prefix notation + const op = { type: 'plain', value: children[opIndex].value }; + const left = children[opIndex - 1]; + const right = children[opIndex + 1]; + const call = { type: 'list', children: [op, left, right] }; + // insert call while keeping other siblings + children = [...children.slice(0, opIndex - 1), call, ...children.slice(opIndex + 2)]; + children = this.unwrap_children(children); + } + return children; + } desugar_ops(children) { while (true) { let opIndex = children.findIndex((child) => child.type === 'op'); @@ -264,6 +286,7 @@ export class MondoParser { children = [{ type: 'plain', value: type }, ...children]; } children = this.desugar_ops(children); + children = this.desugar_ands(children); // children = this.desugar_pipes(children, (children) => this.desugar_dollars(children)); children = this.desugar_pipes(children); return children; diff --git a/packages/mondo/test/mondo.test.mjs b/packages/mondo/test/mondo.test.mjs index 6393b10f9..97f447e78 100644 --- a/packages/mondo/test/mondo.test.mjs +++ b/packages/mondo/test/mondo.test.mjs @@ -117,6 +117,7 @@ describe('mondo sugar', () => { it('should desugar x:y', () => expect(desguar('x:y')).toEqual('(: y x)')); it('should desugar x:y:z', () => expect(desguar('x:y:z')).toEqual('(: z (: y x))')); it('should desugar x:y*x', () => expect(desguar('bd:0*2')).toEqual('(* 2 (: 0 bd))')); + it('should desugar x&y:z', () => expect(desguar('bd&3:8')).toEqual('(& bd (: 8 3))')); it('should desugar a..b', () => expect(desguar('0..2')).toEqual('(.. 2 0)')); /* it('should desugar x $ y', () => expect(desguar('x $ y')).toEqual('(x y)')); it('should desugar x $ y z', () => expect(desguar('x $ y z')).toEqual('(x (y z))')); From b7fa440bda53aa1c281db6fe0a007b610109508c Mon Sep 17 00:00:00 2001 From: Tristan de Cacqueray Date: Tue, 7 Oct 2025 17:33:56 +0200 Subject: [PATCH 261/335] mondough: interpret & --- packages/mondough/mondough.mjs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/mondough/mondough.mjs b/packages/mondough/mondough.mjs index b7ee83787..a299c9a55 100644 --- a/packages/mondough/mondough.mjs +++ b/packages/mondough/mondough.mjs @@ -11,6 +11,7 @@ import { chooseIn, degradeBy, silence, + e, } from '@strudel/core'; import { registerLanguage } from '@strudel/transpiler'; import { MondoRunner } from 'mondolang'; @@ -40,6 +41,7 @@ lib['!'] = extend; lib['@'] = expand; lib['%'] = pace; lib['?'] = degradeBy; // todo: default 0.5 not working.. +lib['&'] = (a, b) => a.e(b); lib[':'] = tail; lib['..'] = range; lib['def'] = () => silence; From f33db5f07f491278995d994b84f06abf3c3c34e0 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Tue, 7 Oct 2025 22:35:29 +0200 Subject: [PATCH 262/335] - refactor bjork -> bjorklund - refactor e -> bjork - flip & desugared arguments --- packages/core/euclid.mjs | 14 +++++++------- packages/mondo/mondo.mjs | 2 +- packages/mondough/mondough.mjs | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/core/euclid.mjs b/packages/core/euclid.mjs index 44ab07f11..98c21a116 100644 --- a/packages/core/euclid.mjs +++ b/packages/core/euclid.mjs @@ -35,18 +35,18 @@ const right = function (n, x) { return result; }; -const _bjork = function (n, x) { +const _bjorklund = function (n, x) { const [ons, offs] = n; - return Math.min(ons, offs) <= 1 ? [n, x] : _bjork(...(ons > offs ? left(n, x) : right(n, x))); + return Math.min(ons, offs) <= 1 ? [n, x] : _bjorklund(...(ons > offs ? left(n, x) : right(n, x))); }; -export const bjork = function (ons, steps) { +export const bjorklund = function (ons, steps) { const inverted = ons < 0; const absOns = Math.abs(ons); const offs = steps - absOns; const ones = Array(absOns).fill([1]); const zeros = Array(offs).fill([0]); - const result = _bjork([absOns, offs], [ones, zeros]); + const result = _bjorklund([absOns, offs], [ones, zeros]); const pattern = flatten(result[1][0]).concat(flatten(result[1][1])); return inverted ? pattern.map((x) => 1 - x) : pattern; }; @@ -128,7 +128,7 @@ export const bjork = function (ons, steps) { */ const _euclidRot = function (pulses, steps, rotation) { - const b = bjork(pulses, steps); + const b = bjorklund(pulses, steps); if (rotation) { return rotate(b, -rotation); } @@ -139,7 +139,7 @@ export const euclid = register('euclid', function (pulses, steps, pat) { return pat.struct(_euclidRot(pulses, steps, 0)); }); -export const e = register('e', function (euc, pat) { +export const bjork = register('bjork', function (euc, pat) { if (!Array.isArray(euc)) { euc = [euc]; } @@ -216,6 +216,6 @@ export const euclidLegatoRot = register(['euclidLegatoRot'], function (pulses, s * .pan(sine.slow(8)) */ export const { euclidish, eish } = register(['euclidish', 'eish'], function (pulses, steps, perc, pat) { - const morphed = _morph(bjork(pulses, steps), new Array(pulses).fill(1), perc); + const morphed = _morph(bjorklund(pulses, steps), new Array(pulses).fill(1), perc); return pat.struct(morphed).setSteps(steps); }); diff --git a/packages/mondo/mondo.mjs b/packages/mondo/mondo.mjs index cdd758431..d419eaff4 100644 --- a/packages/mondo/mondo.mjs +++ b/packages/mondo/mondo.mjs @@ -165,7 +165,7 @@ export class MondoParser { const op = { type: 'plain', value: children[opIndex].value }; const left = children[opIndex - 1]; const right = children[opIndex + 1]; - const call = { type: 'list', children: [op, left, right] }; + const call = { type: 'list', children: [op, right, left] }; // insert call while keeping other siblings children = [...children.slice(0, opIndex - 1), call, ...children.slice(opIndex + 2)]; children = this.unwrap_children(children); diff --git a/packages/mondough/mondough.mjs b/packages/mondough/mondough.mjs index a299c9a55..9b1edb5a5 100644 --- a/packages/mondough/mondough.mjs +++ b/packages/mondough/mondough.mjs @@ -11,7 +11,7 @@ import { chooseIn, degradeBy, silence, - e, + bjork, } from '@strudel/core'; import { registerLanguage } from '@strudel/transpiler'; import { MondoRunner } from 'mondolang'; @@ -41,7 +41,7 @@ lib['!'] = extend; lib['@'] = expand; lib['%'] = pace; lib['?'] = degradeBy; // todo: default 0.5 not working.. -lib['&'] = (a, b) => a.e(b); +lib['&'] = bjork; lib[':'] = tail; lib['..'] = range; lib['def'] = () => silence; From 3a7d50924d190896053a20a783a758da237100bf Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Tue, 7 Oct 2025 22:59:50 +0200 Subject: [PATCH 263/335] refactor: add op_precedence to express & with desugar_ops --- packages/mondo/mondo.mjs | 36 ++++++++---------------------------- 1 file changed, 8 insertions(+), 28 deletions(-) diff --git a/packages/mondo/mondo.mjs b/packages/mondo/mondo.mjs index d419eaff4..00a3b4011 100644 --- a/packages/mondo/mondo.mjs +++ b/packages/mondo/mondo.mjs @@ -21,14 +21,14 @@ export class MondoParser { close_curly: /^\}/, number: /^-?[0-9]*\.?[0-9]+/, // before pipe! // TODO: better error handling when "-" is used as rest, e.g "s [- bd]" - op: /^[*/:!@%?+-]|^\.{2}/, // * / : ! @ % ? .. - and: /^&/, + op: /^[*\/:!@%?+\-&]|^\.{2}/, // * / : ! @ % ? .. // dollar: /^\$/, pipe: /^#/, stack: /^[,$]/, or: /^[|]/, plain: /^[a-zA-Z0-9-~_^#]+/, }; + op_precedence = [['*', '/', ':', '!', '@', '%', '?', '+', '-', '..'], ['&']]; // matches next token next_token(code, offset = 0) { for (let type in this.token_types) { @@ -151,30 +151,9 @@ export class MondoParser { } return children; } - desugar_ands(children) { + desugar_ops(children, types) { while (true) { - let opIndex = children.findIndex((child) => child.type === 'and'); - if (opIndex === -1) break; - if (opIndex === children.length - 1) { - throw new Error(`cannot use & as last child.`); - } - if (opIndex === 0) { - throw new Error(`cannot use & as first child.`); - } - // convert infix to prefix notation - const op = { type: 'plain', value: children[opIndex].value }; - const left = children[opIndex - 1]; - const right = children[opIndex + 1]; - const call = { type: 'list', children: [op, right, left] }; - // insert call while keeping other siblings - children = [...children.slice(0, opIndex - 1), call, ...children.slice(opIndex + 2)]; - children = this.unwrap_children(children); - } - return children; - } - desugar_ops(children) { - while (true) { - let opIndex = children.findIndex((child) => child.type === 'op'); + let opIndex = children.findIndex((child) => child.type === 'op' && types.includes(child.value)); if (opIndex === -1) break; const op = { type: 'plain', value: children[opIndex].value }; if (opIndex === children.length - 1) { @@ -285,9 +264,10 @@ export class MondoParser { // the type we've removed before splitting needs to be added back children = [{ type: 'plain', value: type }, ...children]; } - children = this.desugar_ops(children); - children = this.desugar_ands(children); - // children = this.desugar_pipes(children, (children) => this.desugar_dollars(children)); + // for each precendence group, call desugar_ops once + this.op_precedence.forEach((ops) => { + children = this.desugar_ops(children, ops); + }); children = this.desugar_pipes(children); return children; }), From 319a2d7289ce4cd43e6f2b450e69ea27181d35da Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Tue, 7 Oct 2025 23:05:00 +0200 Subject: [PATCH 264/335] fix: tests --- packages/core/test/euclid.test.js | 16 ++++++++-------- packages/mondo/mondo.mjs | 2 +- packages/mondo/test/mondo.test.mjs | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/core/test/euclid.test.js b/packages/core/test/euclid.test.js index a33ec9514..6169abd71 100644 --- a/packages/core/test/euclid.test.js +++ b/packages/core/test/euclid.test.js @@ -1,14 +1,14 @@ -import { bjork } from '../euclid.mjs'; +import { bjorklund } from '../euclid.mjs'; import { describe, expect, it } from 'vitest'; import { fastcat } from '../pattern.mjs'; -describe('bjork', () => { - it('should apply bjorklund to ons and steps', () => { - expect(bjork(3, 8)).toStrictEqual([1, 0, 0, 1, 0, 0, 1, 0]); - expect(bjork(-3, 8)).toStrictEqual([0, 1, 1, 0, 1, 1, 0, 1]); - expect(bjork(8, 8)).toStrictEqual([1, 1, 1, 1, 1, 1, 1, 1]); - expect(bjork(-8, 8)).toStrictEqual([0, 0, 0, 0, 0, 0, 0, 0]); - expect(bjork(5, 8)).toStrictEqual([1, 0, 1, 1, 0, 1, 1, 0]); +describe('bjorklund', () => { + it('should apply bjorklundlund to ons and steps', () => { + expect(bjorklund(3, 8)).toStrictEqual([1, 0, 0, 1, 0, 0, 1, 0]); + expect(bjorklund(-3, 8)).toStrictEqual([0, 1, 1, 0, 1, 1, 0, 1]); + expect(bjorklund(8, 8)).toStrictEqual([1, 1, 1, 1, 1, 1, 1, 1]); + expect(bjorklund(-8, 8)).toStrictEqual([0, 0, 0, 0, 0, 0, 0, 0]); + expect(bjorklund(5, 8)).toStrictEqual([1, 0, 1, 1, 0, 1, 1, 0]); }); }); diff --git a/packages/mondo/mondo.mjs b/packages/mondo/mondo.mjs index 00a3b4011..b87a8b588 100644 --- a/packages/mondo/mondo.mjs +++ b/packages/mondo/mondo.mjs @@ -21,7 +21,7 @@ export class MondoParser { close_curly: /^\}/, number: /^-?[0-9]*\.?[0-9]+/, // before pipe! // TODO: better error handling when "-" is used as rest, e.g "s [- bd]" - op: /^[*\/:!@%?+\-&]|^\.{2}/, // * / : ! @ % ? .. + op: /^[*/:!@%?+\-&]|^\.{2}/, // * / : ! @ % ? .. // dollar: /^\$/, pipe: /^#/, stack: /^[,$]/, diff --git a/packages/mondo/test/mondo.test.mjs b/packages/mondo/test/mondo.test.mjs index 97f447e78..a02c6fec1 100644 --- a/packages/mondo/test/mondo.test.mjs +++ b/packages/mondo/test/mondo.test.mjs @@ -117,7 +117,7 @@ describe('mondo sugar', () => { it('should desugar x:y', () => expect(desguar('x:y')).toEqual('(: y x)')); it('should desugar x:y:z', () => expect(desguar('x:y:z')).toEqual('(: z (: y x))')); it('should desugar x:y*x', () => expect(desguar('bd:0*2')).toEqual('(* 2 (: 0 bd))')); - it('should desugar x&y:z', () => expect(desguar('bd&3:8')).toEqual('(& bd (: 8 3))')); + it('should desugar x&y:z', () => expect(desguar('bd&3:8')).toEqual('(& (: 8 3) bd)')); it('should desugar a..b', () => expect(desguar('0..2')).toEqual('(.. 2 0)')); /* it('should desugar x $ y', () => expect(desguar('x $ y')).toEqual('(x y)')); it('should desugar x $ y z', () => expect(desguar('x $ y z')).toEqual('(x (y z))')); From 694162a7b1d0c916ffa76461bcb5fb77bf046459 Mon Sep 17 00:00:00 2001 From: Alex McLean Date: Wed, 8 Oct 2025 14:13:33 +0100 Subject: [PATCH 265/335] fix purity of 'withState' so it returns a new pattern --- packages/core/pattern.mjs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index d0be3f599..72f6371b3 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -98,10 +98,7 @@ export class Pattern { // runs func on query state withState(func) { - return this.withHaps((haps, state) => { - func(state); - return haps; - }); + return new Pattern((state) => this.query(func(state))); } /** From fdde05e75114e8aedb38d89648d83d1c58b3b303 Mon Sep 17 00:00:00 2001 From: Alex McLean Date: Wed, 8 Oct 2025 14:51:21 +0100 Subject: [PATCH 266/335] add pattern id to query state controls --- packages/core/repl.mjs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/core/repl.mjs b/packages/core/repl.mjs index 53562f216..8dbfbec75 100644 --- a/packages/core/repl.mjs +++ b/packages/core/repl.mjs @@ -214,7 +214,10 @@ export function repl({ } let { pattern, meta } = await _evaluate(code, transpiler, transpilerOptions); if (Object.keys(pPatterns).length) { - let patterns = Object.values(pPatterns); + let patterns = []; + for (const [key, value] of Object.entries(pPatterns)) { + patterns.push(value.withState(state => state.setControls({id: key}))); + } if (eachTransform) { // Explicit lambda so only element (not index and array) are passed patterns = patterns.map((x) => eachTransform(x)); @@ -228,6 +231,7 @@ export function repl({ pattern = allTransforms[i](pattern); } } + if (!isPattern(pattern)) { const message = `got "${typeof evaluated}" instead of pattern`; throw new Error(message + (typeof evaluated === 'function' ? ', did you forget to call a function?' : '.')); From 086596c47ca564743510301a963815572d6b48b0 Mon Sep 17 00:00:00 2001 From: Alex McLean Date: Wed, 8 Oct 2025 14:52:00 +0100 Subject: [PATCH 267/335] fix setControls to do union with existing controls --- packages/core/state.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/state.mjs b/packages/core/state.mjs index 162dc7da9..928710814 100644 --- a/packages/core/state.mjs +++ b/packages/core/state.mjs @@ -19,9 +19,9 @@ export class State { return this.setSpan(func(this.span)); } - // Returns new State with different controls + // Returns new State with added controls. setControls(controls) { - return new State(this.span, controls); + return new State(this.span, {...this.controls, ...controls}); } } From ffbbc43c8973059a95cfd69d0594e5cac71905ef Mon Sep 17 00:00:00 2001 From: Alex McLean Date: Wed, 8 Oct 2025 15:34:51 +0100 Subject: [PATCH 268/335] add cyclist version to the query metadata --- packages/core/cyclist.mjs | 2 +- packages/core/neocyclist.mjs | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/core/cyclist.mjs b/packages/core/cyclist.mjs index ad0961032..59e410c53 100644 --- a/packages/core/cyclist.mjs +++ b/packages/core/cyclist.mjs @@ -57,7 +57,7 @@ export class Cyclist { } // query the pattern for events - const haps = this.pattern.queryArc(begin, end, { _cps: this.cps }); + const haps = this.pattern.queryArc(begin, end, { _cps: this.cps, cyclist: 'cyclist' }); haps.forEach((hap) => { if (hap.hasOnset()) { diff --git a/packages/core/neocyclist.mjs b/packages/core/neocyclist.mjs index 261f08acb..3e412074d 100644 --- a/packages/core/neocyclist.mjs +++ b/packages/core/neocyclist.mjs @@ -38,8 +38,7 @@ export class NeoCyclist { if (this.started === false) { return; } - - const haps = this.pattern.queryArc(begin, end, { _cps: this.cps }); + const haps = this.pattern.queryArc(begin, end, { _cps: this.cps, cyclist: 'neocyclist' }); haps.forEach((hap) => { if (hap.hasOnset()) { const timeUntilTrigger = cycleToSeconds(hap.whole.begin - this.cycle, this.cps); From 64f16c4f337c63692b5f89e8226e37a0db82c923 Mon Sep 17 00:00:00 2001 From: Alex McLean Date: Wed, 8 Oct 2025 15:35:34 +0100 Subject: [PATCH 269/335] placate format gods --- packages/core/repl.mjs | 2 +- packages/core/state.mjs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/repl.mjs b/packages/core/repl.mjs index 8dbfbec75..171697eb9 100644 --- a/packages/core/repl.mjs +++ b/packages/core/repl.mjs @@ -216,7 +216,7 @@ export function repl({ if (Object.keys(pPatterns).length) { let patterns = []; for (const [key, value] of Object.entries(pPatterns)) { - patterns.push(value.withState(state => state.setControls({id: key}))); + patterns.push(value.withState((state) => state.setControls({ id: key }))); } if (eachTransform) { // Explicit lambda so only element (not index and array) are passed diff --git a/packages/core/state.mjs b/packages/core/state.mjs index 928710814..8aa581954 100644 --- a/packages/core/state.mjs +++ b/packages/core/state.mjs @@ -21,7 +21,7 @@ export class State { // Returns new State with added controls. setControls(controls) { - return new State(this.span, {...this.controls, ...controls}); + return new State(this.span, { ...this.controls, ...controls }); } } From a3b803c3f33d9c029690ad0631adc9feec3c17ab Mon Sep 17 00:00:00 2001 From: Aria Date: Thu, 9 Oct 2025 18:28:59 -0500 Subject: [PATCH 270/335] First pass --- packages/core/controls.mjs | 145 +++++++++++++++++++++++ packages/core/test/pattern.test.mjs | 4 +- packages/superdough/helpers.mjs | 71 +++++++---- packages/superdough/superdough.mjs | 138 ++++++++++----------- packages/superdough/util.mjs | 5 + website/src/components/Header/Search.css | 4 +- website/src/pages/learn/samples.mdx | 2 +- 7 files changed, 271 insertions(+), 98 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 7e3c2a8e2..8a332ac26 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -1288,6 +1288,151 @@ export const { fanchor } = registerControl('fanchor'); */ // currently an alias of 'hcutoff' https://codeberg.org/uzu/strudel/issues/496 // ['hpf'], + +/** + * Rate of the LFO for the lowpass filter + * + * @name lprate + * @param {number | Pattern} rate rate in hertz + */ +export const { lprate } = registerControl('lprate'); + +/** + * Cycle-synced rate of the LFO for the lowpass filter + * + * @name lpsync + * @param {number | Pattern} rate rate in cycles + */ +export const { lpsync } = registerControl('lpsync'); + +/** + * Depth of the LFO for the lowpass filter + * + * @name lpdepth + * @param {number | Pattern} depth depth of modulation + */ +export const { lpdepth } = registerControl('lpdepth'); + +/** + * Shape of the LFO for the lowpass filter + * + * @name lpshape + * @param {number | Pattern} shape Shape of the lfo (0, 1, 2, ..) + */ +export const { lpshape } = registerControl('lpshape'); + +/** + * DC offset of the LFO for the lowpass filter + * + * @name lpdc + * @param {number | Pattern} dcoffset dc offset. set to 0 for unipolar + */ +export const { lpdc } = registerControl('lpdc'); + +/** + * Skew of the LFO for the lowpass filter + * + * @name lpskew + * @param {number | Pattern} skew How much to bend the LFO shape + */ +export const { lpskew } = registerControl('lpskew'); + +/** + * Rate of the LFO for the bandpass filter + * + * @name bprate + * @param {number | Pattern} rate rate in hertz + */ +export const { bprate } = registerControl('bprate'); + +/** + * Cycle-synced rate of the LFO for the bandpass filter + * + * @name bpsync + * @param {number | Pattern} rate rate in cycles + */ +export const { bpsync } = registerControl('bpsync'); + +/** + * Depth of the LFO for the bandpass filter + * + * @name bpdepth + * @param {number | Pattern} depth depth of modulation + */ +export const { bpdepth } = registerControl('bpdepth'); + +/** + * Shape of the LFO for the bandpass filter + * + * @name bpshape + * @param {number | Pattern} shape Shape of the lfo (0, 1, 2, ..) + */ +export const { bpshape } = registerControl('bpshape'); + +/** + * DC offset of the LFO for the bandpass filter + * + * @name bpdc + * @param {number | Pattern} dcoffset dc offset. set to 0 for unipolar + */ +export const { bpdc } = registerControl('bpdc'); + +/** + * Skew of the LFO for the bandpass filter + * + * @name bpskew + * @param {number | Pattern} skew How much to bend the LFO shape + */ +export const { bpskew } = registerControl('bpskew'); + +/** + * Rate of the LFO for the highpass filter + * + * @name hprate + * @param {number | Pattern} rate rate in hertz + */ +export const { hprate } = registerControl('hprate'); + +/** + * Cycle-synced rate of the LFO for the highpass filter + * + * @name hpsync + * @param {number | Pattern} rate rate in cycles + */ +export const { hpsync } = registerControl('hpsync'); + +/** + * Depth of the LFO for the highpass filter + * + * @name hpdepth + * @param {number | Pattern} depth depth of modulation + */ +export const { hpdepth } = registerControl('hpdepth'); + +/** + * Shape of the LFO for the highpass filter + * + * @name hpshape + * @param {number | Pattern} shape Shape of the lfo (0, 1, 2, ..) + */ +export const { hpshape } = registerControl('hpshape'); + +/** + * DC offset of the LFO for the highpass filter + * + * @name hpdc + * @param {number | Pattern} dcoffset dc offset. set to 0 for unipolar + */ +export const { hpdc } = registerControl('hpdc'); + +/** + * Skew of the LFO for the highpass filter + * + * @name hpskew + * @param {number | Pattern} skew How much to bend the LFO shape + */ +export const { hpskew } = registerControl('hpskew'); + /** * Applies a vibrato to the frequency of the oscillator. * diff --git a/packages/core/test/pattern.test.mjs b/packages/core/test/pattern.test.mjs index 1df5c8776..625f40756 100644 --- a/packages/core/test/pattern.test.mjs +++ b/packages/core/test/pattern.test.mjs @@ -796,7 +796,7 @@ describe('Pattern', () => { }); }); describe('apply', () => { - it('Can apply a function', () => { + (it('Can apply a function', () => { expect(sequence('a', 'b').apply(fast(2)).firstCycle()).toStrictEqual(sequence('a', 'b').fast(2).firstCycle()); }), it('Can apply a pattern of functions', () => { @@ -804,7 +804,7 @@ describe('Pattern', () => { expect(sequence('a', 'b').apply(fast(2), fast(3)).firstCycle()).toStrictEqual( sequence('a', 'b').fast(2, 3).firstCycle(), ); - }); + })); }); describe('layer', () => { it('Can layer up multiple functions', () => { diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index 47bca330d..147291ad3 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -153,6 +153,24 @@ export const getADSRValues = (params, curve = 'linear', defaultValues) => { return [Math.max(a ?? 0, envmin), Math.max(d ?? 0, envmin), Math.min(sustain, envmax), Math.max(r ?? 0, releaseMin)]; }; +export function getParamLfo(audioContext, param, start, end, lfoValues) { + let { defaultDepth = 1, depth, dcoffset, ...getLfoInputs } = lfoValues; + if (depth == null) { + const hasLFOParams = Object.values(getLfoInputs).some((v) => v != null); + depth = hasLFOParams ? defaultDepth : 0; + } + let lfo; + if (depth) { + lfo = getLfo(audioContext, start, end, { + depth, + dcoffset, + ...getLfoInputs, + }); + lfo.connect(param); + } + return lfo; +} + // helper utility for applying standard modulators to a parameter export function applyParameterModulators(audioContext, param, start, end, envelopeValues, lfoValues) { let { amount, offset, defaultAmount = 1, curve = 'linear', values, holdEnd, defaultValues } = envelopeValues; @@ -169,41 +187,39 @@ export function applyParameterModulators(audioContext, param, start, end, envelo const [attack, decay, sustain, release] = getADSRValues(values, curve, defaultValues); getParamADSR(param, attack, decay, sustain, release, min, max, start, holdEnd, curve); } - let lfo; - let { defaultDepth = 1, depth, dcoffset, ...getLfoInputs } = lfoValues; - - if (depth == null) { - const hasLFOParams = Object.values(getLfoInputs).some((v) => v != null); - depth = hasLFOParams ? defaultDepth : 0; - } - if (depth) { - lfo = getLfo(audioContext, start, end, { - depth, - dcoffset, - ...getLfoInputs, - }); - lfo.connect(param); - } - + const lfo = getParamLfo(audioContext, param, start, end, lfoValues); return { lfo, disconnect: () => lfo?.disconnect() }; } -export function createFilter(context, type, frequency, Q, att, dec, sus, rel, fenv, start, end, fanchor, model, drive) { - const curve = 'exponential'; - const [attack, decay, sustain, release] = getADSRValues([att, dec, sus, rel], curve, [0.005, 0.14, 0, 0.1]); - let filter; +export function createFilter(context, start, end, params, cps) { + let { + frequency, + fanchor, + fenv, + type, + model, + q = 1, + drive = 0.69, + depth, + dcoffset = -0.5, + skew, + shape, + rate, + sync, + } = params; let frequencyParam; if (model === 'ladder') { - filter = getWorklet(context, 'ladder-processor', { frequency, q: Q, drive }); + filter = getWorklet(context, 'ladder-processor', { frequency, q, drive }); frequencyParam = filter.parameters.get('frequency'); } else { filter = context.createBiquadFilter(); filter.type = type; - filter.Q.value = Q; + filter.Q.value = q; filter.frequency.value = frequency; frequencyParam = filter.frequency; } - + const envelopeValues = [params.attack, params.decay, params.sustain, params.release]; + const [attack, decay, sustain, release] = getADSRValues(envelopeValues, 'exponential', [0.005, 0.14, 0, 0.1]); // envelope is active when any of these values is set const hasEnvelope = att ?? dec ?? sus ?? rel ?? fenv; // Apply ADSR to filter frequency @@ -216,8 +232,15 @@ export function createFilter(context, type, frequency, Q, att, dec, sus, rel, fe let max = clamp(2 ** (fenvAbs - offset) * frequency, 0, 20000); if (fenv < 0) [min, max] = [max, min]; getParamADSR(frequencyParam, attack, decay, sustain, release, min, max, start, end, curve); - return filter; } + + if (sync != null) { + rate = cps * sync; + } + const lfoValues = { depth, dcoffset, skew, shape, frequency: rate }; + getParamLfo(context, frequencyParam, start, end, lfoValues); + // TODO: remember to disconnect LFO + // lfo?.disconnect() return filter; } diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 52ed9bff8..bae422354 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -7,7 +7,7 @@ This program is free software: you can redistribute it and/or modify it under th import './feedbackdelay.mjs'; import './reverb.mjs'; import './vowel.mjs'; -import { nanFallback, _mod, cycleToSeconds } from './util.mjs'; +import { nanFallback, _mod, cycleToSeconds, pickAndRename } from './util.mjs'; import workletsUrl from './worklets.mjs?audioworklet'; import { createFilter, gainNode, getCompressor, getLfo, getWorklet, effectSend } from './helpers.mjs'; import { map } from 'nanostores'; @@ -145,11 +145,6 @@ let defaultDefaultValues = { gain: 0.8, postgain: 1, density: '.03', - ftype: '12db', - fanchor: 0, - resonance: 1, - hresonance: 1, - bandq: 1, channels: [1, 2], phaserdepth: 0.75, shapevol: 1, @@ -432,32 +427,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) djf, // filters fanchor = getDefaultValue('fanchor'), - drive = 0.69, release = 0, - // low pass - cutoff, - lpenv, - lpattack, - lpdecay, - lpsustain, - lprelease, - resonance = getDefaultValue('resonance'), - // high pass - hpenv, - hcutoff, - hpattack, - hpdecay, - hpsustain, - hprelease, - hresonance = getDefaultValue('hresonance'), - // band pass - bpenv, - bandf, - bpattack, - bpdecay, - bpsustain, - bprelease, - bandq = getDefaultValue('bandq'), //phaser phaserrate: phaser, @@ -581,57 +551,87 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) // gain stage chain.push(gainNode(gain)); - //filter + // filter const ftype = getFilterType(value.ftype); - if (cutoff !== undefined) { - let lp = () => - createFilter( - ac, - 'lowpass', - cutoff, - resonance, - lpattack, - lpdecay, - lpsustain, - lprelease, - lpenv, - t, - end, - fanchor, - ftype, - drive, - ); + + if (value.cutoff !== undefined) { + const lpMap = { + frequency: 'cutoff', + q: 'resonance', + attack: 'lpattack', + decay: 'lpdecay', + sustain: 'lpsustain', + release: 'lprelease', + env: 'lpenv', + anchor: 'fanchor', + model: 'ftype', + drive: 'drive', + rate: 'lprate', + sync: 'lpsync', + depth: 'lpdepth', + shape: 'lpshape', + dcoffset: 'lpdc', + skew: 'lpskew', + }; + const lpParams = pickAndRename(value, lpMap); + lpParams.type = 'lowpass'; + let lp = () => createFilter(ac, t, end, lpParams, cps); chain.push(lp()); if (ftype === '24db') { chain.push(lp()); } } - if (hcutoff !== undefined) { - let hp = () => - createFilter( - ac, - 'highpass', - hcutoff, - hresonance, - hpattack, - hpdecay, - hpsustain, - hprelease, - hpenv, - t, - end, - fanchor, - ); + if (value.hcutoff !== undefined) { + const hpMap = { + frequency: 'hcutoff', + q: 'hresonance', + attack: 'hpattack', + decay: 'hpdecay', + sustain: 'hpsustain', + release: 'hprelease', + env: 'hpenv', + anchor: 'fanchor', + model: 'ftype', + drive: 'drive', + rate: 'hprate', + sync: 'hpsync', + depth: 'hpdepth', + shape: 'hpshape', + dcoffset: 'hpdc', + skew: 'hpskew', + }; + const hpParams = pickAndRename(value, hpMap); + hpParams.type = 'highpass'; + let hp = () => createFilter(ac, t, end, hpParams, cps); chain.push(hp()); if (ftype === '24db') { chain.push(hp()); } } - if (bandf !== undefined) { - let bp = () => - createFilter(ac, 'bandpass', bandf, bandq, bpattack, bpdecay, bpsustain, bprelease, bpenv, t, end, fanchor); + if (value.bandf !== undefined) { + const bpMap = { + frequency: 'bandf', + q: 'bandq', + attack: 'bpattack', + decay: 'bpdecay', + sustain: 'bpsustain', + release: 'bprelease', + env: 'bpenv', + anchor: 'fanchor', + model: 'ftype', + drive: 'drive', + rate: 'bprate', + sync: 'bpsync', + depth: 'bpdepth', + shape: 'bpshape', + dcoffset: 'bpdc', + skew: 'bpskew', + }; + const bpParams = pickAndRename(value, bpMap); + bpParams.type = 'bandpass'; + let bp = () => createFilter(ac, t, end, bpParams, cps); chain.push(bp()); if (ftype === '24db') { chain.push(bp()); diff --git a/packages/superdough/util.mjs b/packages/superdough/util.mjs index 475c05f63..f296cca00 100644 --- a/packages/superdough/util.mjs +++ b/packages/superdough/util.mjs @@ -105,3 +105,8 @@ export function getCommonSampleInfo(hapValue, bank) { const label = `${s}:${index}`; return { transpose, url, index, midi, label }; } + +/** Selects entries from `source` and renames them via `map` */ +export const pickAndRename = (source, map) => { + return Object.fromEntries(Object.entries(map).map(([newKey, oldKey]) => [newKey, source[oldKey]])); +}; diff --git a/website/src/components/Header/Search.css b/website/src/components/Header/Search.css index 456ef9f6b..b14146cbd 100644 --- a/website/src/components/Header/Search.css +++ b/website/src/components/Header/Search.css @@ -18,8 +18,8 @@ --docsearch-modal-background: var(--background); --docsearch-muted-color: color-mix(in srgb, var(--foreground), #fff 30%); --docsearch-key-gradient: var(--foreground); - --docsearch-key-shadow: inset 0 -2px 0 0 var(--gutterForeground), inset 0 0 1px 1px var(--foreground), - 0 1px 2px 1px var(--gutterBackground); + --docsearch-key-shadow: + inset 0 -2px 0 0 var(--gutterForeground), inset 0 0 1px 1px var(--foreground), 0 1px 2px 1px var(--gutterBackground); } .dark { --docsearch-muted-color: color-mix(in srgb, var(--foreground), #000 30%); diff --git a/website/src/pages/learn/samples.mdx b/website/src/pages/learn/samples.mdx index eb79cccf7..201d57dfa 100644 --- a/website/src/pages/learn/samples.mdx +++ b/website/src/pages/learn/samples.mdx @@ -381,7 +381,7 @@ Sampler effects are functions that can be used to change the behaviour of sample ### scrub -{' '} + ### speed From 57fac576779d8cfcf8477aa0b32e2e02b3015772 Mon Sep 17 00:00:00 2001 From: Aria Date: Thu, 9 Oct 2025 22:23:28 -0500 Subject: [PATCH 271/335] Remove todo --- packages/superdough/helpers.mjs | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index 147291ad3..f26599855 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -239,8 +239,6 @@ export function createFilter(context, start, end, params, cps) { } const lfoValues = { depth, dcoffset, skew, shape, frequency: rate }; getParamLfo(context, frequencyParam, start, end, lfoValues); - // TODO: remember to disconnect LFO - // lfo?.disconnect() return filter; } From 0065db8569d351954b83469c1e644087f5e7da80 Mon Sep 17 00:00:00 2001 From: Darius Kazemi Date: Sat, 11 Oct 2025 17:40:55 -0700 Subject: [PATCH 272/335] Docs: add example of custom chained function This adds a subsection to the "Understand/Coding Syntax" documentation that shows a simple example of converting the previous chain of effects into a custom, reusable chained function. There's also a prompt for the reader to experiment. --- website/src/pages/learn/code.mdx | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/website/src/pages/learn/code.mdx b/website/src/pages/learn/code.mdx index f9c6b3a25..11b8b0dac 100644 --- a/website/src/pages/learn/code.mdx +++ b/website/src/pages/learn/code.mdx @@ -60,6 +60,25 @@ Strudel makes heavy use of chained functions. Here is a more sophisticated examp .room(0.5)`} /> +## Write your own chained function + +You can write your own chained function using `register`. Here's the above chain but registered as a reusable, chained function. + + pat + .s("sawtooth") + .cutoff(500) + //.delay(0.5) + .room(0.5) + ); +note("a3 c#4 e4 a4").effectChain() +`} +/> + +Try adding `.rev()` after `effectChain()` to see further effects added. + # Comments The `//` in the example above is a line comment, resulting in the `delay` function being ignored. From af53bab2596750b8dc8818a54797e9ccf7d0e5d7 Mon Sep 17 00:00:00 2001 From: Darius Kazemi Date: Sat, 11 Oct 2025 17:50:58 -0700 Subject: [PATCH 273/335] Fixing some syntax and a typo --- website/src/pages/learn/code.mdx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/website/src/pages/learn/code.mdx b/website/src/pages/learn/code.mdx index 11b8b0dac..6ff9e4a95 100644 --- a/website/src/pages/learn/code.mdx +++ b/website/src/pages/learn/code.mdx @@ -66,18 +66,16 @@ You can write your own chained function using `register`. Here's the above chain pat + tune={`const effectChain = register('effectChain', (pat) => pat .s("sawtooth") .cutoff(500) //.delay(0.5) .room(0.5) ); -note("a3 c#4 e4 a4").effectChain() -`} +note("a3 c#4 e4 a4").effectChain()`} /> -Try adding `.rev()` after `effectChain()` to see further effects added. +Try adding `.rev()` after `effectChain()` to hear further effects added. # Comments From 9c5c71c31a08321348e9eeaf4139c1f4e8a4c853 Mon Sep 17 00:00:00 2001 From: Darius Kazemi Date: Sat, 11 Oct 2025 17:52:26 -0700 Subject: [PATCH 274/335] Removing semicolon to be more idiomatic;;; --- website/src/pages/learn/code.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/pages/learn/code.mdx b/website/src/pages/learn/code.mdx index 6ff9e4a95..c454dcceb 100644 --- a/website/src/pages/learn/code.mdx +++ b/website/src/pages/learn/code.mdx @@ -71,7 +71,7 @@ You can write your own chained function using `register`. Here's the above chain .cutoff(500) //.delay(0.5) .room(0.5) - ); + ) note("a3 c#4 e4 a4").effectChain()`} /> From 72eaf96b4fb922fc4aa36ef92d90843f8395b62c Mon Sep 17 00:00:00 2001 From: Erik Fox Date: Sun, 12 Oct 2025 12:30:36 -0400 Subject: [PATCH 275/335] fix: repair REPL sample sources and URL concat (#1640) --- packages/repl/prebake.mjs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/repl/prebake.mjs b/packages/repl/prebake.mjs index 3f421f985..26d875c2b 100644 --- a/packages/repl/prebake.mjs +++ b/packages/repl/prebake.mjs @@ -20,10 +20,13 @@ export async function prebake() { // import('@strudel/osc'), ); // load samples - const ds = 'https://raw.githubusercontent.com/felixroos/dough-samples/main/'; + const ds = 'https://raw.githubusercontent.com/felixroos/dough-samples/main'; // TODO: move this onto the strudel repo - const ts = 'https://raw.githubusercontent.com/todepond/samples/main/'; + const ts = 'https://raw.githubusercontent.com/todepond/samples/main'; + + const tc = 'https://raw.githubusercontent.com/tidalcycles/uzu-drumkit/main'; + await Promise.all([ modulesLoading, registerSynthSounds(), @@ -36,9 +39,9 @@ export async function prebake() { samples(`${ds}/tidal-drum-machines.json`), samples(`${ds}/piano.json`), samples(`${ds}/Dirt-Samples.json`), - samples(`${ds}/uzu-drumkit.json`), samples(`${ds}/vcsl.json`), samples(`${ds}/mridangam.json`), + samples(`${tc}/strudel.json`), ]); aliasBank(`${ts}/tidal-drum-machines-alias.json`); From ac7e9c697851d569ab6681ce735bc7dc8d7d0bd5 Mon Sep 17 00:00:00 2001 From: Aria Date: Tue, 14 Oct 2025 11:37:41 -0500 Subject: [PATCH 276/335] Typos on envelope values --- packages/core/test/pattern.test.mjs | 4 ++-- packages/superdough/helpers.mjs | 24 ++++++++++++------------ website/src/components/Header/Search.css | 4 ++-- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/core/test/pattern.test.mjs b/packages/core/test/pattern.test.mjs index 625f40756..1df5c8776 100644 --- a/packages/core/test/pattern.test.mjs +++ b/packages/core/test/pattern.test.mjs @@ -796,7 +796,7 @@ describe('Pattern', () => { }); }); describe('apply', () => { - (it('Can apply a function', () => { + it('Can apply a function', () => { expect(sequence('a', 'b').apply(fast(2)).firstCycle()).toStrictEqual(sequence('a', 'b').fast(2).firstCycle()); }), it('Can apply a pattern of functions', () => { @@ -804,7 +804,7 @@ describe('Pattern', () => { expect(sequence('a', 'b').apply(fast(2), fast(3)).firstCycle()).toStrictEqual( sequence('a', 'b').fast(2, 3).firstCycle(), ); - })); + }); }); describe('layer', () => { it('Can layer up multiple functions', () => { diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index 8e59eb720..b3fc53356 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -195,8 +195,8 @@ export function applyParameterModulators(audioContext, param, start, end, envelo export function createFilter(context, start, end, params, cps) { let { frequency, - fanchor, - fenv, + anchor, + env, type, model, q = 1, @@ -208,7 +208,7 @@ export function createFilter(context, start, end, params, cps) { rate, sync, } = params; - let frequencyParam; + let frequencyParam, filter; if (model === 'ladder') { filter = getWorklet(context, 'ladder-processor', { frequency, q, drive }); frequencyParam = filter.parameters.get('frequency'); @@ -222,17 +222,17 @@ export function createFilter(context, start, end, params, cps) { const envelopeValues = [params.attack, params.decay, params.sustain, params.release]; const [attack, decay, sustain, release] = getADSRValues(envelopeValues, 'exponential', [0.005, 0.14, 0, 0.1]); // envelope is active when any of these values is set - const hasEnvelope = att ?? dec ?? sus ?? rel ?? fenv; + const hasEnvelope = [...envelopeValues, env].some((v) => v !== undefined); // Apply ADSR to filter frequency - if (hasEnvelope !== undefined) { - fenv = nanFallback(fenv, 1, true); - fanchor = nanFallback(fanchor, 0, true); - const fenvAbs = Math.abs(fenv); - const offset = fenvAbs * fanchor; + if (hasEnvelope) { + env = nanFallback(env, 1, true); + anchor = nanFallback(anchor, 0, true); + const envAbs = Math.abs(env); + const offset = envAbs * anchor; let min = clamp(2 ** -offset * frequency, 0, 20000); - let max = clamp(2 ** (fenvAbs - offset) * frequency, 0, 20000); - if (fenv < 0) [min, max] = [max, min]; - getParamADSR(frequencyParam, attack, decay, sustain, release, min, max, start, end, curve); + let max = clamp(2 ** (envAbs - offset) * frequency, 0, 20000); + if (env < 0) [min, max] = [max, min]; + getParamADSR(frequencyParam, attack, decay, sustain, release, min, max, start, end, 'exponential'); } if (sync != null) { diff --git a/website/src/components/Header/Search.css b/website/src/components/Header/Search.css index b14146cbd..456ef9f6b 100644 --- a/website/src/components/Header/Search.css +++ b/website/src/components/Header/Search.css @@ -18,8 +18,8 @@ --docsearch-modal-background: var(--background); --docsearch-muted-color: color-mix(in srgb, var(--foreground), #fff 30%); --docsearch-key-gradient: var(--foreground); - --docsearch-key-shadow: - inset 0 -2px 0 0 var(--gutterForeground), inset 0 0 1px 1px var(--foreground), 0 1px 2px 1px var(--gutterBackground); + --docsearch-key-shadow: inset 0 -2px 0 0 var(--gutterForeground), inset 0 0 1px 1px var(--foreground), + 0 1px 2px 1px var(--gutterBackground); } .dark { --docsearch-muted-color: color-mix(in srgb, var(--foreground), #000 30%); From 3c1a8c8bdb60ec9e0a89d74fe5b4e79722d36d13 Mon Sep 17 00:00:00 2001 From: Aria Date: Tue, 14 Oct 2025 11:41:11 -0500 Subject: [PATCH 277/335] Format --- packages/core/test/pattern.test.mjs | 4 ++-- website/src/components/Header/Search.css | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/core/test/pattern.test.mjs b/packages/core/test/pattern.test.mjs index 625f40756..1df5c8776 100644 --- a/packages/core/test/pattern.test.mjs +++ b/packages/core/test/pattern.test.mjs @@ -796,7 +796,7 @@ describe('Pattern', () => { }); }); describe('apply', () => { - (it('Can apply a function', () => { + it('Can apply a function', () => { expect(sequence('a', 'b').apply(fast(2)).firstCycle()).toStrictEqual(sequence('a', 'b').fast(2).firstCycle()); }), it('Can apply a pattern of functions', () => { @@ -804,7 +804,7 @@ describe('Pattern', () => { expect(sequence('a', 'b').apply(fast(2), fast(3)).firstCycle()).toStrictEqual( sequence('a', 'b').fast(2, 3).firstCycle(), ); - })); + }); }); describe('layer', () => { it('Can layer up multiple functions', () => { diff --git a/website/src/components/Header/Search.css b/website/src/components/Header/Search.css index b14146cbd..456ef9f6b 100644 --- a/website/src/components/Header/Search.css +++ b/website/src/components/Header/Search.css @@ -18,8 +18,8 @@ --docsearch-modal-background: var(--background); --docsearch-muted-color: color-mix(in srgb, var(--foreground), #fff 30%); --docsearch-key-gradient: var(--foreground); - --docsearch-key-shadow: - inset 0 -2px 0 0 var(--gutterForeground), inset 0 0 1px 1px var(--foreground), 0 1px 2px 1px var(--gutterBackground); + --docsearch-key-shadow: inset 0 -2px 0 0 var(--gutterForeground), inset 0 0 1px 1px var(--foreground), + 0 1px 2px 1px var(--gutterBackground); } .dark { --docsearch-muted-color: color-mix(in srgb, var(--foreground), #000 30%); From ba93bd1bc59d932dc253ec305ab5da38bafc112f Mon Sep 17 00:00:00 2001 From: alex Date: Wed, 15 Oct 2025 18:54:02 +0100 Subject: [PATCH 278/335] Fix onPaint for widgets --- packages/draw/draw.mjs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/draw/draw.mjs b/packages/draw/draw.mjs index a429395ff..95f3aed50 100644 --- a/packages/draw/draw.mjs +++ b/packages/draw/draw.mjs @@ -84,9 +84,18 @@ Pattern.prototype.onPaint = function (painter) { state.controls.painters = []; } state.controls.painters.push(painter); + return state; }); }; +// TODO - Why isn't this pure deep copy not working? +// Pattern.prototype.onPaint = function (painter) { +// return this.withState((state) => { +// const painters = state.controls.painters ? [...state.controls.painters, painter] : [painter]; +// return new State(state.span, { ...state.controls, painters }); +// }); +// }; + Pattern.prototype.getPainters = function () { let painters = []; this.queryArc(0, 0, { painters }); From 909e0154fe9aea8c33d20779e1b083404447501b Mon Sep 17 00:00:00 2001 From: prezmop Date: Sun, 12 Oct 2025 08:01:30 +0200 Subject: [PATCH 279/335] default to samples if repo not found --- packages/superdough/sampler.mjs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/packages/superdough/sampler.mjs b/packages/superdough/sampler.mjs index b195ba79c..02271a689 100644 --- a/packages/superdough/sampler.mjs +++ b/packages/superdough/sampler.mjs @@ -120,13 +120,20 @@ function githubPath(base, subpath = '') { if (!base.startsWith('github:')) { throw new Error('expected "github:" at the start of pseudoUrl'); } - let [_, path] = base.split('github:'); + let path = base.slice('github:'.length); path = path.endsWith('/') ? path.slice(0, -1) : path; - if (path.split('/').length === 2) { - // assume main as default branch if none set - path += '/main'; + + let components = path.split('/'); + let user = components[0]; + let repo = components.length >= 2 ? components[1] : 'samples'; + let branch = components.length >= 3 ? components[2] : 'main'; + let other = components.slice(3); + if (subpath) { + other.push(subpath); } - return `https://raw.githubusercontent.com/${path}/${subpath}`; + other = other.join('/'); + + return `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${other}`; } export const processSampleMap = (sampleMap, fn, baseUrl = sampleMap._base || '') => { From 83c7e63432fec16ea59968863b6ad3f80ad20063 Mon Sep 17 00:00:00 2001 From: prezmop Date: Sun, 12 Oct 2025 08:05:04 +0200 Subject: [PATCH 280/335] update docs --- packages/superdough/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/superdough/README.md b/packages/superdough/README.md index 0c6e4f14c..f5947d83f 100644 --- a/packages/superdough/README.md +++ b/packages/superdough/README.md @@ -153,6 +153,7 @@ samples('github:tidalcycles/dirt-samples') The format is `github://`. +If `` and `` are not specified, they will default to `samples` and `main` respectively. It expects a `strudel.json` file to be present at the root of the given repository, which declares the sample paths in the repo. The format is also expected to be the same as explained above. From c02def03b683a1f37a5b6cd7f53ab51b721fdb26 Mon Sep 17 00:00:00 2001 From: Aria Date: Thu, 16 Oct 2025 16:26:33 -0500 Subject: [PATCH 281/335] Don't tag when scale fails, allow mixed sharps and flats, simplify scale function --- packages/core/pattern.mjs | 2 +- packages/core/test/pattern.test.mjs | 4 +- packages/core/util.mjs | 10 ++- packages/superdough/util.mjs | 6 +- packages/tonal/test/tonal.test.mjs | 7 -- packages/tonal/tonal.mjs | 96 +++++++++++------------ test/__snapshots__/examples.test.mjs.snap | 8 +- website/src/components/Header/Search.css | 4 +- 8 files changed, 67 insertions(+), 70 deletions(-) diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index a85226a8f..51d525f74 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -2574,8 +2574,8 @@ export const { chunkBack, chunkback } = register( * @returns Pattern * @example * "<0 8> 1 2 3 4 5 6 7" - * .fastChunk(4, x => x.color('red')).slow(2) * .scale("C2:major").note() + * .fastChunk(4, x => x.color('red')).slow(2) */ export const { fastchunk, fastChunk } = register( ['fastchunk', 'fastChunk'], diff --git a/packages/core/test/pattern.test.mjs b/packages/core/test/pattern.test.mjs index 625f40756..1df5c8776 100644 --- a/packages/core/test/pattern.test.mjs +++ b/packages/core/test/pattern.test.mjs @@ -796,7 +796,7 @@ describe('Pattern', () => { }); }); describe('apply', () => { - (it('Can apply a function', () => { + it('Can apply a function', () => { expect(sequence('a', 'b').apply(fast(2)).firstCycle()).toStrictEqual(sequence('a', 'b').fast(2).firstCycle()); }), it('Can apply a pattern of functions', () => { @@ -804,7 +804,7 @@ describe('Pattern', () => { expect(sequence('a', 'b').apply(fast(2), fast(3)).firstCycle()).toStrictEqual( sequence('a', 'b').fast(2, 3).firstCycle(), ); - })); + }); }); describe('layer', () => { it('Can layer up multiple functions', () => { diff --git a/packages/core/util.mjs b/packages/core/util.mjs index ef3f1e961..915a2cb77 100644 --- a/packages/core/util.mjs +++ b/packages/core/util.mjs @@ -7,8 +7,8 @@ This program is free software: you can redistribute it and/or modify it under th import { logger } from './logger.mjs'; // returns true if the given string is a note -export const isNoteWithOctave = (name) => /^[a-gA-G][#bs]*[0-9]$/.test(name); -export const isNote = (name) => /^[a-gA-G][#bsf]*-?[0-9]?$/.test(name); +export const isNoteWithOctave = (name) => /^[a-gA-G][#bsf]*[0-9]*$/.test(name); +export const isNote = (name) => /^[a-gA-G][#bsf]*-?[0-9]*$/.test(name); export const tokenizeNote = (note) => { if (typeof note !== 'string') { return []; @@ -23,6 +23,10 @@ export const tokenizeNote = (note) => { const chromas = { c: 0, d: 2, e: 4, f: 5, g: 7, a: 9, b: 11 }; const accs = { '#': 1, b: -1, s: 1, f: -1 }; +export const getAccidentalsOffset = (accidentals) => { + return accidentals?.split('').reduce((o, char) => o + accs[char], 0) || 0; +}; + // turns the given note into its midi number representation export const noteToMidi = (note, defaultOctave = 3) => { const [pc, acc, oct = defaultOctave] = tokenizeNote(note); @@ -30,7 +34,7 @@ export const noteToMidi = (note, defaultOctave = 3) => { throw new Error('not a note: "' + note + '"'); } const chroma = chromas[pc.toLowerCase()]; - const offset = acc?.split('').reduce((o, char) => o + accs[char], 0) || 0; + const offset = getAccidentalsOffset(acc); return (Number(oct) + 1) * 12 + chroma + offset; }; export const midiToFreq = (n) => { diff --git a/packages/superdough/util.mjs b/packages/superdough/util.mjs index 475c05f63..418b7af0a 100644 --- a/packages/superdough/util.mjs +++ b/packages/superdough/util.mjs @@ -16,13 +16,17 @@ export const tokenizeNote = (note) => { const chromas = { c: 0, d: 2, e: 4, f: 5, g: 7, a: 9, b: 11 }; const accs = { '#': 1, b: -1, s: 1, f: -1 }; +export const getAccidentalsOffset = (accidentals) => { + return accidentals?.split('').reduce((o, char) => o + accs[char], 0) || 0; +}; + export const noteToMidi = (note, defaultOctave = 3) => { const [pc, acc, oct = defaultOctave] = tokenizeNote(note); if (!pc) { throw new Error('not a note: "' + note + '"'); } const chroma = chromas[pc.toLowerCase()]; - const offset = acc?.split('').reduce((o, char) => o + accs[char], 0) || 0; + const offset = getAccidentalsOffset(acc); return (Number(oct) + 1) * 12 + chroma + offset; }; export const midiToFreq = (n) => { diff --git a/packages/tonal/test/tonal.test.mjs b/packages/tonal/test/tonal.test.mjs index 5f61b05a9..06aa91188 100644 --- a/packages/tonal/test/tonal.test.mjs +++ b/packages/tonal/test/tonal.test.mjs @@ -61,13 +61,6 @@ describe('tonal', () => { .firstCycleValues.map((h) => h.note), ).toEqual(['B2', 'Eb3', 'A2', 'G3', 'F3']); }); - it('produces silence for mixed sharps and flats', () => { - expect( - n(seq('0b#', '1#b', '2#b#')) - .scale('C major') - .firstCycleValues.map((h) => h.note), - ).toEqual([]); - }); it('snaps notes (upwards) to scale', () => { const inputNotes = ['Cb', 'Eb', 'G', 'A#', 'Bb']; const expectedNotes = ['B2', 'E3', 'G3', 'B3', 'B3']; diff --git a/packages/tonal/tonal.mjs b/packages/tonal/tonal.mjs index e745a33a0..0dc468b20 100644 --- a/packages/tonal/tonal.mjs +++ b/packages/tonal/tonal.mjs @@ -5,9 +5,8 @@ This program is free software: you can redistribute it and/or modify it under th */ import { Note, Interval, Scale } from '@tonaljs/tonal'; -import { register, _mod, silence, logger, pure, isNote } from '@strudel/core'; +import { register, _mod, logger, isNote, noteToMidi, removeUndefineds, getAccidentalsOffset } from '@strudel/core'; import { stepInNamedScale, nearestNumberIndex } from './tonleiter.mjs'; -import { noteToMidi } from '../core/util.mjs'; const octavesInterval = (octaves) => (octaves <= 0 ? -1 : 1) + octaves * 7 + 'P'; @@ -185,17 +184,15 @@ function _convertStepToNumberAndOffset(step) { step = String(step); // Check to see if the step matches the expected format: // - A number (possibly negative) - // - Some number of sharps or flats (but not both) - const match = /^(-?\d+)(#+|b+)?$/.exec(step); + // - Some number of sharps or flats + const match = /^(-?\d+)([#bsf]*)$/.exec(step); if (!match) { throw new Error(`invalid scale step "${step}", expected number or integer with optional # b suffixes`); } asNumber = Number(match[1]); - // These decorations will determine the semitone offset based on the number of - // sharps or flats - const decorations = match[2] || ''; - offset = decorations[0] === '#' ? decorations.length : -decorations.length; + const accidentals = match[2] || ''; + offset = getAccidentalsOffset(accidentals); } return [asNumber, offset]; } @@ -226,7 +223,7 @@ function _getNearestScaleNote(scaleName, note, preferHigher = true) { * Turns numbers into notes in the scale (zero indexed) or quantizes notes to a scale. * * When describing notes via numbers, note that negative numbers can be used to wrap backwards - * in the scale as well as sharps or flats (but not both) to produce notes outside of the scale. + * in the scale as well as sharps or flats to produce notes outside of the scale. * * Also sets scale for other scale operations, like {@link Pattern#scaleTranspose}. * @@ -254,7 +251,6 @@ function _getNearestScaleNote(scaleName, note, preferHigher = true) { * @example * note("C1*16").transpose(irand(36)).scale('Cb2 major').scaleTranspose(3) */ - export const scale = register( 'scale', function (scale, pat) { @@ -262,47 +258,47 @@ export const scale = register( if (Array.isArray(scale)) { scale = scale.flat().join(' '); } - return ( - pat - .fmap((value) => { - const isObject = typeof value === 'object'; - // If value is a pure value, place it on `n` so that we interpret it as a scale - // degree - value = isObject ? value : { n: value }; - if ('note' in value) { - const note = _getNearestScaleNote(scale, value.note); - return pure({ ...value, note }); - } else if ('n' in value || 'value' in value) { - const step = value.n ?? value.value; - delete value.n; // remove n so it won't cause trouble - if (isNote(step)) { - // legacy.. - return pure(step); - } - try { - const [number, offset] = _convertStepToNumberAndOffset(step); - let note; - if (value.anchor) { - note = stepInNamedScale(number, scale, value.anchor); - } else { - note = scaleStep(number, scale); - } - if (offset != 0) note = Note.transpose(note, Interval.fromSemitones(offset)); - value = pure(isObject ? { ...value, note } : note); - } catch (err) { - logger(`[tonal] ${err.message}`, 'error'); - return silence; - } - return value; - } - throw new Error( - `Invalid value format for 'scale'. Value must contain 'n' or 'note' but received ${Object.keys(value)}`, + return pat.withHaps((haps) => { + haps = haps.map((hap) => { + let hVal = hap.value; + const isObject = typeof hVal === 'object'; + // If hVal is a pure value, place it on `n` so that we interpret it as a scale degree + hVal = isObject ? hVal : { n: hVal }; + const { note, n, value, ...otherValues } = hVal; + const noteOrStep = note ?? n ?? value; + if (noteOrStep === undefined) { + logger( + `[tonal] Invalid value format for 'scale'. Value must contain n, note, or value but received keys [${Object.keys(hVal).join(', ')}]`, + 'error', ); - }) - .outerJoin() - // legacy: - .withHap((hap) => hap.setContext({ ...hap.context, scale })) - ); + return hap; // pass the value through unchanged + } + let scaleNote; + if (isNote(noteOrStep)) { + // Note case (quantize to scale) + scaleNote = _getNearestScaleNote(scale, noteOrStep); + hap.value = { ...otherValues, note: scaleNote }; + } else { + // Step case (convert to note in scale) + try { + const [number, offset] = _convertStepToNumberAndOffset(noteOrStep); + if (otherValues.anchor) { + scaleNote = stepInNamedScale(number, scale, otherValues.anchor); + } else { + scaleNote = scaleStep(number, scale); + } + if (offset != 0) scaleNote = Note.transpose(scaleNote, Interval.fromSemitones(offset)); + } catch (err) { + logger(`[tonal] ${err.message}`, 'error'); + return; // will be removed + } + } + hap.value = isObject ? { ...otherValues, note: scaleNote } : scaleNote; + // Tag with scale for downsteam scale-aware operations + return hap.setContext({ ...hap.context, scale }); + }); + return removeUndefineds(haps); + }); }, true, true, // preserve step count diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index 937d42797..fd0a1bb5d 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -3838,8 +3838,8 @@ exports[`runs examples > example "fast" example index 0 1`] = ` exports[`runs examples > example "fastChunk" example index 0 1`] = ` [ - "[ 0/1 → 1/4 | color:red note:0 ]", - "[ 1/4 → 1/2 | color:red note:1 ]", + "[ 0/1 → 1/4 | note:C2 color:red ]", + "[ 1/4 → 1/2 | note:D2 color:red ]", "[ 1/2 → 3/4 | note:E2 ]", "[ 3/4 → 1/1 | note:F2 ]", "[ 1/1 → 5/4 | note:G2 ]", @@ -3848,8 +3848,8 @@ exports[`runs examples > example "fastChunk" example index 0 1`] = ` "[ 7/4 → 2/1 | note:C3 ]", "[ 2/1 → 9/4 | note:D3 ]", "[ 9/4 → 5/2 | note:D2 ]", - "[ 5/2 → 11/4 | color:red note:2 ]", - "[ 11/4 → 3/1 | color:red note:3 ]", + "[ 5/2 → 11/4 | note:E2 color:red ]", + "[ 11/4 → 3/1 | note:F2 color:red ]", "[ 3/1 → 13/4 | note:G2 ]", "[ 13/4 → 7/2 | note:A2 ]", "[ 7/2 → 15/4 | note:B2 ]", diff --git a/website/src/components/Header/Search.css b/website/src/components/Header/Search.css index b14146cbd..456ef9f6b 100644 --- a/website/src/components/Header/Search.css +++ b/website/src/components/Header/Search.css @@ -18,8 +18,8 @@ --docsearch-modal-background: var(--background); --docsearch-muted-color: color-mix(in srgb, var(--foreground), #fff 30%); --docsearch-key-gradient: var(--foreground); - --docsearch-key-shadow: - inset 0 -2px 0 0 var(--gutterForeground), inset 0 0 1px 1px var(--foreground), 0 1px 2px 1px var(--gutterBackground); + --docsearch-key-shadow: inset 0 -2px 0 0 var(--gutterForeground), inset 0 0 1px 1px var(--foreground), + 0 1px 2px 1px var(--gutterBackground); } .dark { --docsearch-muted-color: color-mix(in srgb, var(--foreground), #000 30%); From 105db2a4ca1c05c4f2dd072209b059676d717042 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sat, 18 Oct 2025 08:49:31 +0200 Subject: [PATCH 282/335] fix: tonal import in autocomplete + add tonal to codemirror package dependencies --- packages/codemirror/autocomplete.mjs | 2 +- packages/codemirror/package.json | 1 + packages/tonal/index.mjs | 4 ++-- pnpm-lock.yaml | 3 +++ 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/codemirror/autocomplete.mjs b/packages/codemirror/autocomplete.mjs index 022c3bbaf..b8a569bea 100644 --- a/packages/codemirror/autocomplete.mjs +++ b/packages/codemirror/autocomplete.mjs @@ -3,7 +3,7 @@ import { autocompletion } from '@codemirror/autocomplete'; import { h } from './html'; import { Scale } from '@tonaljs/tonal'; import { soundMap } from 'superdough'; -import { complex } from '../tonal/ireal.mjs'; +import { complex } from '@strudel/tonal'; const escapeHtml = (str) => { const div = document.createElement('div'); diff --git a/packages/codemirror/package.json b/packages/codemirror/package.json index bb1059f11..b4e7d27a8 100644 --- a/packages/codemirror/package.json +++ b/packages/codemirror/package.json @@ -46,6 +46,7 @@ "@replit/codemirror-vscode-keymap": "^6.0.2", "@strudel/core": "workspace:*", "@strudel/draw": "workspace:*", + "@strudel/tonal": "workspace:*", "@strudel/transpiler": "workspace:*", "@tonaljs/tonal": "^4.10.0", "superdough": "workspace:*", diff --git a/packages/tonal/index.mjs b/packages/tonal/index.mjs index a3c0cba39..ebbcf0851 100644 --- a/packages/tonal/index.mjs +++ b/packages/tonal/index.mjs @@ -1,9 +1,9 @@ import './tonal.mjs'; import './voicings.mjs'; +import './ireal.mjs'; export * from './tonal.mjs'; export * from './voicings.mjs'; - -import './ireal.mjs'; +export * from './ireal.mjs'; export const packageName = '@strudel/tonal'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d67f42d28..055bb4bc7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -212,6 +212,9 @@ importers: '@strudel/draw': specifier: workspace:* version: link:../draw + '@strudel/tonal': + specifier: workspace:* + version: link:../tonal '@strudel/transpiler': specifier: workspace:* version: link:../transpiler From 72423c3a25718c8a26f1ca6350dbc7bf2591d051 Mon Sep 17 00:00:00 2001 From: Aria Date: Sat, 18 Oct 2025 10:41:33 -0500 Subject: [PATCH 283/335] Adds back shape to superdough --- packages/superdough/superdough.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index a37504b1d..36bd68969 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -630,6 +630,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) // effects coarse !== undefined && chain.push(getWorklet(ac, 'coarse-processor', { coarse })); crush !== undefined && chain.push(getWorklet(ac, 'crush-processor', { crush })); + shape !== undefined && chain.push(getWorklet(ac, 'shape-processor', { shape, postgain: shapevol })); distort !== undefined && chain.push(getDistortion(distort, distortvol, distorttype)); if (tremolosync != null) { From c2a5562bad41bea5192e089b040ddc7156f51580 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 20 Oct 2025 21:24:13 +0200 Subject: [PATCH 284/335] add new flavour under replicate --- packages/core/pattern.mjs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index fdf27e9fc..f5b0c676e 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -2995,6 +2995,24 @@ export const drop = stepRegister('drop', function (i, pat) { * ).pace(8) */ export const extend = stepRegister('extend', function (factor, pat) { + return pat.fast(factor).expand(factor); +}); + +/** + * *Experimental* + * + * `replicate` is similar to `fast` in that it increases its density, but it also increases the step count + * accordingly. So `stepcat("a b".replicate(2), "c d")` would be the same as `"a b a b c d"`, whereas + * `stepcat("a b".fast(2), "c d")` would be the same as `"[a b] [a b] c d"`. + * + * TODO: find out how this function differs from extend + * @example + * stepcat( + * sound("bd bd - cp").replicate(2), + * sound("bd - sd -") + * ).pace(8) + */ +export const replicate = stepRegister('replicate', function (factor, pat) { return pat.repeatCycles(factor).fast(factor).expand(factor); }); From 188f0e90984b61bf0275b40da7af6edbb9f77aec Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 20 Oct 2025 21:35:28 +0200 Subject: [PATCH 285/335] snapshot --- test/__snapshots__/examples.test.mjs.snap | 27 +++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index 937d42797..d7e13d4d9 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -8307,6 +8307,33 @@ exports[`runs examples > example "repeatCycles" example index 0 1`] = ` ] `; +exports[`runs examples > example "replicate" example index 0 1`] = ` +[ + "[ 0/1 → 1/8 | s:bd ]", + "[ 1/8 → 1/4 | s:bd ]", + "[ 3/8 → 1/2 | s:cp ]", + "[ 1/2 → 5/8 | s:bd ]", + "[ 5/8 → 3/4 | s:bd ]", + "[ 7/8 → 1/1 | s:cp ]", + "[ 1/1 → 9/8 | s:bd ]", + "[ 5/4 → 11/8 | s:sd ]", + "[ 3/2 → 13/8 | s:bd ]", + "[ 13/8 → 7/4 | s:bd ]", + "[ 15/8 → 2/1 | s:cp ]", + "[ 2/1 → 17/8 | s:bd ]", + "[ 17/8 → 9/4 | s:bd ]", + "[ 19/8 → 5/2 | s:cp ]", + "[ 5/2 → 21/8 | s:bd ]", + "[ 11/4 → 23/8 | s:sd ]", + "[ 3/1 → 25/8 | s:bd ]", + "[ 25/8 → 13/4 | s:bd ]", + "[ 27/8 → 7/2 | s:cp ]", + "[ 7/2 → 29/8 | s:bd ]", + "[ 29/8 → 15/4 | s:bd ]", + "[ 31/8 → 4/1 | s:cp ]", +] +`; + exports[`runs examples > example "reset" example index 0 1`] = ` [ "[ 0/1 → 1/8 | s:hh ]", From 20e5fdedfbce14cb0ce8fd84ccdf0cf35da3875c Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 20 Oct 2025 21:38:43 +0200 Subject: [PATCH 286/335] fix: use replicate for ! in mondo --- packages/mondough/mondough.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/mondough/mondough.mjs b/packages/mondough/mondough.mjs index b7ee83787..e2c6dc9ad 100644 --- a/packages/mondough/mondough.mjs +++ b/packages/mondough/mondough.mjs @@ -5,7 +5,7 @@ import { slow, seq, stepcat, - extend, + replicate, expand, pace, chooseIn, @@ -36,7 +36,7 @@ lib.square = (...args) => stepcat(...args).setSteps(1); lib.angle = (...args) => stepcat(...args).pace(1); lib['*'] = fast; lib['/'] = slow; -lib['!'] = extend; +lib['!'] = replicate; lib['@'] = expand; lib['%'] = pace; lib['?'] = degradeBy; // todo: default 0.5 not working.. From 46af6ed9ef9f91b19ec39005951730d04f2ec40e Mon Sep 17 00:00:00 2001 From: milliganf Date: Mon, 20 Oct 2025 22:30:58 +0200 Subject: [PATCH 287/335] Fix a bug introduced by #4e17cfbdd6 When there's no subpath for a Github path, the URL should end with a '/'. Otherwise when we concatenate values on from a sample map it doesn't separate the base URL from the filename. Signed-off-by: milliganf --- packages/superdough/sampler.mjs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/superdough/sampler.mjs b/packages/superdough/sampler.mjs index 3232fa476..14e6d3fa3 100644 --- a/packages/superdough/sampler.mjs +++ b/packages/superdough/sampler.mjs @@ -129,12 +129,9 @@ function githubPath(base, subpath = '') { let repo = components.length >= 2 ? components[1] : 'samples'; let branch = components.length >= 3 ? components[2] : 'main'; let other = components.slice(3); - if (subpath) { - other.push(subpath); - } other = other.join('/'); - return `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${other}`; + return `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${other}/${subpath}`; } export const processSampleMap = (sampleMap, fn, baseUrl = sampleMap._base || '') => { From 06ea5a36e238e90aae35fd779cce4b9376ea780d Mon Sep 17 00:00:00 2001 From: alex Date: Wed, 22 Oct 2025 10:15:48 +0100 Subject: [PATCH 288/335] Make osc port and host configurable. Changes dependencies. --- packages/core/controls.mjs | 18 ++ packages/osc/osc.mjs | 33 +-- packages/osc/package.json | 3 +- packages/osc/server.js | 111 +++++----- pnpm-lock.yaml | 244 +++++++++++++++++++++- test/__snapshots__/examples.test.mjs.snap | 18 ++ 6 files changed, 343 insertions(+), 84 deletions(-) mode change 100644 => 100755 packages/osc/server.js diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 3475fc2f4..a3ca638aa 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -2320,6 +2320,24 @@ export const { miditouch } = registerControl('miditouch'); // TODO: what is this? export const { polyTouch } = registerControl('polyTouch'); +/** + * The host to send open sound control messages to. Requires running the OSC bridge. + * @name oschost + * @param {string | Pattern} oschost e.g. 'localhost' + * @example + * note("c4").oschost('127.0.0.1').oscport(57120).osc(); + */ +export const { oschost } = registerControl('oschost'); + +/** + * The port to send open sound control messages to. Requires running the OSC bridge. + * @name oscport + * @param {number | Pattern} oscport e.g. 57120 + * @example + * note("c4").oschost('127.0.0.1').oscport(57120).osc(); + */ +export const { oscport } = registerControl('oscport'); + export const getControlName = (alias) => { if (controlAlias.has(alias)) { return controlAlias.get(alias); diff --git a/packages/osc/osc.mjs b/packages/osc/osc.mjs index fe0691522..68caab3a7 100644 --- a/packages/osc/osc.mjs +++ b/packages/osc/osc.mjs @@ -4,8 +4,6 @@ Copyright (C) 2022 Strudel contributors - see . */ -import OSC from 'osc-js'; - import { logger, parseNumeral, register, isNote, noteToMidi, ClockCollator } from '@strudel/core'; let connection; // Promise @@ -13,19 +11,18 @@ function connect() { if (!connection) { // make sure this runs only once connection = new Promise((resolve, reject) => { - const osc = new OSC(); - osc.open(); - osc.on('open', () => { - const url = osc.options?.plugin?.socket?.url; - logger(`[osc] connected${url ? ` to ${url}` : ''}`); - resolve(osc); + const ws = new WebSocket('ws://localhost:8080'); + ws.addEventListener('open', (event) => { + logger(`[osc] websocket connected`); + resolve(ws); }); - osc.on('close', () => { + ws.addEventListener('close', (event) => { + logger(`[osc] websocket closed`); connection = undefined; // allows new connection afterwards console.log('[osc] disconnected'); reject('OSC connection closed'); }); - osc.on('error', (err) => reject(err)); + ws.addEventListener('error', (err) => reject(err)); }).catch((err) => { connection = undefined; throw new Error('Could not connect to OSC server. Is it running?'); @@ -61,15 +58,19 @@ export function parseControlsFromHap(hap, cps) { const collator = new ClockCollator({}); export async function oscTrigger(hap, currentTime, cps = 1, targetTime) { - const osc = await connect(); + const ws = await connect(); const controls = parseControlsFromHap(hap, cps); const keyvals = Object.entries(controls).flat(); + const ts = collator.calculateTimestamp(currentTime, targetTime) * 1000; + const msg = { address: '/dirt/play', args: keyvals, timestamp: ts }; - const ts = Math.round(collator.calculateTimestamp(currentTime, targetTime) * 1000); - const message = new OSC.Message('/dirt/play', ...keyvals); - const bundle = new OSC.Bundle([message], ts); - bundle.timestamp(ts); // workaround for https://github.com/adzialocha/osc-js/issues/60 - osc.send(bundle); + if ('oschost' in hap.value) { + msg['host'] = hap.value['oschost']; + } + if ('oscport' in hap.value) { + msg['port'] = hap.value['oscport']; + } + ws.send(JSON.stringify(msg)); } /** diff --git a/packages/osc/package.json b/packages/osc/package.json index bc828d798..ea453e1eb 100644 --- a/packages/osc/package.json +++ b/packages/osc/package.json @@ -38,7 +38,8 @@ "homepage": "https://codeberg.org/uzu/strudel#readme", "dependencies": { "@strudel/core": "workspace:*", - "osc-js": "^2.4.1" + "osc": "^2.4.5", + "ws": "^8.18.3" }, "devDependencies": { "pkg": "^5.8.1", diff --git a/packages/osc/server.js b/packages/osc/server.js old mode 100644 new mode 100755 index d7ec21c4b..ede35e975 --- a/packages/osc/server.js +++ b/packages/osc/server.js @@ -6,70 +6,59 @@ Copyright (C) 2022 Strudel contributors - see . */ -import OSC from 'osc-js'; +// import OSC from 'osc-js'; -const args = process.argv.slice(2); -function getArgValue(flag) { - const i = args.indexOf(flag); - if (i !== -1) { - const nextIsFlag = args[i + 1]?.startsWith('--') ?? true; - if (nextIsFlag) return true; - return args[i + 1]; - } -} +import { WebSocketServer } from 'ws'; +import osc from 'osc'; -let udpClientPort = Number(getArgValue('--port')) || 57120; -let debug = Number(getArgValue('--debug')) || 0; +const WS_PORT = 8080; // WebSocket server port +const OSC_REMOTE_IP = '127.0.0.1'; +const OSC_REMOTE_PORT = 57120; -const config = { - receiver: 'ws', // @param {string} Where messages sent via 'send' method will be delivered to, 'ws' for Websocket clients, 'udp' for udp client - udpServer: { - host: 'localhost', // @param {string} Hostname of udp server to bind to - port: 57121, // @param {number} Port of udp client for messaging - // enabling the following line will receive tidal messages: - // port: 57120, // @param {number} Port of udp client for messaging - exclusive: false, // @param {boolean} Exclusive flag - }, - udpClient: { - host: 'localhost', // @param {string} Hostname of udp client for messaging - port: udpClientPort, // @param {number} Port of udp client for messaging - }, - wsServer: { - host: 'localhost', // @param {string} Hostname of WebSocket server - port: 8080, // @param {number} Port of WebSocket server - }, -}; - -const osc = new OSC({ plugin: new OSC.BridgePlugin(config) }); - -if (debug) { - osc.on('*', (message) => { - const { address, args } = message; - let str = ''; - for (let i = 0; i < args.length; i += 2) { - str += `${args[i]}: ${args[i + 1]} `; - } - console.log(`${address} ${str}`); - }); -} - -osc.on('error', (message) => { - if (message.toString().includes('EADDRINUSE')) { - console.log(`------ ERROR ------- -a server is already running on port 57121! to stop it: -1. run "lsof -ti :57121 | xargs kill -9" (macos / linux) -2. re-run the osc server -`); - } else { - console.log(message); - } +const udpPort = new osc.UDPPort({ + localAddress: '0.0.0.0', + localPort: 0, + remoteAddress: OSC_REMOTE_IP, + remotePort: OSC_REMOTE_PORT, }); -osc.open(); +udpPort.open(); +console.log(`[Sending OSC] ${OSC_REMOTE_IP}:${OSC_REMOTE_PORT}`); -console.log('osc client running on port', config.udpClient.port); -console.log('osc server running on port', config.udpServer.port); -console.log('websocket server running on port', config.wsServer.port); -if (debug) { - console.log('debug logs enabled. incoming messages will appear below'); -} +udpPort.on('error', (e) => { + console.log('Error: ', e); +}); + +const wss = new WebSocketServer({ port: WS_PORT }); +console.log(`[Listening WS] ws://localhost:${WS_PORT}`); + +wss.on('connection', (ws) => { + console.log('New WebSocket connection'); + + ws.on('message', (message) => { + let osc_host = '127.0.0.1'; + let osc_port = 57120; + + try { + const data = JSON.parse(message); + if ('host' in data) { + osc_host = data['host']; + } + if ('port' in data) { + osc_port = data['port']; + } + let msg = { address: data['address'], args: data['args'] }; + if ('timestamp' in data) { + msg = { timeTag: osc.timeTag(0, data['timestamp']), packets: [msg] }; + } + + udpPort.send(msg, osc_host, osc_port); + } catch (err) { + console.error('Error parsing message:', err); + } + }); + + ws.on('close', () => { + console.log('WebSocket connection closed'); + }); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 055bb4bc7..7b524ebf9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -41,7 +41,7 @@ importers: version: 2.2.7 '@vitest/coverage-v8': specifier: 3.0.4 - version: 3.0.4(vitest@3.0.4) + version: 3.0.4(vitest@3.0.4(@types/debug@4.1.12)(@types/node@22.10.10)(@vitest/ui@3.0.4)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.37.0)(yaml@2.7.0)) '@vitest/ui': specifier: ^3.0.4 version: 3.0.4(vitest@3.0.4) @@ -415,9 +415,12 @@ importers: '@strudel/core': specifier: workspace:* version: link:../core - osc-js: - specifier: ^2.4.1 - version: 2.4.1 + osc: + specifier: ^2.4.5 + version: 2.4.5 + ws: + specifier: ^8.18.3 + version: 8.18.3 devDependencies: pkg: specifier: ^5.8.1 @@ -2429,6 +2432,70 @@ packages: '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + '@serialport/binding-mock@10.2.2': + resolution: {integrity: sha512-HAFzGhk9OuFMpuor7aT5G1ChPgn5qSsklTFOTUX72Rl6p0xwcSVsRtG/xaGp6bxpN7fI9D/S8THLBWbBgS6ldw==} + engines: {node: '>=12.0.0'} + + '@serialport/bindings-cpp@12.0.1': + resolution: {integrity: sha512-r2XOwY2dDvbW7dKqSPIk2gzsr6M6Qpe9+/Ngs94fNaNlcTRCV02PfaoDmRgcubpNVVcLATlxSxPTIDw12dbKOg==} + engines: {node: '>=16.0.0'} + + '@serialport/bindings-interface@1.2.2': + resolution: {integrity: sha512-CJaUd5bLvtM9c5dmO9rPBHPXTa9R2UwpkJ0wdh9JCYcbrPWsKz+ErvR0hBLeo7NPeiFdjFO4sonRljiw4d2XiA==} + engines: {node: ^12.22 || ^14.13 || >=16} + + '@serialport/parser-byte-length@12.0.0': + resolution: {integrity: sha512-0ei0txFAj+s6FTiCJFBJ1T2hpKkX8Md0Pu6dqMrYoirjPskDLJRgZGLqoy3/lnU1bkvHpnJO+9oJ3PB9v8rNlg==} + engines: {node: '>=12.0.0'} + + '@serialport/parser-cctalk@12.0.0': + resolution: {integrity: sha512-0PfLzO9t2X5ufKuBO34DQKLXrCCqS9xz2D0pfuaLNeTkyGUBv426zxoMf3rsMRodDOZNbFblu3Ae84MOQXjnZw==} + engines: {node: '>=12.0.0'} + + '@serialport/parser-delimiter@11.0.0': + resolution: {integrity: sha512-aZLJhlRTjSmEwllLG7S4J8s8ctRAS0cbvCpO87smLvl3e4BgzbVgF6Z6zaJd3Aji2uSiYgfedCdNc4L6W+1E2g==} + engines: {node: '>=12.0.0'} + + '@serialport/parser-delimiter@12.0.0': + resolution: {integrity: sha512-gu26tVt5lQoybhorLTPsH2j2LnX3AOP2x/34+DUSTNaUTzu2fBXw+isVjQJpUBFWu6aeQRZw5bJol5X9Gxjblw==} + engines: {node: '>=12.0.0'} + + '@serialport/parser-inter-byte-timeout@12.0.0': + resolution: {integrity: sha512-GnCh8K0NAESfhCuXAt+FfBRz1Cf9CzIgXfp7SdMgXwrtuUnCC/yuRTUFWRvuzhYKoAo1TL0hhUo77SFHUH1T/w==} + engines: {node: '>=12.0.0'} + + '@serialport/parser-packet-length@12.0.0': + resolution: {integrity: sha512-p1hiCRqvGHHLCN/8ZiPUY/G0zrxd7gtZs251n+cfNTn+87rwcdUeu9Dps3Aadx30/sOGGFL6brIRGK4l/t7MuQ==} + engines: {node: '>=8.6.0'} + + '@serialport/parser-readline@11.0.0': + resolution: {integrity: sha512-rRAivhRkT3YO28WjmmG4FQX6L+KMb5/ikhyylRfzWPw0nSXy97+u07peS9CbHqaNvJkMhH1locp2H36aGMOEIA==} + engines: {node: '>=12.0.0'} + + '@serialport/parser-readline@12.0.0': + resolution: {integrity: sha512-O7cywCWC8PiOMvo/gglEBfAkLjp/SENEML46BXDykfKP5mTPM46XMaX1L0waWU6DXJpBgjaL7+yX6VriVPbN4w==} + engines: {node: '>=12.0.0'} + + '@serialport/parser-ready@12.0.0': + resolution: {integrity: sha512-ygDwj3O4SDpZlbrRUraoXIoIqb8sM7aMKryGjYTIF0JRnKeB1ys8+wIp0RFMdFbO62YriUDextHB5Um5cKFSWg==} + engines: {node: '>=12.0.0'} + + '@serialport/parser-regex@12.0.0': + resolution: {integrity: sha512-dCAVh4P/pZrLcPv9NJ2mvPRBg64L5jXuiRxIlyxxdZGH4WubwXVXY/kBTihQmiAMPxbT3yshSX8f2+feqWsxqA==} + engines: {node: '>=12.0.0'} + + '@serialport/parser-slip-encoder@12.0.0': + resolution: {integrity: sha512-0APxDGR9YvJXTRfY+uRGhzOhTpU5akSH183RUcwzN7QXh8/1jwFsFLCu0grmAUfi+fItCkR+Xr1TcNJLR13VNA==} + engines: {node: '>=12.0.0'} + + '@serialport/parser-spacepacket@12.0.0': + resolution: {integrity: sha512-dozONxhPC/78pntuxpz/NOtVps8qIc/UZzdc/LuPvVsqCoJXiRxOg6ZtCP/W58iibJDKPZPAWPGYeZt9DJxI+Q==} + engines: {node: '>=12.0.0'} + + '@serialport/stream@12.0.0': + resolution: {integrity: sha512-9On64rhzuqKdOQyiYLYv2lQOh3TZU/D3+IWCR5gk0alPel2nwpp4YwDEGiUBfrQZEdQ6xww0PWkzqth4wqwX3Q==} + engines: {node: '>=12.0.0'} + '@shikijs/core@1.29.1': resolution: {integrity: sha512-Mo1gGGkuOYjDu5H8YwzmOuly9vNr8KDVkqj9xiKhhhFS8jisAtDSEWB9hzqRHLVQgFdA310e8XRJcW4tYhRB2A==} @@ -3681,6 +3748,15 @@ packages: supports-color: optional: true + debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + debug@4.4.0: resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} engines: {node: '>=6.0'} @@ -5290,6 +5366,9 @@ packages: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} + long@4.0.0: + resolution: {integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==} + longest-streak@3.1.0: resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} @@ -5673,6 +5752,9 @@ packages: ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -5731,6 +5813,9 @@ packages: resolution: {integrity: sha512-z8iYzQGBu35ZkTQ9mtR8RqugJZ9RCLn8fv3d7LsgDBzOijGQP3RdKTX4LA7LXw03ZhU5z0l4xfhIMgSES31+cg==} engines: {node: '>=10'} + node-addon-api@7.0.0: + resolution: {integrity: sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA==} + node-addon-api@8.3.0: resolution: {integrity: sha512-8VOpLHFrOQlAH+qA0ZzuGRlALRA6/LVh8QJldbrC4DY0hXoMP0l4Acq8TzFC018HztWiRqyCEj2aTWY2UvnJUg==} engines: {node: ^18 || ^20 || >= 21} @@ -5769,6 +5854,10 @@ packages: resolution: {integrity: sha512-yqkmYrMbK1wPrfz7mgeYvA4tBperLg9FQ4S3Sau3nSAkpOA0x0zC8nQ1siBwozy1f4SE8vq2n1WKv99r+PCa1Q==} engines: {node: '>= 0.6.0'} + node-gyp-build@4.6.0: + resolution: {integrity: sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==} + hasBin: true + node-gyp-build@4.8.4: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true @@ -5930,6 +6019,9 @@ packages: osc-js@2.4.1: resolution: {integrity: sha512-QlSeRKJclL47FNvO1MUCAAp9frmCF9zcYbnf6R9HpcklAst8ZyX3ISsk1v/Vghr/5GmXn0bhVjFXF9h+hfnl4Q==} + osc@2.4.5: + resolution: {integrity: sha512-Nc4/qcl+vA/CMxiKS1xrYgzjfnyB3W94gZnrkn3eTzihlndbEml6+wj1YQNKBI4r+qrw3obCcEoU7SVH/OxpxA==} + own-keys@1.0.1: resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} engines: {node: '>= 0.4'} @@ -6689,6 +6781,10 @@ packages: serialize-javascript@4.0.0: resolution: {integrity: sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==} + serialport@12.0.0: + resolution: {integrity: sha512-AmH3D9hHPFmnF/oq/rvigfiAouAKyK/TjnrkwZRYSFZxNggJxwvbAbfYrLeuvq7ktUdhuHdVdSjj852Z55R+uA==} + engines: {node: '>=16.0.0'} + set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} @@ -6776,6 +6872,9 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} + slip@1.0.2: + resolution: {integrity: sha512-XrcHe3NAcyD3wO+O4I13RcS4/3AF+S9RvGNj9JhJeS02HyImwD2E3QWLrmn9hBfL+fB6yapagwxRkeyYzhk98g==} + smart-buffer@4.2.0: resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} @@ -7651,6 +7750,9 @@ packages: resolution: {integrity: sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==} engines: {node: '>=18'} + wolfy87-eventemitter@5.2.9: + resolution: {integrity: sha512-P+6vtWyuDw+MB01X7UeF8TaHBvbCovf4HPEMF/SV7BdDc1SMTiBy13SRD71lQh4ExFTG1d/WNzDGDCyOKSMblw==} + word-wrap@1.2.5: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} @@ -7773,6 +7875,18 @@ packages: utf-8-validate: optional: true + ws@8.18.3: + resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + xmlcreate@2.0.4: resolution: {integrity: sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==} @@ -9769,6 +9883,76 @@ snapshots: '@rtsao/scc@1.1.0': {} + '@serialport/binding-mock@10.2.2': + dependencies: + '@serialport/bindings-interface': 1.2.2 + debug: 4.4.0 + transitivePeerDependencies: + - supports-color + optional: true + + '@serialport/bindings-cpp@12.0.1': + dependencies: + '@serialport/bindings-interface': 1.2.2 + '@serialport/parser-readline': 11.0.0 + debug: 4.3.4 + node-addon-api: 7.0.0 + node-gyp-build: 4.6.0 + transitivePeerDependencies: + - supports-color + optional: true + + '@serialport/bindings-interface@1.2.2': + optional: true + + '@serialport/parser-byte-length@12.0.0': + optional: true + + '@serialport/parser-cctalk@12.0.0': + optional: true + + '@serialport/parser-delimiter@11.0.0': + optional: true + + '@serialport/parser-delimiter@12.0.0': + optional: true + + '@serialport/parser-inter-byte-timeout@12.0.0': + optional: true + + '@serialport/parser-packet-length@12.0.0': + optional: true + + '@serialport/parser-readline@11.0.0': + dependencies: + '@serialport/parser-delimiter': 11.0.0 + optional: true + + '@serialport/parser-readline@12.0.0': + dependencies: + '@serialport/parser-delimiter': 12.0.0 + optional: true + + '@serialport/parser-ready@12.0.0': + optional: true + + '@serialport/parser-regex@12.0.0': + optional: true + + '@serialport/parser-slip-encoder@12.0.0': + optional: true + + '@serialport/parser-spacepacket@12.0.0': + optional: true + + '@serialport/stream@12.0.0': + dependencies: + '@serialport/bindings-interface': 1.2.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + optional: true + '@shikijs/core@1.29.1': dependencies: '@shikijs/engine-javascript': 1.29.1 @@ -10373,7 +10557,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitest/coverage-v8@3.0.4(vitest@3.0.4)': + '@vitest/coverage-v8@3.0.4(vitest@3.0.4(@types/debug@4.1.12)(@types/node@22.10.10)(@vitest/ui@3.0.4)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.37.0)(yaml@2.7.0))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 @@ -11281,6 +11465,11 @@ snapshots: dependencies: ms: 2.1.3 + debug@4.3.4: + dependencies: + ms: 2.1.2 + optional: true + debug@4.4.0: dependencies: ms: 2.1.3 @@ -13150,6 +13339,8 @@ snapshots: chalk: 4.1.2 is-unicode-supported: 0.1.0 + long@4.0.0: {} + longest-streak@3.1.0: {} loupe@3.1.2: {} @@ -13827,6 +14018,9 @@ snapshots: ms@2.0.0: {} + ms@2.1.2: + optional: true + ms@2.1.3: {} multimatch@5.0.0: @@ -13876,6 +14070,9 @@ snapshots: dependencies: semver: 7.6.3 + node-addon-api@7.0.0: + optional: true + node-addon-api@8.3.0: {} node-domexception@1.0.0: {} @@ -13902,6 +14099,9 @@ snapshots: node-getopt@0.3.2: {} + node-gyp-build@4.6.0: + optional: true + node-gyp-build@4.8.4: {} node-gyp@10.3.1: @@ -14153,11 +14353,17 @@ snapshots: os-tmpdir@1.0.2: {} - osc-js@2.4.1: + osc@2.4.5: dependencies: + long: 4.0.0 + slip: 1.0.2 + wolfy87-eventemitter: 5.2.9 ws: 8.18.0 + optionalDependencies: + serialport: 12.0.0 transitivePeerDependencies: - bufferutil + - supports-color - utf-8-validate own-keys@1.0.1: @@ -15052,6 +15258,26 @@ snapshots: dependencies: randombytes: 2.1.0 + serialport@12.0.0: + dependencies: + '@serialport/binding-mock': 10.2.2 + '@serialport/bindings-cpp': 12.0.1 + '@serialport/parser-byte-length': 12.0.0 + '@serialport/parser-cctalk': 12.0.0 + '@serialport/parser-delimiter': 12.0.0 + '@serialport/parser-inter-byte-timeout': 12.0.0 + '@serialport/parser-packet-length': 12.0.0 + '@serialport/parser-readline': 12.0.0 + '@serialport/parser-ready': 12.0.0 + '@serialport/parser-regex': 12.0.0 + '@serialport/parser-slip-encoder': 12.0.0 + '@serialport/parser-spacepacket': 12.0.0 + '@serialport/stream': 12.0.0 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + optional: true + set-blocking@2.0.0: {} set-function-length@1.2.2: @@ -15194,6 +15420,8 @@ snapshots: slash@3.0.0: {} + slip@1.0.2: {} + smart-buffer@4.2.0: {} socks-proxy-agent@8.0.5: @@ -16103,6 +16331,8 @@ snapshots: dependencies: string-width: 7.2.0 + wolfy87-eventemitter@5.2.9: {} + word-wrap@1.2.5: {} wordwrap@0.0.3: {} @@ -16302,6 +16532,8 @@ snapshots: ws@8.18.0: {} + ws@8.18.3: {} + xmlcreate@2.0.4: {} xtend@4.0.2: {} diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index d7e13d4d9..c39bb87bf 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -6958,6 +6958,24 @@ exports[`runs examples > example "orbit" example index 0 1`] = ` ] `; +exports[`runs examples > example "oschost" example index 0 1`] = ` +[ + "[ 0/1 → 1/1 | note:c4 oschost:127.0.0.1 oscport:57120 ]", + "[ 1/1 → 2/1 | note:c4 oschost:127.0.0.1 oscport:57120 ]", + "[ 2/1 → 3/1 | note:c4 oschost:127.0.0.1 oscport:57120 ]", + "[ 3/1 → 4/1 | note:c4 oschost:127.0.0.1 oscport:57120 ]", +] +`; + +exports[`runs examples > example "oscport" example index 0 1`] = ` +[ + "[ 0/1 → 1/1 | note:c4 oschost:127.0.0.1 oscport:57120 ]", + "[ 1/1 → 2/1 | note:c4 oschost:127.0.0.1 oscport:57120 ]", + "[ 2/1 → 3/1 | note:c4 oschost:127.0.0.1 oscport:57120 ]", + "[ 3/1 → 4/1 | note:c4 oschost:127.0.0.1 oscport:57120 ]", +] +`; + exports[`runs examples > example "outside" example index 0 1`] = ` [ "[ 0/1 → 1/1 | note:A3 ]", From f0bd5bffaa5e9b930b38c0d00ecad3a732bb75c9 Mon Sep 17 00:00:00 2001 From: jeromew Date: Wed, 22 Oct 2025 21:39:08 +0200 Subject: [PATCH 289/335] Fix sampler.mjs githubPath PR https://codeberg.org/uzu/strudel/pulls/1679 introduced a subtle bug when both other and subpath are empty. The url should not end with '//' --- packages/superdough/sampler.mjs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/superdough/sampler.mjs b/packages/superdough/sampler.mjs index 14e6d3fa3..8aba9d26d 100644 --- a/packages/superdough/sampler.mjs +++ b/packages/superdough/sampler.mjs @@ -129,9 +129,10 @@ function githubPath(base, subpath = '') { let repo = components.length >= 2 ? components[1] : 'samples'; let branch = components.length >= 3 ? components[2] : 'main'; let other = components.slice(3); + other.push(subpath ? subpath : '') other = other.join('/'); - return `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${other}/${subpath}`; + return `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${other}`; } export const processSampleMap = (sampleMap, fn, baseUrl = sampleMap._base || '') => { From ea91d30ce48ee0d6abc1d92669bb2f19e7e0a0e7 Mon Sep 17 00:00:00 2001 From: jeromew Date: Wed, 22 Oct 2025 21:52:53 +0200 Subject: [PATCH 290/335] Add semicolon --- packages/superdough/sampler.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/superdough/sampler.mjs b/packages/superdough/sampler.mjs index 8aba9d26d..84bac3582 100644 --- a/packages/superdough/sampler.mjs +++ b/packages/superdough/sampler.mjs @@ -129,7 +129,7 @@ function githubPath(base, subpath = '') { let repo = components.length >= 2 ? components[1] : 'samples'; let branch = components.length >= 3 ? components[2] : 'main'; let other = components.slice(3); - other.push(subpath ? subpath : '') + other.push(subpath ? subpath : ''); other = other.join('/'); return `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${other}`; From 8f7b439dce8c40c135e2d0c0bb8672e4804fc591 Mon Sep 17 00:00:00 2001 From: yaxu Date: Thu, 23 Oct 2025 10:39:26 +0200 Subject: [PATCH 291/335] Move deploy location to deploy/strudel.cc --- .forgejo/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.forgejo/workflows/deploy.yml b/.forgejo/workflows/deploy.yml index 561fee658..f4a3ca0f3 100644 --- a/.forgejo/workflows/deploy.yml +++ b/.forgejo/workflows/deploy.yml @@ -34,4 +34,4 @@ jobs: apt update && apt install -y rsync mkdir ~/.ssh ssh-keyscan matrix.toplap.org > ~/.ssh/known_hosts - rsync -atv --delete --delete-after --progress ./website/dist/ strudel@matrix.toplap.org:/home/strudel/deploy \ No newline at end of file + rsync -atv --delete --delete-after --progress ./website/dist/ strudel@matrix.toplap.org:/home/strudel/deploy/strudel.cc \ No newline at end of file From b09230fe903d40f0122e66002c2f00ec55cabfbf Mon Sep 17 00:00:00 2001 From: yaxu Date: Thu, 23 Oct 2025 10:40:08 +0200 Subject: [PATCH 292/335] Update .forgejo/workflows/deploy.yml --- .forgejo/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.forgejo/workflows/deploy.yml b/.forgejo/workflows/deploy.yml index f4a3ca0f3..0643f9be1 100644 --- a/.forgejo/workflows/deploy.yml +++ b/.forgejo/workflows/deploy.yml @@ -1,4 +1,4 @@ -name: Build and Deploy +name: Build and Deploy to live (strudel.cc) on: [workflow_dispatch] From ccb5ec16859073f44edea9635d8dc5a6f5516ca6 Mon Sep 17 00:00:00 2001 From: yaxu Date: Thu, 23 Oct 2025 10:41:29 +0200 Subject: [PATCH 293/335] Add action to deploy 'beta' version to warm.strudel.cc --- .forgejo/workflows/deploy-warm-beta.yml | 37 +++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .forgejo/workflows/deploy-warm-beta.yml diff --git a/.forgejo/workflows/deploy-warm-beta.yml b/.forgejo/workflows/deploy-warm-beta.yml new file mode 100644 index 000000000..2de6670c8 --- /dev/null +++ b/.forgejo/workflows/deploy-warm-beta.yml @@ -0,0 +1,37 @@ +name: Build and Deploy to beta (warm.strudel.cc) + +on: [workflow_dispatch] + +# Allow one concurrent deployment +concurrency: + group: "pages" + cancel-in-progress: true + +jobs: + build: + runs-on: docker + env: + SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + with: + version: 9.12.2 + - uses: actions/setup-node@v4 + with: + node-version: 20 + # cache: "pnpm" + - name: Install Dependencies + run: pnpm install + + - name: Build + run: pnpm build + + - name: Deploy + run: | + eval $(ssh-agent -s) + echo "$SSH_PRIVATE_KEY" | ssh-add - + apt update && apt install -y rsync + mkdir ~/.ssh + ssh-keyscan matrix.toplap.org > ~/.ssh/known_hosts + rsync -atv --delete --delete-after --progress ./website/dist/ strudel@matrix.toplap.org:/home/strudel/deploy/warm.strudel.cc \ No newline at end of file From 39e2221c29fab34bb4fda6532084d6e624ca38fa Mon Sep 17 00:00:00 2001 From: Alex McLean Date: Thu, 23 Oct 2025 15:05:39 +0100 Subject: [PATCH 294/335] add _processParts() --- packages/core/pattern.mjs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index f5b0c676e..ddea674ac 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -62,7 +62,12 @@ export class Pattern { this.__steps = steps === undefined ? undefined : Fraction(steps); } + _processParts() { + return this.withHap((hap) => hap.withContext((c) => ({ ...c, processParts: true }))); + } + setSteps(steps) { + // TODO should this be pure? this._steps = steps; return this; } From 7071dec77598e0cc0cc0da03bde37873b1c129c6 Mon Sep 17 00:00:00 2001 From: yaxu Date: Thu, 23 Oct 2025 16:07:42 +0200 Subject: [PATCH 295/335] revert 39e2221c29fab34bb4fda6532084d6e624ca38fa revert add _processParts() --- packages/core/pattern.mjs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index ddea674ac..f5b0c676e 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -62,12 +62,7 @@ export class Pattern { this.__steps = steps === undefined ? undefined : Fraction(steps); } - _processParts() { - return this.withHap((hap) => hap.withContext((c) => ({ ...c, processParts: true }))); - } - setSteps(steps) { - // TODO should this be pure? this._steps = steps; return this; } From fd0a910bfbcf9127d0f970c8475f445b94082f96 Mon Sep 17 00:00:00 2001 From: Jason Dufair Date: Wed, 22 Oct 2025 19:38:22 -0400 Subject: [PATCH 296/335] Voicings JSDoc --- packages/core/controls.mjs | 53 +++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index a3ca638aa..6f247180d 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -1750,17 +1750,58 @@ export const { semitone } = registerControl('semitone'); // TODO: synth param export const { voice } = registerControl('voice'); // voicings // https://codeberg.org/uzu/strudel/issues/506 -// chord to voice, like C Eb Fm7 G7. the symbols can be defined via addVoicings +/** + * The chord to voice + * @name chord + * @param {string | Pattern} symbols chord symbols to voice e.g., C, Eb, Fm7, G7. The symbols can be defined via addVoicings + * @example + * chord("").voicing() + **/ export const { chord } = registerControl('chord'); -// which dictionary to use for the voicings +/** + * Which dictionary to use for the voicings. This falls back to the default dictionary if not provided + * + * @name dictionary + * @param {string} dictionaryName which dictionary (having been defined with `addVoicings`) to use + * @example + * chord("Am C D F Am E Am E").dict('house').voicing + **/ export const { dictionary, dict } = registerControl('dictionary', 'dict'); -// the top note to align the voicing to, defaults to c5 +/** The top note to align the voicing to. Defaults to c5 + * + * @name anchor + * @param {string | Pattern} anchorNote the note to align the voicings to + * @example + * anchor("").chord("C").voicing() + **/ export const { anchor } = registerControl('anchor'); -// how the voicing is offset from the anchored position +/** + * Sets how the voicing is offset from the anchored position + * + * @name offset + * @param {number | Pattern} shift the amount to shift the voicing up or down + * @example + * chord("").offset("<0 1 2 3 4 5>") // alter the voicing each time + **/ export const { offset } = registerControl('offset'); -// how many octaves are voicing steps spread apart, defaults to 1 +/** + * How many octaves are voicing steps spread apart, defaults to 1 + * + * @name octaves + * @param {number | Pattern} count the number of octaves + * @example + * chord("").octaves("<2 4>").voicing() + **/ export const { octaves } = registerControl('octaves'); -// below = anchor note will be removed from the voicing, useful for melody harmonization +/** + * Remove anchor note from the voicing. Useful for melody harmonization + * + * @name mode + * @param {string | Pattern} modeName one of {below | above | duck | root} + * @example + * mode("").chord("C").voicing() + * + **/ export const { mode } = registerControl(['mode', 'anchor']); /** From a8c613b7eb46df2c3bdfa39b2930434306225cc4 Mon Sep 17 00:00:00 2001 From: Ignacio Ortega Date: Thu, 23 Oct 2025 12:45:44 +0200 Subject: [PATCH 297/335] Refactor sound stopping and triggering logic in SoundsTab component --- .../src/repl/components/panel/SoundsTab.jsx | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/website/src/repl/components/panel/SoundsTab.jsx b/website/src/repl/components/panel/SoundsTab.jsx index 363f6b98a..a9f10bf12 100644 --- a/website/src/repl/components/panel/SoundsTab.jsx +++ b/website/src/repl/components/panel/SoundsTab.jsx @@ -62,11 +62,9 @@ export function SoundsTab() { // stop current sound on mouseup useEvent('mouseup', () => { - const t = trigRef.current; + const ref = trigRef.current; trigRef.current = undefined; - t?.then((ref) => { - ref?.stop(getAudioContext().currentTime + 0.01); - }); + ref?.stop?.(getAudioContext().currentTime + 0.01); }); return (
@@ -124,12 +122,19 @@ export function SoundsTab() { duration: 0.5, }; soundPreviewIdx++; - const time = ctx.currentTime + 0.05; const onended = () => trigRef.current?.node?.disconnect(); - trigRef.current = Promise.resolve(onTrigger(time, params, onended)); - trigRef.current.then((ref) => { - connectToDestination(ref?.node); - }); + try { + // Pre-load the sample by calling onTrigger with a future time + // This triggers the loading but schedules playback for later + const time = ctx.currentTime + 0.5; // Give 500ms for loading + const ref = await onTrigger(time, params, onended); + trigRef.current = ref; + if (ref?.node) { + connectToDestination(ref.node); + } + } catch (err) { + console.warn('Failed to trigger sound:', err); + } }} > {' '} From 20bbda30f8aa9d8d56c9cf65c98dc51ccc78f8a2 Mon Sep 17 00:00:00 2001 From: moumar Date: Thu, 23 Oct 2025 23:15:21 +0200 Subject: [PATCH 298/335] Add setting to toggle pattern auto-start on pattern change --- website/src/repl/components/panel/PatternsTab.jsx | 12 ++++++------ website/src/repl/components/panel/SettingsTab.jsx | 6 ++++++ website/src/settings.mjs | 1 + 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/website/src/repl/components/panel/PatternsTab.jsx b/website/src/repl/components/panel/PatternsTab.jsx index 8e2b75b96..519461442 100644 --- a/website/src/repl/components/panel/PatternsTab.jsx +++ b/website/src/repl/components/panel/PatternsTab.jsx @@ -79,13 +79,11 @@ const updateCodeWindow = (context, patternData, reset = false) => { context.handleUpdate(patternData, reset); }; -const autoResetPatternOnChange = !isUdels(); - function UserPatterns({ context }) { const activePattern = useActivePattern(); const viewingPatternStore = useViewingPatternData(); const viewingPatternData = parseJSON(viewingPatternStore); - const { userPatterns, patternFilter } = useSettings(); + const { userPatterns, patternFilter, patternAutoStart } = useSettings(); const viewingPatternID = viewingPatternData?.id; return (
@@ -139,7 +137,7 @@ function UserPatterns({ context }) { updateCodeWindow( context, { ...userPatterns[id], collection: userPattern.collection }, - autoResetPatternOnChange, + patternAutoStart, ) } patterns={userPatterns} @@ -188,6 +186,7 @@ function FeaturedPatterns({ context }) { const examplePatterns = useExamplePatterns(); const collections = examplePatterns.collections; const patterns = collections.get(patternFilterName.featured); + const { patternAutoStart } = useSettings(); return ( { @@ -213,13 +212,14 @@ function LatestPatterns({ context }) { const examplePatterns = useExamplePatterns(); const collections = examplePatterns.collections; const patterns = collections.get(patternFilterName.public); + const { patternAutoStart } = useSettings(); return ( { - updateCodeWindow(context, { ...patterns[id], collection: patternFilterName.public }, autoResetPatternOnChange); + updateCodeWindow(context, { ...patterns[id], collection: patternFilterName.public }, patternAutoStart); }} paginationOnChange={async (pageNum) => { await loadAndSetPublicPatterns(pageNum - 1); diff --git a/website/src/repl/components/panel/SettingsTab.jsx b/website/src/repl/components/panel/SettingsTab.jsx index 80daef018..c898609d2 100644 --- a/website/src/repl/components/panel/SettingsTab.jsx +++ b/website/src/repl/components/panel/SettingsTab.jsx @@ -112,6 +112,7 @@ export function SettingsTab({ started }) { multiChannelOrbits, isTabIndentationEnabled, isMultiCursorEnabled, + patternAutoStart } = useSettings(); const shouldAlwaysSync = isUdels(); const canChangeAudioDevice = AudioContext.prototype.setSinkId != null; @@ -304,6 +305,11 @@ export function SettingsTab({ started }) { onChange={(cbEvent) => settingsMap.setKey('isCSSAnimationDisabled', cbEvent.target.checked)} value={isCSSAnimationDisabled} /> + settingsMap.setKey('patternAutoStart', cbEvent.target.checked)} + value={patternAutoStart} + /> Try clicking the logo in the top left! diff --git a/website/src/settings.mjs b/website/src/settings.mjs index 9365a6db5..bbf893551 100644 --- a/website/src/settings.mjs +++ b/website/src/settings.mjs @@ -96,6 +96,7 @@ export function useSettings() { isPanelOpen: parseBoolean(state.isPanelOpen), userPatterns: userPatterns, multiChannelOrbits: parseBoolean(state.multiChannelOrbits), + patternAutoStart: isUdels() ? false : parseBoolean(state.patternAutoStart) }; } From 28056deb66583cb9ae0c2c94e3d5538413050924 Mon Sep 17 00:00:00 2001 From: moumar Date: Thu, 23 Oct 2025 23:15:53 +0200 Subject: [PATCH 299/335] Fix ZZFX example ZZFX example did not produce any sound out of the box, fixed by updating tremolo param. --- website/src/pages/learn/synths.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/pages/learn/synths.mdx b/website/src/pages/learn/synths.mdx index 21a9b917e..0fcc41363 100644 --- a/website/src/pages/learn/synths.mdx +++ b/website/src/pages/learn/synths.mdx @@ -157,7 +157,7 @@ It has 20 parameters in total, here is a snippet that uses all: .pitchJump(0) // +/- pitch change after pitchJumpTime .pitchJumpTime(0) // >0 time after pitchJump is applied .lfo(0) // >0 resets slide + pitchJump + sets tremolo speed - .tremolo(0) // 0-1 lfo volume modulation amount + .tremolo(0.5) // 0-1 lfo volume modulation amount //.duration(.2) // overwrite strudel event duration //.gain(1) // change volume ._scope() // vizualise waveform (not zzfx related) From 1a362bd8ea640cfc250832db66255d1b95ff0db7 Mon Sep 17 00:00:00 2001 From: Jason Dufair Date: Fri, 24 Oct 2025 09:19:02 -0400 Subject: [PATCH 300/335] Fix example --- packages/core/controls.mjs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 6f247180d..e317af357 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -1764,7 +1764,13 @@ export const { chord } = registerControl('chord'); * @name dictionary * @param {string} dictionaryName which dictionary (having been defined with `addVoicings`) to use * @example - * chord("Am C D F Am E Am E").dict('house').voicing + * addVoicings('house', { +'': ['7 12 16', '0 7 16', '4 7 12'], +'m': ['0 3 7'] +}) +chord("") +.dict('house').anchor(66) +.voicing().room(.5) **/ export const { dictionary, dict } = registerControl('dictionary', 'dict'); /** The top note to align the voicing to. Defaults to c5 From 6d4787ee33df83f83a8ee54ae7338e4c90702e60 Mon Sep 17 00:00:00 2001 From: Jason Dufair Date: Fri, 24 Oct 2025 09:21:04 -0400 Subject: [PATCH 301/335] Test snapshot --- test/__snapshots__/examples.test.mjs.snap | 123 ++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index c39bb87bf..8ab10e8e0 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -840,6 +840,31 @@ exports[`runs examples > example "amp" example index 0 1`] = ` ] `; +exports[`runs examples > example "anchor" example index 0 1`] = ` +[ + "[ 0/1 → 1/1 | note:E2 ]", + "[ 0/1 → 1/1 | note:C3 ]", + "[ 0/1 → 1/1 | note:E3 ]", + "[ 0/1 → 1/1 | note:G3 ]", + "[ 0/1 → 1/1 | note:C4 ]", + "[ 1/1 → 2/1 | note:C3 ]", + "[ 1/1 → 2/1 | note:G3 ]", + "[ 1/1 → 2/1 | note:C4 ]", + "[ 1/1 → 2/1 | note:E4 ]", + "[ 1/1 → 2/1 | note:G4 ]", + "[ 2/1 → 3/1 | note:E3 ]", + "[ 2/1 → 3/1 | note:C4 ]", + "[ 2/1 → 3/1 | note:E4 ]", + "[ 2/1 → 3/1 | note:G4 ]", + "[ 2/1 → 3/1 | note:C5 ]", + "[ 3/1 → 4/1 | note:C4 ]", + "[ 3/1 → 4/1 | note:G4 ]", + "[ 3/1 → 4/1 | note:C5 ]", + "[ 3/1 → 4/1 | note:E5 ]", + "[ 3/1 → 4/1 | note:G5 ]", +] +`; + exports[`runs examples > example "apply" example index 0 1`] = ` [ "[ 0/1 → 1/1 | note:C3 ]", @@ -1847,6 +1872,31 @@ exports[`runs examples > example "chop" example index 0 1`] = ` ] `; +exports[`runs examples > example "chord" example index 0 1`] = ` +[ + "[ 0/1 → 1/1 | note:A3 ]", + "[ 0/1 → 1/1 | note:C4 ]", + "[ 0/1 → 1/1 | note:E4 ]", + "[ 0/1 → 1/1 | note:A4 ]", + "[ 0/1 → 1/1 | note:C5 ]", + "[ 1/1 → 2/1 | note:E3 ]", + "[ 1/1 → 2/1 | note:C4 ]", + "[ 1/1 → 2/1 | note:E4 ]", + "[ 1/1 → 2/1 | note:G4 ]", + "[ 1/1 → 2/1 | note:C5 ]", + "[ 2/1 → 3/1 | note:D3 ]", + "[ 2/1 → 3/1 | note:A3 ]", + "[ 2/1 → 3/1 | note:D4 ]", + "[ 2/1 → 3/1 | note:Gb4 ]", + "[ 2/1 → 3/1 | note:A4 ]", + "[ 3/1 → 4/1 | note:F3 ]", + "[ 3/1 → 4/1 | note:C4 ]", + "[ 3/1 → 4/1 | note:F4 ]", + "[ 3/1 → 4/1 | note:A4 ]", + "[ 3/1 → 4/1 | note:C5 ]", +] +`; + exports[`runs examples > example "chorus" example index 0 1`] = ` [ "[ 0/1 → 1/4 | note:d s:sawtooth chorus:0.5 ]", @@ -2739,6 +2789,23 @@ exports[`runs examples > example "detune" example index 0 1`] = ` ] `; +exports[`runs examples > example "dictionary" example index 0 1`] = ` +[ + "[ 0/1 → 1/1 | note:A3 room:0.5 ]", + "[ 0/1 → 1/1 | note:C4 room:0.5 ]", + "[ 0/1 → 1/1 | note:E4 room:0.5 ]", + "[ 1/1 → 2/1 | note:G3 room:0.5 ]", + "[ 1/1 → 2/1 | note:C4 room:0.5 ]", + "[ 1/1 → 2/1 | note:E4 room:0.5 ]", + "[ 2/1 → 3/1 | note:A3 room:0.5 ]", + "[ 2/1 → 3/1 | note:D4 room:0.5 ]", + "[ 2/1 → 3/1 | note:Gb4 room:0.5 ]", + "[ 3/1 → 4/1 | note:A3 room:0.5 ]", + "[ 3/1 → 4/1 | note:C4 room:0.5 ]", + "[ 3/1 → 4/1 | note:F4 room:0.5 ]", +] +`; + exports[`runs examples > example "distort" example index 0 1`] = ` [ "[ 0/1 → 1/8 | s:hh distort:0 ]", @@ -6496,6 +6563,28 @@ exports[`runs examples > example "miditouch" example index 0 1`] = ` ] `; +exports[`runs examples > example "mode" example index 0 1`] = ` +[ + "[ 0/1 → 1/1 | note:E3 ]", + "[ 0/1 → 1/1 | note:C4 ]", + "[ 0/1 → 1/1 | note:E4 ]", + "[ 0/1 → 1/1 | note:G4 ]", + "[ 0/1 → 1/1 | note:C5 ]", + "[ 1/1 → 2/1 | note:C5 ]", + "[ 1/1 → 2/1 | note:G5 ]", + "[ 1/1 → 2/1 | note:C6 ]", + "[ 1/1 → 2/1 | note:E6 ]", + "[ 2/1 → 3/1 | note:E3 ]", + "[ 2/1 → 3/1 | note:C4 ]", + "[ 2/1 → 3/1 | note:E4 ]", + "[ 2/1 → 3/1 | note:G4 ]", + "[ 3/1 → 4/1 | note:C5 ]", + "[ 3/1 → 4/1 | note:G5 ]", + "[ 3/1 → 4/1 | note:C6 ]", + "[ 3/1 → 4/1 | note:E6 ]", +] +`; + exports[`runs examples > example "morph" example index 0 1`] = ` [ "[ 0/1 → 1/8 | s:hh ]", @@ -6814,6 +6903,31 @@ exports[`runs examples > example "octave" example index 0 1`] = ` ] `; +exports[`runs examples > example "octaves" example index 0 1`] = ` +[ + "[ 0/1 → 1/1 | note:A3 ]", + "[ 0/1 → 1/1 | note:C4 ]", + "[ 0/1 → 1/1 | note:E4 ]", + "[ 0/1 → 1/1 | note:A4 ]", + "[ 0/1 → 1/1 | note:C5 ]", + "[ 1/1 → 2/1 | note:E3 ]", + "[ 1/1 → 2/1 | note:C4 ]", + "[ 1/1 → 2/1 | note:E4 ]", + "[ 1/1 → 2/1 | note:G4 ]", + "[ 1/1 → 2/1 | note:C5 ]", + "[ 2/1 → 3/1 | note:D3 ]", + "[ 2/1 → 3/1 | note:A3 ]", + "[ 2/1 → 3/1 | note:D4 ]", + "[ 2/1 → 3/1 | note:Gb4 ]", + "[ 2/1 → 3/1 | note:A4 ]", + "[ 3/1 → 4/1 | note:F3 ]", + "[ 3/1 → 4/1 | note:C4 ]", + "[ 3/1 → 4/1 | note:F4 ]", + "[ 3/1 → 4/1 | note:A4 ]", + "[ 3/1 → 4/1 | note:C5 ]", +] +`; + exports[`runs examples > example "off" example index 0 1`] = ` [ "[ -5/24 ⇜ (0/1 → 1/8) | note:62 ]", @@ -6847,6 +6961,15 @@ exports[`runs examples > example "off" example index 0 1`] = ` ] `; +exports[`runs examples > example "offset" example index 0 1`] = ` +[ + "[ 0/1 → 1/1 | chord:Am offset:0 ]", + "[ 1/1 → 2/1 | chord:C offset:1 ]", + "[ 2/1 → 3/1 | chord:D offset:2 ]", + "[ 3/1 → 4/1 | chord:F offset:3 ]", +] +`; + exports[`runs examples > example "often" example index 0 1`] = ` [ "[ 0/1 → 1/8 | s:hh speed:0.5 ]", From fddf2ff2a76eb04f900f187642e6c2e978d97df9 Mon Sep 17 00:00:00 2001 From: moumar Date: Sun, 26 Oct 2025 14:06:31 +0100 Subject: [PATCH 302/335] Set pattern auto-start to true by default --- website/src/settings.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/settings.mjs b/website/src/settings.mjs index bbf893551..ef074b785 100644 --- a/website/src/settings.mjs +++ b/website/src/settings.mjs @@ -96,7 +96,7 @@ export function useSettings() { isPanelOpen: parseBoolean(state.isPanelOpen), userPatterns: userPatterns, multiChannelOrbits: parseBoolean(state.multiChannelOrbits), - patternAutoStart: isUdels() ? false : parseBoolean(state.patternAutoStart) + patternAutoStart: isUdels() ? false : state.patternAutoStart === undefined ? true : parseBoolean(state.patternAutoStart) }; } From fcd83cce5556541c4fcb72e05a2468ef902af157 Mon Sep 17 00:00:00 2001 From: moumar Date: Sun, 26 Oct 2025 14:07:36 +0100 Subject: [PATCH 303/335] Re-evaluate pattern if activated --- website/src/repl/components/panel/PatternsTab.jsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/website/src/repl/components/panel/PatternsTab.jsx b/website/src/repl/components/panel/PatternsTab.jsx index 519461442..38b7294de 100644 --- a/website/src/repl/components/panel/PatternsTab.jsx +++ b/website/src/repl/components/panel/PatternsTab.jsx @@ -133,13 +133,17 @@ function UserPatterns({ context }) {
{/* {patternFilter === patternFilterName.user && ( */} + onClick={(id) => { updateCodeWindow( context, { ...userPatterns[id], collection: userPattern.collection }, patternAutoStart, ) - } + + if (context.started && activePattern === id) { + context.handleEvaluate() + } + }} patterns={userPatterns} started={context.started} activePattern={activePattern} From ee43d85f2983cad68a3dc6ae184560038053bdd4 Mon Sep 17 00:00:00 2001 From: Greg Ervin Date: Sun, 26 Oct 2025 13:31:13 -0500 Subject: [PATCH 304/335] Add stick button mappings to gamepad implementation and improve docs --- packages/gamepad/README.md | 6 ++++++ packages/gamepad/docs/gamepad.mdx | 4 ++++ packages/gamepad/gamepad.mjs | 4 ++++ 3 files changed, 14 insertions(+) diff --git a/packages/gamepad/README.md b/packages/gamepad/README.md index 239353fb7..a84177bc2 100644 --- a/packages/gamepad/README.md +++ b/packages/gamepad/README.md @@ -40,6 +40,12 @@ const pattern = sequence([ - D-Pad - `up`, `down`, `left`, `right` (or `u`, `d`, `l`, `r` or uppercase) - Toggle versions: `tglUp`, `tglDown`, `tglLeft`, `tglRight`(or `tglU`, `tglD`, `tglL`, `tglR`) +- Stick Buttons + - `l3`, `r3` (or `ls`, `rs`) + - Toggle versions: `tglL3`, `tglR3` (or `tglLS`, `tglRS`) +- System Buttons + - `start`, `back` (or uppercase `START`, `BACK`) + - Toggle versions: `tglStart`, `tglBack` (or `tglSTART`, `tglBACK`) ### Analog Sticks - Left Stick diff --git a/packages/gamepad/docs/gamepad.mdx b/packages/gamepad/docs/gamepad.mdx index e2da594ea..5071e3d58 100644 --- a/packages/gamepad/docs/gamepad.mdx +++ b/packages/gamepad/docs/gamepad.mdx @@ -29,6 +29,10 @@ The gamepad module provides access to buttons and analog sticks as normalized si | | Toggle versions: `tglLB`, `tglRB`, `tglLT`, `tglRT` | | D-Pad | `up`, `down`, `left`, `right` (or `u`, `d`, `l`, `r` or uppercase) | | | Toggle versions: `tglUp`, `tglDown`, `tglLeft`, `tglRight` (or `tglU`, `tglD`, `tglL`, `tglR`) | +| Stick Buttons | `l3`, 'r3' (or `ls`, `rs`) | +| | Toggle versions: `tglL3`, 'tglR3' (or `tglLs`, `tglRs`) | +| System Buttons | `start`, `back` (or uppercase `START`, `BACK`) | +| | Toggle versions: `tglStart`, `tglBack` (or `tglSTART`, `tglBACK`) | ### Analog Sticks diff --git a/packages/gamepad/gamepad.mjs b/packages/gamepad/gamepad.mjs index 7667a3620..069c54af1 100644 --- a/packages/gamepad/gamepad.mjs +++ b/packages/gamepad/gamepad.mjs @@ -14,6 +14,10 @@ export const buttonMap = { rt: 7, back: 8, start: 9, + l3: 10, + ls: 10, + r3: 11, + rs: 11, u: 12, up: 12, d: 13, From 5cc93996ce4148c79b43ad514aef4277b29b2240 Mon Sep 17 00:00:00 2001 From: alex Date: Sun, 26 Oct 2025 21:49:10 +0000 Subject: [PATCH 305/335] degithub --- website/src/repl/prebake.mjs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/src/repl/prebake.mjs b/website/src/repl/prebake.mjs index 1fbc84021..6218d72a4 100644 --- a/website/src/repl/prebake.mjs +++ b/website/src/repl/prebake.mjs @@ -23,8 +23,8 @@ export async function prebake() { // https://github.com/sgossner/VCSL/ // https://api.github.com/repositories/126427031/contents/ // LICENSE: CC0 general-purpose - samples(`${baseNoTrailing}/vcsl.json`, 'github:sgossner/VCSL/master/', { prebake: true }), - samples(`${baseNoTrailing}/tidal-drum-machines.json`, 'github:ritchse/tidal-drum-machines/main/machines/', { + samples(`${baseNoTrailing}/vcsl.json`, 'https://strudel.b-cdn.net/VCSL/', { prebake: true }), + samples(`${baseNoTrailing}/tidal-drum-machines.json`, 'https://strudel.b-cdn.net/tidal-drum-machines/machines/', { prebake: true, tag: 'drum-machines', }), @@ -145,7 +145,7 @@ export async function prebake() { 'num/20.wav', ], }, - 'github:tidalcycles/dirt-samples', + 'https://strudel.b-cdn.net/Dirt-Samples/', { prebake: true, }, From 8398385dcd7f9fc488bf334257c4489ed47dfe13 Mon Sep 17 00:00:00 2001 From: alex Date: Sun, 26 Oct 2025 22:18:37 +0000 Subject: [PATCH 306/335] piano via bunnycdn --- website/src/repl/prebake.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/repl/prebake.mjs b/website/src/repl/prebake.mjs index 6218d72a4..b6d2d55f2 100644 --- a/website/src/repl/prebake.mjs +++ b/website/src/repl/prebake.mjs @@ -19,7 +19,7 @@ export async function prebake() { // => getting "window is not defined", as soon as "@strudel/soundfonts" is imported statically // seems to be a problem with soundfont2 import('@strudel/soundfonts').then(({ registerSoundfonts }) => registerSoundfonts()), - samples(`${baseNoTrailing}/piano.json`, undefined, { prebake: true }), + samples(`${baseNoTrailing}/piano.json`, 'https://strudel.b-cdn.net/piano/', { prebake: true }), // https://github.com/sgossner/VCSL/ // https://api.github.com/repositories/126427031/contents/ // LICENSE: CC0 general-purpose From 9ff0449ca35741b7d6cc7c1776c44c38ef897400 Mon Sep 17 00:00:00 2001 From: alex Date: Mon, 27 Oct 2025 09:24:17 +0000 Subject: [PATCH 307/335] use json files in dough-samples via bunny cdn --- website/src/repl/prebake.mjs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/website/src/repl/prebake.mjs b/website/src/repl/prebake.mjs index b6d2d55f2..8a6ccc7e0 100644 --- a/website/src/repl/prebake.mjs +++ b/website/src/repl/prebake.mjs @@ -6,6 +6,7 @@ import './files.mjs'; const { BASE_URL } = import.meta.env; const baseNoTrailing = BASE_URL.endsWith('/') ? BASE_URL.slice(0, -1) : BASE_URL; +const baseCDN = 'https://strudel.b-cdn.net'; export async function prebake() { // https://archive.org/details/SalamanderGrandPianoV3 @@ -19,23 +20,23 @@ export async function prebake() { // => getting "window is not defined", as soon as "@strudel/soundfonts" is imported statically // seems to be a problem with soundfont2 import('@strudel/soundfonts').then(({ registerSoundfonts }) => registerSoundfonts()), - samples(`${baseNoTrailing}/piano.json`, 'https://strudel.b-cdn.net/piano/', { prebake: true }), + samples(`${baseCDN}/piano.json`, `${baseCDN}/piano/`, { prebake: true }), // https://github.com/sgossner/VCSL/ // https://api.github.com/repositories/126427031/contents/ // LICENSE: CC0 general-purpose - samples(`${baseNoTrailing}/vcsl.json`, 'https://strudel.b-cdn.net/VCSL/', { prebake: true }), - samples(`${baseNoTrailing}/tidal-drum-machines.json`, 'https://strudel.b-cdn.net/tidal-drum-machines/machines/', { + samples(`${baseCDN}/vcsl.json`, `${baseCDN}/VCSL/`, { prebake: true }), + samples(`${baseCDN}/tidal-drum-machines.json`, `${baseCDN}/tidal-drum-machines/machines/`, { prebake: true, tag: 'drum-machines', }), - samples(`${baseNoTrailing}/uzu-drumkit.json`, undefined, { + samples(`${baseCDN}/uzu-drumkit.json`, `${baseCDN}/uzu-drumkit/`, { prebake: true, tag: 'drum-machines', }), - samples(`${baseNoTrailing}/uzu-wavetables.json`, undefined, { + samples(`${baseCDN}/uzu-wavetables.json`, `${baseCDN}/uzu-wavetables/`, { prebake: true, }), - samples(`${baseNoTrailing}/mridangam.json`, undefined, { prebake: true, tag: 'drum-machines' }), + samples(`${baseCDN}/mridangam.json`, `${baseCDN}/mrid/`, { prebake: true, tag: 'drum-machines' }), samples( { casio: ['casio/high.wav', 'casio/low.wav', 'casio/noise.wav'], @@ -145,14 +146,14 @@ export async function prebake() { 'num/20.wav', ], }, - 'https://strudel.b-cdn.net/Dirt-Samples/', + `${baseCDN}/Dirt-Samples/`, { prebake: true, }, ), ]); - aliasBank(`${baseNoTrailing}/tidal-drum-machines-alias.json`); + aliasBank(`${baseCDN}/tidal-drum-machines-alias.json`); } const maxPan = noteToMidi('C8'); From cbe7aaacfbf8a51f5f5cf39bf79319f273214e24 Mon Sep 17 00:00:00 2001 From: alex Date: Mon, 27 Oct 2025 15:38:32 +0000 Subject: [PATCH 308/335] Publish - @strudel/codemirror@1.2.6 - @strudel/core@1.2.5 - @strudel/csound@1.2.6 - @strudel/draw@1.2.5 - @strudel/gamepad@1.2.5 - @strudel/hydra@1.2.5 - @strudel/midi@1.2.6 - @strudel/mini@1.2.5 - @strudel/mondo@1.1.5 - @strudel/motion@1.2.5 - @strudel/mqtt@1.2.5 - @strudel/osc@1.3.0 - @strudel/repl@1.2.7 - @strudel/serial@1.2.5 - @strudel/soundfonts@1.2.6 - superdough@1.2.6 - supradough@1.2.4 - @strudel/tonal@1.2.5 - @strudel/transpiler@1.2.5 - @strudel/web@1.2.6 - @strudel/webaudio@1.2.6 - @strudel/xen@1.2.5 --- packages/codemirror/package.json | 6 +++--- packages/core/package.json | 2 +- packages/csound/package.json | 2 +- packages/draw/package.json | 2 +- packages/gamepad/package.json | 2 +- packages/hydra/package.json | 2 +- packages/midi/package.json | 2 +- packages/mini/package.json | 2 +- packages/mondough/package.json | 2 +- packages/motion/package.json | 2 +- packages/mqtt/package.json | 2 +- packages/osc/package.json | 2 +- packages/repl/package.json | 2 +- packages/serial/package.json | 2 +- packages/soundfonts/package.json | 2 +- packages/superdough/package.json | 2 +- packages/supradough/package.json | 5 ++--- packages/tonal/package.json | 2 +- packages/transpiler/package.json | 2 +- packages/web/package.json | 2 +- packages/webaudio/package.json | 2 +- packages/xen/package.json | 2 +- pnpm-lock.yaml | 3 --- 23 files changed, 25 insertions(+), 29 deletions(-) diff --git a/packages/codemirror/package.json b/packages/codemirror/package.json index b4e7d27a8..e54c4a428 100644 --- a/packages/codemirror/package.json +++ b/packages/codemirror/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/codemirror", - "version": "1.2.5", + "version": "1.2.6", "description": "Codemirror Extensions for Strudel", "main": "index.mjs", "publishConfig": { @@ -49,8 +49,8 @@ "@strudel/tonal": "workspace:*", "@strudel/transpiler": "workspace:*", "@tonaljs/tonal": "^4.10.0", - "superdough": "workspace:*", - "nanostores": "^0.11.3" + "nanostores": "^0.11.3", + "superdough": "workspace:*" }, "devDependencies": { "vite": "^6.0.11" diff --git a/packages/core/package.json b/packages/core/package.json index 7cf20cea7..c33432f14 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/core", - "version": "1.2.4", + "version": "1.2.5", "description": "Port of Tidal Cycles to JavaScript", "main": "index.mjs", "type": "module", diff --git a/packages/csound/package.json b/packages/csound/package.json index 90130a101..058b8d774 100644 --- a/packages/csound/package.json +++ b/packages/csound/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/csound", - "version": "1.2.5", + "version": "1.2.6", "description": "csound bindings for strudel", "main": "index.mjs", "type": "module", diff --git a/packages/draw/package.json b/packages/draw/package.json index 6a4c57540..ac2123985 100644 --- a/packages/draw/package.json +++ b/packages/draw/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/draw", - "version": "1.2.4", + "version": "1.2.5", "description": "Helpers for drawing with Strudel", "main": "index.mjs", "type": "module", diff --git a/packages/gamepad/package.json b/packages/gamepad/package.json index 555eac03f..8605e35cd 100644 --- a/packages/gamepad/package.json +++ b/packages/gamepad/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/gamepad", - "version": "1.2.4", + "version": "1.2.5", "description": "Gamepad Inputs for strudel", "main": "index.mjs", "type": "module", diff --git a/packages/hydra/package.json b/packages/hydra/package.json index 7ba79d5d0..eccdde52f 100644 --- a/packages/hydra/package.json +++ b/packages/hydra/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/hydra", - "version": "1.2.4", + "version": "1.2.5", "description": "Hydra integration for strudel", "main": "hydra.mjs", "type": "module", diff --git a/packages/midi/package.json b/packages/midi/package.json index 2342cf7e9..ebb07fc3a 100644 --- a/packages/midi/package.json +++ b/packages/midi/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/midi", - "version": "1.2.5", + "version": "1.2.6", "description": "Midi API for strudel", "main": "index.mjs", "type": "module", diff --git a/packages/mini/package.json b/packages/mini/package.json index 6eeaab0da..05bbd019b 100644 --- a/packages/mini/package.json +++ b/packages/mini/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/mini", - "version": "1.2.4", + "version": "1.2.5", "description": "Mini notation for strudel", "main": "index.mjs", "type": "module", diff --git a/packages/mondough/package.json b/packages/mondough/package.json index c81d76cb6..593d2264a 100644 --- a/packages/mondough/package.json +++ b/packages/mondough/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/mondo", - "version": "1.1.4", + "version": "1.1.5", "description": "mondo notation for strudel", "main": "mondough.mjs", "type": "module", diff --git a/packages/motion/package.json b/packages/motion/package.json index 57cac9cc8..b0a4d5565 100644 --- a/packages/motion/package.json +++ b/packages/motion/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/motion", - "version": "1.2.4", + "version": "1.2.5", "description": "DeviceMotion API for strudel", "main": "index.mjs", "type": "module", diff --git a/packages/mqtt/package.json b/packages/mqtt/package.json index 2e32825fe..1b34a4eae 100644 --- a/packages/mqtt/package.json +++ b/packages/mqtt/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/mqtt", - "version": "1.2.4", + "version": "1.2.5", "description": "MQTT API for strudel", "main": "mqtt.mjs", "type": "module", diff --git a/packages/osc/package.json b/packages/osc/package.json index ea453e1eb..173b76744 100644 --- a/packages/osc/package.json +++ b/packages/osc/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/osc", - "version": "1.2.10", + "version": "1.3.0", "description": "OSC messaging for strudel", "main": "osc.mjs", "bin": "./server.js", diff --git a/packages/repl/package.json b/packages/repl/package.json index 41a165c34..1ad173c61 100644 --- a/packages/repl/package.json +++ b/packages/repl/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/repl", - "version": "1.2.6", + "version": "1.2.7", "description": "Strudel REPL as a Web Component", "module": "index.mjs", "publishConfig": { diff --git a/packages/serial/package.json b/packages/serial/package.json index 9ed89cf2a..d73b05a1c 100644 --- a/packages/serial/package.json +++ b/packages/serial/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/serial", - "version": "1.2.4", + "version": "1.2.5", "description": "Webserial API for strudel", "main": "serial.mjs", "type": "module", diff --git a/packages/soundfonts/package.json b/packages/soundfonts/package.json index 07e35674b..8c41a5d50 100644 --- a/packages/soundfonts/package.json +++ b/packages/soundfonts/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/soundfonts", - "version": "1.2.5", + "version": "1.2.6", "description": "Soundsfont support for strudel", "main": "index.mjs", "publishConfig": { diff --git a/packages/superdough/package.json b/packages/superdough/package.json index a82117774..a95fc5ed0 100644 --- a/packages/superdough/package.json +++ b/packages/superdough/package.json @@ -1,6 +1,6 @@ { "name": "superdough", - "version": "1.2.5", + "version": "1.2.6", "description": "simple web audio synth and sampler intended for live coding. inspired by superdirt and webdirt.", "main": "index.mjs", "type": "module", diff --git a/packages/supradough/package.json b/packages/supradough/package.json index 7e465c0a9..503043718 100644 --- a/packages/supradough/package.json +++ b/packages/supradough/package.json @@ -1,6 +1,6 @@ { "name": "supradough", - "version": "1.2.3", + "version": "1.2.4", "description": "platform agnostic synth and sampler intended for live coding. a reimplementation of superdough.", "main": "index.mjs", "type": "module", @@ -32,6 +32,5 @@ "vite": "^6.0.11", "vite-plugin-bundle-audioworklet": "workspace:*", "wav-encoder": "^1.3.0" - }, - "dependencies": {} + } } diff --git a/packages/tonal/package.json b/packages/tonal/package.json index 1461bdc8e..611df6766 100644 --- a/packages/tonal/package.json +++ b/packages/tonal/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/tonal", - "version": "1.2.4", + "version": "1.2.5", "description": "Tonal functions for strudel", "main": "index.mjs", "publishConfig": { diff --git a/packages/transpiler/package.json b/packages/transpiler/package.json index 18722bdc2..bd28a19f4 100644 --- a/packages/transpiler/package.json +++ b/packages/transpiler/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/transpiler", - "version": "1.2.4", + "version": "1.2.5", "description": "Transpiler for strudel user code. Converts syntactically correct but semantically meaningless JS into evaluatable strudel code.", "main": "index.mjs", "type": "module", diff --git a/packages/web/package.json b/packages/web/package.json index df21f4055..aef044c79 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/web", - "version": "1.2.5", + "version": "1.2.6", "description": "Easy to setup, opiniated bundle of Strudel for the browser.", "module": "web.mjs", "publishConfig": { diff --git a/packages/webaudio/package.json b/packages/webaudio/package.json index 49da00f23..2d5cd420c 100644 --- a/packages/webaudio/package.json +++ b/packages/webaudio/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/webaudio", - "version": "1.2.5", + "version": "1.2.6", "description": "Web Audio helpers for Strudel", "main": "index.mjs", "type": "module", diff --git a/packages/xen/package.json b/packages/xen/package.json index 0a6736d9c..4015c437d 100644 --- a/packages/xen/package.json +++ b/packages/xen/package.json @@ -1,6 +1,6 @@ { "name": "@strudel/xen", - "version": "1.2.4", + "version": "1.2.5", "description": "Xenharmonic API for strudel", "main": "index.mjs", "type": "module", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7b524ebf9..23903fcac 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6016,9 +6016,6 @@ packages: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} - osc-js@2.4.1: - resolution: {integrity: sha512-QlSeRKJclL47FNvO1MUCAAp9frmCF9zcYbnf6R9HpcklAst8ZyX3ISsk1v/Vghr/5GmXn0bhVjFXF9h+hfnl4Q==} - osc@2.4.5: resolution: {integrity: sha512-Nc4/qcl+vA/CMxiKS1xrYgzjfnyB3W94gZnrkn3eTzihlndbEml6+wj1YQNKBI4r+qrw3obCcEoU7SVH/OxpxA==} From 484c5e6cddd7426138da77c32da96f63d8172cbc Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sat, 1 Nov 2025 01:26:25 -0400 Subject: [PATCH 309/335] working --- website/src/repl/idbutils.mjs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/website/src/repl/idbutils.mjs b/website/src/repl/idbutils.mjs index d87d649c2..9dfc9faae 100644 --- a/website/src/repl/idbutils.mjs +++ b/website/src/repl/idbutils.mjs @@ -92,11 +92,7 @@ export function registerSamplesFromDB(config = userSamplesDBConfig, onComplete = async function blobToDataUrl(blob) { return new Promise((resolve) => { - var reader = new FileReader(); - reader.onload = function (event) { - resolve(event.target.result); - }; - reader.readAsDataURL(blob); + resolve(URL.createObjectURL(blob)) }); } From f38792c5699c7f00aedcdfddc80c726dc21810de Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sat, 1 Nov 2025 01:32:24 -0400 Subject: [PATCH 310/335] format --- packages/superdough/sampler.mjs | 1 + website/src/repl/idbutils.mjs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/superdough/sampler.mjs b/packages/superdough/sampler.mjs index 3232fa476..7b7a6d3b6 100644 --- a/packages/superdough/sampler.mjs +++ b/packages/superdough/sampler.mjs @@ -349,6 +349,7 @@ export async function onTriggerSample(t, value, onended, bank, resolveUrl) { } function registerSample(key, bank, params) { + console.info({ key, bank }); registerSound(key, (t, hapValue, onended) => onTriggerSample(t, hapValue, onended, bank), { type: 'sample', samples: bank, diff --git a/website/src/repl/idbutils.mjs b/website/src/repl/idbutils.mjs index 9dfc9faae..e1ca3a604 100644 --- a/website/src/repl/idbutils.mjs +++ b/website/src/repl/idbutils.mjs @@ -92,7 +92,7 @@ export function registerSamplesFromDB(config = userSamplesDBConfig, onComplete = async function blobToDataUrl(blob) { return new Promise((resolve) => { - resolve(URL.createObjectURL(blob)) + resolve(URL.createObjectURL(blob)); }); } From a41b07c67a19fd6361c75b2e251f04dcac9c8a91 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sat, 1 Nov 2025 01:44:32 -0400 Subject: [PATCH 311/335] fixed build --- packages/codemirror/autocomplete.mjs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/packages/codemirror/autocomplete.mjs b/packages/codemirror/autocomplete.mjs index b8a569bea..fd8ff9e29 100644 --- a/packages/codemirror/autocomplete.mjs +++ b/packages/codemirror/autocomplete.mjs @@ -1,8 +1,9 @@ import jsdoc from '../../doc.json'; import { autocompletion } from '@codemirror/autocomplete'; import { h } from './html'; -import { Scale } from '@tonaljs/tonal'; -import { soundMap } from 'superdough'; +//TODO: fix tonal scale import +// import { Scale } from '@tonaljs/tonal'; +import { soundMap } from '@strudel/webaudio'; import { complex } from '@strudel/tonal'; const escapeHtml = (str) => { @@ -90,13 +91,13 @@ export function bankCompletions() { .map((name) => ({ label: name, type: 'bank' })); } -// Attempt to get all scale names from Tonal -let scaleCompletions = []; -try { - scaleCompletions = (Scale.names ? Scale.names() : []).map((name) => ({ label: name, type: 'scale' })); -} catch (e) { - console.warn('[autocomplete] Could not load scale names from Tonal:', e); -} +// Attempt to get all scale names from Tonal TODO: FIX IMPORT +// let scaleCompletions = []; +// try { +// scaleCompletions = (Scale.names ? Scale.names() : []).map((name) => ({ label: name, type: 'scale' })); +// } catch (e) { +// console.warn('[autocomplete] Could not load scale names from Tonal:', e); +// } // Valid mode values for voicing const modeCompletions = [ From 10bfe32a2d7e4f6e81a8b87c5c24d0cd2fb8a94a Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sat, 1 Nov 2025 01:48:42 -0400 Subject: [PATCH 312/335] rm console --- packages/superdough/sampler.mjs | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/superdough/sampler.mjs b/packages/superdough/sampler.mjs index 9cf96d478..84bac3582 100644 --- a/packages/superdough/sampler.mjs +++ b/packages/superdough/sampler.mjs @@ -347,7 +347,6 @@ export async function onTriggerSample(t, value, onended, bank, resolveUrl) { } function registerSample(key, bank, params) { - console.info({ key, bank }); registerSound(key, (t, hapValue, onended) => onTriggerSample(t, hapValue, onended, bank), { type: 'sample', samples: bank, From 7b928749091f204d23810c2b48e187b87479a237 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sat, 1 Nov 2025 01:55:05 -0400 Subject: [PATCH 313/335] fix broken array --- packages/codemirror/autocomplete.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/codemirror/autocomplete.mjs b/packages/codemirror/autocomplete.mjs index fd8ff9e29..0e15a41f7 100644 --- a/packages/codemirror/autocomplete.mjs +++ b/packages/codemirror/autocomplete.mjs @@ -92,7 +92,7 @@ export function bankCompletions() { } // Attempt to get all scale names from Tonal TODO: FIX IMPORT -// let scaleCompletions = []; +let scaleCompletions = []; // try { // scaleCompletions = (Scale.names ? Scale.names() : []).map((name) => ({ label: name, type: 'scale' })); // } catch (e) { From 2b575d50b9af222039aa9c42fa466413cbf8dd17 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sat, 1 Nov 2025 02:39:43 -0400 Subject: [PATCH 314/335] temporarily disable sample autocomplete --- packages/codemirror/autocomplete.mjs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/codemirror/autocomplete.mjs b/packages/codemirror/autocomplete.mjs index 0e15a41f7..9d01f8e9b 100644 --- a/packages/codemirror/autocomplete.mjs +++ b/packages/codemirror/autocomplete.mjs @@ -3,7 +3,8 @@ import { autocompletion } from '@codemirror/autocomplete'; import { h } from './html'; //TODO: fix tonal scale import // import { Scale } from '@tonaljs/tonal'; -import { soundMap } from '@strudel/webaudio'; +// import { soundMap } from '@strudel/webaudio'; +let soundMap = undefined; import { complex } from '@strudel/tonal'; const escapeHtml = (str) => { @@ -80,7 +81,9 @@ const hasExcludedTags = (doc) => ['superdirtOnly', 'noAutocomplete'].some((tag) => doc.tags?.find((t) => t.originalTitle === tag)); export function bankCompletions() { - const soundDict = soundMap.get(); + // TODO: FIX IMPORT + const soundDict = soundMap?.get() ?? {}; + const banks = new Set(); for (const key of Object.keys(soundDict)) { const [bank, suffix] = key.split('_'); @@ -269,7 +272,7 @@ function soundHandler(context) { const inside = text.slice(quoteIdx + 1); const fragMatch = inside.match(SOUND_FRAGMENT_MATCH_REGEX); const fragment = fragMatch ? fragMatch[1] : inside; - const soundNames = Object.keys(soundMap.get()).sort(); + const soundNames = Object.keys(soundMap?.get() ?? {}).sort(); const filteredSounds = soundNames.filter((name) => name.includes(fragment)); let options = filteredSounds.map((name) => ({ label: name, type: 'sound' })); const from = soundContext.to - fragment.length; From 4f046ae88355fb384a1a01d35dd51e2c5fb85457 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sat, 1 Nov 2025 02:40:40 -0400 Subject: [PATCH 315/335] cf --- packages/codemirror/autocomplete.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/codemirror/autocomplete.mjs b/packages/codemirror/autocomplete.mjs index 9d01f8e9b..20c128188 100644 --- a/packages/codemirror/autocomplete.mjs +++ b/packages/codemirror/autocomplete.mjs @@ -83,7 +83,7 @@ const hasExcludedTags = (doc) => export function bankCompletions() { // TODO: FIX IMPORT const soundDict = soundMap?.get() ?? {}; - + const banks = new Set(); for (const key of Object.keys(soundDict)) { const [bank, suffix] = key.split('_'); From 91e1cc136e1169b1864b784cdbb02b8e29e14cb5 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sat, 1 Nov 2025 23:34:10 -0400 Subject: [PATCH 316/335] working --- packages/midi/midi.mjs | 101 +++++++++++++++++++------------- packages/superdough/helpers.mjs | 5 ++ 2 files changed, 64 insertions(+), 42 deletions(-) diff --git a/packages/midi/midi.mjs b/packages/midi/midi.mjs index ae983d200..32f030125 100644 --- a/packages/midi/midi.mjs +++ b/packages/midi/midi.mjs @@ -5,9 +5,10 @@ This program is free software: you can redistribute it and/or modify it under th */ import * as _WebMidi from 'webmidi'; -import { Pattern, getEventOffsetMs, isPattern, logger, ref } from '@strudel/core'; +import { Pattern, isPattern, logger, ref } from '@strudel/core'; import { noteToMidi, getControlName } from '@strudel/core'; import { Note } from 'webmidi'; +import { scheduleAtTime } from '../superdough/helpers.mjs'; // if you use WebMidi from outside of this package, make sure to import that instance: export const { WebMidi } = _WebMidi; @@ -190,7 +191,7 @@ function mapCC(mapping, value) { } // sends a cc message to the given device on the given channel -function sendCC(ccn, ccv, device, midichan, timeOffsetString) { +function sendCC(ccn, ccv, device, midichan, targetTime) { if (typeof ccv !== 'number' || ccv < 0 || ccv > 1) { throw new Error('expected ccv to be a number between 0 and 1'); } @@ -198,19 +199,23 @@ function sendCC(ccn, ccv, device, midichan, timeOffsetString) { throw new Error('expected ccn to be a number or a string'); } const scaled = Math.round(ccv * 127); - device.sendControlChange(ccn, scaled, midichan, { time: timeOffsetString }); + scheduleAtTime(() => { + device.sendControlChange(ccn, scaled, midichan); + }, targetTime); } // sends a program change message to the given device on the given channel -function sendProgramChange(progNum, device, midichan, timeOffsetString) { +function sendProgramChange(progNum, device, midichan, targetTime) { if (typeof progNum !== 'number' || progNum < 0 || progNum > 127) { throw new Error('expected progNum (program change) to be a number between 0 and 127'); } - device.sendProgramChange(progNum, midichan, { time: timeOffsetString }); + scheduleAtTime(() => { + device.sendProgramChange(progNum, midichan); + }, targetTime); } // sends a sysex message to the given device on the given channel -function sendSysex(sysexid, sysexdata, device, timeOffsetString) { +function sendSysex(sysexid, sysexdata, device, targetTime) { if (Array.isArray(sysexid)) { if (!sysexid.every((byte) => Number.isInteger(byte) && byte >= 0 && byte <= 255)) { throw new Error('all sysexid bytes must be integers between 0 and 255'); @@ -225,11 +230,13 @@ function sendSysex(sysexid, sysexdata, device, timeOffsetString) { if (!sysexdata.every((byte) => Number.isInteger(byte) && byte >= 0 && byte <= 255)) { throw new Error('all sysex bytes must be integers between 0 and 255'); } - device.sendSysex(sysexid, sysexdata, { time: timeOffsetString }); + scheduleAtTime(() => { + device.sendSysex(sysexid, sysexdata); + }, targetTime); } // sends a NRPN message to the given device on the given channel -function sendNRPN(nrpnn, nrpv, device, midichan, timeOffsetString) { +function sendNRPN(nrpnn, nrpv, device, midichan, targetTime) { if (Array.isArray(nrpnn)) { if (!nrpnn.every((byte) => Number.isInteger(byte) && byte >= 0 && byte <= 255)) { throw new Error('all nrpnn bytes must be integers between 0 and 255'); @@ -237,28 +244,34 @@ function sendNRPN(nrpnn, nrpv, device, midichan, timeOffsetString) { } else if (!Number.isInteger(nrpv) || nrpv < 0 || nrpv > 255) { throw new Error('A:sysexid must be an number between 0 and 255 or an array of such integers'); } - - device.sendNRPN(nrpnn, nrpv, midichan, { time: timeOffsetString }); + scheduleAtTime(() => { + device.sendNRPN(nrpnn, nrpv, midichan); + }, targetTime); } // sends a pitch bend message to the given device on the given channel -function sendPitchBend(midibend, device, midichan, timeOffsetString) { +function sendPitchBend(midibend, device, midichan, targetTime) { if (typeof midibend !== 'number' || midibend < -1 || midibend > 1) { throw new Error('expected midibend to be a number between -1 and 1'); } - device.sendPitchBend(midibend, midichan, { time: timeOffsetString }); + scheduleAtTime(() => { + device.sendPitchBend(midibend, midichan); + }, targetTime); } // sends a channel aftertouch message to the given device on the given channel -function sendAftertouch(miditouch, device, midichan, timeOffsetString) { +function sendAftertouch(miditouch, device, midichan, targetTime) { if (typeof miditouch !== 'number' || miditouch < 0 || miditouch > 1) { throw new Error('expected miditouch to be a number between 0 and 1'); } - device.sendChannelAftertouch(miditouch, midichan, { time: timeOffsetString }); + + scheduleAtTime(() => { + device.sendChannelAftertouch(miditouch, midichan); + }, targetTime); } // sends a note message to the given device on the given channel -function sendNote(note, velocity, duration, device, midichan, timeOffsetString) { +function sendNote(note, velocity, duration, device, midichan, targetTime) { if (note == null || note === '') { throw new Error('note cannot be null or empty'); } @@ -268,12 +281,12 @@ function sendNote(note, velocity, duration, device, midichan, timeOffsetString) if (duration != null && (typeof duration !== 'number' || duration < 0)) { throw new Error('duration must be a positive number'); } - const midiNumber = typeof note === 'number' ? note : noteToMidi(note); const midiNote = new Note(midiNumber, { attack: velocity, duration }); - device.playNote(midiNote, midichan, { - time: timeOffsetString, - }); + + scheduleAtTime(() => { + device.playNote(midiNote, midichan); + }, targetTime); } /** @@ -309,7 +322,6 @@ Pattern.prototype.midi = function (midiport, options = {}) { let midiConfig = { // Default configuration values isController: false, // Disable sending notes for midi controllers - latencyMs: 34, // Default latency to get audio engine to line up in ms noteOffsetMs: 10, // Default note-off offset to prevent glitching in ms midichannel: 1, // Default MIDI channel velocity: 0.9, // Default velocity @@ -333,18 +345,13 @@ Pattern.prototype.midi = function (midiport, options = {}) { logger(`Midi device disconnected! Available: ${getMidiDeviceNamesString(outputs)}`), }); - return this.onTrigger((hap, currentTime, cps, targetTime) => { + return this.onTrigger((hap, _currentTime, cps, targetTime) => { if (!WebMidi.enabled) { logger('Midi not enabled'); return; } hap.ensureObjectValue(); - //magic number to get audio engine to line up, can probably be calculated somehow - const latencyMs = midiConfig.latencyMs; - // passing a string with a +num into the webmidi api adds an offset to the current time https://webmidijs.org/api/classes/Output - const timeOffsetString = `+${getEventOffsetMs(targetTime, currentTime) + latencyMs}`; - // midi event values from hap with configurable defaults let { note, @@ -380,7 +387,7 @@ Pattern.prototype.midi = function (midiport, options = {}) { // if midimap is set, send a cc messages from defined controls if (midicontrolMap.has(midimap)) { const ccs = mapCC(midicontrolMap.get(midimap), hap.value); - ccs.forEach(({ ccn, ccv }) => sendCC(ccn, ccv, device, midichan, timeOffsetString)); + ccs.forEach(({ ccn, ccv }) => sendCC(ccn, ccv, device, midichan, targetTime)); } else if (midimap !== 'default') { // Add warning when a non-existent midimap is specified logger(`[midi] midimap "${midimap}" not found! Available maps: ${[...midicontrolMap.keys()].join(', ')}`); @@ -392,12 +399,12 @@ Pattern.prototype.midi = function (midiport, options = {}) { // try to prevent glitching by subtracting noteOffsetMs from the duration length const duration = (hap.duration.valueOf() / cps) * 1000 - midiConfig.noteOffsetMs; - sendNote(note, velocity, duration, device, midichan, timeOffsetString); + sendNote(note, velocity, duration, device, midichan, targetTime); } // Handle program change if (progNum !== undefined) { - sendProgramChange(progNum, device, midichan, timeOffsetString); + sendProgramChange(progNum, device, midichan, targetTime); } // Handle sysex @@ -407,53 +414,63 @@ Pattern.prototype.midi = function (midiport, options = {}) { // if sysexid is an array the first byte is 0x00 if (sysexid !== undefined && sysexdata !== undefined) { - sendSysex(sysexid, sysexdata, device, timeOffsetString); + sendSysex(sysexid, sysexdata, device, targetTime); } // Handle control change if (ccv !== undefined && ccn !== undefined) { - sendCC(ccn, ccv, device, midichan, timeOffsetString); + sendCC(ccn, ccv, device, midichan, targetTime); } // Handle NRPN non-registered parameter number if (nrpnn !== undefined && nrpv !== undefined) { - sendNRPN(nrpnn, nrpv, device, midichan, timeOffsetString); + sendNRPN(nrpnn, nrpv, device, midichan, targetTime); } // Handle midibend if (midibend !== undefined) { - sendPitchBend(midibend, device, midichan, timeOffsetString); + sendPitchBend(midibend, device, midichan, targetTime); } // Handle miditouch if (miditouch !== undefined) { - sendAftertouch(miditouch, device, midichan, timeOffsetString); + sendAftertouch(miditouch, device, midichan, targetTime); } // Handle midicmd if (hap.whole.begin + 0 === 0) { // we need to start here because we have the timing info - device.sendStart({ time: timeOffsetString }); + scheduleAtTime(() => { + device.sendStart(); + }, targetTime); } if (['clock', 'midiClock'].includes(midicmd)) { - device.sendClock({ time: timeOffsetString }); + scheduleAtTime(() => { + device.sendClock(); + }, targetTime); } else if (['start'].includes(midicmd)) { - device.sendStart({ time: timeOffsetString }); + scheduleAtTime(() => { + device.sendStart(); + }, targetTime); } else if (['stop'].includes(midicmd)) { - device.sendStop({ time: timeOffsetString }); + scheduleAtTime(() => { + device.sendStop(); + }, targetTime); } else if (['continue'].includes(midicmd)) { - device.sendContinue({ time: timeOffsetString }); + scheduleAtTime(() => { + device.sendContinue(); + }, targetTime); } else if (Array.isArray(midicmd)) { if (midicmd[0] === 'progNum') { - sendProgramChange(midicmd[1], device, midichan, timeOffsetString); + sendProgramChange(midicmd[1], device, midichan, targetTime); } else if (midicmd[0] === 'cc') { if (midicmd.length === 2) { - sendCC(midicmd[0], midicmd[1] / 127, device, midichan, timeOffsetString); + sendCC(midicmd[0], midicmd[1] / 127, device, midichan, targetTime); } } else if (midicmd[0] === 'sysex') { if (midicmd.length === 3) { const [_, id, data] = midicmd; - sendSysex(id, data, device, timeOffsetString); + sendSysex(id, data, device, targetTime); } } } diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index a471da9dd..b06f584a0 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -280,6 +280,11 @@ export function getVibratoOscillator(param, value, t) { return vibratoOscillator; } } + +export function scheduleAtTime(callback, targetTime, audioContext = getAudioContext()) { + const currentTime = audioContext.currentTime; + webAudioTimeout(audioContext, callback, currentTime, targetTime); +} // ConstantSource inherits AudioScheduledSourceNode, which has scheduling abilities // a bit of a hack, but it works very well :) export function webAudioTimeout(audioContext, onComplete, startTime, stopTime) { From bc1c83ed64243831dc6e612c9aa7cf63d52c8a7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dami=C3=A1n=20Silvani?= Date: Sun, 2 Nov 2025 09:21:25 -0300 Subject: [PATCH 317/335] fix: Add missing vite.config.js to supradough package --- packages/supradough/vite.config.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 packages/supradough/vite.config.js diff --git a/packages/supradough/vite.config.js b/packages/supradough/vite.config.js new file mode 100644 index 000000000..deb488e3e --- /dev/null +++ b/packages/supradough/vite.config.js @@ -0,0 +1,16 @@ +import { defineConfig } from 'vite'; +import { resolve } from 'path'; +import bundleAudioWorkletPlugin from 'vite-plugin-bundle-audioworklet'; + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [bundleAudioWorkletPlugin()], + build: { + lib: { + entry: resolve(__dirname, 'index.mjs'), + formats: ['es'], + fileName: (ext) => ({ es: 'index.mjs' })[ext], + }, + target: 'esnext', + }, +}); From 404d9999f30be56d5cf454423dc4200796b9bfab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dami=C3=A1n=20Silvani?= Date: Sun, 2 Nov 2025 09:21:40 -0300 Subject: [PATCH 318/335] fix: Update github.com links --- packages/supradough/package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/supradough/package.json b/packages/supradough/package.json index 503043718..7611a9b58 100644 --- a/packages/supradough/package.json +++ b/packages/supradough/package.json @@ -13,7 +13,7 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/tidalcycles/strudel.git" + "url": "git+https://codeberg.org/uzu/strudel.git" }, "keywords": [ "tidalcycles", @@ -25,9 +25,9 @@ "author": "Felix Roos ", "license": "AGPL-3.0-or-later", "bugs": { - "url": "https://github.com/tidalcycles/strudel/issues" + "url": "https://codeberg.org/uzu/strudel/issues" }, - "homepage": "https://github.com/tidalcycles/strudel#readme", + "homepage": "https://codeberg.org/uzu/strudel#readme", "devDependencies": { "vite": "^6.0.11", "vite-plugin-bundle-audioworklet": "workspace:*", From 809eb7132c43cb4ea6e7c22511f9d314bd403498 Mon Sep 17 00:00:00 2001 From: moumar Date: Sun, 2 Nov 2025 15:20:31 +0100 Subject: [PATCH 319/335] codeformat --- website/src/repl/components/panel/PatternsTab.jsx | 14 +++----------- website/src/repl/components/panel/SettingsTab.jsx | 2 +- website/src/settings.mjs | 6 +++++- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/website/src/repl/components/panel/PatternsTab.jsx b/website/src/repl/components/panel/PatternsTab.jsx index 38b7294de..5e0d50e72 100644 --- a/website/src/repl/components/panel/PatternsTab.jsx +++ b/website/src/repl/components/panel/PatternsTab.jsx @@ -134,14 +134,10 @@ function UserPatterns({ context }) { {/* {patternFilter === patternFilterName.user && ( */} { - updateCodeWindow( - context, - { ...userPatterns[id], collection: userPattern.collection }, - patternAutoStart, - ) + updateCodeWindow(context, { ...userPatterns[id], collection: userPattern.collection }, patternAutoStart); if (context.started && activePattern === id) { - context.handleEvaluate() + context.handleEvaluate(); } }} patterns={userPatterns} @@ -197,11 +193,7 @@ function FeaturedPatterns({ context }) { context={context} initialPage={featuredPageNum} patternOnClick={(id) => { - updateCodeWindow( - context, - { ...patterns[id], collection: patternFilterName.featured }, - patternAutoStart, - ); + updateCodeWindow(context, { ...patterns[id], collection: patternFilterName.featured }, patternAutoStart); }} paginationOnChange={async (pageNum) => { await loadAndSetFeaturedPatterns(pageNum - 1); diff --git a/website/src/repl/components/panel/SettingsTab.jsx b/website/src/repl/components/panel/SettingsTab.jsx index c898609d2..85991f55c 100644 --- a/website/src/repl/components/panel/SettingsTab.jsx +++ b/website/src/repl/components/panel/SettingsTab.jsx @@ -112,7 +112,7 @@ export function SettingsTab({ started }) { multiChannelOrbits, isTabIndentationEnabled, isMultiCursorEnabled, - patternAutoStart + patternAutoStart, } = useSettings(); const shouldAlwaysSync = isUdels(); const canChangeAudioDevice = AudioContext.prototype.setSinkId != null; diff --git a/website/src/settings.mjs b/website/src/settings.mjs index ef074b785..7c62b0ded 100644 --- a/website/src/settings.mjs +++ b/website/src/settings.mjs @@ -96,7 +96,11 @@ export function useSettings() { isPanelOpen: parseBoolean(state.isPanelOpen), userPatterns: userPatterns, multiChannelOrbits: parseBoolean(state.multiChannelOrbits), - patternAutoStart: isUdels() ? false : state.patternAutoStart === undefined ? true : parseBoolean(state.patternAutoStart) + patternAutoStart: isUdels() + ? false + : state.patternAutoStart === undefined + ? true + : parseBoolean(state.patternAutoStart), }; } From 4df2cc30867b5ad4c4cf602028654768c8d4b3b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C5=BD=C3=A1ra?= Date: Mon, 3 Nov 2025 22:03:39 +0100 Subject: [PATCH 320/335] added docs for spaces in scale names --- packages/tonal/tonal.mjs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/tonal/tonal.mjs b/packages/tonal/tonal.mjs index 0dc468b20..427a66f4c 100644 --- a/packages/tonal/tonal.mjs +++ b/packages/tonal/tonal.mjs @@ -229,6 +229,9 @@ function _getNearestScaleNote(scaleName, note, preferHigher = true) { * * A scale consists of a root note (e.g. `c4`, `c`, `f#`, `bb4`) followed by semicolon (':') and then a [scale type](https://github.com/tonaljs/tonal/blob/main/packages/scale-type/data.ts). * + * The scale name must be written without spaces (because it would be interpreted as a multi-step pattern otherwise). + * If your scale name includes spaces, replace them with colons. + * * The root note defaults to octave 3, if no octave number is given. * * @name scale @@ -250,6 +253,8 @@ function _getNearestScaleNote(scaleName, note, preferHigher = true) { * .s("piano") * @example * note("C1*16").transpose(irand(36)).scale('Cb2 major').scaleTranspose(3) + * @example + * n("[0 0] [1 2] [3 4] [5 6]").scale("C:major:blues") */ export const scale = register( 'scale', From 247bf9b930a265a7e654f87a8f93a5b1eab10db7 Mon Sep 17 00:00:00 2001 From: Alex Victoria Date: Tue, 4 Nov 2025 20:36:25 -0600 Subject: [PATCH 321/335] fix for node 24 support #1718 --- .nvmrc | 1 + README.md | 2 +- examples/codemirror-repl/package.json | 3 + examples/headless-repl/package.json | 3 + examples/minimal-repl/package.json | 3 + examples/superdough/package.json | 3 + examples/tidal-repl/package.json | 3 + package.json | 5 +- packages/codemirror/package.json | 3 + packages/core/package.json | 3 + packages/csound/package.json | 3 + packages/desktopbridge/package.json | 5 +- packages/draw/package.json | 3 + packages/embed/package.json | 5 +- packages/gamepad/package.json | 3 + packages/hs2js/package.json | 3 + packages/hydra/package.json | 3 + packages/midi/package.json | 3 + packages/mini/package.json | 3 + packages/mondo/package.json | 3 + packages/mondough/package.json | 3 + packages/motion/package.json | 3 + packages/mqtt/package.json | 3 + packages/osc/package.json | 3 + packages/reference/package.json | 3 + packages/repl/package.json | 3 + packages/sampler/package.json | 3 + packages/serial/package.json | 3 + packages/soundfonts/package.json | 3 + packages/superdough/package.json | 3 + packages/supradough/package.json | 3 + packages/tidal/package.json | 3 + packages/tonal/package.json | 3 + packages/transpiler/package.json | 3 + .../package.json | 3 + packages/web/package.json | 3 + packages/webaudio/package.json | 3 + packages/xen/package.json | 3 + test/__snapshots__/tunes.test.mjs.snap | 12672 ++++++++-------- test/tunes.test.mjs | 16 +- tools/dbpatch/package.json | 3 + website/package.json | 3 + 42 files changed, 6470 insertions(+), 6341 deletions(-) create mode 100644 .nvmrc diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 000000000..2bd5a0a98 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +22 diff --git a/README.md b/README.md index baaac82b2..779769d57 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ https://strudel.cc/ After cloning the project, you can run the REPL locally: -1. Install [Node.js](https://nodejs.org/) +1. Install [Node.js](https://nodejs.org/) 18 or newer 2. Install [pnpm](https://pnpm.io/installation) 3. Install dependencies by running the following command: ```bash diff --git a/examples/codemirror-repl/package.json b/examples/codemirror-repl/package.json index e0ce35b8a..0a65eb71c 100644 --- a/examples/codemirror-repl/package.json +++ b/examples/codemirror-repl/package.json @@ -20,5 +20,8 @@ "@strudel/tonal": "workspace:*", "@strudel/transpiler": "workspace:*", "@strudel/webaudio": "workspace:*" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/examples/headless-repl/package.json b/examples/headless-repl/package.json index 0a2941797..b3e62971c 100644 --- a/examples/headless-repl/package.json +++ b/examples/headless-repl/package.json @@ -14,5 +14,8 @@ }, "dependencies": { "@strudel/web": "workspace:*" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/examples/minimal-repl/package.json b/examples/minimal-repl/package.json index 8f904c61c..a2e37123e 100644 --- a/examples/minimal-repl/package.json +++ b/examples/minimal-repl/package.json @@ -18,5 +18,8 @@ "@strudel/transpiler": "workspace:*", "@strudel/webaudio": "workspace:*", "@strudel/tonal": "workspace:*" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/examples/superdough/package.json b/examples/superdough/package.json index eb5d8e9fd..aaa021c1d 100644 --- a/examples/superdough/package.json +++ b/examples/superdough/package.json @@ -13,5 +13,8 @@ }, "devDependencies": { "vite": "^6.0.11" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/examples/tidal-repl/package.json b/examples/tidal-repl/package.json index 21c8ee177..5b18c6de1 100644 --- a/examples/tidal-repl/package.json +++ b/examples/tidal-repl/package.json @@ -32,5 +32,8 @@ }, "devDependencies": { "vite": "^6.0.11" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/package.json b/package.json index d18291eb2..b74c85753 100644 --- a/package.json +++ b/package.json @@ -73,5 +73,8 @@ "prettier": "^3.4.2", "vitest": "^3.0.4", "vite-plugin-bundle-audioworklet": "workspace:*" + }, + "engines": { + "node": ">=18.0.0" } -} \ No newline at end of file +} diff --git a/packages/codemirror/package.json b/packages/codemirror/package.json index e54c4a428..a3735491f 100644 --- a/packages/codemirror/package.json +++ b/packages/codemirror/package.json @@ -54,5 +54,8 @@ }, "devDependencies": { "vite": "^6.0.11" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/packages/core/package.json b/packages/core/package.json index c33432f14..fa0761039 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -37,5 +37,8 @@ "devDependencies": { "vite": "^6.0.11", "vitest": "^3.0.4" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/packages/csound/package.json b/packages/csound/package.json index 058b8d774..762131d65 100644 --- a/packages/csound/package.json +++ b/packages/csound/package.json @@ -38,5 +38,8 @@ }, "devDependencies": { "vite": "^6.0.11" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/packages/desktopbridge/package.json b/packages/desktopbridge/package.json index a01ec1f8a..a7352d6b0 100644 --- a/packages/desktopbridge/package.json +++ b/packages/desktopbridge/package.json @@ -25,5 +25,8 @@ "@strudel/core": "workspace:*", "@tauri-apps/api": "^2.2.0" }, - "homepage": "https://codeberg.org/uzu/strudel#readme" + "homepage": "https://codeberg.org/uzu/strudel#readme", + "engines": { + "node": ">=18.0.0" + } } diff --git a/packages/draw/package.json b/packages/draw/package.json index ac2123985..b0af8418b 100644 --- a/packages/draw/package.json +++ b/packages/draw/package.json @@ -33,5 +33,8 @@ }, "devDependencies": { "vite": "^6.0.11" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/packages/embed/package.json b/packages/embed/package.json index 6a00ee904..ffafdc8bc 100644 --- a/packages/embed/package.json +++ b/packages/embed/package.json @@ -20,5 +20,8 @@ "bugs": { "url": "https://codeberg.org/uzu/strudel/issues" }, - "homepage": "https://codeberg.org/uzu/strudel#readme" + "homepage": "https://codeberg.org/uzu/strudel#readme", + "engines": { + "node": ">=18.0.0" + } } diff --git a/packages/gamepad/package.json b/packages/gamepad/package.json index 8605e35cd..6a07df968 100644 --- a/packages/gamepad/package.json +++ b/packages/gamepad/package.json @@ -33,5 +33,8 @@ }, "devDependencies": { "vite": "^6.0.11" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/packages/hs2js/package.json b/packages/hs2js/package.json index c0bf8fa8c..e8d698601 100644 --- a/packages/hs2js/package.json +++ b/packages/hs2js/package.json @@ -34,5 +34,8 @@ "devDependencies": { "tree-sitter-haskell": "^0.23.1", "vite": "^6.0.11" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/packages/hydra/package.json b/packages/hydra/package.json index eccdde52f..16d6f0f4c 100644 --- a/packages/hydra/package.json +++ b/packages/hydra/package.json @@ -40,5 +40,8 @@ "devDependencies": { "pkg": "^5.8.1", "vite": "^6.0.11" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/packages/midi/package.json b/packages/midi/package.json index ebb07fc3a..11fe9a3f7 100644 --- a/packages/midi/package.json +++ b/packages/midi/package.json @@ -35,5 +35,8 @@ }, "devDependencies": { "vite": "^6.0.11" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/packages/mini/package.json b/packages/mini/package.json index 05bbd019b..b9a50fb60 100644 --- a/packages/mini/package.json +++ b/packages/mini/package.json @@ -38,5 +38,8 @@ "peggy": "^4.2.0", "vite": "^6.0.11", "vitest": "^3.0.4" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/packages/mondo/package.json b/packages/mondo/package.json index a59bfc344..ebdbd329a 100644 --- a/packages/mondo/package.json +++ b/packages/mondo/package.json @@ -33,5 +33,8 @@ "devDependencies": { "vite": "^6.0.11", "vitest": "^3.0.4" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/packages/mondough/package.json b/packages/mondough/package.json index 593d2264a..9b170fde5 100644 --- a/packages/mondough/package.json +++ b/packages/mondough/package.json @@ -40,5 +40,8 @@ "mondo": "*", "vite": "^6.0.11", "vitest": "^3.0.4" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/packages/motion/package.json b/packages/motion/package.json index b0a4d5565..fd1fae890 100644 --- a/packages/motion/package.json +++ b/packages/motion/package.json @@ -33,5 +33,8 @@ }, "devDependencies": { "vite": "^6.0.11" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/packages/mqtt/package.json b/packages/mqtt/package.json index 1b34a4eae..492d915d5 100644 --- a/packages/mqtt/package.json +++ b/packages/mqtt/package.json @@ -34,5 +34,8 @@ }, "devDependencies": { "vite": "^6.0.11" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/packages/osc/package.json b/packages/osc/package.json index 173b76744..00faffbd0 100644 --- a/packages/osc/package.json +++ b/packages/osc/package.json @@ -44,5 +44,8 @@ "devDependencies": { "pkg": "^5.8.1", "vite": "^6.0.11" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/packages/reference/package.json b/packages/reference/package.json index 634057e4c..6d1fa1807 100644 --- a/packages/reference/package.json +++ b/packages/reference/package.json @@ -33,5 +33,8 @@ "homepage": "https://codeberg.org/uzu/strudel#readme", "devDependencies": { "vite": "^6.0.11" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/packages/repl/package.json b/packages/repl/package.json index 1ad173c61..e5216316e 100644 --- a/packages/repl/package.json +++ b/packages/repl/package.json @@ -48,5 +48,8 @@ "@rollup/plugin-replace": "^6.0.2", "vite": "^6.0.11", "vite-plugin-bundle-audioworklet": "workspace:*" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/packages/sampler/package.json b/packages/sampler/package.json index 2bf0607b1..b9ea4c2a1 100644 --- a/packages/sampler/package.json +++ b/packages/sampler/package.json @@ -15,5 +15,8 @@ "type": "module", "dependencies": { "cowsay": "^1.6.0" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/packages/serial/package.json b/packages/serial/package.json index d73b05a1c..9dc6c8999 100644 --- a/packages/serial/package.json +++ b/packages/serial/package.json @@ -33,5 +33,8 @@ }, "devDependencies": { "vite": "^6.0.11" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/packages/soundfonts/package.json b/packages/soundfonts/package.json index 8c41a5d50..9bf0c4006 100644 --- a/packages/soundfonts/package.json +++ b/packages/soundfonts/package.json @@ -37,5 +37,8 @@ "devDependencies": { "node-fetch": "^3.3.2", "vite": "^6.0.11" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/packages/superdough/package.json b/packages/superdough/package.json index a95fc5ed0..36201297a 100644 --- a/packages/superdough/package.json +++ b/packages/superdough/package.json @@ -37,5 +37,8 @@ }, "dependencies": { "nanostores": "^0.11.3" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/packages/supradough/package.json b/packages/supradough/package.json index 503043718..87d4a56c3 100644 --- a/packages/supradough/package.json +++ b/packages/supradough/package.json @@ -32,5 +32,8 @@ "vite": "^6.0.11", "vite-plugin-bundle-audioworklet": "workspace:*", "wav-encoder": "^1.3.0" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/packages/tidal/package.json b/packages/tidal/package.json index 960b09001..bd299b397 100644 --- a/packages/tidal/package.json +++ b/packages/tidal/package.json @@ -25,5 +25,8 @@ }, "devDependencies": { "vite": "^6.0.11" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/packages/tonal/package.json b/packages/tonal/package.json index 611df6766..14ffabc7b 100644 --- a/packages/tonal/package.json +++ b/packages/tonal/package.json @@ -38,5 +38,8 @@ "devDependencies": { "vite": "^6.0.11", "vitest": "^3.0.4" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/packages/transpiler/package.json b/packages/transpiler/package.json index bd28a19f4..513550442 100644 --- a/packages/transpiler/package.json +++ b/packages/transpiler/package.json @@ -39,5 +39,8 @@ "devDependencies": { "vite": "^6.0.11", "vitest": "^3.0.4" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/packages/vite-plugin-bundle-audioworklet/package.json b/packages/vite-plugin-bundle-audioworklet/package.json index f803ae065..198a4f9cf 100644 --- a/packages/vite-plugin-bundle-audioworklet/package.json +++ b/packages/vite-plugin-bundle-audioworklet/package.json @@ -12,5 +12,8 @@ "type": "module", "devDependencies": { "vite": "^6.0.11" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/packages/web/package.json b/packages/web/package.json index aef044c79..f02d86139 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -43,5 +43,8 @@ "@rollup/plugin-replace": "^6.0.2", "vite": "^6.0.11", "vite-plugin-bundle-audioworklet": "workspace:*" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/packages/webaudio/package.json b/packages/webaudio/package.json index 2d5cd420c..f0bc4043f 100644 --- a/packages/webaudio/package.json +++ b/packages/webaudio/package.json @@ -40,5 +40,8 @@ }, "devDependencies": { "vite": "^6.0.11" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/packages/xen/package.json b/packages/xen/package.json index 4015c437d..c178c5de4 100644 --- a/packages/xen/package.json +++ b/packages/xen/package.json @@ -35,5 +35,8 @@ "devDependencies": { "vite": "^6.0.11", "vitest": "^3.0.4" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/test/__snapshots__/tunes.test.mjs.snap b/test/__snapshots__/tunes.test.mjs.snap index 4a0ddd539..fc77616c4 100644 --- a/test/__snapshots__/tunes.test.mjs.snap +++ b/test/__snapshots__/tunes.test.mjs.snap @@ -7,12 +7,12 @@ exports[`renders tunes > tune: amensister 1`] = ` "[ 1/16 → 1/8 | s:breath room:1 shape:0.6 begin:0.875 end:0.9375 ]", "[ 1/8 → 3/16 | s:breath room:1 shape:0.6 begin:0.8125 end:0.875 ]", "[ 1/8 → 1/4 | n:0 s:amencutup room:0.5 ]", - "[ 1/8 → 1/4 | note:G1 s:sawtooth gain:0.4 decay:0.1 sustain:0 lpattack:0.1 lpenv:-4 resonance:10 cutoff:300.0522648640107 ]", - "[ 1/8 → 1/4 | note:G1 s:sawtooth gain:0.4 decay:0.1 sustain:0 lpattack:0.1 lpenv:-4 resonance:10 cutoff:300.0522648640107 ]", + "[ 1/8 → 1/4 | note:G1 s:sawtooth gain:0.4 decay:0.1 sustain:0 lpattack:0.1 lpenv:-4 resonance:10 cutoff:300.052264864011 ]", + "[ 1/8 → 1/4 | note:G1 s:sawtooth gain:0.4 decay:0.1 sustain:0 lpattack:0.1 lpenv:-4 resonance:10 cutoff:300.052264864011 ]", "[ 3/16 → 1/4 | s:breath room:1 shape:0.6 begin:0.75 end:0.8125 ]", "[ 1/4 → 5/16 | s:breath room:1 shape:0.6 begin:0.6875 end:0.75 ]", - "[ 1/4 → 3/8 | note:A1 s:sawtooth gain:0.4 decay:0.1 sustain:0 lpattack:0.1 lpenv:-4 resonance:10 cutoff:300.4082736884894 ]", - "[ 1/4 → 3/8 | note:A1 s:sawtooth gain:0.4 decay:0.1 sustain:0 lpattack:0.1 lpenv:-4 resonance:10 cutoff:300.4082736884894 ]", + "[ 1/4 → 3/8 | note:A1 s:sawtooth gain:0.4 decay:0.1 sustain:0 lpattack:0.1 lpenv:-4 resonance:10 cutoff:300.408273688489 ]", + "[ 1/4 → 3/8 | note:A1 s:sawtooth gain:0.4 decay:0.1 sustain:0 lpattack:0.1 lpenv:-4 resonance:10 cutoff:300.408273688489 ]", "[ 1/4 → 1/2 | n:1 s:amencutup room:0.5 ]", "[ 5/16 → 3/8 | s:breath room:1 shape:0.6 begin:0.625 end:0.6875 ]", "[ 3/8 → 7/16 | s:breath room:1 shape:0.6 begin:0.5625 end:0.625 ]", @@ -27,231 +27,231 @@ exports[`renders tunes > tune: amensister 1`] = ` "[ 11/16 → 3/4 | s:breath room:1 shape:0.6 begin:0.25 end:0.3125 ]", "[ 3/4 → 13/16 | s:breath room:1 shape:0.6 begin:0.1875 end:0.25 ]", "[ 3/4 → 7/8 | n:3 s:amencutup room:0.5 ]", - "[ 3/4 → 7/8 | note:34 s:sawtooth gain:0.4 decay:0.1 sustain:0 lpattack:0.1 lpenv:-4 resonance:10 cutoff:309.9939679933326 ]", - "[ 3/4 → 7/8 | note:34 s:sawtooth gain:0.4 decay:0.1 sustain:0 lpattack:0.1 lpenv:-4 resonance:10 cutoff:309.9939679933326 ]", + "[ 3/4 → 7/8 | note:34 s:sawtooth gain:0.4 decay:0.1 sustain:0 lpattack:0.1 lpenv:-4 resonance:10 cutoff:309.993967993333 ]", + "[ 3/4 → 7/8 | note:34 s:sawtooth gain:0.4 decay:0.1 sustain:0 lpattack:0.1 lpenv:-4 resonance:10 cutoff:309.993967993333 ]", "[ 13/16 → 7/8 | s:breath room:1 shape:0.6 begin:0.125 end:0.1875 ]", "[ 7/8 → 15/16 | s:breath room:1 shape:0.6 begin:0.0625 end:0.125 ]", "[ 7/8 → 1/1 | n:3 delay:0.5 s:amencutup room:0.5 ]", - "[ 7/8 → 1/1 | note:C1 s:sawtooth gain:0.4 decay:0.1 sustain:0 lpattack:0.1 lpenv:-4 resonance:10 cutoff:315.47482330436543 ]", - "[ 7/8 → 1/1 | note:C1 s:sawtooth gain:0.4 decay:0.1 sustain:0 lpattack:0.1 lpenv:-4 resonance:10 cutoff:315.47482330436543 ]", + "[ 7/8 → 1/1 | note:C1 s:sawtooth gain:0.4 decay:0.1 sustain:0 lpattack:0.1 lpenv:-4 resonance:10 cutoff:315.474823304365 ]", + "[ 7/8 → 1/1 | note:C1 s:sawtooth gain:0.4 decay:0.1 sustain:0 lpattack:0.1 lpenv:-4 resonance:10 cutoff:315.474823304365 ]", "[ 15/16 → 1/1 | s:breath room:1 shape:0.6 begin:0 end:0.0625 ]", ] `; exports[`renders tunes > tune: arpoon 1`] = ` [ - "[ (0/1 → 1/4) ⇝ 1/3 | note:55 clip:2 cutoff:500 resonance:12 gain:0.5 decay:0.16 sustain:0.5 delay:0.2 room:0.5 pan:0.44999999999999996 s:piano ]", - "[ (0/1 → 1/4) ⇝ 1/3 | note:64 clip:2 cutoff:500 resonance:12 gain:0.5 decay:0.16 sustain:0.5 delay:0.2 room:0.5 pan:0.44999999999999996 s:piano ]", + "[ (0/1 → 1/4) ⇝ 1/3 | note:55 clip:2 cutoff:500 resonance:12 gain:0.5 decay:0.16 sustain:0.5 delay:0.2 room:0.5 pan:0.45 s:piano ]", + "[ (0/1 → 1/4) ⇝ 1/3 | note:64 clip:2 cutoff:500 resonance:12 gain:0.5 decay:0.16 sustain:0.5 delay:0.2 room:0.5 pan:0.45 s:piano ]", "[ 0/1 → 1/2 | s:bd bank:RolandTR909 gain:0.5 ]", "[ 0/1 → 1/1 | note:33 s:sawtooth cutoff:180 lpattack:0.1 lpenv:2 ]", "[ 0/1 → 1/1 | note:33.12 s:sawtooth cutoff:180 lpattack:0.1 lpenv:2 ]", - "[ 0/1 ⇜ (1/4 → 1/3) | note:55 clip:2 cutoff:500 resonance:12 gain:0.8 decay:0.16 sustain:0.5 delay:0.2 room:0.5 pan:0.44999999999999996 s:piano ]", - "[ 0/1 ⇜ (1/4 → 1/3) | note:64 clip:2 cutoff:500 resonance:12 gain:0.8 decay:0.16 sustain:0.5 delay:0.2 room:0.5 pan:0.44999999999999996 s:piano ]", - "[ (1/3 → 1/2) ⇝ 2/3 | note:60.00052866221468 clip:2 cutoff:509.2515887569149 resonance:12 gain:0.8 decay:0.16 sustain:0.5 delay:0.2 room:0.5 pan:0.5249999999999999 s:piano ]", - "[ 1/3 ⇜ (1/2 → 2/3) | note:60.00052866221468 clip:2 cutoff:509.2515887569149 resonance:12 gain:0.5 decay:0.16 sustain:0.5 delay:0.2 room:0.5 pan:0.5249999999999999 s:piano ]", + "[ 0/1 ⇜ (1/4 → 1/3) | note:55 clip:2 cutoff:500 resonance:12 gain:0.8 decay:0.16 sustain:0.5 delay:0.2 room:0.5 pan:0.45 s:piano ]", + "[ 0/1 ⇜ (1/4 → 1/3) | note:64 clip:2 cutoff:500 resonance:12 gain:0.8 decay:0.16 sustain:0.5 delay:0.2 room:0.5 pan:0.45 s:piano ]", + "[ (1/3 → 1/2) ⇝ 2/3 | note:60.000528662215 clip:2 cutoff:509.251588756915 resonance:12 gain:0.8 decay:0.16 sustain:0.5 delay:0.2 room:0.5 pan:0.525 s:piano ]", + "[ 1/3 ⇜ (1/2 → 2/3) | note:60.000528662215 clip:2 cutoff:509.251588756915 resonance:12 gain:0.5 decay:0.16 sustain:0.5 delay:0.2 room:0.5 pan:0.525 s:piano ]", "[ 1/2 → 2/3 | s:hh bank:RolandTR909 gain:0.5 ]", "[ 1/2 → 1/1 | s:bd bank:RolandTR909 gain:0.5 ]", - "[ (2/3 → 3/4) ⇝ 1/1 | note:59.003688107962134 clip:2 cutoff:564.5418893373399 resonance:12 gain:0.5 decay:0.16 sustain:0.5 delay:0.2 room:0.5 pan:0.5799038105676657 s:piano ]", - "[ (2/3 → 3/4) ⇝ 1/1 | note:64.00368810796213 clip:2 cutoff:564.5418893373399 resonance:12 gain:0.5 decay:0.16 sustain:0.5 delay:0.2 room:0.5 pan:0.5799038105676657 s:piano ]", - "[ 2/3 ⇜ (3/4 → 1/1) | note:59.003688107962134 clip:2 cutoff:564.5418893373399 resonance:12 gain:0.8 decay:0.16 sustain:0.5 delay:0.2 room:0.5 pan:0.5799038105676657 s:piano ]", - "[ 2/3 ⇜ (3/4 → 1/1) | note:64.00368810796213 clip:2 cutoff:564.5418893373399 resonance:12 gain:0.8 decay:0.16 sustain:0.5 delay:0.2 room:0.5 pan:0.5799038105676657 s:piano ]", + "[ (2/3 → 3/4) ⇝ 1/1 | note:59.003688107962 clip:2 cutoff:564.54188933734 resonance:12 gain:0.5 decay:0.16 sustain:0.5 delay:0.2 room:0.5 pan:0.579903810568 s:piano ]", + "[ (2/3 → 3/4) ⇝ 1/1 | note:64.003688107962 clip:2 cutoff:564.54188933734 resonance:12 gain:0.5 decay:0.16 sustain:0.5 delay:0.2 room:0.5 pan:0.579903810568 s:piano ]", + "[ 2/3 ⇜ (3/4 → 1/1) | note:59.003688107962 clip:2 cutoff:564.54188933734 resonance:12 gain:0.8 decay:0.16 sustain:0.5 delay:0.2 room:0.5 pan:0.579903810568 s:piano ]", + "[ 2/3 ⇜ (3/4 → 1/1) | note:64.003688107962 clip:2 cutoff:564.54188933734 resonance:12 gain:0.8 decay:0.16 sustain:0.5 delay:0.2 room:0.5 pan:0.579903810568 s:piano ]", ] `; exports[`renders tunes > tune: barryHarris 1`] = ` [ - "[ 0/1 → 1/1 | note:B3 clip:1 s:piano release:0.1 pan:0.5231481481481481 color:#00B8D4 ]", - "[ (0/1 → 1/1) ⇝ 2/1 | note:C3 clip:1 s:piano release:0.1 pan:0.4722222222222222 color:#00B8D4 ]", - "[ (0/1 → 1/1) ⇝ 2/1 | note:E3 clip:1 s:piano release:0.1 pan:0.4907407407407407 color:#00B8D4 ]", - "[ 0/1 ⇜ (1/1 → 2/1) | note:C3 clip:1 s:piano release:0.1 pan:0.4722222222222222 color:#00B8D4 ]", - "[ 0/1 ⇜ (1/1 → 2/1) | note:E3 clip:1 s:piano release:0.1 pan:0.4907407407407407 color:#00B8D4 ]", - "[ 1/1 → 2/1 | note:A3 clip:1 s:piano release:0.1 pan:0.5138888888888888 color:#00B8D4 ]", - "[ 2/1 → 3/1 | note:C4 clip:1 s:piano release:0.1 pan:0.5277777777777778 color:#00B8D4 ]", - "[ (2/1 → 3/1) ⇝ 4/1 | note:D3 clip:1 s:piano release:0.1 pan:0.4814814814814815 color:#00B8D4 ]", - "[ (2/1 → 3/1) ⇝ 4/1 | note:F3 clip:1 s:piano release:0.1 pan:0.49537037037037035 color:#00B8D4 ]", - "[ 2/1 ⇜ (3/1 → 4/1) | note:D3 clip:1 s:piano release:0.1 pan:0.4814814814814815 color:#00B8D4 ]", - "[ 2/1 ⇜ (3/1 → 4/1) | note:F3 clip:1 s:piano release:0.1 pan:0.49537037037037035 color:#00B8D4 ]", - "[ 3/1 → 4/1 | note:B3 clip:1 s:piano release:0.1 pan:0.5231481481481481 color:#00B8D4 ]", - "[ 4/1 → 5/1 | note:D4 clip:1 s:piano release:0.1 pan:0.537037037037037 color:#00B8D4 ]", - "[ (4/1 → 5/1) ⇝ 6/1 | note:E3 clip:1 s:piano release:0.1 pan:0.4907407407407407 color:#00B8D4 ]", - "[ (4/1 → 5/1) ⇝ 6/1 | note:G3 clip:1 s:piano release:0.1 pan:0.5046296296296297 color:#00B8D4 ]", - "[ 4/1 ⇜ (5/1 → 6/1) | note:E3 clip:1 s:piano release:0.1 pan:0.4907407407407407 color:#00B8D4 ]", - "[ 4/1 ⇜ (5/1 → 6/1) | note:G3 clip:1 s:piano release:0.1 pan:0.5046296296296297 color:#00B8D4 ]", - "[ 5/1 → 6/1 | note:C4 clip:1 s:piano release:0.1 pan:0.5277777777777778 color:#00B8D4 ]", - "[ 6/1 → 7/1 | note:E4 clip:1 s:piano release:0.1 pan:0.5462962962962963 color:#00B8D4 ]", - "[ (6/1 → 7/1) ⇝ 8/1 | note:F3 clip:1 s:piano release:0.1 pan:0.49537037037037035 color:#00B8D4 ]", - "[ (6/1 → 7/1) ⇝ 8/1 | note:G#3 clip:1 s:piano release:0.1 pan:0.5092592592592593 color:#00B8D4 ]", - "[ 6/1 ⇜ (7/1 → 8/1) | note:F3 clip:1 s:piano release:0.1 pan:0.49537037037037035 color:#00B8D4 ]", - "[ 6/1 ⇜ (7/1 → 8/1) | note:G#3 clip:1 s:piano release:0.1 pan:0.5092592592592593 color:#00B8D4 ]", - "[ 7/1 → 8/1 | note:D4 clip:1 s:piano release:0.1 pan:0.537037037037037 color:#00B8D4 ]", - "[ 8/1 → 9/1 | note:F4 clip:1 s:piano release:0.1 pan:0.5509259259259259 color:#00B8D4 ]", - "[ (8/1 → 9/1) ⇝ 10/1 | note:G3 clip:1 s:piano release:0.1 pan:0.5046296296296297 color:#00B8D4 ]", - "[ (8/1 → 9/1) ⇝ 10/1 | note:A3 clip:1 s:piano release:0.1 pan:0.5138888888888888 color:#00B8D4 ]", - "[ 8/1 ⇜ (9/1 → 10/1) | note:G3 clip:1 s:piano release:0.1 pan:0.5046296296296297 color:#00B8D4 ]", - "[ 8/1 ⇜ (9/1 → 10/1) | note:A3 clip:1 s:piano release:0.1 pan:0.5138888888888888 color:#00B8D4 ]", - "[ 9/1 → 10/1 | note:E4 clip:1 s:piano release:0.1 pan:0.5462962962962963 color:#00B8D4 ]", - "[ 10/1 → 11/1 | note:G4 clip:1 s:piano release:0.1 pan:0.5601851851851851 color:#00B8D4 ]", - "[ (10/1 → 11/1) ⇝ 12/1 | note:G#3 clip:1 s:piano release:0.1 pan:0.5092592592592593 color:#00B8D4 ]", - "[ (10/1 → 11/1) ⇝ 12/1 | note:B3 clip:1 s:piano release:0.1 pan:0.5231481481481481 color:#00B8D4 ]", - "[ 10/1 ⇜ (11/1 → 12/1) | note:G#3 clip:1 s:piano release:0.1 pan:0.5092592592592593 color:#00B8D4 ]", - "[ 10/1 ⇜ (11/1 → 12/1) | note:B3 clip:1 s:piano release:0.1 pan:0.5231481481481481 color:#00B8D4 ]", - "[ 11/1 → 12/1 | note:F4 clip:1 s:piano release:0.1 pan:0.5509259259259259 color:#00B8D4 ]", - "[ 12/1 → 13/1 | note:A4 clip:1 s:piano release:0.1 pan:0.5694444444444444 color:#00B8D4 ]", - "[ (12/1 → 13/1) ⇝ 14/1 | note:B3 clip:1 s:piano release:0.1 pan:0.5231481481481481 color:#00B8D4 ]", - "[ (12/1 → 13/1) ⇝ 14/1 | note:D4 clip:1 s:piano release:0.1 pan:0.537037037037037 color:#00B8D4 ]", - "[ 12/1 ⇜ (13/1 → 14/1) | note:B3 clip:1 s:piano release:0.1 pan:0.5231481481481481 color:#00B8D4 ]", - "[ 12/1 ⇜ (13/1 → 14/1) | note:D4 clip:1 s:piano release:0.1 pan:0.537037037037037 color:#00B8D4 ]", - "[ 13/1 → 14/1 | note:G#4 clip:1 s:piano release:0.1 pan:0.5648148148148149 color:#00B8D4 ]", - "[ 14/1 → 15/1 | note:B4 clip:1 s:piano release:0.1 pan:0.5787037037037037 color:#00B8D4 ]", - "[ (14/1 → 15/1) ⇝ 16/1 | note:C4 clip:1 s:piano release:0.1 pan:0.5277777777777778 color:#00B8D4 ]", - "[ (14/1 → 15/1) ⇝ 16/1 | note:E4 clip:1 s:piano release:0.1 pan:0.5462962962962963 color:#00B8D4 ]", - "[ 14/1 ⇜ (15/1 → 16/1) | note:C4 clip:1 s:piano release:0.1 pan:0.5277777777777778 color:#00B8D4 ]", - "[ 14/1 ⇜ (15/1 → 16/1) | note:E4 clip:1 s:piano release:0.1 pan:0.5462962962962963 color:#00B8D4 ]", - "[ 15/1 → 16/1 | note:A4 clip:1 s:piano release:0.1 pan:0.5694444444444444 color:#00B8D4 ]", - "[ 16/1 → 17/1 | note:C4 clip:1 s:piano release:0.1 pan:0.5277777777777778 color:#00B8D4 ]", - "[ (16/1 → 17/1) ⇝ 18/1 | note:Db3 clip:1 s:piano release:0.1 pan:0.47685185185185186 color:#00B8D4 ]", - "[ (16/1 → 17/1) ⇝ 18/1 | note:F3 clip:1 s:piano release:0.1 pan:0.49537037037037035 color:#00B8D4 ]", - "[ 16/1 ⇜ (17/1 → 18/1) | note:Db3 clip:1 s:piano release:0.1 pan:0.47685185185185186 color:#00B8D4 ]", - "[ 16/1 ⇜ (17/1 → 18/1) | note:F3 clip:1 s:piano release:0.1 pan:0.49537037037037035 color:#00B8D4 ]", - "[ 17/1 → 18/1 | note:Bb3 clip:1 s:piano release:0.1 pan:0.5185185185185186 color:#00B8D4 ]", - "[ 18/1 → 19/1 | note:Db4 clip:1 s:piano release:0.1 pan:0.5324074074074074 color:#00B8D4 ]", - "[ (18/1 → 19/1) ⇝ 20/1 | note:Eb3 clip:1 s:piano release:0.1 pan:0.4861111111111111 color:#00B8D4 ]", + "[ 0/1 → 1/1 | note:B3 clip:1 s:piano release:0.1 pan:0.523148148148 color:#00B8D4 ]", + "[ (0/1 → 1/1) ⇝ 2/1 | note:C3 clip:1 s:piano release:0.1 pan:0.472222222222 color:#00B8D4 ]", + "[ (0/1 → 1/1) ⇝ 2/1 | note:E3 clip:1 s:piano release:0.1 pan:0.490740740741 color:#00B8D4 ]", + "[ 0/1 ⇜ (1/1 → 2/1) | note:C3 clip:1 s:piano release:0.1 pan:0.472222222222 color:#00B8D4 ]", + "[ 0/1 ⇜ (1/1 → 2/1) | note:E3 clip:1 s:piano release:0.1 pan:0.490740740741 color:#00B8D4 ]", + "[ 1/1 → 2/1 | note:A3 clip:1 s:piano release:0.1 pan:0.513888888889 color:#00B8D4 ]", + "[ 2/1 → 3/1 | note:C4 clip:1 s:piano release:0.1 pan:0.527777777778 color:#00B8D4 ]", + "[ (2/1 → 3/1) ⇝ 4/1 | note:D3 clip:1 s:piano release:0.1 pan:0.481481481481 color:#00B8D4 ]", + "[ (2/1 → 3/1) ⇝ 4/1 | note:F3 clip:1 s:piano release:0.1 pan:0.49537037037 color:#00B8D4 ]", + "[ 2/1 ⇜ (3/1 → 4/1) | note:D3 clip:1 s:piano release:0.1 pan:0.481481481481 color:#00B8D4 ]", + "[ 2/1 ⇜ (3/1 → 4/1) | note:F3 clip:1 s:piano release:0.1 pan:0.49537037037 color:#00B8D4 ]", + "[ 3/1 → 4/1 | note:B3 clip:1 s:piano release:0.1 pan:0.523148148148 color:#00B8D4 ]", + "[ 4/1 → 5/1 | note:D4 clip:1 s:piano release:0.1 pan:0.537037037037 color:#00B8D4 ]", + "[ (4/1 → 5/1) ⇝ 6/1 | note:E3 clip:1 s:piano release:0.1 pan:0.490740740741 color:#00B8D4 ]", + "[ (4/1 → 5/1) ⇝ 6/1 | note:G3 clip:1 s:piano release:0.1 pan:0.50462962963 color:#00B8D4 ]", + "[ 4/1 ⇜ (5/1 → 6/1) | note:E3 clip:1 s:piano release:0.1 pan:0.490740740741 color:#00B8D4 ]", + "[ 4/1 ⇜ (5/1 → 6/1) | note:G3 clip:1 s:piano release:0.1 pan:0.50462962963 color:#00B8D4 ]", + "[ 5/1 → 6/1 | note:C4 clip:1 s:piano release:0.1 pan:0.527777777778 color:#00B8D4 ]", + "[ 6/1 → 7/1 | note:E4 clip:1 s:piano release:0.1 pan:0.546296296296 color:#00B8D4 ]", + "[ (6/1 → 7/1) ⇝ 8/1 | note:F3 clip:1 s:piano release:0.1 pan:0.49537037037 color:#00B8D4 ]", + "[ (6/1 → 7/1) ⇝ 8/1 | note:G#3 clip:1 s:piano release:0.1 pan:0.509259259259 color:#00B8D4 ]", + "[ 6/1 ⇜ (7/1 → 8/1) | note:F3 clip:1 s:piano release:0.1 pan:0.49537037037 color:#00B8D4 ]", + "[ 6/1 ⇜ (7/1 → 8/1) | note:G#3 clip:1 s:piano release:0.1 pan:0.509259259259 color:#00B8D4 ]", + "[ 7/1 → 8/1 | note:D4 clip:1 s:piano release:0.1 pan:0.537037037037 color:#00B8D4 ]", + "[ 8/1 → 9/1 | note:F4 clip:1 s:piano release:0.1 pan:0.550925925926 color:#00B8D4 ]", + "[ (8/1 → 9/1) ⇝ 10/1 | note:G3 clip:1 s:piano release:0.1 pan:0.50462962963 color:#00B8D4 ]", + "[ (8/1 → 9/1) ⇝ 10/1 | note:A3 clip:1 s:piano release:0.1 pan:0.513888888889 color:#00B8D4 ]", + "[ 8/1 ⇜ (9/1 → 10/1) | note:G3 clip:1 s:piano release:0.1 pan:0.50462962963 color:#00B8D4 ]", + "[ 8/1 ⇜ (9/1 → 10/1) | note:A3 clip:1 s:piano release:0.1 pan:0.513888888889 color:#00B8D4 ]", + "[ 9/1 → 10/1 | note:E4 clip:1 s:piano release:0.1 pan:0.546296296296 color:#00B8D4 ]", + "[ 10/1 → 11/1 | note:G4 clip:1 s:piano release:0.1 pan:0.560185185185 color:#00B8D4 ]", + "[ (10/1 → 11/1) ⇝ 12/1 | note:G#3 clip:1 s:piano release:0.1 pan:0.509259259259 color:#00B8D4 ]", + "[ (10/1 → 11/1) ⇝ 12/1 | note:B3 clip:1 s:piano release:0.1 pan:0.523148148148 color:#00B8D4 ]", + "[ 10/1 ⇜ (11/1 → 12/1) | note:G#3 clip:1 s:piano release:0.1 pan:0.509259259259 color:#00B8D4 ]", + "[ 10/1 ⇜ (11/1 → 12/1) | note:B3 clip:1 s:piano release:0.1 pan:0.523148148148 color:#00B8D4 ]", + "[ 11/1 → 12/1 | note:F4 clip:1 s:piano release:0.1 pan:0.550925925926 color:#00B8D4 ]", + "[ 12/1 → 13/1 | note:A4 clip:1 s:piano release:0.1 pan:0.569444444444 color:#00B8D4 ]", + "[ (12/1 → 13/1) ⇝ 14/1 | note:B3 clip:1 s:piano release:0.1 pan:0.523148148148 color:#00B8D4 ]", + "[ (12/1 → 13/1) ⇝ 14/1 | note:D4 clip:1 s:piano release:0.1 pan:0.537037037037 color:#00B8D4 ]", + "[ 12/1 ⇜ (13/1 → 14/1) | note:B3 clip:1 s:piano release:0.1 pan:0.523148148148 color:#00B8D4 ]", + "[ 12/1 ⇜ (13/1 → 14/1) | note:D4 clip:1 s:piano release:0.1 pan:0.537037037037 color:#00B8D4 ]", + "[ 13/1 → 14/1 | note:G#4 clip:1 s:piano release:0.1 pan:0.564814814815 color:#00B8D4 ]", + "[ 14/1 → 15/1 | note:B4 clip:1 s:piano release:0.1 pan:0.578703703704 color:#00B8D4 ]", + "[ (14/1 → 15/1) ⇝ 16/1 | note:C4 clip:1 s:piano release:0.1 pan:0.527777777778 color:#00B8D4 ]", + "[ (14/1 → 15/1) ⇝ 16/1 | note:E4 clip:1 s:piano release:0.1 pan:0.546296296296 color:#00B8D4 ]", + "[ 14/1 ⇜ (15/1 → 16/1) | note:C4 clip:1 s:piano release:0.1 pan:0.527777777778 color:#00B8D4 ]", + "[ 14/1 ⇜ (15/1 → 16/1) | note:E4 clip:1 s:piano release:0.1 pan:0.546296296296 color:#00B8D4 ]", + "[ 15/1 → 16/1 | note:A4 clip:1 s:piano release:0.1 pan:0.569444444444 color:#00B8D4 ]", + "[ 16/1 → 17/1 | note:C4 clip:1 s:piano release:0.1 pan:0.527777777778 color:#00B8D4 ]", + "[ (16/1 → 17/1) ⇝ 18/1 | note:Db3 clip:1 s:piano release:0.1 pan:0.476851851852 color:#00B8D4 ]", + "[ (16/1 → 17/1) ⇝ 18/1 | note:F3 clip:1 s:piano release:0.1 pan:0.49537037037 color:#00B8D4 ]", + "[ 16/1 ⇜ (17/1 → 18/1) | note:Db3 clip:1 s:piano release:0.1 pan:0.476851851852 color:#00B8D4 ]", + "[ 16/1 ⇜ (17/1 → 18/1) | note:F3 clip:1 s:piano release:0.1 pan:0.49537037037 color:#00B8D4 ]", + "[ 17/1 → 18/1 | note:Bb3 clip:1 s:piano release:0.1 pan:0.518518518519 color:#00B8D4 ]", + "[ 18/1 → 19/1 | note:Db4 clip:1 s:piano release:0.1 pan:0.532407407407 color:#00B8D4 ]", + "[ (18/1 → 19/1) ⇝ 20/1 | note:Eb3 clip:1 s:piano release:0.1 pan:0.486111111111 color:#00B8D4 ]", "[ (18/1 → 19/1) ⇝ 20/1 | note:Gb3 clip:1 s:piano release:0.1 pan:0.5 color:#00B8D4 ]", - "[ 18/1 ⇜ (19/1 → 20/1) | note:Eb3 clip:1 s:piano release:0.1 pan:0.4861111111111111 color:#00B8D4 ]", + "[ 18/1 ⇜ (19/1 → 20/1) | note:Eb3 clip:1 s:piano release:0.1 pan:0.486111111111 color:#00B8D4 ]", "[ 18/1 ⇜ (19/1 → 20/1) | note:Gb3 clip:1 s:piano release:0.1 pan:0.5 color:#00B8D4 ]", - "[ 19/1 → 20/1 | note:C4 clip:1 s:piano release:0.1 pan:0.5277777777777778 color:#00B8D4 ]", - "[ 20/1 → 21/1 | note:Eb4 clip:1 s:piano release:0.1 pan:0.5416666666666667 color:#00B8D4 ]", - "[ (20/1 → 21/1) ⇝ 22/1 | note:F3 clip:1 s:piano release:0.1 pan:0.49537037037037035 color:#00B8D4 ]", - "[ (20/1 → 21/1) ⇝ 22/1 | note:Ab3 clip:1 s:piano release:0.1 pan:0.5092592592592593 color:#00B8D4 ]", - "[ 20/1 ⇜ (21/1 → 22/1) | note:F3 clip:1 s:piano release:0.1 pan:0.49537037037037035 color:#00B8D4 ]", - "[ 20/1 ⇜ (21/1 → 22/1) | note:Ab3 clip:1 s:piano release:0.1 pan:0.5092592592592593 color:#00B8D4 ]", - "[ 21/1 → 22/1 | note:Db4 clip:1 s:piano release:0.1 pan:0.5324074074074074 color:#00B8D4 ]", - "[ 22/1 → 23/1 | note:F4 clip:1 s:piano release:0.1 pan:0.5509259259259259 color:#00B8D4 ]", + "[ 19/1 → 20/1 | note:C4 clip:1 s:piano release:0.1 pan:0.527777777778 color:#00B8D4 ]", + "[ 20/1 → 21/1 | note:Eb4 clip:1 s:piano release:0.1 pan:0.541666666667 color:#00B8D4 ]", + "[ (20/1 → 21/1) ⇝ 22/1 | note:F3 clip:1 s:piano release:0.1 pan:0.49537037037 color:#00B8D4 ]", + "[ (20/1 → 21/1) ⇝ 22/1 | note:Ab3 clip:1 s:piano release:0.1 pan:0.509259259259 color:#00B8D4 ]", + "[ 20/1 ⇜ (21/1 → 22/1) | note:F3 clip:1 s:piano release:0.1 pan:0.49537037037 color:#00B8D4 ]", + "[ 20/1 ⇜ (21/1 → 22/1) | note:Ab3 clip:1 s:piano release:0.1 pan:0.509259259259 color:#00B8D4 ]", + "[ 21/1 → 22/1 | note:Db4 clip:1 s:piano release:0.1 pan:0.532407407407 color:#00B8D4 ]", + "[ 22/1 → 23/1 | note:F4 clip:1 s:piano release:0.1 pan:0.550925925926 color:#00B8D4 ]", "[ (22/1 → 23/1) ⇝ 24/1 | note:Gb3 clip:1 s:piano release:0.1 pan:0.5 color:#00B8D4 ]", - "[ (22/1 → 23/1) ⇝ 24/1 | note:A3 clip:1 s:piano release:0.1 pan:0.5138888888888888 color:#00B8D4 ]", + "[ (22/1 → 23/1) ⇝ 24/1 | note:A3 clip:1 s:piano release:0.1 pan:0.513888888889 color:#00B8D4 ]", "[ 22/1 ⇜ (23/1 → 24/1) | note:Gb3 clip:1 s:piano release:0.1 pan:0.5 color:#00B8D4 ]", - "[ 22/1 ⇜ (23/1 → 24/1) | note:A3 clip:1 s:piano release:0.1 pan:0.5138888888888888 color:#00B8D4 ]", - "[ 23/1 → 24/1 | note:Eb4 clip:1 s:piano release:0.1 pan:0.5416666666666667 color:#00B8D4 ]", - "[ 24/1 → 25/1 | note:Gb4 clip:1 s:piano release:0.1 pan:0.5555555555555556 color:#00B8D4 ]", - "[ (24/1 → 25/1) ⇝ 26/1 | note:Ab3 clip:1 s:piano release:0.1 pan:0.5092592592592593 color:#00B8D4 ]", - "[ (24/1 → 25/1) ⇝ 26/1 | note:Bb3 clip:1 s:piano release:0.1 pan:0.5185185185185186 color:#00B8D4 ]", - "[ 24/1 ⇜ (25/1 → 26/1) | note:Ab3 clip:1 s:piano release:0.1 pan:0.5092592592592593 color:#00B8D4 ]", - "[ 24/1 ⇜ (25/1 → 26/1) | note:Bb3 clip:1 s:piano release:0.1 pan:0.5185185185185186 color:#00B8D4 ]", - "[ 25/1 → 26/1 | note:F4 clip:1 s:piano release:0.1 pan:0.5509259259259259 color:#00B8D4 ]", - "[ 26/1 → 27/1 | note:Ab4 clip:1 s:piano release:0.1 pan:0.5648148148148149 color:#00B8D4 ]", - "[ (26/1 → 27/1) ⇝ 28/1 | note:A3 clip:1 s:piano release:0.1 pan:0.5138888888888888 color:#00B8D4 ]", - "[ (26/1 → 27/1) ⇝ 28/1 | note:C4 clip:1 s:piano release:0.1 pan:0.5277777777777778 color:#00B8D4 ]", - "[ 26/1 ⇜ (27/1 → 28/1) | note:A3 clip:1 s:piano release:0.1 pan:0.5138888888888888 color:#00B8D4 ]", - "[ 26/1 ⇜ (27/1 → 28/1) | note:C4 clip:1 s:piano release:0.1 pan:0.5277777777777778 color:#00B8D4 ]", - "[ 27/1 → 28/1 | note:Gb4 clip:1 s:piano release:0.1 pan:0.5555555555555556 color:#00B8D4 ]", - "[ 28/1 → 29/1 | note:Bb4 clip:1 s:piano release:0.1 pan:0.5740740740740741 color:#00B8D4 ]", - "[ (28/1 → 29/1) ⇝ 30/1 | note:C4 clip:1 s:piano release:0.1 pan:0.5277777777777778 color:#00B8D4 ]", - "[ (28/1 → 29/1) ⇝ 30/1 | note:Eb4 clip:1 s:piano release:0.1 pan:0.5416666666666667 color:#00B8D4 ]", - "[ 28/1 ⇜ (29/1 → 30/1) | note:C4 clip:1 s:piano release:0.1 pan:0.5277777777777778 color:#00B8D4 ]", - "[ 28/1 ⇜ (29/1 → 30/1) | note:Eb4 clip:1 s:piano release:0.1 pan:0.5416666666666667 color:#00B8D4 ]", - "[ 29/1 → 30/1 | note:A4 clip:1 s:piano release:0.1 pan:0.5694444444444444 color:#00B8D4 ]", - "[ 30/1 → 31/1 | note:C5 clip:1 s:piano release:0.1 pan:0.5833333333333333 color:#00B8D4 ]", - "[ (30/1 → 31/1) ⇝ 32/1 | note:Db4 clip:1 s:piano release:0.1 pan:0.5324074074074074 color:#00B8D4 ]", - "[ (30/1 → 31/1) ⇝ 32/1 | note:F4 clip:1 s:piano release:0.1 pan:0.5509259259259259 color:#00B8D4 ]", - "[ 30/1 ⇜ (31/1 → 32/1) | note:Db4 clip:1 s:piano release:0.1 pan:0.5324074074074074 color:#00B8D4 ]", - "[ 30/1 ⇜ (31/1 → 32/1) | note:F4 clip:1 s:piano release:0.1 pan:0.5509259259259259 color:#00B8D4 ]", - "[ 31/1 → 32/1 | note:Bb4 clip:1 s:piano release:0.1 pan:0.5740740740740741 color:#00B8D4 ]", - "[ 32/1 → 33/1 | note:C#4 clip:1 s:piano release:0.1 pan:0.5324074074074074 color:#00B8D4 ]", - "[ (32/1 → 33/1) ⇝ 34/1 | note:D3 clip:1 s:piano release:0.1 pan:0.4814814814814815 color:#00B8D4 ]", + "[ 22/1 ⇜ (23/1 → 24/1) | note:A3 clip:1 s:piano release:0.1 pan:0.513888888889 color:#00B8D4 ]", + "[ 23/1 → 24/1 | note:Eb4 clip:1 s:piano release:0.1 pan:0.541666666667 color:#00B8D4 ]", + "[ 24/1 → 25/1 | note:Gb4 clip:1 s:piano release:0.1 pan:0.555555555556 color:#00B8D4 ]", + "[ (24/1 → 25/1) ⇝ 26/1 | note:Ab3 clip:1 s:piano release:0.1 pan:0.509259259259 color:#00B8D4 ]", + "[ (24/1 → 25/1) ⇝ 26/1 | note:Bb3 clip:1 s:piano release:0.1 pan:0.518518518519 color:#00B8D4 ]", + "[ 24/1 ⇜ (25/1 → 26/1) | note:Ab3 clip:1 s:piano release:0.1 pan:0.509259259259 color:#00B8D4 ]", + "[ 24/1 ⇜ (25/1 → 26/1) | note:Bb3 clip:1 s:piano release:0.1 pan:0.518518518519 color:#00B8D4 ]", + "[ 25/1 → 26/1 | note:F4 clip:1 s:piano release:0.1 pan:0.550925925926 color:#00B8D4 ]", + "[ 26/1 → 27/1 | note:Ab4 clip:1 s:piano release:0.1 pan:0.564814814815 color:#00B8D4 ]", + "[ (26/1 → 27/1) ⇝ 28/1 | note:A3 clip:1 s:piano release:0.1 pan:0.513888888889 color:#00B8D4 ]", + "[ (26/1 → 27/1) ⇝ 28/1 | note:C4 clip:1 s:piano release:0.1 pan:0.527777777778 color:#00B8D4 ]", + "[ 26/1 ⇜ (27/1 → 28/1) | note:A3 clip:1 s:piano release:0.1 pan:0.513888888889 color:#00B8D4 ]", + "[ 26/1 ⇜ (27/1 → 28/1) | note:C4 clip:1 s:piano release:0.1 pan:0.527777777778 color:#00B8D4 ]", + "[ 27/1 → 28/1 | note:Gb4 clip:1 s:piano release:0.1 pan:0.555555555556 color:#00B8D4 ]", + "[ 28/1 → 29/1 | note:Bb4 clip:1 s:piano release:0.1 pan:0.574074074074 color:#00B8D4 ]", + "[ (28/1 → 29/1) ⇝ 30/1 | note:C4 clip:1 s:piano release:0.1 pan:0.527777777778 color:#00B8D4 ]", + "[ (28/1 → 29/1) ⇝ 30/1 | note:Eb4 clip:1 s:piano release:0.1 pan:0.541666666667 color:#00B8D4 ]", + "[ 28/1 ⇜ (29/1 → 30/1) | note:C4 clip:1 s:piano release:0.1 pan:0.527777777778 color:#00B8D4 ]", + "[ 28/1 ⇜ (29/1 → 30/1) | note:Eb4 clip:1 s:piano release:0.1 pan:0.541666666667 color:#00B8D4 ]", + "[ 29/1 → 30/1 | note:A4 clip:1 s:piano release:0.1 pan:0.569444444444 color:#00B8D4 ]", + "[ 30/1 → 31/1 | note:C5 clip:1 s:piano release:0.1 pan:0.583333333333 color:#00B8D4 ]", + "[ (30/1 → 31/1) ⇝ 32/1 | note:Db4 clip:1 s:piano release:0.1 pan:0.532407407407 color:#00B8D4 ]", + "[ (30/1 → 31/1) ⇝ 32/1 | note:F4 clip:1 s:piano release:0.1 pan:0.550925925926 color:#00B8D4 ]", + "[ 30/1 ⇜ (31/1 → 32/1) | note:Db4 clip:1 s:piano release:0.1 pan:0.532407407407 color:#00B8D4 ]", + "[ 30/1 ⇜ (31/1 → 32/1) | note:F4 clip:1 s:piano release:0.1 pan:0.550925925926 color:#00B8D4 ]", + "[ 31/1 → 32/1 | note:Bb4 clip:1 s:piano release:0.1 pan:0.574074074074 color:#00B8D4 ]", + "[ 32/1 → 33/1 | note:C#4 clip:1 s:piano release:0.1 pan:0.532407407407 color:#00B8D4 ]", + "[ (32/1 → 33/1) ⇝ 34/1 | note:D3 clip:1 s:piano release:0.1 pan:0.481481481481 color:#00B8D4 ]", "[ (32/1 → 33/1) ⇝ 34/1 | note:F#3 clip:1 s:piano release:0.1 pan:0.5 color:#00B8D4 ]", - "[ 32/1 ⇜ (33/1 → 34/1) | note:D3 clip:1 s:piano release:0.1 pan:0.4814814814814815 color:#00B8D4 ]", + "[ 32/1 ⇜ (33/1 → 34/1) | note:D3 clip:1 s:piano release:0.1 pan:0.481481481481 color:#00B8D4 ]", "[ 32/1 ⇜ (33/1 → 34/1) | note:F#3 clip:1 s:piano release:0.1 pan:0.5 color:#00B8D4 ]", - "[ 33/1 → 34/1 | note:B3 clip:1 s:piano release:0.1 pan:0.5231481481481481 color:#00B8D4 ]", - "[ 34/1 → 35/1 | note:D4 clip:1 s:piano release:0.1 pan:0.537037037037037 color:#00B8D4 ]", - "[ (34/1 → 35/1) ⇝ 36/1 | note:E3 clip:1 s:piano release:0.1 pan:0.4907407407407407 color:#00B8D4 ]", - "[ (34/1 → 35/1) ⇝ 36/1 | note:G3 clip:1 s:piano release:0.1 pan:0.5046296296296297 color:#00B8D4 ]", - "[ 34/1 ⇜ (35/1 → 36/1) | note:E3 clip:1 s:piano release:0.1 pan:0.4907407407407407 color:#00B8D4 ]", - "[ 34/1 ⇜ (35/1 → 36/1) | note:G3 clip:1 s:piano release:0.1 pan:0.5046296296296297 color:#00B8D4 ]", - "[ 35/1 → 36/1 | note:C#4 clip:1 s:piano release:0.1 pan:0.5324074074074074 color:#00B8D4 ]", - "[ 36/1 → 37/1 | note:E4 clip:1 s:piano release:0.1 pan:0.5462962962962963 color:#00B8D4 ]", + "[ 33/1 → 34/1 | note:B3 clip:1 s:piano release:0.1 pan:0.523148148148 color:#00B8D4 ]", + "[ 34/1 → 35/1 | note:D4 clip:1 s:piano release:0.1 pan:0.537037037037 color:#00B8D4 ]", + "[ (34/1 → 35/1) ⇝ 36/1 | note:E3 clip:1 s:piano release:0.1 pan:0.490740740741 color:#00B8D4 ]", + "[ (34/1 → 35/1) ⇝ 36/1 | note:G3 clip:1 s:piano release:0.1 pan:0.50462962963 color:#00B8D4 ]", + "[ 34/1 ⇜ (35/1 → 36/1) | note:E3 clip:1 s:piano release:0.1 pan:0.490740740741 color:#00B8D4 ]", + "[ 34/1 ⇜ (35/1 → 36/1) | note:G3 clip:1 s:piano release:0.1 pan:0.50462962963 color:#00B8D4 ]", + "[ 35/1 → 36/1 | note:C#4 clip:1 s:piano release:0.1 pan:0.532407407407 color:#00B8D4 ]", + "[ 36/1 → 37/1 | note:E4 clip:1 s:piano release:0.1 pan:0.546296296296 color:#00B8D4 ]", "[ (36/1 → 37/1) ⇝ 38/1 | note:F#3 clip:1 s:piano release:0.1 pan:0.5 color:#00B8D4 ]", - "[ (36/1 → 37/1) ⇝ 38/1 | note:A3 clip:1 s:piano release:0.1 pan:0.5138888888888888 color:#00B8D4 ]", + "[ (36/1 → 37/1) ⇝ 38/1 | note:A3 clip:1 s:piano release:0.1 pan:0.513888888889 color:#00B8D4 ]", "[ 36/1 ⇜ (37/1 → 38/1) | note:F#3 clip:1 s:piano release:0.1 pan:0.5 color:#00B8D4 ]", - "[ 36/1 ⇜ (37/1 → 38/1) | note:A3 clip:1 s:piano release:0.1 pan:0.5138888888888888 color:#00B8D4 ]", - "[ 37/1 → 38/1 | note:D4 clip:1 s:piano release:0.1 pan:0.537037037037037 color:#00B8D4 ]", - "[ 38/1 → 39/1 | note:F#4 clip:1 s:piano release:0.1 pan:0.5555555555555556 color:#00B8D4 ]", - "[ (38/1 → 39/1) ⇝ 40/1 | note:G3 clip:1 s:piano release:0.1 pan:0.5046296296296297 color:#00B8D4 ]", - "[ (38/1 → 39/1) ⇝ 40/1 | note:A#3 clip:1 s:piano release:0.1 pan:0.5185185185185186 color:#00B8D4 ]", - "[ 38/1 ⇜ (39/1 → 40/1) | note:G3 clip:1 s:piano release:0.1 pan:0.5046296296296297 color:#00B8D4 ]", - "[ 38/1 ⇜ (39/1 → 40/1) | note:A#3 clip:1 s:piano release:0.1 pan:0.5185185185185186 color:#00B8D4 ]", - "[ 39/1 → 40/1 | note:E4 clip:1 s:piano release:0.1 pan:0.5462962962962963 color:#00B8D4 ]", - "[ 40/1 → 41/1 | note:G4 clip:1 s:piano release:0.1 pan:0.5601851851851851 color:#00B8D4 ]", - "[ (40/1 → 41/1) ⇝ 42/1 | note:A3 clip:1 s:piano release:0.1 pan:0.5138888888888888 color:#00B8D4 ]", - "[ (40/1 → 41/1) ⇝ 42/1 | note:B3 clip:1 s:piano release:0.1 pan:0.5231481481481481 color:#00B8D4 ]", - "[ 40/1 ⇜ (41/1 → 42/1) | note:A3 clip:1 s:piano release:0.1 pan:0.5138888888888888 color:#00B8D4 ]", - "[ 40/1 ⇜ (41/1 → 42/1) | note:B3 clip:1 s:piano release:0.1 pan:0.5231481481481481 color:#00B8D4 ]", - "[ 41/1 → 42/1 | note:F#4 clip:1 s:piano release:0.1 pan:0.5555555555555556 color:#00B8D4 ]", - "[ 42/1 → 43/1 | note:A4 clip:1 s:piano release:0.1 pan:0.5694444444444444 color:#00B8D4 ]", - "[ (42/1 → 43/1) ⇝ 44/1 | note:A#3 clip:1 s:piano release:0.1 pan:0.5185185185185186 color:#00B8D4 ]", - "[ (42/1 → 43/1) ⇝ 44/1 | note:C#4 clip:1 s:piano release:0.1 pan:0.5324074074074074 color:#00B8D4 ]", - "[ 42/1 ⇜ (43/1 → 44/1) | note:A#3 clip:1 s:piano release:0.1 pan:0.5185185185185186 color:#00B8D4 ]", - "[ 42/1 ⇜ (43/1 → 44/1) | note:C#4 clip:1 s:piano release:0.1 pan:0.5324074074074074 color:#00B8D4 ]", - "[ 43/1 → 44/1 | note:G4 clip:1 s:piano release:0.1 pan:0.5601851851851851 color:#00B8D4 ]", - "[ 44/1 → 45/1 | note:B4 clip:1 s:piano release:0.1 pan:0.5787037037037037 color:#00B8D4 ]", - "[ (44/1 → 45/1) ⇝ 46/1 | note:C#4 clip:1 s:piano release:0.1 pan:0.5324074074074074 color:#00B8D4 ]", - "[ (44/1 → 45/1) ⇝ 46/1 | note:E4 clip:1 s:piano release:0.1 pan:0.5462962962962963 color:#00B8D4 ]", - "[ 44/1 ⇜ (45/1 → 46/1) | note:C#4 clip:1 s:piano release:0.1 pan:0.5324074074074074 color:#00B8D4 ]", - "[ 44/1 ⇜ (45/1 → 46/1) | note:E4 clip:1 s:piano release:0.1 pan:0.5462962962962963 color:#00B8D4 ]", - "[ 45/1 → 46/1 | note:A#4 clip:1 s:piano release:0.1 pan:0.5740740740740741 color:#00B8D4 ]", - "[ 46/1 → 47/1 | note:C#5 clip:1 s:piano release:0.1 pan:0.587962962962963 color:#00B8D4 ]", - "[ (46/1 → 47/1) ⇝ 48/1 | note:D4 clip:1 s:piano release:0.1 pan:0.537037037037037 color:#00B8D4 ]", - "[ (46/1 → 47/1) ⇝ 48/1 | note:F#4 clip:1 s:piano release:0.1 pan:0.5555555555555556 color:#00B8D4 ]", - "[ 46/1 ⇜ (47/1 → 48/1) | note:D4 clip:1 s:piano release:0.1 pan:0.537037037037037 color:#00B8D4 ]", - "[ 46/1 ⇜ (47/1 → 48/1) | note:F#4 clip:1 s:piano release:0.1 pan:0.5555555555555556 color:#00B8D4 ]", - "[ 47/1 → 48/1 | note:B4 clip:1 s:piano release:0.1 pan:0.5787037037037037 color:#00B8D4 ]", - "[ 48/1 → 49/1 | note:C4 clip:1 s:piano release:0.1 pan:0.5277777777777778 color:#00B8D4 ]", - "[ (48/1 → 49/1) ⇝ 50/1 | note:Db3 clip:1 s:piano release:0.1 pan:0.47685185185185186 color:#00B8D4 ]", - "[ (48/1 → 49/1) ⇝ 50/1 | note:F3 clip:1 s:piano release:0.1 pan:0.49537037037037035 color:#00B8D4 ]", - "[ 48/1 ⇜ (49/1 → 50/1) | note:Db3 clip:1 s:piano release:0.1 pan:0.47685185185185186 color:#00B8D4 ]", - "[ 48/1 ⇜ (49/1 → 50/1) | note:F3 clip:1 s:piano release:0.1 pan:0.49537037037037035 color:#00B8D4 ]", - "[ 49/1 → 50/1 | note:Bb3 clip:1 s:piano release:0.1 pan:0.5185185185185186 color:#00B8D4 ]", - "[ 50/1 → 51/1 | note:Db4 clip:1 s:piano release:0.1 pan:0.5324074074074074 color:#00B8D4 ]", - "[ (50/1 → 51/1) ⇝ 52/1 | note:Eb3 clip:1 s:piano release:0.1 pan:0.4861111111111111 color:#00B8D4 ]", + "[ 36/1 ⇜ (37/1 → 38/1) | note:A3 clip:1 s:piano release:0.1 pan:0.513888888889 color:#00B8D4 ]", + "[ 37/1 → 38/1 | note:D4 clip:1 s:piano release:0.1 pan:0.537037037037 color:#00B8D4 ]", + "[ 38/1 → 39/1 | note:F#4 clip:1 s:piano release:0.1 pan:0.555555555556 color:#00B8D4 ]", + "[ (38/1 → 39/1) ⇝ 40/1 | note:G3 clip:1 s:piano release:0.1 pan:0.50462962963 color:#00B8D4 ]", + "[ (38/1 → 39/1) ⇝ 40/1 | note:A#3 clip:1 s:piano release:0.1 pan:0.518518518519 color:#00B8D4 ]", + "[ 38/1 ⇜ (39/1 → 40/1) | note:G3 clip:1 s:piano release:0.1 pan:0.50462962963 color:#00B8D4 ]", + "[ 38/1 ⇜ (39/1 → 40/1) | note:A#3 clip:1 s:piano release:0.1 pan:0.518518518519 color:#00B8D4 ]", + "[ 39/1 → 40/1 | note:E4 clip:1 s:piano release:0.1 pan:0.546296296296 color:#00B8D4 ]", + "[ 40/1 → 41/1 | note:G4 clip:1 s:piano release:0.1 pan:0.560185185185 color:#00B8D4 ]", + "[ (40/1 → 41/1) ⇝ 42/1 | note:A3 clip:1 s:piano release:0.1 pan:0.513888888889 color:#00B8D4 ]", + "[ (40/1 → 41/1) ⇝ 42/1 | note:B3 clip:1 s:piano release:0.1 pan:0.523148148148 color:#00B8D4 ]", + "[ 40/1 ⇜ (41/1 → 42/1) | note:A3 clip:1 s:piano release:0.1 pan:0.513888888889 color:#00B8D4 ]", + "[ 40/1 ⇜ (41/1 → 42/1) | note:B3 clip:1 s:piano release:0.1 pan:0.523148148148 color:#00B8D4 ]", + "[ 41/1 → 42/1 | note:F#4 clip:1 s:piano release:0.1 pan:0.555555555556 color:#00B8D4 ]", + "[ 42/1 → 43/1 | note:A4 clip:1 s:piano release:0.1 pan:0.569444444444 color:#00B8D4 ]", + "[ (42/1 → 43/1) ⇝ 44/1 | note:A#3 clip:1 s:piano release:0.1 pan:0.518518518519 color:#00B8D4 ]", + "[ (42/1 → 43/1) ⇝ 44/1 | note:C#4 clip:1 s:piano release:0.1 pan:0.532407407407 color:#00B8D4 ]", + "[ 42/1 ⇜ (43/1 → 44/1) | note:A#3 clip:1 s:piano release:0.1 pan:0.518518518519 color:#00B8D4 ]", + "[ 42/1 ⇜ (43/1 → 44/1) | note:C#4 clip:1 s:piano release:0.1 pan:0.532407407407 color:#00B8D4 ]", + "[ 43/1 → 44/1 | note:G4 clip:1 s:piano release:0.1 pan:0.560185185185 color:#00B8D4 ]", + "[ 44/1 → 45/1 | note:B4 clip:1 s:piano release:0.1 pan:0.578703703704 color:#00B8D4 ]", + "[ (44/1 → 45/1) ⇝ 46/1 | note:C#4 clip:1 s:piano release:0.1 pan:0.532407407407 color:#00B8D4 ]", + "[ (44/1 → 45/1) ⇝ 46/1 | note:E4 clip:1 s:piano release:0.1 pan:0.546296296296 color:#00B8D4 ]", + "[ 44/1 ⇜ (45/1 → 46/1) | note:C#4 clip:1 s:piano release:0.1 pan:0.532407407407 color:#00B8D4 ]", + "[ 44/1 ⇜ (45/1 → 46/1) | note:E4 clip:1 s:piano release:0.1 pan:0.546296296296 color:#00B8D4 ]", + "[ 45/1 → 46/1 | note:A#4 clip:1 s:piano release:0.1 pan:0.574074074074 color:#00B8D4 ]", + "[ 46/1 → 47/1 | note:C#5 clip:1 s:piano release:0.1 pan:0.587962962963 color:#00B8D4 ]", + "[ (46/1 → 47/1) ⇝ 48/1 | note:D4 clip:1 s:piano release:0.1 pan:0.537037037037 color:#00B8D4 ]", + "[ (46/1 → 47/1) ⇝ 48/1 | note:F#4 clip:1 s:piano release:0.1 pan:0.555555555556 color:#00B8D4 ]", + "[ 46/1 ⇜ (47/1 → 48/1) | note:D4 clip:1 s:piano release:0.1 pan:0.537037037037 color:#00B8D4 ]", + "[ 46/1 ⇜ (47/1 → 48/1) | note:F#4 clip:1 s:piano release:0.1 pan:0.555555555556 color:#00B8D4 ]", + "[ 47/1 → 48/1 | note:B4 clip:1 s:piano release:0.1 pan:0.578703703704 color:#00B8D4 ]", + "[ 48/1 → 49/1 | note:C4 clip:1 s:piano release:0.1 pan:0.527777777778 color:#00B8D4 ]", + "[ (48/1 → 49/1) ⇝ 50/1 | note:Db3 clip:1 s:piano release:0.1 pan:0.476851851852 color:#00B8D4 ]", + "[ (48/1 → 49/1) ⇝ 50/1 | note:F3 clip:1 s:piano release:0.1 pan:0.49537037037 color:#00B8D4 ]", + "[ 48/1 ⇜ (49/1 → 50/1) | note:Db3 clip:1 s:piano release:0.1 pan:0.476851851852 color:#00B8D4 ]", + "[ 48/1 ⇜ (49/1 → 50/1) | note:F3 clip:1 s:piano release:0.1 pan:0.49537037037 color:#00B8D4 ]", + "[ 49/1 → 50/1 | note:Bb3 clip:1 s:piano release:0.1 pan:0.518518518519 color:#00B8D4 ]", + "[ 50/1 → 51/1 | note:Db4 clip:1 s:piano release:0.1 pan:0.532407407407 color:#00B8D4 ]", + "[ (50/1 → 51/1) ⇝ 52/1 | note:Eb3 clip:1 s:piano release:0.1 pan:0.486111111111 color:#00B8D4 ]", "[ (50/1 → 51/1) ⇝ 52/1 | note:Gb3 clip:1 s:piano release:0.1 pan:0.5 color:#00B8D4 ]", - "[ 50/1 ⇜ (51/1 → 52/1) | note:Eb3 clip:1 s:piano release:0.1 pan:0.4861111111111111 color:#00B8D4 ]", + "[ 50/1 ⇜ (51/1 → 52/1) | note:Eb3 clip:1 s:piano release:0.1 pan:0.486111111111 color:#00B8D4 ]", "[ 50/1 ⇜ (51/1 → 52/1) | note:Gb3 clip:1 s:piano release:0.1 pan:0.5 color:#00B8D4 ]", - "[ 51/1 → 52/1 | note:C4 clip:1 s:piano release:0.1 pan:0.5277777777777778 color:#00B8D4 ]", - "[ 52/1 → 53/1 | note:Eb4 clip:1 s:piano release:0.1 pan:0.5416666666666667 color:#00B8D4 ]", - "[ (52/1 → 53/1) ⇝ 54/1 | note:F3 clip:1 s:piano release:0.1 pan:0.49537037037037035 color:#00B8D4 ]", - "[ (52/1 → 53/1) ⇝ 54/1 | note:Ab3 clip:1 s:piano release:0.1 pan:0.5092592592592593 color:#00B8D4 ]", - "[ 52/1 ⇜ (53/1 → 54/1) | note:F3 clip:1 s:piano release:0.1 pan:0.49537037037037035 color:#00B8D4 ]", - "[ 52/1 ⇜ (53/1 → 54/1) | note:Ab3 clip:1 s:piano release:0.1 pan:0.5092592592592593 color:#00B8D4 ]", - "[ 53/1 → 54/1 | note:Db4 clip:1 s:piano release:0.1 pan:0.5324074074074074 color:#00B8D4 ]", - "[ 54/1 → 55/1 | note:F4 clip:1 s:piano release:0.1 pan:0.5509259259259259 color:#00B8D4 ]", + "[ 51/1 → 52/1 | note:C4 clip:1 s:piano release:0.1 pan:0.527777777778 color:#00B8D4 ]", + "[ 52/1 → 53/1 | note:Eb4 clip:1 s:piano release:0.1 pan:0.541666666667 color:#00B8D4 ]", + "[ (52/1 → 53/1) ⇝ 54/1 | note:F3 clip:1 s:piano release:0.1 pan:0.49537037037 color:#00B8D4 ]", + "[ (52/1 → 53/1) ⇝ 54/1 | note:Ab3 clip:1 s:piano release:0.1 pan:0.509259259259 color:#00B8D4 ]", + "[ 52/1 ⇜ (53/1 → 54/1) | note:F3 clip:1 s:piano release:0.1 pan:0.49537037037 color:#00B8D4 ]", + "[ 52/1 ⇜ (53/1 → 54/1) | note:Ab3 clip:1 s:piano release:0.1 pan:0.509259259259 color:#00B8D4 ]", + "[ 53/1 → 54/1 | note:Db4 clip:1 s:piano release:0.1 pan:0.532407407407 color:#00B8D4 ]", + "[ 54/1 → 55/1 | note:F4 clip:1 s:piano release:0.1 pan:0.550925925926 color:#00B8D4 ]", "[ (54/1 → 55/1) ⇝ 56/1 | note:Gb3 clip:1 s:piano release:0.1 pan:0.5 color:#00B8D4 ]", - "[ (54/1 → 55/1) ⇝ 56/1 | note:A3 clip:1 s:piano release:0.1 pan:0.5138888888888888 color:#00B8D4 ]", + "[ (54/1 → 55/1) ⇝ 56/1 | note:A3 clip:1 s:piano release:0.1 pan:0.513888888889 color:#00B8D4 ]", "[ 54/1 ⇜ (55/1 → 56/1) | note:Gb3 clip:1 s:piano release:0.1 pan:0.5 color:#00B8D4 ]", - "[ 54/1 ⇜ (55/1 → 56/1) | note:A3 clip:1 s:piano release:0.1 pan:0.5138888888888888 color:#00B8D4 ]", - "[ 55/1 → 56/1 | note:Eb4 clip:1 s:piano release:0.1 pan:0.5416666666666667 color:#00B8D4 ]", - "[ 56/1 → 57/1 | note:Gb4 clip:1 s:piano release:0.1 pan:0.5555555555555556 color:#00B8D4 ]", - "[ (56/1 → 57/1) ⇝ 58/1 | note:Ab3 clip:1 s:piano release:0.1 pan:0.5092592592592593 color:#00B8D4 ]", - "[ (56/1 → 57/1) ⇝ 58/1 | note:Bb3 clip:1 s:piano release:0.1 pan:0.5185185185185186 color:#00B8D4 ]", - "[ 56/1 ⇜ (57/1 → 58/1) | note:Ab3 clip:1 s:piano release:0.1 pan:0.5092592592592593 color:#00B8D4 ]", - "[ 56/1 ⇜ (57/1 → 58/1) | note:Bb3 clip:1 s:piano release:0.1 pan:0.5185185185185186 color:#00B8D4 ]", - "[ 57/1 → 58/1 | note:F4 clip:1 s:piano release:0.1 pan:0.5509259259259259 color:#00B8D4 ]", - "[ 58/1 → 59/1 | note:Ab4 clip:1 s:piano release:0.1 pan:0.5648148148148149 color:#00B8D4 ]", - "[ (58/1 → 59/1) ⇝ 60/1 | note:A3 clip:1 s:piano release:0.1 pan:0.5138888888888888 color:#00B8D4 ]", - "[ (58/1 → 59/1) ⇝ 60/1 | note:C4 clip:1 s:piano release:0.1 pan:0.5277777777777778 color:#00B8D4 ]", - "[ 58/1 ⇜ (59/1 → 60/1) | note:A3 clip:1 s:piano release:0.1 pan:0.5138888888888888 color:#00B8D4 ]", - "[ 58/1 ⇜ (59/1 → 60/1) | note:C4 clip:1 s:piano release:0.1 pan:0.5277777777777778 color:#00B8D4 ]", - "[ 59/1 → 60/1 | note:Gb4 clip:1 s:piano release:0.1 pan:0.5555555555555556 color:#00B8D4 ]", - "[ 60/1 → 61/1 | note:Bb4 clip:1 s:piano release:0.1 pan:0.5740740740740741 color:#00B8D4 ]", - "[ (60/1 → 61/1) ⇝ 62/1 | note:C4 clip:1 s:piano release:0.1 pan:0.5277777777777778 color:#00B8D4 ]", - "[ (60/1 → 61/1) ⇝ 62/1 | note:Eb4 clip:1 s:piano release:0.1 pan:0.5416666666666667 color:#00B8D4 ]", - "[ 60/1 ⇜ (61/1 → 62/1) | note:C4 clip:1 s:piano release:0.1 pan:0.5277777777777778 color:#00B8D4 ]", - "[ 60/1 ⇜ (61/1 → 62/1) | note:Eb4 clip:1 s:piano release:0.1 pan:0.5416666666666667 color:#00B8D4 ]", - "[ 61/1 → 62/1 | note:A4 clip:1 s:piano release:0.1 pan:0.5694444444444444 color:#00B8D4 ]", - "[ 62/1 → 63/1 | note:C5 clip:1 s:piano release:0.1 pan:0.5833333333333333 color:#00B8D4 ]", - "[ (62/1 → 63/1) ⇝ 64/1 | note:Db4 clip:1 s:piano release:0.1 pan:0.5324074074074074 color:#00B8D4 ]", - "[ (62/1 → 63/1) ⇝ 64/1 | note:F4 clip:1 s:piano release:0.1 pan:0.5509259259259259 color:#00B8D4 ]", - "[ 62/1 ⇜ (63/1 → 64/1) | note:Db4 clip:1 s:piano release:0.1 pan:0.5324074074074074 color:#00B8D4 ]", - "[ 62/1 ⇜ (63/1 → 64/1) | note:F4 clip:1 s:piano release:0.1 pan:0.5509259259259259 color:#00B8D4 ]", - "[ 63/1 → 64/1 | note:Bb4 clip:1 s:piano release:0.1 pan:0.5740740740740741 color:#00B8D4 ]", + "[ 54/1 ⇜ (55/1 → 56/1) | note:A3 clip:1 s:piano release:0.1 pan:0.513888888889 color:#00B8D4 ]", + "[ 55/1 → 56/1 | note:Eb4 clip:1 s:piano release:0.1 pan:0.541666666667 color:#00B8D4 ]", + "[ 56/1 → 57/1 | note:Gb4 clip:1 s:piano release:0.1 pan:0.555555555556 color:#00B8D4 ]", + "[ (56/1 → 57/1) ⇝ 58/1 | note:Ab3 clip:1 s:piano release:0.1 pan:0.509259259259 color:#00B8D4 ]", + "[ (56/1 → 57/1) ⇝ 58/1 | note:Bb3 clip:1 s:piano release:0.1 pan:0.518518518519 color:#00B8D4 ]", + "[ 56/1 ⇜ (57/1 → 58/1) | note:Ab3 clip:1 s:piano release:0.1 pan:0.509259259259 color:#00B8D4 ]", + "[ 56/1 ⇜ (57/1 → 58/1) | note:Bb3 clip:1 s:piano release:0.1 pan:0.518518518519 color:#00B8D4 ]", + "[ 57/1 → 58/1 | note:F4 clip:1 s:piano release:0.1 pan:0.550925925926 color:#00B8D4 ]", + "[ 58/1 → 59/1 | note:Ab4 clip:1 s:piano release:0.1 pan:0.564814814815 color:#00B8D4 ]", + "[ (58/1 → 59/1) ⇝ 60/1 | note:A3 clip:1 s:piano release:0.1 pan:0.513888888889 color:#00B8D4 ]", + "[ (58/1 → 59/1) ⇝ 60/1 | note:C4 clip:1 s:piano release:0.1 pan:0.527777777778 color:#00B8D4 ]", + "[ 58/1 ⇜ (59/1 → 60/1) | note:A3 clip:1 s:piano release:0.1 pan:0.513888888889 color:#00B8D4 ]", + "[ 58/1 ⇜ (59/1 → 60/1) | note:C4 clip:1 s:piano release:0.1 pan:0.527777777778 color:#00B8D4 ]", + "[ 59/1 → 60/1 | note:Gb4 clip:1 s:piano release:0.1 pan:0.555555555556 color:#00B8D4 ]", + "[ 60/1 → 61/1 | note:Bb4 clip:1 s:piano release:0.1 pan:0.574074074074 color:#00B8D4 ]", + "[ (60/1 → 61/1) ⇝ 62/1 | note:C4 clip:1 s:piano release:0.1 pan:0.527777777778 color:#00B8D4 ]", + "[ (60/1 → 61/1) ⇝ 62/1 | note:Eb4 clip:1 s:piano release:0.1 pan:0.541666666667 color:#00B8D4 ]", + "[ 60/1 ⇜ (61/1 → 62/1) | note:C4 clip:1 s:piano release:0.1 pan:0.527777777778 color:#00B8D4 ]", + "[ 60/1 ⇜ (61/1 → 62/1) | note:Eb4 clip:1 s:piano release:0.1 pan:0.541666666667 color:#00B8D4 ]", + "[ 61/1 → 62/1 | note:A4 clip:1 s:piano release:0.1 pan:0.569444444444 color:#00B8D4 ]", + "[ 62/1 → 63/1 | note:C5 clip:1 s:piano release:0.1 pan:0.583333333333 color:#00B8D4 ]", + "[ (62/1 → 63/1) ⇝ 64/1 | note:Db4 clip:1 s:piano release:0.1 pan:0.532407407407 color:#00B8D4 ]", + "[ (62/1 → 63/1) ⇝ 64/1 | note:F4 clip:1 s:piano release:0.1 pan:0.550925925926 color:#00B8D4 ]", + "[ 62/1 ⇜ (63/1 → 64/1) | note:Db4 clip:1 s:piano release:0.1 pan:0.532407407407 color:#00B8D4 ]", + "[ 62/1 ⇜ (63/1 → 64/1) | note:F4 clip:1 s:piano release:0.1 pan:0.550925925926 color:#00B8D4 ]", + "[ 63/1 → 64/1 | note:Bb4 clip:1 s:piano release:0.1 pan:0.574074074074 color:#00B8D4 ]", ] `; @@ -260,40 +260,40 @@ exports[`renders tunes > tune: bassFuge 1`] = ` "[ 0/1 → 1/8 | note:A2 s:flbass n:0 gain:0.3 cutoff:2100 resonance:10 clip:1 ]", "[ -7/4 ⇜ (0/1 → 1/4) | note:C4 s:flbass n:0 gain:0.3 cutoff:200 resonance:10 clip:1 ]", "[ -7/4 ⇜ (0/1 → 1/4) | note:E4 s:flbass n:0 gain:0.3 cutoff:200 resonance:10 clip:1 ]", - "[ -3/2 ⇜ (0/1 → 1/4) ⇝ 1/2 | gain:0.3 note:A4 s:flbass n:0 cutoff:247.63696685453513 resonance:10 clip:1 ]", - "[ -3/2 ⇜ (0/1 → 1/4) ⇝ 1/2 | gain:0.3 note:C5 s:flbass n:0 cutoff:247.63696685453513 resonance:10 clip:1 ]", - "[ -5/4 ⇜ (0/1 → 1/4) ⇝ 3/4 | gain:0.15 note:A4 s:flbass n:0 cutoff:388.1591509854036 resonance:10 clip:1 ]", - "[ -5/4 ⇜ (0/1 → 1/4) ⇝ 3/4 | gain:0.15 note:C5 s:flbass n:0 cutoff:388.1591509854036 resonance:10 clip:1 ]", + "[ -3/2 ⇜ (0/1 → 1/4) ⇝ 1/2 | gain:0.3 note:A4 s:flbass n:0 cutoff:247.636966854535 resonance:10 clip:1 ]", + "[ -3/2 ⇜ (0/1 → 1/4) ⇝ 1/2 | gain:0.3 note:C5 s:flbass n:0 cutoff:247.636966854535 resonance:10 clip:1 ]", + "[ -5/4 ⇜ (0/1 → 1/4) ⇝ 3/4 | gain:0.15 note:A4 s:flbass n:0 cutoff:388.159150985404 resonance:10 clip:1 ]", + "[ -5/4 ⇜ (0/1 → 1/4) ⇝ 3/4 | gain:0.15 note:C5 s:flbass n:0 cutoff:388.159150985404 resonance:10 clip:1 ]", "[ 0/1 → 1/4 | note:A3 s:flbass n:0 gain:0.3 cutoff:2100 resonance:10 clip:1 ]", - "[ -1/1 ⇜ (0/1 → 1/2) ⇝ 1/1 | gain:0.075 note:A4 s:flbass n:0 cutoff:614.5201833107434 resonance:10 clip:1 ]", - "[ -1/1 ⇜ (0/1 → 1/2) ⇝ 1/1 | gain:0.075 note:C5 s:flbass n:0 cutoff:614.5201833107434 resonance:10 clip:1 ]", + "[ -1/1 ⇜ (0/1 → 1/2) ⇝ 1/1 | gain:0.075 note:A4 s:flbass n:0 cutoff:614.520183310743 resonance:10 clip:1 ]", + "[ -1/1 ⇜ (0/1 → 1/2) ⇝ 1/1 | gain:0.075 note:C5 s:flbass n:0 cutoff:614.520183310743 resonance:10 clip:1 ]", "[ 0/1 → 1/2 | s:bd n:1 ]", - "[ -3/4 ⇜ (0/1 → 3/4) ⇝ 5/4 | gain:0.0375 note:A4 s:flbass n:0 cutoff:915.3693764684064 resonance:10 clip:1 ]", - "[ -3/4 ⇜ (0/1 → 3/4) ⇝ 5/4 | gain:0.0375 note:C5 s:flbass n:0 cutoff:915.3693764684064 resonance:10 clip:1 ]", - "[ -3/2 ⇜ (1/4 → 1/2) | gain:0.3 note:A4 s:flbass n:0 cutoff:247.63696685453513 resonance:10 clip:1 ]", - "[ -3/2 ⇜ (1/4 → 1/2) | gain:0.3 note:C5 s:flbass n:0 cutoff:247.63696685453513 resonance:10 clip:1 ]", - "[ -5/4 ⇜ (1/4 → 1/2) ⇝ 3/4 | gain:0.15 note:A4 s:flbass n:0 cutoff:388.1591509854036 resonance:10 clip:1 ]", - "[ -5/4 ⇜ (1/4 → 1/2) ⇝ 3/4 | gain:0.15 note:C5 s:flbass n:0 cutoff:388.1591509854036 resonance:10 clip:1 ]", + "[ -3/4 ⇜ (0/1 → 3/4) ⇝ 5/4 | gain:0.0375 note:A4 s:flbass n:0 cutoff:915.369376468406 resonance:10 clip:1 ]", + "[ -3/4 ⇜ (0/1 → 3/4) ⇝ 5/4 | gain:0.0375 note:C5 s:flbass n:0 cutoff:915.369376468406 resonance:10 clip:1 ]", + "[ -3/2 ⇜ (1/4 → 1/2) | gain:0.3 note:A4 s:flbass n:0 cutoff:247.636966854535 resonance:10 clip:1 ]", + "[ -3/2 ⇜ (1/4 → 1/2) | gain:0.3 note:C5 s:flbass n:0 cutoff:247.636966854535 resonance:10 clip:1 ]", + "[ -5/4 ⇜ (1/4 → 1/2) ⇝ 3/4 | gain:0.15 note:A4 s:flbass n:0 cutoff:388.159150985404 resonance:10 clip:1 ]", + "[ -5/4 ⇜ (1/4 → 1/2) ⇝ 3/4 | gain:0.15 note:C5 s:flbass n:0 cutoff:388.159150985404 resonance:10 clip:1 ]", "[ 1/4 → 1/2 | note:C4 s:flbass n:0 gain:0.3 cutoff:2522.789774516997 resonance:10 clip:1 ]", "[ 1/4 → 1/2 | note:E4 s:flbass n:0 gain:0.3 cutoff:2522.789774516997 resonance:10 clip:1 ]", "[ 1/4 → 1/2 | s:hh n:0 ]", - "[ 3/8 → 1/2 | note:A2 s:flbass n:0 gain:0.3 cutoff:2727.5302177148174 resonance:10 clip:1 ]", - "[ -5/4 ⇜ (1/2 → 3/4) | gain:0.15 note:A4 s:flbass n:0 cutoff:388.1591509854036 resonance:10 clip:1 ]", - "[ -5/4 ⇜ (1/2 → 3/4) | gain:0.15 note:C5 s:flbass n:0 cutoff:388.1591509854036 resonance:10 clip:1 ]", - "[ -1/1 ⇜ (1/2 → 3/4) ⇝ 1/1 | gain:0.075 note:A4 s:flbass n:0 cutoff:614.5201833107434 resonance:10 clip:1 ]", - "[ -1/1 ⇜ (1/2 → 3/4) ⇝ 1/1 | gain:0.075 note:C5 s:flbass n:0 cutoff:614.5201833107434 resonance:10 clip:1 ]", - "[ 1/2 → 3/4 | gain:0.3 note:A4 s:flbass n:0 cutoff:2924.3791043233605 resonance:10 clip:1 ]", - "[ 1/2 → 3/4 | gain:0.3 note:C5 s:flbass n:0 cutoff:2924.3791043233605 resonance:10 clip:1 ]", + "[ 3/8 → 1/2 | note:A2 s:flbass n:0 gain:0.3 cutoff:2727.530217714817 resonance:10 clip:1 ]", + "[ -5/4 ⇜ (1/2 → 3/4) | gain:0.15 note:A4 s:flbass n:0 cutoff:388.159150985404 resonance:10 clip:1 ]", + "[ -5/4 ⇜ (1/2 → 3/4) | gain:0.15 note:C5 s:flbass n:0 cutoff:388.159150985404 resonance:10 clip:1 ]", + "[ -1/1 ⇜ (1/2 → 3/4) ⇝ 1/1 | gain:0.075 note:A4 s:flbass n:0 cutoff:614.520183310743 resonance:10 clip:1 ]", + "[ -1/1 ⇜ (1/2 → 3/4) ⇝ 1/1 | gain:0.075 note:C5 s:flbass n:0 cutoff:614.520183310743 resonance:10 clip:1 ]", + "[ 1/2 → 3/4 | gain:0.3 note:A4 s:flbass n:0 cutoff:2924.37910432336 resonance:10 clip:1 ]", + "[ 1/2 → 3/4 | gain:0.3 note:C5 s:flbass n:0 cutoff:2924.37910432336 resonance:10 clip:1 ]", "[ 1/2 → 1/1 | s:bd n:1 ]", "[ 1/2 → 1/1 | s:sd n:0 ]", - "[ 3/4 → 7/8 | note:A2 s:flbass n:0 gain:0.3 cutoff:3284.6306235315933 resonance:10 clip:1 ]", - "[ -1/1 ⇜ (3/4 → 1/1) | gain:0.075 note:A4 s:flbass n:0 cutoff:614.5201833107434 resonance:10 clip:1 ]", - "[ -1/1 ⇜ (3/4 → 1/1) | gain:0.075 note:C5 s:flbass n:0 cutoff:614.5201833107434 resonance:10 clip:1 ]", - "[ -3/4 ⇜ (3/4 → 1/1) ⇝ 5/4 | gain:0.0375 note:A4 s:flbass n:0 cutoff:915.3693764684064 resonance:10 clip:1 ]", - "[ -3/4 ⇜ (3/4 → 1/1) ⇝ 5/4 | gain:0.0375 note:C5 s:flbass n:0 cutoff:915.3693764684064 resonance:10 clip:1 ]", - "[ 3/4 → 1/1 | note:A3 s:flbass n:0 gain:0.3 cutoff:3284.6306235315933 resonance:10 clip:1 ]", - "[ 3/4 → 1/1 | gain:0.15 note:A4 s:flbass n:0 cutoff:3284.6306235315933 resonance:10 clip:1 ]", - "[ 3/4 → 1/1 | gain:0.15 note:C5 s:flbass n:0 cutoff:3284.6306235315933 resonance:10 clip:1 ]", + "[ 3/4 → 7/8 | note:A2 s:flbass n:0 gain:0.3 cutoff:3284.630623531593 resonance:10 clip:1 ]", + "[ -1/1 ⇜ (3/4 → 1/1) | gain:0.075 note:A4 s:flbass n:0 cutoff:614.520183310743 resonance:10 clip:1 ]", + "[ -1/1 ⇜ (3/4 → 1/1) | gain:0.075 note:C5 s:flbass n:0 cutoff:614.520183310743 resonance:10 clip:1 ]", + "[ -3/4 ⇜ (3/4 → 1/1) ⇝ 5/4 | gain:0.0375 note:A4 s:flbass n:0 cutoff:915.369376468406 resonance:10 clip:1 ]", + "[ -3/4 ⇜ (3/4 → 1/1) ⇝ 5/4 | gain:0.0375 note:C5 s:flbass n:0 cutoff:915.369376468406 resonance:10 clip:1 ]", + "[ 3/4 → 1/1 | note:A3 s:flbass n:0 gain:0.3 cutoff:3284.630623531593 resonance:10 clip:1 ]", + "[ 3/4 → 1/1 | gain:0.15 note:A4 s:flbass n:0 cutoff:3284.630623531593 resonance:10 clip:1 ]", + "[ 3/4 → 1/1 | gain:0.15 note:C5 s:flbass n:0 cutoff:3284.630623531593 resonance:10 clip:1 ]", "[ 3/4 → 1/1 | s:hh n:0 ]", ] `; @@ -303,16 +303,16 @@ exports[`renders tunes > tune: belldub 1`] = ` "[ 0/1 → 5/16 | s:mt gain:0.5 room:0.5 speed:0.5 ]", "[ 0/1 → 5/8 | note:G1 s:sawtooth cutoff:200 resonance:20 gain:0.15 shape:0.6 release:0.05 ]", "[ 0/1 → 5/8 | note:31.02 s:sawtooth cutoff:200 resonance:20 gain:0.15 shape:0.6 release:0.05 ]", - "[ (0/1 → 1/1) ⇝ 5/1 | s:misc n:2 speed:1 delay:0.5 delaytime:0.3333333333333333 gain:0.4 ]", - "[ (5/8 → 1/1) ⇝ 5/4 | s:hh room:0 end:0.028173022316468635 ]", - "[ (5/8 → 1/1) ⇝ 5/4 | note:58 s:sawtooth gain:0.8 cutoff:400.0503291283066 decay:0.05125097280354112 sustain:0 delay:0.9 room:1 ]", - "[ (5/8 → 1/1) ⇝ 5/4 | note:58.1 s:sawtooth gain:0.8 cutoff:400.0503291283066 decay:0.05125097280354112 sustain:0 delay:0.9 room:1 ]", - "[ (5/8 → 1/1) ⇝ 5/4 | note:62 s:sawtooth gain:0.8 cutoff:400.0503291283066 decay:0.05125097280354112 sustain:0 delay:0.9 room:1 ]", - "[ (5/8 → 1/1) ⇝ 5/4 | note:62.1 s:sawtooth gain:0.8 cutoff:400.0503291283066 decay:0.05125097280354112 sustain:0 delay:0.9 room:1 ]", - "[ (5/8 → 1/1) ⇝ 5/4 | note:65 s:sawtooth gain:0.8 cutoff:400.0503291283066 decay:0.05125097280354112 sustain:0 delay:0.9 room:1 ]", - "[ (5/8 → 1/1) ⇝ 5/4 | note:65.1 s:sawtooth gain:0.8 cutoff:400.0503291283066 decay:0.05125097280354112 sustain:0 delay:0.9 room:1 ]", - "[ (5/8 → 1/1) ⇝ 5/4 | note:69 s:sawtooth gain:0.8 cutoff:400.0503291283066 decay:0.05125097280354112 sustain:0 delay:0.9 room:1 ]", - "[ (5/8 → 1/1) ⇝ 5/4 | note:69.1 s:sawtooth gain:0.8 cutoff:400.0503291283066 decay:0.05125097280354112 sustain:0 delay:0.9 room:1 ]", + "[ (0/1 → 1/1) ⇝ 5/1 | s:misc n:2 speed:1 delay:0.5 delaytime:0.333333333333 gain:0.4 ]", + "[ (5/8 → 1/1) ⇝ 5/4 | s:hh room:0 end:0.028173022316 ]", + "[ (5/8 → 1/1) ⇝ 5/4 | note:58 s:sawtooth gain:0.8 cutoff:400.050329128307 decay:0.051250972804 sustain:0 delay:0.9 room:1 ]", + "[ (5/8 → 1/1) ⇝ 5/4 | note:58.1 s:sawtooth gain:0.8 cutoff:400.050329128307 decay:0.051250972804 sustain:0 delay:0.9 room:1 ]", + "[ (5/8 → 1/1) ⇝ 5/4 | note:62 s:sawtooth gain:0.8 cutoff:400.050329128307 decay:0.051250972804 sustain:0 delay:0.9 room:1 ]", + "[ (5/8 → 1/1) ⇝ 5/4 | note:62.1 s:sawtooth gain:0.8 cutoff:400.050329128307 decay:0.051250972804 sustain:0 delay:0.9 room:1 ]", + "[ (5/8 → 1/1) ⇝ 5/4 | note:65 s:sawtooth gain:0.8 cutoff:400.050329128307 decay:0.051250972804 sustain:0 delay:0.9 room:1 ]", + "[ (5/8 → 1/1) ⇝ 5/4 | note:65.1 s:sawtooth gain:0.8 cutoff:400.050329128307 decay:0.051250972804 sustain:0 delay:0.9 room:1 ]", + "[ (5/8 → 1/1) ⇝ 5/4 | note:69 s:sawtooth gain:0.8 cutoff:400.050329128307 decay:0.051250972804 sustain:0 delay:0.9 room:1 ]", + "[ (5/8 → 1/1) ⇝ 5/4 | note:69.1 s:sawtooth gain:0.8 cutoff:400.050329128307 decay:0.051250972804 sustain:0 delay:0.9 room:1 ]", "[ (5/8 → 1/1) ⇝ 5/4 | note:F4 s:bell begin:0.05 delay:0.2 gain:0.4 ]", "[ (15/16 → 1/1) ⇝ 5/4 | s:lt gain:0.5 room:0.5 speed:0.5 ]", ] @@ -320,21 +320,21 @@ exports[`renders tunes > tune: belldub 1`] = ` exports[`renders tunes > tune: blippyRhodes 1`] = ` [ - "[ 0/1 → 1/6 | note:G4 clip:0.3 s:rhodes room:0.5 delay:0.3 delayfeedback:0.4 delaytime:0.08333333333333333 gain:0.5 color:#7ED321 ]", + "[ 0/1 → 1/6 | note:G4 clip:0.3 s:rhodes room:0.5 delay:0.3 delayfeedback:0.4 delaytime:0.083333333333 gain:0.5 color:#7ED321 ]", "[ 0/1 → 1/3 | s:bd color:#00B8D4 ]", "[ (0/1 → 2/3) ⇝ 4/3 | note:36 gain:0.3 clip:1 cutoff:600 lpattack:0.2 lpenv:-4 s:sawtooth color:#F8E71C ]", "[ (0/1 → 2/3) ⇝ 4/3 | note:36.02 gain:0.3 clip:1 cutoff:600 lpattack:0.2 lpenv:-4 s:sawtooth color:#F8E71C ]", - "[ 1/6 → 1/3 | note:G4 clip:0.3 s:rhodes room:0.5 delay:0.3 delayfeedback:0.4 delaytime:0.08333333333333333 gain:0.5 color:#7ED321 ]", - "[ 1/3 → 1/2 | note:B3 clip:0.3 s:rhodes room:0.5 delay:0.3 delayfeedback:0.4 delaytime:0.08333333333333333 gain:0.5 color:#7ED321 ]", - "[ 1/3 → 1/2 | note:E4 clip:0.3 s:rhodes room:0.5 delay:0.3 delayfeedback:0.4 delaytime:0.08333333333333333 gain:0.5 color:#7ED321 ]", + "[ 1/6 → 1/3 | note:G4 clip:0.3 s:rhodes room:0.5 delay:0.3 delayfeedback:0.4 delaytime:0.083333333333 gain:0.5 color:#7ED321 ]", + "[ 1/3 → 1/2 | note:B3 clip:0.3 s:rhodes room:0.5 delay:0.3 delayfeedback:0.4 delaytime:0.083333333333 gain:0.5 color:#7ED321 ]", + "[ 1/3 → 1/2 | note:E4 clip:0.3 s:rhodes room:0.5 delay:0.3 delayfeedback:0.4 delaytime:0.083333333333 gain:0.5 color:#7ED321 ]", "[ 1/3 → 2/3 | s:hh color:#00B8D4 ]", - "[ 1/2 → 2/3 | note:B3 clip:0.3 s:rhodes room:0.5 delay:0.3 delayfeedback:0.4 delaytime:0.08333333333333333 gain:0.5 color:#7ED321 ]", - "[ 1/2 → 2/3 | note:E4 clip:0.3 s:rhodes room:0.5 delay:0.3 delayfeedback:0.4 delaytime:0.08333333333333333 gain:0.5 color:#7ED321 ]", - "[ 2/3 → 5/6 | note:G3 clip:0.3 s:rhodes room:0.5 delay:0.3 delayfeedback:0.4 delaytime:0.08333333333333333 gain:0.5 color:#7ED321 ]", + "[ 1/2 → 2/3 | note:B3 clip:0.3 s:rhodes room:0.5 delay:0.3 delayfeedback:0.4 delaytime:0.083333333333 gain:0.5 color:#7ED321 ]", + "[ 1/2 → 2/3 | note:E4 clip:0.3 s:rhodes room:0.5 delay:0.3 delayfeedback:0.4 delaytime:0.083333333333 gain:0.5 color:#7ED321 ]", + "[ 2/3 → 5/6 | note:G3 clip:0.3 s:rhodes room:0.5 delay:0.3 delayfeedback:0.4 delaytime:0.083333333333 gain:0.5 color:#7ED321 ]", "[ 0/1 ⇜ (2/3 → 1/1) ⇝ 4/3 | note:36 gain:0.3 clip:1 cutoff:600 lpattack:0.2 lpenv:-4 s:sawtooth color:#F8E71C ]", "[ 0/1 ⇜ (2/3 → 1/1) ⇝ 4/3 | note:36.02 gain:0.3 clip:1 cutoff:600 lpattack:0.2 lpenv:-4 s:sawtooth color:#F8E71C ]", "[ 2/3 → 1/1 | s:sn color:#00B8D4 ]", - "[ 5/6 → 1/1 | note:G3 clip:0.3 s:rhodes room:0.5 delay:0.3 delayfeedback:0.4 delaytime:0.08333333333333333 gain:0.5 color:#7ED321 ]", + "[ 5/6 → 1/1 | note:G3 clip:0.3 s:rhodes room:0.5 delay:0.3 delayfeedback:0.4 delaytime:0.083333333333 gain:0.5 color:#7ED321 ]", ] `; @@ -1148,5748 +1148,5748 @@ exports[`renders tunes > tune: dinofunk 1`] = ` exports[`renders tunes > tune: echoPiano 1`] = ` [ - "[ -3/8 ⇜ (0/1 → 1/8) | color:salmon note:G3 gain:0.5 clip:1 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ -3/8 ⇜ (0/1 → 1/8) | color:steelblue note:F4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ -3/8 ⇜ (0/1 → 1/8) | color:green note:Bb3 gain:0.125 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ -1/8 ⇜ (0/1 → 1/8) | color:steelblue note:D5 gain:0.125 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ -1/8 ⇜ (0/1 → 1/8) ⇝ 3/8 | color:green note:Bb3 gain:0.5 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ -1/8 ⇜ (0/1 → 1/8) ⇝ 3/8 | color:steelblue note:A4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ -1/4 ⇜ (0/1 → 1/4) | color:green note:Bb3 gain:1 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ -1/4 ⇜ (0/1 → 1/4) | color:steelblue note:A4 gain:1 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ -1/4 ⇜ (0/1 → 1/4) | color:salmon note:G3 gain:0.25 clip:1 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ -1/4 ⇜ (0/1 → 1/4) | color:steelblue note:F4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (0/1 → 1/4) ⇝ 1/2 | color:green note:Bb3 gain:0.25 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ (0/1 → 1/4) ⇝ 1/2 | color:steelblue note:A4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ -1/8 ⇜ (0/1 → 3/8) | color:salmon note:G3 gain:0.125 clip:1 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ -1/8 ⇜ (0/1 → 3/8) | color:steelblue note:F4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 0/1 → 1/2 | color:steelblue note:F4 gain:1 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 0/1 → 1/1 | color:salmon note:D3 gain:1 clip:1 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ -1/8 ⇜ (1/8 → 3/8) | color:green note:Bb3 gain:0.5 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ -1/8 ⇜ (1/8 → 3/8) | color:steelblue note:A4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (1/8 → 3/8) ⇝ 5/8 | color:green note:Bb3 gain:0.125 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ (1/8 → 3/8) ⇝ 5/8 | color:steelblue note:A4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 1/8 → 5/8 | color:steelblue note:F4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (1/8 → 1/1) ⇝ 9/8 | color:salmon note:D3 gain:0.5 clip:1 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ 0/1 ⇜ (1/4 → 1/2) | color:green note:Bb3 gain:0.25 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 0/1 ⇜ (1/4 → 1/2) | color:steelblue note:A4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (1/4 → 1/2) ⇝ 3/4 | color:steelblue note:A4 gain:1 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 1/4 → 3/4 | color:steelblue note:F4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (1/4 → 1/1) ⇝ 5/4 | color:green note:F3 gain:1 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ (1/4 → 1/1) ⇝ 5/4 | color:salmon note:D3 gain:0.25 clip:1 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ 1/8 ⇜ (3/8 → 5/8) | color:green note:Bb3 gain:0.125 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 1/8 ⇜ (3/8 → 5/8) | color:steelblue note:A4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (3/8 → 5/8) ⇝ 7/8 | color:steelblue note:A4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 3/8 → 7/8 | color:steelblue note:F4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (3/8 → 1/1) ⇝ 11/8 | color:green note:F3 gain:0.5 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ (3/8 → 1/1) ⇝ 11/8 | color:salmon note:D3 gain:0.125 clip:1 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ 1/4 ⇜ (1/2 → 3/4) | color:steelblue note:A4 gain:1 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (1/2 → 3/4) ⇝ 1/1 | color:steelblue note:A4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (1/2 → 1/1) ⇝ 3/2 | color:steelblue note:C4 gain:1 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ (1/2 → 1/1) ⇝ 3/2 | color:green note:F3 gain:0.25 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 3/8 ⇜ (5/8 → 7/8) | color:steelblue note:A4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (5/8 → 7/8) ⇝ 9/8 | color:steelblue note:A4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (5/8 → 1/1) ⇝ 13/8 | color:steelblue note:C4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ (5/8 → 1/1) ⇝ 13/8 | color:green note:F3 gain:0.125 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 1/2 ⇜ (3/4 → 1/1) | color:steelblue note:A4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (3/4 → 1/1) ⇝ 7/4 | color:steelblue note:E4 gain:1 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (3/4 → 1/1) ⇝ 7/4 | color:steelblue note:C4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 5/8 ⇜ (7/8 → 1/1) ⇝ 9/8 | color:steelblue note:A4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (7/8 → 1/1) ⇝ 15/8 | color:steelblue note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (7/8 → 1/1) ⇝ 15/8 | color:steelblue note:C4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 1/8 ⇜ (1/1 → 9/8) | color:salmon note:D3 gain:0.5 clip:1 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ 3/8 ⇜ (1/1 → 9/8) ⇝ 11/8 | color:green note:F3 gain:0.5 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 5/8 ⇜ (1/1 → 9/8) | color:steelblue note:A4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 5/8 ⇜ (1/1 → 9/8) ⇝ 13/8 | color:steelblue note:C4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 7/8 ⇜ (1/1 → 9/8) ⇝ 15/8 | color:steelblue note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 1/4 ⇜ (1/1 → 5/4) | color:green note:F3 gain:1 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 1/4 ⇜ (1/1 → 5/4) | color:salmon note:D3 gain:0.25 clip:1 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ 1/2 ⇜ (1/1 → 5/4) ⇝ 3/2 | color:green note:F3 gain:0.25 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 3/4 ⇜ (1/1 → 5/4) ⇝ 7/4 | color:steelblue note:C4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ (1/1 → 5/4) ⇝ 2/1 | color:steelblue note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 3/8 ⇜ (1/1 → 11/8) | color:salmon note:D3 gain:0.125 clip:1 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ 5/8 ⇜ (1/1 → 11/8) ⇝ 13/8 | color:green note:F3 gain:0.125 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 7/8 ⇜ (1/1 → 11/8) ⇝ 15/8 | color:steelblue note:C4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 1/2 ⇜ (1/1 → 3/2) | color:steelblue note:C4 gain:1 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 3/4 ⇜ (1/1 → 3/2) ⇝ 7/4 | color:steelblue note:E4 gain:1 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 1/1 → 2/1 | color:salmon note:F3 gain:1 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 3/8 ⇜ (9/8 → 11/8) | color:green note:F3 gain:0.5 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ (9/8 → 11/8) ⇝ 17/8 | color:steelblue note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 5/8 ⇜ (9/8 → 13/8) | color:steelblue note:C4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 7/8 ⇜ (9/8 → 13/8) ⇝ 15/8 | color:steelblue note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (9/8 → 2/1) ⇝ 17/8 | color:salmon note:F3 gain:0.5 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 1/2 ⇜ (5/4 → 3/2) | color:green note:F3 gain:0.25 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 3/4 ⇜ (5/4 → 7/4) | color:steelblue note:C4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 1/1 ⇜ (5/4 → 7/4) ⇝ 2/1 | color:steelblue note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (5/4 → 2/1) ⇝ 9/4 | color:green note:A3 gain:1 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ (5/4 → 2/1) ⇝ 9/4 | color:salmon note:F3 gain:0.25 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 5/8 ⇜ (11/8 → 13/8) | color:green note:F3 gain:0.125 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 7/8 ⇜ (11/8 → 15/8) | color:steelblue note:C4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 9/8 ⇜ (11/8 → 15/8) ⇝ 17/8 | color:steelblue note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (11/8 → 2/1) ⇝ 19/8 | color:green note:A3 gain:0.5 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ (11/8 → 2/1) ⇝ 19/8 | color:salmon note:F3 gain:0.125 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 3/4 ⇜ (3/2 → 7/4) | color:steelblue note:E4 gain:1 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (3/2 → 2/1) ⇝ 5/2 | color:steelblue note:E4 gain:1 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (3/2 → 2/1) ⇝ 5/2 | color:green note:A3 gain:0.25 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 7/8 ⇜ (13/8 → 15/8) | color:steelblue note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (13/8 → 2/1) ⇝ 21/8 | color:steelblue note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (13/8 → 2/1) ⇝ 21/8 | color:green note:A3 gain:0.125 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 1/1 ⇜ (7/4 → 2/1) | color:steelblue note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (7/4 → 2/1) ⇝ 11/4 | color:steelblue note:G4 gain:1 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (7/4 → 2/1) ⇝ 11/4 | color:steelblue note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 9/8 ⇜ (15/8 → 2/1) ⇝ 17/8 | color:steelblue note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (15/8 → 2/1) ⇝ 23/8 | color:steelblue note:G4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (15/8 → 2/1) ⇝ 23/8 | color:steelblue note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 9/8 ⇜ (2/1 → 17/8) | color:salmon note:F3 gain:0.5 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 9/8 ⇜ (2/1 → 17/8) | color:steelblue note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 11/8 ⇜ (2/1 → 17/8) ⇝ 19/8 | color:green note:A3 gain:0.5 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 13/8 ⇜ (2/1 → 17/8) ⇝ 21/8 | color:steelblue note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 15/8 ⇜ (2/1 → 17/8) ⇝ 23/8 | color:steelblue note:G4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/4 ⇜ (2/1 → 9/4) | color:green note:A3 gain:1 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 5/4 ⇜ (2/1 → 9/4) | color:salmon note:F3 gain:0.25 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 3/2 ⇜ (2/1 → 9/4) ⇝ 5/2 | color:green note:A3 gain:0.25 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 7/4 ⇜ (2/1 → 9/4) ⇝ 11/4 | color:steelblue note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 2/1 → 9/4 | color:salmon note:A3 gain:1 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ (2/1 → 9/4) ⇝ 3/1 | color:steelblue note:G4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 11/8 ⇜ (2/1 → 19/8) | color:salmon note:F3 gain:0.125 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 13/8 ⇜ (2/1 → 19/8) ⇝ 21/8 | color:green note:A3 gain:0.125 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 15/8 ⇜ (2/1 → 19/8) ⇝ 23/8 | color:steelblue note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 3/2 ⇜ (2/1 → 5/2) | color:steelblue note:E4 gain:1 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 7/4 ⇜ (2/1 → 5/2) ⇝ 11/4 | color:steelblue note:G4 gain:1 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 11/8 ⇜ (17/8 → 19/8) | color:green note:A3 gain:0.5 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 17/8 → 19/8 | color:salmon note:A3 gain:0.5 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ (17/8 → 19/8) ⇝ 25/8 | color:steelblue note:G4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 13/8 ⇜ (17/8 → 21/8) | color:steelblue note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 15/8 ⇜ (17/8 → 21/8) ⇝ 23/8 | color:steelblue note:G4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 3/2 ⇜ (9/4 → 5/2) | color:green note:A3 gain:0.25 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 9/4 → 5/2 | color:green note:C4 gain:1 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 9/4 → 5/2 | color:salmon note:A3 gain:0.25 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 7/4 ⇜ (9/4 → 11/4) | color:steelblue note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 2/1 ⇜ (9/4 → 11/4) ⇝ 3/1 | color:steelblue note:G4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 13/8 ⇜ (19/8 → 21/8) | color:green note:A3 gain:0.125 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 19/8 → 21/8 | color:green note:C4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 19/8 → 21/8 | color:salmon note:A3 gain:0.125 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 15/8 ⇜ (19/8 → 23/8) | color:steelblue note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 17/8 ⇜ (19/8 → 23/8) ⇝ 25/8 | color:steelblue note:G4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 7/4 ⇜ (5/2 → 11/4) | color:steelblue note:G4 gain:1 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/2 → 11/4 | color:salmon note:C4 gain:1 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 5/2 → 11/4 | color:steelblue note:G4 gain:1 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/2 → 11/4 | color:green note:C4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 15/8 ⇜ (21/8 → 23/8) | color:steelblue note:G4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 21/8 → 23/8 | color:salmon note:C4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 21/8 → 23/8 | color:steelblue note:G4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 21/8 → 23/8 | color:green note:C4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 2/1 ⇜ (11/4 → 3/1) | color:steelblue note:G4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 11/4 → 3/1 | color:salmon note:C4 gain:1 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 11/4 → 3/1 | color:green note:E4 gain:1 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 11/4 → 3/1 | color:steelblue note:Bb4 gain:1 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 11/4 → 3/1 | color:salmon note:C4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 11/4 → 3/1 | color:steelblue note:G4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 17/8 ⇜ (23/8 → 3/1) ⇝ 25/8 | color:steelblue note:G4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (23/8 → 3/1) ⇝ 25/8 | color:salmon note:C4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ (23/8 → 3/1) ⇝ 25/8 | color:green note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (23/8 → 3/1) ⇝ 25/8 | color:steelblue note:Bb4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ (23/8 → 3/1) ⇝ 25/8 | color:salmon note:C4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ (23/8 → 3/1) ⇝ 25/8 | color:steelblue note:G4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 17/8 ⇜ (3/1 → 25/8) | color:steelblue note:G4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 23/8 ⇜ (3/1 → 25/8) | color:salmon note:C4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 23/8 ⇜ (3/1 → 25/8) | color:green note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 23/8 ⇜ (3/1 → 25/8) | color:steelblue note:Bb4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 23/8 ⇜ (3/1 → 25/8) | color:salmon note:C4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 23/8 ⇜ (3/1 → 25/8) | color:steelblue note:G4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 3/1 → 13/4 | color:green note:E4 gain:1 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 3/1 → 13/4 | color:steelblue note:Bb4 gain:1 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 3/1 → 13/4 | color:salmon note:C4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 3/1 → 13/4 | color:green note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 3/1 → 13/4 | color:steelblue note:Bb4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 3/1 → 7/2 | color:salmon note:G3 gain:1 clip:1 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 25/8 → 27/8 | color:green note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 25/8 → 27/8 | color:steelblue note:Bb4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 25/8 → 27/8 | color:salmon note:C4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 25/8 → 27/8 | color:green note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 25/8 → 27/8 | color:steelblue note:Bb4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 25/8 → 29/8 | color:salmon note:G3 gain:0.5 clip:1 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 13/4 → 7/2 | color:steelblue note:Bb4 gain:1 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 13/4 → 7/2 | color:steelblue note:D5 gain:1 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 13/4 → 7/2 | color:green note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 13/4 → 7/2 | color:steelblue note:Bb4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 13/4 → 15/4 | color:green note:Bb3 gain:1 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 13/4 → 15/4 | color:salmon note:G3 gain:0.25 clip:1 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 27/8 → 29/8 | color:steelblue note:Bb4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 27/8 → 29/8 | color:steelblue note:D5 gain:0.5 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 27/8 → 29/8 | color:green note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 27/8 → 29/8 | color:steelblue note:Bb4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 27/8 → 31/8 | color:green note:Bb3 gain:0.5 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 27/8 → 31/8 | color:salmon note:G3 gain:0.125 clip:1 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 7/2 → 15/4 | color:steelblue note:D5 gain:1 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 7/2 → 15/4 | color:steelblue note:Bb4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 7/2 → 15/4 | color:steelblue note:D5 gain:0.25 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 7/2 → 4/1 | color:salmon note:G3 gain:1 clip:1 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 7/2 → 4/1 | color:steelblue note:F4 gain:1 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 7/2 → 4/1 | color:green note:Bb3 gain:0.25 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/8 → 31/8 | color:steelblue note:D5 gain:0.5 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 29/8 → 31/8 | color:steelblue note:Bb4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 29/8 → 31/8 | color:steelblue note:D5 gain:0.125 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (29/8 → 4/1) ⇝ 33/8 | color:salmon note:G3 gain:0.5 clip:1 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ (29/8 → 4/1) ⇝ 33/8 | color:steelblue note:F4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (29/8 → 4/1) ⇝ 33/8 | color:green note:Bb3 gain:0.125 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 15/4 → 4/1 | color:steelblue note:D5 gain:0.25 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (15/4 → 4/1) ⇝ 17/4 | color:green note:Bb3 gain:1 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ (15/4 → 4/1) ⇝ 17/4 | color:steelblue note:A4 gain:1 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (15/4 → 4/1) ⇝ 17/4 | color:salmon note:G3 gain:0.25 clip:1 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ (15/4 → 4/1) ⇝ 17/4 | color:steelblue note:F4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (31/8 → 4/1) ⇝ 33/8 | color:steelblue note:D5 gain:0.125 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (31/8 → 4/1) ⇝ 35/8 | color:green note:Bb3 gain:0.5 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ (31/8 → 4/1) ⇝ 35/8 | color:steelblue note:A4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (31/8 → 4/1) ⇝ 35/8 | color:salmon note:G3 gain:0.125 clip:1 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ (31/8 → 4/1) ⇝ 35/8 | color:steelblue note:F4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 29/8 ⇜ (4/1 → 33/8) | color:salmon note:G3 gain:0.5 clip:1 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 29/8 ⇜ (4/1 → 33/8) | color:steelblue note:F4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 29/8 ⇜ (4/1 → 33/8) | color:green note:Bb3 gain:0.125 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 31/8 ⇜ (4/1 → 33/8) | color:steelblue note:D5 gain:0.125 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 31/8 ⇜ (4/1 → 33/8) ⇝ 35/8 | color:green note:Bb3 gain:0.5 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 31/8 ⇜ (4/1 → 33/8) ⇝ 35/8 | color:steelblue note:A4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 15/4 ⇜ (4/1 → 17/4) | color:green note:Bb3 gain:1 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 15/4 ⇜ (4/1 → 17/4) | color:steelblue note:A4 gain:1 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 15/4 ⇜ (4/1 → 17/4) | color:salmon note:G3 gain:0.25 clip:1 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 15/4 ⇜ (4/1 → 17/4) | color:steelblue note:F4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (4/1 → 17/4) ⇝ 9/2 | color:green note:Bb3 gain:0.25 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ (4/1 → 17/4) ⇝ 9/2 | color:steelblue note:A4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 31/8 ⇜ (4/1 → 35/8) | color:salmon note:G3 gain:0.125 clip:1 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 31/8 ⇜ (4/1 → 35/8) | color:steelblue note:F4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 4/1 → 9/2 | color:steelblue note:F4 gain:1 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 4/1 → 5/1 | color:salmon note:D3 gain:1 clip:1 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ 31/8 ⇜ (33/8 → 35/8) | color:green note:Bb3 gain:0.5 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 31/8 ⇜ (33/8 → 35/8) | color:steelblue note:A4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (33/8 → 35/8) ⇝ 37/8 | color:green note:Bb3 gain:0.125 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ (33/8 → 35/8) ⇝ 37/8 | color:steelblue note:A4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 33/8 → 37/8 | color:steelblue note:F4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (33/8 → 5/1) ⇝ 41/8 | color:salmon note:D3 gain:0.5 clip:1 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ 4/1 ⇜ (17/4 → 9/2) | color:green note:Bb3 gain:0.25 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 4/1 ⇜ (17/4 → 9/2) | color:steelblue note:A4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (17/4 → 9/2) ⇝ 19/4 | color:steelblue note:A4 gain:1 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 17/4 → 19/4 | color:steelblue note:F4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (17/4 → 5/1) ⇝ 21/4 | color:green note:F3 gain:1 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ (17/4 → 5/1) ⇝ 21/4 | color:salmon note:D3 gain:0.25 clip:1 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ 33/8 ⇜ (35/8 → 37/8) | color:green note:Bb3 gain:0.125 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 33/8 ⇜ (35/8 → 37/8) | color:steelblue note:A4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (35/8 → 37/8) ⇝ 39/8 | color:steelblue note:A4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 35/8 → 39/8 | color:steelblue note:F4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (35/8 → 5/1) ⇝ 43/8 | color:green note:F3 gain:0.5 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ (35/8 → 5/1) ⇝ 43/8 | color:salmon note:D3 gain:0.125 clip:1 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ 17/4 ⇜ (9/2 → 19/4) | color:steelblue note:A4 gain:1 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (9/2 → 19/4) ⇝ 5/1 | color:steelblue note:A4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (9/2 → 5/1) ⇝ 11/2 | color:steelblue note:C4 gain:1 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ (9/2 → 5/1) ⇝ 11/2 | color:green note:F3 gain:0.25 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 35/8 ⇜ (37/8 → 39/8) | color:steelblue note:A4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (37/8 → 39/8) ⇝ 41/8 | color:steelblue note:A4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (37/8 → 5/1) ⇝ 45/8 | color:steelblue note:C4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ (37/8 → 5/1) ⇝ 45/8 | color:green note:F3 gain:0.125 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 9/2 ⇜ (19/4 → 5/1) | color:steelblue note:A4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (19/4 → 5/1) ⇝ 23/4 | color:steelblue note:E4 gain:1 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (19/4 → 5/1) ⇝ 23/4 | color:steelblue note:C4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 37/8 ⇜ (39/8 → 5/1) ⇝ 41/8 | color:steelblue note:A4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (39/8 → 5/1) ⇝ 47/8 | color:steelblue note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (39/8 → 5/1) ⇝ 47/8 | color:steelblue note:C4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 33/8 ⇜ (5/1 → 41/8) | color:salmon note:D3 gain:0.5 clip:1 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ 35/8 ⇜ (5/1 → 41/8) ⇝ 43/8 | color:green note:F3 gain:0.5 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 37/8 ⇜ (5/1 → 41/8) | color:steelblue note:A4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 37/8 ⇜ (5/1 → 41/8) ⇝ 45/8 | color:steelblue note:C4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 39/8 ⇜ (5/1 → 41/8) ⇝ 47/8 | color:steelblue note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 17/4 ⇜ (5/1 → 21/4) | color:green note:F3 gain:1 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 17/4 ⇜ (5/1 → 21/4) | color:salmon note:D3 gain:0.25 clip:1 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ 9/2 ⇜ (5/1 → 21/4) ⇝ 11/2 | color:green note:F3 gain:0.25 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 19/4 ⇜ (5/1 → 21/4) ⇝ 23/4 | color:steelblue note:C4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ (5/1 → 21/4) ⇝ 6/1 | color:steelblue note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 35/8 ⇜ (5/1 → 43/8) | color:salmon note:D3 gain:0.125 clip:1 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ 37/8 ⇜ (5/1 → 43/8) ⇝ 45/8 | color:green note:F3 gain:0.125 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 39/8 ⇜ (5/1 → 43/8) ⇝ 47/8 | color:steelblue note:C4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 9/2 ⇜ (5/1 → 11/2) | color:steelblue note:C4 gain:1 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 19/4 ⇜ (5/1 → 11/2) ⇝ 23/4 | color:steelblue note:E4 gain:1 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 5/1 → 6/1 | color:salmon note:F3 gain:1 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 35/8 ⇜ (41/8 → 43/8) | color:green note:F3 gain:0.5 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ (41/8 → 43/8) ⇝ 49/8 | color:steelblue note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 37/8 ⇜ (41/8 → 45/8) | color:steelblue note:C4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 39/8 ⇜ (41/8 → 45/8) ⇝ 47/8 | color:steelblue note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (41/8 → 6/1) ⇝ 49/8 | color:salmon note:F3 gain:0.5 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 9/2 ⇜ (21/4 → 11/2) | color:green note:F3 gain:0.25 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 19/4 ⇜ (21/4 → 23/4) | color:steelblue note:C4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 5/1 ⇜ (21/4 → 23/4) ⇝ 6/1 | color:steelblue note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (21/4 → 6/1) ⇝ 25/4 | color:green note:A3 gain:1 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ (21/4 → 6/1) ⇝ 25/4 | color:salmon note:F3 gain:0.25 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 37/8 ⇜ (43/8 → 45/8) | color:green note:F3 gain:0.125 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 39/8 ⇜ (43/8 → 47/8) | color:steelblue note:C4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 41/8 ⇜ (43/8 → 47/8) ⇝ 49/8 | color:steelblue note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (43/8 → 6/1) ⇝ 51/8 | color:green note:A3 gain:0.5 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ (43/8 → 6/1) ⇝ 51/8 | color:salmon note:F3 gain:0.125 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 19/4 ⇜ (11/2 → 23/4) | color:steelblue note:E4 gain:1 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (11/2 → 6/1) ⇝ 13/2 | color:steelblue note:E4 gain:1 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (11/2 → 6/1) ⇝ 13/2 | color:green note:A3 gain:0.25 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 39/8 ⇜ (45/8 → 47/8) | color:steelblue note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (45/8 → 6/1) ⇝ 53/8 | color:steelblue note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (45/8 → 6/1) ⇝ 53/8 | color:green note:A3 gain:0.125 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 5/1 ⇜ (23/4 → 6/1) | color:steelblue note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (23/4 → 6/1) ⇝ 27/4 | color:steelblue note:G4 gain:1 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (23/4 → 6/1) ⇝ 27/4 | color:steelblue note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 41/8 ⇜ (47/8 → 6/1) ⇝ 49/8 | color:steelblue note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (47/8 → 6/1) ⇝ 55/8 | color:steelblue note:G4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (47/8 → 6/1) ⇝ 55/8 | color:steelblue note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 41/8 ⇜ (6/1 → 49/8) | color:salmon note:F3 gain:0.5 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 41/8 ⇜ (6/1 → 49/8) | color:steelblue note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 43/8 ⇜ (6/1 → 49/8) ⇝ 51/8 | color:green note:A3 gain:0.5 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 45/8 ⇜ (6/1 → 49/8) ⇝ 53/8 | color:steelblue note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 47/8 ⇜ (6/1 → 49/8) ⇝ 55/8 | color:steelblue note:G4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 21/4 ⇜ (6/1 → 25/4) | color:green note:A3 gain:1 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 21/4 ⇜ (6/1 → 25/4) | color:salmon note:F3 gain:0.25 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 11/2 ⇜ (6/1 → 25/4) ⇝ 13/2 | color:green note:A3 gain:0.25 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 23/4 ⇜ (6/1 → 25/4) ⇝ 27/4 | color:steelblue note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 6/1 → 25/4 | color:salmon note:A3 gain:1 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ (6/1 → 25/4) ⇝ 7/1 | color:steelblue note:G4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 43/8 ⇜ (6/1 → 51/8) | color:salmon note:F3 gain:0.125 clip:1 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 45/8 ⇜ (6/1 → 51/8) ⇝ 53/8 | color:green note:A3 gain:0.125 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 47/8 ⇜ (6/1 → 51/8) ⇝ 55/8 | color:steelblue note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 11/2 ⇜ (6/1 → 13/2) | color:steelblue note:E4 gain:1 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 23/4 ⇜ (6/1 → 13/2) ⇝ 27/4 | color:steelblue note:G4 gain:1 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 43/8 ⇜ (49/8 → 51/8) | color:green note:A3 gain:0.5 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 49/8 → 51/8 | color:salmon note:A3 gain:0.5 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ (49/8 → 51/8) ⇝ 57/8 | color:steelblue note:G4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 45/8 ⇜ (49/8 → 53/8) | color:steelblue note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 47/8 ⇜ (49/8 → 53/8) ⇝ 55/8 | color:steelblue note:G4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 11/2 ⇜ (25/4 → 13/2) | color:green note:A3 gain:0.25 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 25/4 → 13/2 | color:green note:C4 gain:1 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 25/4 → 13/2 | color:salmon note:A3 gain:0.25 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 23/4 ⇜ (25/4 → 27/4) | color:steelblue note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 6/1 ⇜ (25/4 → 27/4) ⇝ 7/1 | color:steelblue note:G4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 45/8 ⇜ (51/8 → 53/8) | color:green note:A3 gain:0.125 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 51/8 → 53/8 | color:green note:C4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 51/8 → 53/8 | color:salmon note:A3 gain:0.125 clip:1 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 47/8 ⇜ (51/8 → 55/8) | color:steelblue note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 49/8 ⇜ (51/8 → 55/8) ⇝ 57/8 | color:steelblue note:G4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 23/4 ⇜ (13/2 → 27/4) | color:steelblue note:G4 gain:1 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 13/2 → 27/4 | color:salmon note:C4 gain:1 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 13/2 → 27/4 | color:steelblue note:G4 gain:1 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 13/2 → 27/4 | color:green note:C4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 47/8 ⇜ (53/8 → 55/8) | color:steelblue note:G4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 53/8 → 55/8 | color:salmon note:C4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 53/8 → 55/8 | color:steelblue note:G4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 53/8 → 55/8 | color:green note:C4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 6/1 ⇜ (27/4 → 7/1) | color:steelblue note:G4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 27/4 → 7/1 | color:salmon note:C4 gain:1 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 27/4 → 7/1 | color:green note:E4 gain:1 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 27/4 → 7/1 | color:steelblue note:Bb4 gain:1 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 27/4 → 7/1 | color:salmon note:C4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 27/4 → 7/1 | color:steelblue note:G4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 49/8 ⇜ (55/8 → 7/1) ⇝ 57/8 | color:steelblue note:G4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (55/8 → 7/1) ⇝ 57/8 | color:salmon note:C4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ (55/8 → 7/1) ⇝ 57/8 | color:green note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (55/8 → 7/1) ⇝ 57/8 | color:steelblue note:Bb4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ (55/8 → 7/1) ⇝ 57/8 | color:salmon note:C4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ (55/8 → 7/1) ⇝ 57/8 | color:steelblue note:G4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 49/8 ⇜ (7/1 → 57/8) | color:steelblue note:G4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 55/8 ⇜ (7/1 → 57/8) | color:salmon note:C4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 55/8 ⇜ (7/1 → 57/8) | color:green note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 55/8 ⇜ (7/1 → 57/8) | color:steelblue note:Bb4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 55/8 ⇜ (7/1 → 57/8) | color:salmon note:C4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 55/8 ⇜ (7/1 → 57/8) | color:steelblue note:G4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 7/1 → 29/4 | color:green note:E4 gain:1 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 7/1 → 29/4 | color:steelblue note:Bb4 gain:1 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 7/1 → 29/4 | color:salmon note:C4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 7/1 → 29/4 | color:green note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 7/1 → 29/4 | color:steelblue note:Bb4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 7/1 → 15/2 | color:salmon note:G3 gain:1 clip:1 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 57/8 → 59/8 | color:green note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 57/8 → 59/8 | color:steelblue note:Bb4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 57/8 → 59/8 | color:salmon note:C4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 57/8 → 59/8 | color:green note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 57/8 → 59/8 | color:steelblue note:Bb4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 57/8 → 61/8 | color:salmon note:G3 gain:0.5 clip:1 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 29/4 → 15/2 | color:steelblue note:Bb4 gain:1 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 29/4 → 15/2 | color:steelblue note:D5 gain:1 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 29/4 → 15/2 | color:green note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/4 → 15/2 | color:steelblue note:Bb4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 29/4 → 31/4 | color:green note:Bb3 gain:1 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/4 → 31/4 | color:salmon note:G3 gain:0.25 clip:1 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 59/8 → 61/8 | color:steelblue note:Bb4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 59/8 → 61/8 | color:steelblue note:D5 gain:0.5 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 59/8 → 61/8 | color:green note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 59/8 → 61/8 | color:steelblue note:Bb4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 59/8 → 63/8 | color:green note:Bb3 gain:0.5 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 59/8 → 63/8 | color:salmon note:G3 gain:0.125 clip:1 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 15/2 → 31/4 | color:steelblue note:D5 gain:1 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 15/2 → 31/4 | color:steelblue note:Bb4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 15/2 → 31/4 | color:steelblue note:D5 gain:0.25 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 15/2 → 8/1 | color:salmon note:G3 gain:1 clip:1 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 15/2 → 8/1 | color:steelblue note:F4 gain:1 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 15/2 → 8/1 | color:green note:Bb3 gain:0.25 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 61/8 → 63/8 | color:steelblue note:D5 gain:0.5 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 61/8 → 63/8 | color:steelblue note:Bb4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 61/8 → 63/8 | color:steelblue note:D5 gain:0.125 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (61/8 → 8/1) ⇝ 65/8 | color:salmon note:G3 gain:0.5 clip:1 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ (61/8 → 8/1) ⇝ 65/8 | color:steelblue note:F4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (61/8 → 8/1) ⇝ 65/8 | color:green note:Bb3 gain:0.125 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 31/4 → 8/1 | color:steelblue note:D5 gain:0.25 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (31/4 → 8/1) ⇝ 33/4 | color:green note:Bb3 gain:1 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ (31/4 → 8/1) ⇝ 33/4 | color:steelblue note:A4 gain:1 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (31/4 → 8/1) ⇝ 33/4 | color:salmon note:G3 gain:0.25 clip:1 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ (31/4 → 8/1) ⇝ 33/4 | color:steelblue note:F4 gain:0.25 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (63/8 → 8/1) ⇝ 65/8 | color:steelblue note:D5 gain:0.125 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (63/8 → 8/1) ⇝ 67/8 | color:green note:Bb3 gain:0.5 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ (63/8 → 8/1) ⇝ 67/8 | color:steelblue note:A4 gain:0.5 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (63/8 → 8/1) ⇝ 67/8 | color:salmon note:G3 gain:0.125 clip:1 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ (63/8 → 8/1) ⇝ 67/8 | color:steelblue note:F4 gain:0.125 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", + "[ -3/8 ⇜ (0/1 → 1/8) | color:salmon note:G3 gain:0.5 clip:1 s:piano release:0.1 pan:0.50462962963 ]", + "[ -3/8 ⇜ (0/1 → 1/8) | color:steelblue note:F4 gain:0.5 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ -3/8 ⇜ (0/1 → 1/8) | color:green note:Bb3 gain:0.125 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ -1/8 ⇜ (0/1 → 1/8) | color:steelblue note:D5 gain:0.125 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ -1/8 ⇜ (0/1 → 1/8) ⇝ 3/8 | color:green note:Bb3 gain:0.5 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ -1/8 ⇜ (0/1 → 1/8) ⇝ 3/8 | color:steelblue note:A4 gain:0.5 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ -1/4 ⇜ (0/1 → 1/4) | color:green note:Bb3 gain:1 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ -1/4 ⇜ (0/1 → 1/4) | color:steelblue note:A4 gain:1 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ -1/4 ⇜ (0/1 → 1/4) | color:salmon note:G3 gain:0.25 clip:1 s:piano release:0.1 pan:0.50462962963 ]", + "[ -1/4 ⇜ (0/1 → 1/4) | color:steelblue note:F4 gain:0.25 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ (0/1 → 1/4) ⇝ 1/2 | color:green note:Bb3 gain:0.25 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ (0/1 → 1/4) ⇝ 1/2 | color:steelblue note:A4 gain:0.25 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ -1/8 ⇜ (0/1 → 3/8) | color:salmon note:G3 gain:0.125 clip:1 s:piano release:0.1 pan:0.50462962963 ]", + "[ -1/8 ⇜ (0/1 → 3/8) | color:steelblue note:F4 gain:0.125 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 0/1 → 1/2 | color:steelblue note:F4 gain:1 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 0/1 → 1/1 | color:salmon note:D3 gain:1 clip:1 s:piano release:0.1 pan:0.481481481481 ]", + "[ -1/8 ⇜ (1/8 → 3/8) | color:green note:Bb3 gain:0.5 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ -1/8 ⇜ (1/8 → 3/8) | color:steelblue note:A4 gain:0.5 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ (1/8 → 3/8) ⇝ 5/8 | color:green note:Bb3 gain:0.125 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ (1/8 → 3/8) ⇝ 5/8 | color:steelblue note:A4 gain:0.125 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 1/8 → 5/8 | color:steelblue note:F4 gain:0.5 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ (1/8 → 1/1) ⇝ 9/8 | color:salmon note:D3 gain:0.5 clip:1 s:piano release:0.1 pan:0.481481481481 ]", + "[ 0/1 ⇜ (1/4 → 1/2) | color:green note:Bb3 gain:0.25 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 0/1 ⇜ (1/4 → 1/2) | color:steelblue note:A4 gain:0.25 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ (1/4 → 1/2) ⇝ 3/4 | color:steelblue note:A4 gain:1 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 1/4 → 3/4 | color:steelblue note:F4 gain:0.25 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ (1/4 → 1/1) ⇝ 5/4 | color:green note:F3 gain:1 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ (1/4 → 1/1) ⇝ 5/4 | color:salmon note:D3 gain:0.25 clip:1 s:piano release:0.1 pan:0.481481481481 ]", + "[ 1/8 ⇜ (3/8 → 5/8) | color:green note:Bb3 gain:0.125 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 1/8 ⇜ (3/8 → 5/8) | color:steelblue note:A4 gain:0.125 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ (3/8 → 5/8) ⇝ 7/8 | color:steelblue note:A4 gain:0.5 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 3/8 → 7/8 | color:steelblue note:F4 gain:0.125 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ (3/8 → 1/1) ⇝ 11/8 | color:green note:F3 gain:0.5 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ (3/8 → 1/1) ⇝ 11/8 | color:salmon note:D3 gain:0.125 clip:1 s:piano release:0.1 pan:0.481481481481 ]", + "[ 1/4 ⇜ (1/2 → 3/4) | color:steelblue note:A4 gain:1 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ (1/2 → 3/4) ⇝ 1/1 | color:steelblue note:A4 gain:0.25 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ (1/2 → 1/1) ⇝ 3/2 | color:steelblue note:C4 gain:1 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ (1/2 → 1/1) ⇝ 3/2 | color:green note:F3 gain:0.25 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 3/8 ⇜ (5/8 → 7/8) | color:steelblue note:A4 gain:0.5 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ (5/8 → 7/8) ⇝ 9/8 | color:steelblue note:A4 gain:0.125 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ (5/8 → 1/1) ⇝ 13/8 | color:steelblue note:C4 gain:0.5 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ (5/8 → 1/1) ⇝ 13/8 | color:green note:F3 gain:0.125 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 1/2 ⇜ (3/4 → 1/1) | color:steelblue note:A4 gain:0.25 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ (3/4 → 1/1) ⇝ 7/4 | color:steelblue note:E4 gain:1 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (3/4 → 1/1) ⇝ 7/4 | color:steelblue note:C4 gain:0.25 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 5/8 ⇜ (7/8 → 1/1) ⇝ 9/8 | color:steelblue note:A4 gain:0.125 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ (7/8 → 1/1) ⇝ 15/8 | color:steelblue note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (7/8 → 1/1) ⇝ 15/8 | color:steelblue note:C4 gain:0.125 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 1/8 ⇜ (1/1 → 9/8) | color:salmon note:D3 gain:0.5 clip:1 s:piano release:0.1 pan:0.481481481481 ]", + "[ 3/8 ⇜ (1/1 → 9/8) ⇝ 11/8 | color:green note:F3 gain:0.5 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 5/8 ⇜ (1/1 → 9/8) | color:steelblue note:A4 gain:0.125 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 5/8 ⇜ (1/1 → 9/8) ⇝ 13/8 | color:steelblue note:C4 gain:0.5 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 7/8 ⇜ (1/1 → 9/8) ⇝ 15/8 | color:steelblue note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 1/4 ⇜ (1/1 → 5/4) | color:green note:F3 gain:1 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 1/4 ⇜ (1/1 → 5/4) | color:salmon note:D3 gain:0.25 clip:1 s:piano release:0.1 pan:0.481481481481 ]", + "[ 1/2 ⇜ (1/1 → 5/4) ⇝ 3/2 | color:green note:F3 gain:0.25 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 3/4 ⇜ (1/1 → 5/4) ⇝ 7/4 | color:steelblue note:C4 gain:0.25 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ (1/1 → 5/4) ⇝ 2/1 | color:steelblue note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 3/8 ⇜ (1/1 → 11/8) | color:salmon note:D3 gain:0.125 clip:1 s:piano release:0.1 pan:0.481481481481 ]", + "[ 5/8 ⇜ (1/1 → 11/8) ⇝ 13/8 | color:green note:F3 gain:0.125 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 7/8 ⇜ (1/1 → 11/8) ⇝ 15/8 | color:steelblue note:C4 gain:0.125 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 1/2 ⇜ (1/1 → 3/2) | color:steelblue note:C4 gain:1 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 3/4 ⇜ (1/1 → 3/2) ⇝ 7/4 | color:steelblue note:E4 gain:1 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 1/1 → 2/1 | color:salmon note:F3 gain:1 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 3/8 ⇜ (9/8 → 11/8) | color:green note:F3 gain:0.5 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ (9/8 → 11/8) ⇝ 17/8 | color:steelblue note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 5/8 ⇜ (9/8 → 13/8) | color:steelblue note:C4 gain:0.5 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 7/8 ⇜ (9/8 → 13/8) ⇝ 15/8 | color:steelblue note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (9/8 → 2/1) ⇝ 17/8 | color:salmon note:F3 gain:0.5 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 1/2 ⇜ (5/4 → 3/2) | color:green note:F3 gain:0.25 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 3/4 ⇜ (5/4 → 7/4) | color:steelblue note:C4 gain:0.25 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 1/1 ⇜ (5/4 → 7/4) ⇝ 2/1 | color:steelblue note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (5/4 → 2/1) ⇝ 9/4 | color:green note:A3 gain:1 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ (5/4 → 2/1) ⇝ 9/4 | color:salmon note:F3 gain:0.25 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 5/8 ⇜ (11/8 → 13/8) | color:green note:F3 gain:0.125 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 7/8 ⇜ (11/8 → 15/8) | color:steelblue note:C4 gain:0.125 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 9/8 ⇜ (11/8 → 15/8) ⇝ 17/8 | color:steelblue note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (11/8 → 2/1) ⇝ 19/8 | color:green note:A3 gain:0.5 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ (11/8 → 2/1) ⇝ 19/8 | color:salmon note:F3 gain:0.125 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 3/4 ⇜ (3/2 → 7/4) | color:steelblue note:E4 gain:1 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (3/2 → 2/1) ⇝ 5/2 | color:steelblue note:E4 gain:1 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (3/2 → 2/1) ⇝ 5/2 | color:green note:A3 gain:0.25 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ 7/8 ⇜ (13/8 → 15/8) | color:steelblue note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (13/8 → 2/1) ⇝ 21/8 | color:steelblue note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (13/8 → 2/1) ⇝ 21/8 | color:green note:A3 gain:0.125 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ 1/1 ⇜ (7/4 → 2/1) | color:steelblue note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (7/4 → 2/1) ⇝ 11/4 | color:steelblue note:G4 gain:1 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (7/4 → 2/1) ⇝ 11/4 | color:steelblue note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 9/8 ⇜ (15/8 → 2/1) ⇝ 17/8 | color:steelblue note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (15/8 → 2/1) ⇝ 23/8 | color:steelblue note:G4 gain:0.5 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (15/8 → 2/1) ⇝ 23/8 | color:steelblue note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 9/8 ⇜ (2/1 → 17/8) | color:salmon note:F3 gain:0.5 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 9/8 ⇜ (2/1 → 17/8) | color:steelblue note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 11/8 ⇜ (2/1 → 17/8) ⇝ 19/8 | color:green note:A3 gain:0.5 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ 13/8 ⇜ (2/1 → 17/8) ⇝ 21/8 | color:steelblue note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 15/8 ⇜ (2/1 → 17/8) ⇝ 23/8 | color:steelblue note:G4 gain:0.5 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/4 ⇜ (2/1 → 9/4) | color:green note:A3 gain:1 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ 5/4 ⇜ (2/1 → 9/4) | color:salmon note:F3 gain:0.25 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 3/2 ⇜ (2/1 → 9/4) ⇝ 5/2 | color:green note:A3 gain:0.25 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ 7/4 ⇜ (2/1 → 9/4) ⇝ 11/4 | color:steelblue note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 2/1 → 9/4 | color:salmon note:A3 gain:1 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ (2/1 → 9/4) ⇝ 3/1 | color:steelblue note:G4 gain:0.25 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 11/8 ⇜ (2/1 → 19/8) | color:salmon note:F3 gain:0.125 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 13/8 ⇜ (2/1 → 19/8) ⇝ 21/8 | color:green note:A3 gain:0.125 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ 15/8 ⇜ (2/1 → 19/8) ⇝ 23/8 | color:steelblue note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 3/2 ⇜ (2/1 → 5/2) | color:steelblue note:E4 gain:1 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 7/4 ⇜ (2/1 → 5/2) ⇝ 11/4 | color:steelblue note:G4 gain:1 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 11/8 ⇜ (17/8 → 19/8) | color:green note:A3 gain:0.5 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ 17/8 → 19/8 | color:salmon note:A3 gain:0.5 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ (17/8 → 19/8) ⇝ 25/8 | color:steelblue note:G4 gain:0.125 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 13/8 ⇜ (17/8 → 21/8) | color:steelblue note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 15/8 ⇜ (17/8 → 21/8) ⇝ 23/8 | color:steelblue note:G4 gain:0.5 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 3/2 ⇜ (9/4 → 5/2) | color:green note:A3 gain:0.25 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ 9/4 → 5/2 | color:green note:C4 gain:1 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 9/4 → 5/2 | color:salmon note:A3 gain:0.25 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ 7/4 ⇜ (9/4 → 11/4) | color:steelblue note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 2/1 ⇜ (9/4 → 11/4) ⇝ 3/1 | color:steelblue note:G4 gain:0.25 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 13/8 ⇜ (19/8 → 21/8) | color:green note:A3 gain:0.125 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ 19/8 → 21/8 | color:green note:C4 gain:0.5 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 19/8 → 21/8 | color:salmon note:A3 gain:0.125 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ 15/8 ⇜ (19/8 → 23/8) | color:steelblue note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 17/8 ⇜ (19/8 → 23/8) ⇝ 25/8 | color:steelblue note:G4 gain:0.125 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 7/4 ⇜ (5/2 → 11/4) | color:steelblue note:G4 gain:1 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/2 → 11/4 | color:salmon note:C4 gain:1 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 5/2 → 11/4 | color:steelblue note:G4 gain:1 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/2 → 11/4 | color:green note:C4 gain:0.25 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 15/8 ⇜ (21/8 → 23/8) | color:steelblue note:G4 gain:0.5 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 21/8 → 23/8 | color:salmon note:C4 gain:0.5 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 21/8 → 23/8 | color:steelblue note:G4 gain:0.5 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 21/8 → 23/8 | color:green note:C4 gain:0.125 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 2/1 ⇜ (11/4 → 3/1) | color:steelblue note:G4 gain:0.25 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 11/4 → 3/1 | color:salmon note:C4 gain:1 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 11/4 → 3/1 | color:green note:E4 gain:1 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 11/4 → 3/1 | color:steelblue note:Bb4 gain:1 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 11/4 → 3/1 | color:salmon note:C4 gain:0.25 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 11/4 → 3/1 | color:steelblue note:G4 gain:0.25 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 17/8 ⇜ (23/8 → 3/1) ⇝ 25/8 | color:steelblue note:G4 gain:0.125 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (23/8 → 3/1) ⇝ 25/8 | color:salmon note:C4 gain:0.5 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ (23/8 → 3/1) ⇝ 25/8 | color:green note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (23/8 → 3/1) ⇝ 25/8 | color:steelblue note:Bb4 gain:0.5 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ (23/8 → 3/1) ⇝ 25/8 | color:salmon note:C4 gain:0.125 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ (23/8 → 3/1) ⇝ 25/8 | color:steelblue note:G4 gain:0.125 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 17/8 ⇜ (3/1 → 25/8) | color:steelblue note:G4 gain:0.125 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 23/8 ⇜ (3/1 → 25/8) | color:salmon note:C4 gain:0.5 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 23/8 ⇜ (3/1 → 25/8) | color:green note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 23/8 ⇜ (3/1 → 25/8) | color:steelblue note:Bb4 gain:0.5 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 23/8 ⇜ (3/1 → 25/8) | color:salmon note:C4 gain:0.125 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 23/8 ⇜ (3/1 → 25/8) | color:steelblue note:G4 gain:0.125 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 3/1 → 13/4 | color:green note:E4 gain:1 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 3/1 → 13/4 | color:steelblue note:Bb4 gain:1 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 3/1 → 13/4 | color:salmon note:C4 gain:0.25 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 3/1 → 13/4 | color:green note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 3/1 → 13/4 | color:steelblue note:Bb4 gain:0.25 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 3/1 → 7/2 | color:salmon note:G3 gain:1 clip:1 s:piano release:0.1 pan:0.50462962963 ]", + "[ 25/8 → 27/8 | color:green note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 25/8 → 27/8 | color:steelblue note:Bb4 gain:0.5 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 25/8 → 27/8 | color:salmon note:C4 gain:0.125 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 25/8 → 27/8 | color:green note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 25/8 → 27/8 | color:steelblue note:Bb4 gain:0.125 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 25/8 → 29/8 | color:salmon note:G3 gain:0.5 clip:1 s:piano release:0.1 pan:0.50462962963 ]", + "[ 13/4 → 7/2 | color:steelblue note:Bb4 gain:1 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 13/4 → 7/2 | color:steelblue note:D5 gain:1 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 13/4 → 7/2 | color:green note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 13/4 → 7/2 | color:steelblue note:Bb4 gain:0.25 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 13/4 → 15/4 | color:green note:Bb3 gain:1 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 13/4 → 15/4 | color:salmon note:G3 gain:0.25 clip:1 s:piano release:0.1 pan:0.50462962963 ]", + "[ 27/8 → 29/8 | color:steelblue note:Bb4 gain:0.5 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 27/8 → 29/8 | color:steelblue note:D5 gain:0.5 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 27/8 → 29/8 | color:green note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 27/8 → 29/8 | color:steelblue note:Bb4 gain:0.125 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 27/8 → 31/8 | color:green note:Bb3 gain:0.5 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 27/8 → 31/8 | color:salmon note:G3 gain:0.125 clip:1 s:piano release:0.1 pan:0.50462962963 ]", + "[ 7/2 → 15/4 | color:steelblue note:D5 gain:1 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 7/2 → 15/4 | color:steelblue note:Bb4 gain:0.25 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 7/2 → 15/4 | color:steelblue note:D5 gain:0.25 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 7/2 → 4/1 | color:salmon note:G3 gain:1 clip:1 s:piano release:0.1 pan:0.50462962963 ]", + "[ 7/2 → 4/1 | color:steelblue note:F4 gain:1 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 7/2 → 4/1 | color:green note:Bb3 gain:0.25 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/8 → 31/8 | color:steelblue note:D5 gain:0.5 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 29/8 → 31/8 | color:steelblue note:Bb4 gain:0.125 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 29/8 → 31/8 | color:steelblue note:D5 gain:0.125 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ (29/8 → 4/1) ⇝ 33/8 | color:salmon note:G3 gain:0.5 clip:1 s:piano release:0.1 pan:0.50462962963 ]", + "[ (29/8 → 4/1) ⇝ 33/8 | color:steelblue note:F4 gain:0.5 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ (29/8 → 4/1) ⇝ 33/8 | color:green note:Bb3 gain:0.125 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 15/4 → 4/1 | color:steelblue note:D5 gain:0.25 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ (15/4 → 4/1) ⇝ 17/4 | color:green note:Bb3 gain:1 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ (15/4 → 4/1) ⇝ 17/4 | color:steelblue note:A4 gain:1 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ (15/4 → 4/1) ⇝ 17/4 | color:salmon note:G3 gain:0.25 clip:1 s:piano release:0.1 pan:0.50462962963 ]", + "[ (15/4 → 4/1) ⇝ 17/4 | color:steelblue note:F4 gain:0.25 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ (31/8 → 4/1) ⇝ 33/8 | color:steelblue note:D5 gain:0.125 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ (31/8 → 4/1) ⇝ 35/8 | color:green note:Bb3 gain:0.5 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ (31/8 → 4/1) ⇝ 35/8 | color:steelblue note:A4 gain:0.5 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ (31/8 → 4/1) ⇝ 35/8 | color:salmon note:G3 gain:0.125 clip:1 s:piano release:0.1 pan:0.50462962963 ]", + "[ (31/8 → 4/1) ⇝ 35/8 | color:steelblue note:F4 gain:0.125 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 29/8 ⇜ (4/1 → 33/8) | color:salmon note:G3 gain:0.5 clip:1 s:piano release:0.1 pan:0.50462962963 ]", + "[ 29/8 ⇜ (4/1 → 33/8) | color:steelblue note:F4 gain:0.5 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 29/8 ⇜ (4/1 → 33/8) | color:green note:Bb3 gain:0.125 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 31/8 ⇜ (4/1 → 33/8) | color:steelblue note:D5 gain:0.125 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 31/8 ⇜ (4/1 → 33/8) ⇝ 35/8 | color:green note:Bb3 gain:0.5 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 31/8 ⇜ (4/1 → 33/8) ⇝ 35/8 | color:steelblue note:A4 gain:0.5 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 15/4 ⇜ (4/1 → 17/4) | color:green note:Bb3 gain:1 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 15/4 ⇜ (4/1 → 17/4) | color:steelblue note:A4 gain:1 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 15/4 ⇜ (4/1 → 17/4) | color:salmon note:G3 gain:0.25 clip:1 s:piano release:0.1 pan:0.50462962963 ]", + "[ 15/4 ⇜ (4/1 → 17/4) | color:steelblue note:F4 gain:0.25 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ (4/1 → 17/4) ⇝ 9/2 | color:green note:Bb3 gain:0.25 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ (4/1 → 17/4) ⇝ 9/2 | color:steelblue note:A4 gain:0.25 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 31/8 ⇜ (4/1 → 35/8) | color:salmon note:G3 gain:0.125 clip:1 s:piano release:0.1 pan:0.50462962963 ]", + "[ 31/8 ⇜ (4/1 → 35/8) | color:steelblue note:F4 gain:0.125 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 4/1 → 9/2 | color:steelblue note:F4 gain:1 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 4/1 → 5/1 | color:salmon note:D3 gain:1 clip:1 s:piano release:0.1 pan:0.481481481481 ]", + "[ 31/8 ⇜ (33/8 → 35/8) | color:green note:Bb3 gain:0.5 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 31/8 ⇜ (33/8 → 35/8) | color:steelblue note:A4 gain:0.5 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ (33/8 → 35/8) ⇝ 37/8 | color:green note:Bb3 gain:0.125 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ (33/8 → 35/8) ⇝ 37/8 | color:steelblue note:A4 gain:0.125 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 33/8 → 37/8 | color:steelblue note:F4 gain:0.5 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ (33/8 → 5/1) ⇝ 41/8 | color:salmon note:D3 gain:0.5 clip:1 s:piano release:0.1 pan:0.481481481481 ]", + "[ 4/1 ⇜ (17/4 → 9/2) | color:green note:Bb3 gain:0.25 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 4/1 ⇜ (17/4 → 9/2) | color:steelblue note:A4 gain:0.25 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ (17/4 → 9/2) ⇝ 19/4 | color:steelblue note:A4 gain:1 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 17/4 → 19/4 | color:steelblue note:F4 gain:0.25 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ (17/4 → 5/1) ⇝ 21/4 | color:green note:F3 gain:1 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ (17/4 → 5/1) ⇝ 21/4 | color:salmon note:D3 gain:0.25 clip:1 s:piano release:0.1 pan:0.481481481481 ]", + "[ 33/8 ⇜ (35/8 → 37/8) | color:green note:Bb3 gain:0.125 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 33/8 ⇜ (35/8 → 37/8) | color:steelblue note:A4 gain:0.125 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ (35/8 → 37/8) ⇝ 39/8 | color:steelblue note:A4 gain:0.5 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 35/8 → 39/8 | color:steelblue note:F4 gain:0.125 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ (35/8 → 5/1) ⇝ 43/8 | color:green note:F3 gain:0.5 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ (35/8 → 5/1) ⇝ 43/8 | color:salmon note:D3 gain:0.125 clip:1 s:piano release:0.1 pan:0.481481481481 ]", + "[ 17/4 ⇜ (9/2 → 19/4) | color:steelblue note:A4 gain:1 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ (9/2 → 19/4) ⇝ 5/1 | color:steelblue note:A4 gain:0.25 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ (9/2 → 5/1) ⇝ 11/2 | color:steelblue note:C4 gain:1 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ (9/2 → 5/1) ⇝ 11/2 | color:green note:F3 gain:0.25 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 35/8 ⇜ (37/8 → 39/8) | color:steelblue note:A4 gain:0.5 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ (37/8 → 39/8) ⇝ 41/8 | color:steelblue note:A4 gain:0.125 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ (37/8 → 5/1) ⇝ 45/8 | color:steelblue note:C4 gain:0.5 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ (37/8 → 5/1) ⇝ 45/8 | color:green note:F3 gain:0.125 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 9/2 ⇜ (19/4 → 5/1) | color:steelblue note:A4 gain:0.25 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ (19/4 → 5/1) ⇝ 23/4 | color:steelblue note:E4 gain:1 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (19/4 → 5/1) ⇝ 23/4 | color:steelblue note:C4 gain:0.25 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 37/8 ⇜ (39/8 → 5/1) ⇝ 41/8 | color:steelblue note:A4 gain:0.125 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ (39/8 → 5/1) ⇝ 47/8 | color:steelblue note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (39/8 → 5/1) ⇝ 47/8 | color:steelblue note:C4 gain:0.125 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 33/8 ⇜ (5/1 → 41/8) | color:salmon note:D3 gain:0.5 clip:1 s:piano release:0.1 pan:0.481481481481 ]", + "[ 35/8 ⇜ (5/1 → 41/8) ⇝ 43/8 | color:green note:F3 gain:0.5 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 37/8 ⇜ (5/1 → 41/8) | color:steelblue note:A4 gain:0.125 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 37/8 ⇜ (5/1 → 41/8) ⇝ 45/8 | color:steelblue note:C4 gain:0.5 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 39/8 ⇜ (5/1 → 41/8) ⇝ 47/8 | color:steelblue note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 17/4 ⇜ (5/1 → 21/4) | color:green note:F3 gain:1 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 17/4 ⇜ (5/1 → 21/4) | color:salmon note:D3 gain:0.25 clip:1 s:piano release:0.1 pan:0.481481481481 ]", + "[ 9/2 ⇜ (5/1 → 21/4) ⇝ 11/2 | color:green note:F3 gain:0.25 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 19/4 ⇜ (5/1 → 21/4) ⇝ 23/4 | color:steelblue note:C4 gain:0.25 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ (5/1 → 21/4) ⇝ 6/1 | color:steelblue note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 35/8 ⇜ (5/1 → 43/8) | color:salmon note:D3 gain:0.125 clip:1 s:piano release:0.1 pan:0.481481481481 ]", + "[ 37/8 ⇜ (5/1 → 43/8) ⇝ 45/8 | color:green note:F3 gain:0.125 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 39/8 ⇜ (5/1 → 43/8) ⇝ 47/8 | color:steelblue note:C4 gain:0.125 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 9/2 ⇜ (5/1 → 11/2) | color:steelblue note:C4 gain:1 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 19/4 ⇜ (5/1 → 11/2) ⇝ 23/4 | color:steelblue note:E4 gain:1 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 5/1 → 6/1 | color:salmon note:F3 gain:1 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 35/8 ⇜ (41/8 → 43/8) | color:green note:F3 gain:0.5 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ (41/8 → 43/8) ⇝ 49/8 | color:steelblue note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 37/8 ⇜ (41/8 → 45/8) | color:steelblue note:C4 gain:0.5 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 39/8 ⇜ (41/8 → 45/8) ⇝ 47/8 | color:steelblue note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (41/8 → 6/1) ⇝ 49/8 | color:salmon note:F3 gain:0.5 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 9/2 ⇜ (21/4 → 11/2) | color:green note:F3 gain:0.25 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 19/4 ⇜ (21/4 → 23/4) | color:steelblue note:C4 gain:0.25 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 5/1 ⇜ (21/4 → 23/4) ⇝ 6/1 | color:steelblue note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (21/4 → 6/1) ⇝ 25/4 | color:green note:A3 gain:1 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ (21/4 → 6/1) ⇝ 25/4 | color:salmon note:F3 gain:0.25 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 37/8 ⇜ (43/8 → 45/8) | color:green note:F3 gain:0.125 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 39/8 ⇜ (43/8 → 47/8) | color:steelblue note:C4 gain:0.125 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 41/8 ⇜ (43/8 → 47/8) ⇝ 49/8 | color:steelblue note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (43/8 → 6/1) ⇝ 51/8 | color:green note:A3 gain:0.5 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ (43/8 → 6/1) ⇝ 51/8 | color:salmon note:F3 gain:0.125 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 19/4 ⇜ (11/2 → 23/4) | color:steelblue note:E4 gain:1 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (11/2 → 6/1) ⇝ 13/2 | color:steelblue note:E4 gain:1 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (11/2 → 6/1) ⇝ 13/2 | color:green note:A3 gain:0.25 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ 39/8 ⇜ (45/8 → 47/8) | color:steelblue note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (45/8 → 6/1) ⇝ 53/8 | color:steelblue note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (45/8 → 6/1) ⇝ 53/8 | color:green note:A3 gain:0.125 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ 5/1 ⇜ (23/4 → 6/1) | color:steelblue note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (23/4 → 6/1) ⇝ 27/4 | color:steelblue note:G4 gain:1 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (23/4 → 6/1) ⇝ 27/4 | color:steelblue note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 41/8 ⇜ (47/8 → 6/1) ⇝ 49/8 | color:steelblue note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (47/8 → 6/1) ⇝ 55/8 | color:steelblue note:G4 gain:0.5 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (47/8 → 6/1) ⇝ 55/8 | color:steelblue note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 41/8 ⇜ (6/1 → 49/8) | color:salmon note:F3 gain:0.5 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 41/8 ⇜ (6/1 → 49/8) | color:steelblue note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 43/8 ⇜ (6/1 → 49/8) ⇝ 51/8 | color:green note:A3 gain:0.5 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ 45/8 ⇜ (6/1 → 49/8) ⇝ 53/8 | color:steelblue note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 47/8 ⇜ (6/1 → 49/8) ⇝ 55/8 | color:steelblue note:G4 gain:0.5 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 21/4 ⇜ (6/1 → 25/4) | color:green note:A3 gain:1 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ 21/4 ⇜ (6/1 → 25/4) | color:salmon note:F3 gain:0.25 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 11/2 ⇜ (6/1 → 25/4) ⇝ 13/2 | color:green note:A3 gain:0.25 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ 23/4 ⇜ (6/1 → 25/4) ⇝ 27/4 | color:steelblue note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 6/1 → 25/4 | color:salmon note:A3 gain:1 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ (6/1 → 25/4) ⇝ 7/1 | color:steelblue note:G4 gain:0.25 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 43/8 ⇜ (6/1 → 51/8) | color:salmon note:F3 gain:0.125 clip:1 s:piano release:0.1 pan:0.49537037037 ]", + "[ 45/8 ⇜ (6/1 → 51/8) ⇝ 53/8 | color:green note:A3 gain:0.125 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ 47/8 ⇜ (6/1 → 51/8) ⇝ 55/8 | color:steelblue note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 11/2 ⇜ (6/1 → 13/2) | color:steelblue note:E4 gain:1 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 23/4 ⇜ (6/1 → 13/2) ⇝ 27/4 | color:steelblue note:G4 gain:1 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 43/8 ⇜ (49/8 → 51/8) | color:green note:A3 gain:0.5 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ 49/8 → 51/8 | color:salmon note:A3 gain:0.5 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ (49/8 → 51/8) ⇝ 57/8 | color:steelblue note:G4 gain:0.125 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 45/8 ⇜ (49/8 → 53/8) | color:steelblue note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 47/8 ⇜ (49/8 → 53/8) ⇝ 55/8 | color:steelblue note:G4 gain:0.5 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 11/2 ⇜ (25/4 → 13/2) | color:green note:A3 gain:0.25 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ 25/4 → 13/2 | color:green note:C4 gain:1 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 25/4 → 13/2 | color:salmon note:A3 gain:0.25 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ 23/4 ⇜ (25/4 → 27/4) | color:steelblue note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 6/1 ⇜ (25/4 → 27/4) ⇝ 7/1 | color:steelblue note:G4 gain:0.25 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 45/8 ⇜ (51/8 → 53/8) | color:green note:A3 gain:0.125 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ 51/8 → 53/8 | color:green note:C4 gain:0.5 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 51/8 → 53/8 | color:salmon note:A3 gain:0.125 clip:1 s:piano release:0.1 pan:0.513888888889 ]", + "[ 47/8 ⇜ (51/8 → 55/8) | color:steelblue note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 49/8 ⇜ (51/8 → 55/8) ⇝ 57/8 | color:steelblue note:G4 gain:0.125 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 23/4 ⇜ (13/2 → 27/4) | color:steelblue note:G4 gain:1 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 13/2 → 27/4 | color:salmon note:C4 gain:1 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 13/2 → 27/4 | color:steelblue note:G4 gain:1 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 13/2 → 27/4 | color:green note:C4 gain:0.25 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 47/8 ⇜ (53/8 → 55/8) | color:steelblue note:G4 gain:0.5 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 53/8 → 55/8 | color:salmon note:C4 gain:0.5 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 53/8 → 55/8 | color:steelblue note:G4 gain:0.5 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 53/8 → 55/8 | color:green note:C4 gain:0.125 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 6/1 ⇜ (27/4 → 7/1) | color:steelblue note:G4 gain:0.25 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 27/4 → 7/1 | color:salmon note:C4 gain:1 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 27/4 → 7/1 | color:green note:E4 gain:1 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 27/4 → 7/1 | color:steelblue note:Bb4 gain:1 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 27/4 → 7/1 | color:salmon note:C4 gain:0.25 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 27/4 → 7/1 | color:steelblue note:G4 gain:0.25 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 49/8 ⇜ (55/8 → 7/1) ⇝ 57/8 | color:steelblue note:G4 gain:0.125 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (55/8 → 7/1) ⇝ 57/8 | color:salmon note:C4 gain:0.5 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ (55/8 → 7/1) ⇝ 57/8 | color:green note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (55/8 → 7/1) ⇝ 57/8 | color:steelblue note:Bb4 gain:0.5 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ (55/8 → 7/1) ⇝ 57/8 | color:salmon note:C4 gain:0.125 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ (55/8 → 7/1) ⇝ 57/8 | color:steelblue note:G4 gain:0.125 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 49/8 ⇜ (7/1 → 57/8) | color:steelblue note:G4 gain:0.125 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 55/8 ⇜ (7/1 → 57/8) | color:salmon note:C4 gain:0.5 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 55/8 ⇜ (7/1 → 57/8) | color:green note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 55/8 ⇜ (7/1 → 57/8) | color:steelblue note:Bb4 gain:0.5 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 55/8 ⇜ (7/1 → 57/8) | color:salmon note:C4 gain:0.125 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 55/8 ⇜ (7/1 → 57/8) | color:steelblue note:G4 gain:0.125 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 7/1 → 29/4 | color:green note:E4 gain:1 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 7/1 → 29/4 | color:steelblue note:Bb4 gain:1 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 7/1 → 29/4 | color:salmon note:C4 gain:0.25 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 7/1 → 29/4 | color:green note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 7/1 → 29/4 | color:steelblue note:Bb4 gain:0.25 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 7/1 → 15/2 | color:salmon note:G3 gain:1 clip:1 s:piano release:0.1 pan:0.50462962963 ]", + "[ 57/8 → 59/8 | color:green note:E4 gain:0.5 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 57/8 → 59/8 | color:steelblue note:Bb4 gain:0.5 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 57/8 → 59/8 | color:salmon note:C4 gain:0.125 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 57/8 → 59/8 | color:green note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 57/8 → 59/8 | color:steelblue note:Bb4 gain:0.125 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 57/8 → 61/8 | color:salmon note:G3 gain:0.5 clip:1 s:piano release:0.1 pan:0.50462962963 ]", + "[ 29/4 → 15/2 | color:steelblue note:Bb4 gain:1 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 29/4 → 15/2 | color:steelblue note:D5 gain:1 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 29/4 → 15/2 | color:green note:E4 gain:0.25 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/4 → 15/2 | color:steelblue note:Bb4 gain:0.25 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 29/4 → 31/4 | color:green note:Bb3 gain:1 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/4 → 31/4 | color:salmon note:G3 gain:0.25 clip:1 s:piano release:0.1 pan:0.50462962963 ]", + "[ 59/8 → 61/8 | color:steelblue note:Bb4 gain:0.5 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 59/8 → 61/8 | color:steelblue note:D5 gain:0.5 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 59/8 → 61/8 | color:green note:E4 gain:0.125 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 59/8 → 61/8 | color:steelblue note:Bb4 gain:0.125 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 59/8 → 63/8 | color:green note:Bb3 gain:0.5 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 59/8 → 63/8 | color:salmon note:G3 gain:0.125 clip:1 s:piano release:0.1 pan:0.50462962963 ]", + "[ 15/2 → 31/4 | color:steelblue note:D5 gain:1 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 15/2 → 31/4 | color:steelblue note:Bb4 gain:0.25 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 15/2 → 31/4 | color:steelblue note:D5 gain:0.25 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 15/2 → 8/1 | color:salmon note:G3 gain:1 clip:1 s:piano release:0.1 pan:0.50462962963 ]", + "[ 15/2 → 8/1 | color:steelblue note:F4 gain:1 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 15/2 → 8/1 | color:green note:Bb3 gain:0.25 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 61/8 → 63/8 | color:steelblue note:D5 gain:0.5 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 61/8 → 63/8 | color:steelblue note:Bb4 gain:0.125 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 61/8 → 63/8 | color:steelblue note:D5 gain:0.125 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ (61/8 → 8/1) ⇝ 65/8 | color:salmon note:G3 gain:0.5 clip:1 s:piano release:0.1 pan:0.50462962963 ]", + "[ (61/8 → 8/1) ⇝ 65/8 | color:steelblue note:F4 gain:0.5 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ (61/8 → 8/1) ⇝ 65/8 | color:green note:Bb3 gain:0.125 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 31/4 → 8/1 | color:steelblue note:D5 gain:0.25 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ (31/4 → 8/1) ⇝ 33/4 | color:green note:Bb3 gain:1 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ (31/4 → 8/1) ⇝ 33/4 | color:steelblue note:A4 gain:1 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ (31/4 → 8/1) ⇝ 33/4 | color:salmon note:G3 gain:0.25 clip:1 s:piano release:0.1 pan:0.50462962963 ]", + "[ (31/4 → 8/1) ⇝ 33/4 | color:steelblue note:F4 gain:0.25 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ (63/8 → 8/1) ⇝ 65/8 | color:steelblue note:D5 gain:0.125 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ (63/8 → 8/1) ⇝ 67/8 | color:green note:Bb3 gain:0.5 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ (63/8 → 8/1) ⇝ 67/8 | color:steelblue note:A4 gain:0.5 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ (63/8 → 8/1) ⇝ 67/8 | color:salmon note:G3 gain:0.125 clip:1 s:piano release:0.1 pan:0.50462962963 ]", + "[ (63/8 → 8/1) ⇝ 67/8 | color:steelblue note:F4 gain:0.125 clip:1 s:piano release:0.1 pan:0.550925925926 ]", ] `; exports[`renders tunes > tune: festivalOfFingers 1`] = ` [ - "[ (0/1 → 1/64) ⇝ 1/4 | note:C2 gain:0.44000000000000006 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 0/1 ⇜ (1/64 → 1/32) ⇝ 1/4 | note:C2 gain:0.5814213562373095 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 0/1 ⇜ (1/32 → 3/64) ⇝ 1/4 | note:C2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ (1/28 → 3/64) ⇝ 2/7 | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ (1/28 → 3/64) ⇝ 2/7 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ (1/28 → 3/64) ⇝ 2/7 | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ (1/28 → 3/64) ⇝ 2/7 | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 0/1 ⇜ (3/64 → 1/16) ⇝ 1/4 | note:C2 gain:0.5814213562373095 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/28 ⇜ (3/64 → 1/16) ⇝ 2/7 | note:70 gain:0.05814213562373095 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 1/28 ⇜ (3/64 → 1/16) ⇝ 2/7 | note:75 gain:0.05814213562373095 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 1/28 ⇜ (3/64 → 1/16) ⇝ 2/7 | note:76 gain:0.05814213562373095 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 1/28 ⇜ (3/64 → 1/16) ⇝ 2/7 | note:80 gain:0.05814213562373095 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 0/1 ⇜ (1/16 → 5/64) ⇝ 1/4 | note:C2 gain:0.44000000000000006 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/28 ⇜ (1/16 → 5/64) ⇝ 2/7 | note:70 gain:0.04400000000000001 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 1/28 ⇜ (1/16 → 5/64) ⇝ 2/7 | note:75 gain:0.04400000000000001 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 1/28 ⇜ (1/16 → 5/64) ⇝ 2/7 | note:76 gain:0.04400000000000001 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 1/28 ⇜ (1/16 → 5/64) ⇝ 2/7 | note:80 gain:0.04400000000000001 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 0/1 ⇜ (5/64 → 3/32) ⇝ 1/4 | note:C2 gain:0.2985786437626905 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/28 ⇜ (5/64 → 3/32) ⇝ 2/7 | note:70 gain:0.029857864376269052 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 1/28 ⇜ (5/64 → 3/32) ⇝ 2/7 | note:75 gain:0.029857864376269052 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 1/28 ⇜ (5/64 → 3/32) ⇝ 2/7 | note:76 gain:0.029857864376269052 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 1/28 ⇜ (5/64 → 3/32) ⇝ 2/7 | note:80 gain:0.029857864376269052 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 0/1 ⇜ (3/32 → 7/64) ⇝ 1/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/28 ⇜ (3/32 → 7/64) ⇝ 2/7 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 1/28 ⇜ (3/32 → 7/64) ⇝ 2/7 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 1/28 ⇜ (3/32 → 7/64) ⇝ 2/7 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 1/28 ⇜ (3/32 → 7/64) ⇝ 2/7 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 0/1 ⇜ (7/64 → 1/8) ⇝ 1/4 | note:C2 gain:0.29857864376269044 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/28 ⇜ (7/64 → 1/8) ⇝ 2/7 | note:70 gain:0.029857864376269045 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 1/28 ⇜ (7/64 → 1/8) ⇝ 2/7 | note:75 gain:0.029857864376269045 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 1/28 ⇜ (7/64 → 1/8) ⇝ 2/7 | note:76 gain:0.029857864376269045 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 1/28 ⇜ (7/64 → 1/8) ⇝ 2/7 | note:80 gain:0.029857864376269045 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 0/1 ⇜ (1/8 → 9/64) ⇝ 1/4 | note:C2 gain:0.43999999999999995 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/28 ⇜ (1/8 → 9/64) ⇝ 2/7 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 1/28 ⇜ (1/8 → 9/64) ⇝ 2/7 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 1/28 ⇜ (1/8 → 9/64) ⇝ 2/7 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 1/28 ⇜ (1/8 → 9/64) ⇝ 2/7 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ (1/8 → 9/64) ⇝ 1/4 | note:C4 gain:0.43999999999999995 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ (1/8 → 9/64) ⇝ 1/4 | note:Eb4 gain:0.43999999999999995 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 0/1 ⇜ (9/64 → 5/32) ⇝ 1/4 | note:C2 gain:0.5814213562373095 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/28 ⇜ (9/64 → 5/32) ⇝ 2/7 | note:70 gain:0.05814213562373095 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 1/28 ⇜ (9/64 → 5/32) ⇝ 2/7 | note:75 gain:0.05814213562373095 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 1/28 ⇜ (9/64 → 5/32) ⇝ 2/7 | note:76 gain:0.05814213562373095 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 1/28 ⇜ (9/64 → 5/32) ⇝ 2/7 | note:80 gain:0.05814213562373095 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 1/8 ⇜ (9/64 → 5/32) ⇝ 1/4 | note:C4 gain:0.5814213562373095 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 1/8 ⇜ (9/64 → 5/32) ⇝ 1/4 | note:Eb4 gain:0.5814213562373095 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 0/1 ⇜ (5/32 → 11/64) ⇝ 1/4 | note:C2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/28 ⇜ (5/32 → 11/64) ⇝ 2/7 | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 1/28 ⇜ (5/32 → 11/64) ⇝ 2/7 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 1/28 ⇜ (5/32 → 11/64) ⇝ 2/7 | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 1/28 ⇜ (5/32 → 11/64) ⇝ 2/7 | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 1/8 ⇜ (5/32 → 11/64) ⇝ 1/4 | note:C4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 1/8 ⇜ (5/32 → 11/64) ⇝ 1/4 | note:Eb4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 0/1 ⇜ (11/64 → 3/16) ⇝ 1/4 | note:C2 gain:0.5814213562373096 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/28 ⇜ (11/64 → 3/16) ⇝ 2/7 | note:70 gain:0.05814213562373097 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 1/28 ⇜ (11/64 → 3/16) ⇝ 2/7 | note:75 gain:0.05814213562373097 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 1/28 ⇜ (11/64 → 3/16) ⇝ 2/7 | note:76 gain:0.05814213562373097 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 1/28 ⇜ (11/64 → 3/16) ⇝ 2/7 | note:80 gain:0.05814213562373097 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 1/8 ⇜ (11/64 → 3/16) ⇝ 1/4 | note:C4 gain:0.5814213562373096 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 1/8 ⇜ (11/64 → 3/16) ⇝ 1/4 | note:Eb4 gain:0.5814213562373096 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 0/1 ⇜ (3/16 → 13/64) ⇝ 1/4 | note:C2 gain:0.44000000000000006 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/28 ⇜ (3/16 → 13/64) ⇝ 2/7 | note:70 gain:0.04400000000000001 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 1/28 ⇜ (3/16 → 13/64) ⇝ 2/7 | note:75 gain:0.04400000000000001 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 1/28 ⇜ (3/16 → 13/64) ⇝ 2/7 | note:76 gain:0.04400000000000001 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 1/28 ⇜ (3/16 → 13/64) ⇝ 2/7 | note:80 gain:0.04400000000000001 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 1/8 ⇜ (3/16 → 13/64) ⇝ 1/4 | note:C4 gain:0.44000000000000006 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 1/8 ⇜ (3/16 → 13/64) ⇝ 1/4 | note:Eb4 gain:0.44000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 0/1 ⇜ (13/64 → 7/32) ⇝ 1/4 | note:C2 gain:0.29857864376269044 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/28 ⇜ (13/64 → 7/32) ⇝ 2/7 | note:70 gain:0.029857864376269045 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 1/28 ⇜ (13/64 → 7/32) ⇝ 2/7 | note:75 gain:0.029857864376269045 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 1/28 ⇜ (13/64 → 7/32) ⇝ 2/7 | note:76 gain:0.029857864376269045 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 1/28 ⇜ (13/64 → 7/32) ⇝ 2/7 | note:80 gain:0.029857864376269045 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 1/8 ⇜ (13/64 → 7/32) ⇝ 1/4 | note:C4 gain:0.29857864376269044 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 1/8 ⇜ (13/64 → 7/32) ⇝ 1/4 | note:Eb4 gain:0.29857864376269044 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 0/1 ⇜ (7/32 → 15/64) ⇝ 1/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/28 ⇜ (7/32 → 15/64) ⇝ 2/7 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 1/28 ⇜ (7/32 → 15/64) ⇝ 2/7 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 1/28 ⇜ (7/32 → 15/64) ⇝ 2/7 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 1/28 ⇜ (7/32 → 15/64) ⇝ 2/7 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 1/8 ⇜ (7/32 → 15/64) ⇝ 1/4 | note:C4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 1/8 ⇜ (7/32 → 15/64) ⇝ 1/4 | note:Eb4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 0/1 ⇜ (15/64 → 1/4) | note:C2 gain:0.2985786437626903 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/28 ⇜ (15/64 → 1/4) ⇝ 2/7 | note:70 gain:0.029857864376269028 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 1/28 ⇜ (15/64 → 1/4) ⇝ 2/7 | note:75 gain:0.029857864376269028 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 1/28 ⇜ (15/64 → 1/4) ⇝ 2/7 | note:76 gain:0.029857864376269028 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 1/28 ⇜ (15/64 → 1/4) ⇝ 2/7 | note:80 gain:0.029857864376269028 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 1/8 ⇜ (15/64 → 1/4) | note:C4 gain:0.2985786437626903 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 1/8 ⇜ (15/64 → 1/4) | note:Eb4 gain:0.2985786437626903 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 1/28 ⇜ (1/4 → 17/64) ⇝ 2/7 | note:70 gain:0.04399999999999999 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 1/28 ⇜ (1/4 → 17/64) ⇝ 2/7 | note:75 gain:0.04399999999999999 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 1/28 ⇜ (1/4 → 17/64) ⇝ 2/7 | note:76 gain:0.04399999999999999 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 1/28 ⇜ (1/4 → 17/64) ⇝ 2/7 | note:80 gain:0.04399999999999999 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 1/28 ⇜ (17/64 → 9/32) ⇝ 2/7 | note:70 gain:0.05814213562373097 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 1/28 ⇜ (17/64 → 9/32) ⇝ 2/7 | note:75 gain:0.05814213562373097 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 1/28 ⇜ (17/64 → 9/32) ⇝ 2/7 | note:76 gain:0.05814213562373097 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 1/28 ⇜ (17/64 → 9/32) ⇝ 2/7 | note:80 gain:0.05814213562373097 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 1/28 ⇜ (9/32 → 2/7) | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 1/28 ⇜ (9/32 → 2/7) | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 1/28 ⇜ (9/32 → 2/7) | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 1/28 ⇜ (9/32 → 2/7) | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ (1/2 → 33/64) ⇝ 5/8 | note:G4 gain:0.4399999999999998 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (1/2 → 33/64) ⇝ 5/8 | note:Bb4 gain:0.4399999999999998 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ (1/2 → 33/64) ⇝ 3/4 | note:Bb3 gain:0.2199999999999999 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ (1/2 → 33/64) ⇝ 3/4 | note:D4 gain:0.2199999999999999 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ (1/2 → 33/64) ⇝ 3/4 | note:Eb4 gain:0.2199999999999999 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ (1/2 → 33/64) ⇝ 3/4 | note:G4 gain:0.2199999999999999 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (1/2 → 33/64) ⇝ 3/4 | note:C2 gain:0.4399999999999998 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/2 ⇜ (33/64 → 17/32) ⇝ 5/8 | note:G4 gain:0.5814213562373095 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 1/2 ⇜ (33/64 → 17/32) ⇝ 5/8 | note:Bb4 gain:0.5814213562373095 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 1/2 ⇜ (33/64 → 17/32) ⇝ 3/4 | note:Bb3 gain:0.29071067811865475 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 1/2 ⇜ (33/64 → 17/32) ⇝ 3/4 | note:D4 gain:0.29071067811865475 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 1/2 ⇜ (33/64 → 17/32) ⇝ 3/4 | note:Eb4 gain:0.29071067811865475 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 1/2 ⇜ (33/64 → 17/32) ⇝ 3/4 | note:G4 gain:0.29071067811865475 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 1/2 ⇜ (33/64 → 17/32) ⇝ 3/4 | note:C2 gain:0.5814213562373095 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/2 ⇜ (17/32 → 35/64) ⇝ 5/8 | note:G4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 1/2 ⇜ (17/32 → 35/64) ⇝ 5/8 | note:Bb4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 1/2 ⇜ (17/32 → 35/64) ⇝ 3/4 | note:Bb3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 1/2 ⇜ (17/32 → 35/64) ⇝ 3/4 | note:D4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 1/2 ⇜ (17/32 → 35/64) ⇝ 3/4 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 1/2 ⇜ (17/32 → 35/64) ⇝ 3/4 | note:G4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 1/2 ⇜ (17/32 → 35/64) ⇝ 3/4 | note:C2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/2 ⇜ (35/64 → 9/16) ⇝ 5/8 | note:G4 gain:0.5814213562373098 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 1/2 ⇜ (35/64 → 9/16) ⇝ 5/8 | note:Bb4 gain:0.5814213562373098 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 1/2 ⇜ (35/64 → 9/16) ⇝ 3/4 | note:Bb3 gain:0.2907106781186549 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 1/2 ⇜ (35/64 → 9/16) ⇝ 3/4 | note:D4 gain:0.2907106781186549 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 1/2 ⇜ (35/64 → 9/16) ⇝ 3/4 | note:Eb4 gain:0.2907106781186549 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 1/2 ⇜ (35/64 → 9/16) ⇝ 3/4 | note:G4 gain:0.2907106781186549 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 1/2 ⇜ (35/64 → 9/16) ⇝ 3/4 | note:C2 gain:0.5814213562373098 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/2 ⇜ (9/16 → 37/64) ⇝ 5/8 | note:G4 gain:0.4400000000000002 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 1/2 ⇜ (9/16 → 37/64) ⇝ 5/8 | note:Bb4 gain:0.4400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 1/2 ⇜ (9/16 → 37/64) ⇝ 3/4 | note:Bb3 gain:0.2200000000000001 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 1/2 ⇜ (9/16 → 37/64) ⇝ 3/4 | note:D4 gain:0.2200000000000001 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 1/2 ⇜ (9/16 → 37/64) ⇝ 3/4 | note:Eb4 gain:0.2200000000000001 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 1/2 ⇜ (9/16 → 37/64) ⇝ 3/4 | note:G4 gain:0.2200000000000001 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 1/2 ⇜ (9/16 → 37/64) ⇝ 3/4 | note:C2 gain:0.4400000000000002 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/2 ⇜ (37/64 → 19/32) ⇝ 5/8 | note:G4 gain:0.29857864376269055 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 1/2 ⇜ (37/64 → 19/32) ⇝ 5/8 | note:Bb4 gain:0.29857864376269055 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 1/2 ⇜ (37/64 → 19/32) ⇝ 3/4 | note:Bb3 gain:0.14928932188134528 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 1/2 ⇜ (37/64 → 19/32) ⇝ 3/4 | note:D4 gain:0.14928932188134528 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 1/2 ⇜ (37/64 → 19/32) ⇝ 3/4 | note:Eb4 gain:0.14928932188134528 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 1/2 ⇜ (37/64 → 19/32) ⇝ 3/4 | note:G4 gain:0.14928932188134528 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 1/2 ⇜ (37/64 → 19/32) ⇝ 3/4 | note:C2 gain:0.29857864376269055 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/2 ⇜ (19/32 → 39/64) ⇝ 5/8 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 1/2 ⇜ (19/32 → 39/64) ⇝ 5/8 | note:Bb4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 1/2 ⇜ (19/32 → 39/64) ⇝ 3/4 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 1/2 ⇜ (19/32 → 39/64) ⇝ 3/4 | note:D4 gain:0.12 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 1/2 ⇜ (19/32 → 39/64) ⇝ 3/4 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 1/2 ⇜ (19/32 → 39/64) ⇝ 3/4 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 1/2 ⇜ (19/32 → 39/64) ⇝ 3/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/2 ⇜ (39/64 → 5/8) | note:G4 gain:0.2985786437626902 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 1/2 ⇜ (39/64 → 5/8) | note:Bb4 gain:0.2985786437626902 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 1/2 ⇜ (39/64 → 5/8) ⇝ 3/4 | note:Bb3 gain:0.1492893218813451 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 1/2 ⇜ (39/64 → 5/8) ⇝ 3/4 | note:D4 gain:0.1492893218813451 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 1/2 ⇜ (39/64 → 5/8) ⇝ 3/4 | note:Eb4 gain:0.1492893218813451 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 1/2 ⇜ (39/64 → 5/8) ⇝ 3/4 | note:G4 gain:0.1492893218813451 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 1/2 ⇜ (39/64 → 5/8) ⇝ 3/4 | note:C2 gain:0.2985786437626902 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/2 ⇜ (5/8 → 41/64) ⇝ 3/4 | note:Bb3 gain:0.2199999999999999 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 1/2 ⇜ (5/8 → 41/64) ⇝ 3/4 | note:D4 gain:0.2199999999999999 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 1/2 ⇜ (5/8 → 41/64) ⇝ 3/4 | note:Eb4 gain:0.2199999999999999 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 1/2 ⇜ (5/8 → 41/64) ⇝ 3/4 | note:G4 gain:0.2199999999999999 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 1/2 ⇜ (5/8 → 41/64) ⇝ 3/4 | note:C2 gain:0.4399999999999998 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/2 ⇜ (41/64 → 21/32) ⇝ 3/4 | note:Bb3 gain:0.2907106781186545 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 1/2 ⇜ (41/64 → 21/32) ⇝ 3/4 | note:D4 gain:0.2907106781186545 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 1/2 ⇜ (41/64 → 21/32) ⇝ 3/4 | note:Eb4 gain:0.2907106781186545 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 1/2 ⇜ (41/64 → 21/32) ⇝ 3/4 | note:G4 gain:0.2907106781186545 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 1/2 ⇜ (41/64 → 21/32) ⇝ 3/4 | note:C2 gain:0.581421356237309 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/2 ⇜ (21/32 → 43/64) ⇝ 3/4 | note:Bb3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 1/2 ⇜ (21/32 → 43/64) ⇝ 3/4 | note:D4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 1/2 ⇜ (21/32 → 43/64) ⇝ 3/4 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 1/2 ⇜ (21/32 → 43/64) ⇝ 3/4 | note:G4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 1/2 ⇜ (21/32 → 43/64) ⇝ 3/4 | note:C2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/2 ⇜ (43/64 → 11/16) ⇝ 3/4 | note:Bb3 gain:0.2907106781186549 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 1/2 ⇜ (43/64 → 11/16) ⇝ 3/4 | note:D4 gain:0.2907106781186549 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 1/2 ⇜ (43/64 → 11/16) ⇝ 3/4 | note:Eb4 gain:0.2907106781186549 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 1/2 ⇜ (43/64 → 11/16) ⇝ 3/4 | note:G4 gain:0.2907106781186549 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 1/2 ⇜ (43/64 → 11/16) ⇝ 3/4 | note:C2 gain:0.5814213562373098 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/2 ⇜ (11/16 → 45/64) ⇝ 3/4 | note:Bb3 gain:0.22000000000000047 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 1/2 ⇜ (11/16 → 45/64) ⇝ 3/4 | note:D4 gain:0.22000000000000047 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 1/2 ⇜ (11/16 → 45/64) ⇝ 3/4 | note:Eb4 gain:0.22000000000000047 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 1/2 ⇜ (11/16 → 45/64) ⇝ 3/4 | note:G4 gain:0.22000000000000047 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 1/2 ⇜ (11/16 → 45/64) ⇝ 3/4 | note:C2 gain:0.44000000000000095 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/2 ⇜ (45/64 → 23/32) ⇝ 3/4 | note:Bb3 gain:0.14928932188134528 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 1/2 ⇜ (45/64 → 23/32) ⇝ 3/4 | note:D4 gain:0.14928932188134528 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 1/2 ⇜ (45/64 → 23/32) ⇝ 3/4 | note:Eb4 gain:0.14928932188134528 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 1/2 ⇜ (45/64 → 23/32) ⇝ 3/4 | note:G4 gain:0.14928932188134528 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 1/2 ⇜ (45/64 → 23/32) ⇝ 3/4 | note:C2 gain:0.29857864376269055 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/2 ⇜ (23/32 → 47/64) ⇝ 3/4 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 1/2 ⇜ (23/32 → 47/64) ⇝ 3/4 | note:D4 gain:0.12 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 1/2 ⇜ (23/32 → 47/64) ⇝ 3/4 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 1/2 ⇜ (23/32 → 47/64) ⇝ 3/4 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 1/2 ⇜ (23/32 → 47/64) ⇝ 3/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/2 ⇜ (47/64 → 3/4) | note:Bb3 gain:0.14928932188134533 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 1/2 ⇜ (47/64 → 3/4) | note:D4 gain:0.14928932188134533 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 1/2 ⇜ (47/64 → 3/4) | note:Eb4 gain:0.14928932188134533 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 1/2 ⇜ (47/64 → 3/4) | note:G4 gain:0.14928932188134533 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 1/2 ⇜ (47/64 → 3/4) | note:C2 gain:0.29857864376269067 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ (3/4 → 49/64) ⇝ 7/8 | note:C4 gain:0.4399999999999997 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ (3/4 → 49/64) ⇝ 7/8 | note:Eb4 gain:0.4399999999999997 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 3/4 ⇜ (49/64 → 25/32) ⇝ 7/8 | note:C4 gain:0.581421356237309 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 3/4 ⇜ (49/64 → 25/32) ⇝ 7/8 | note:Eb4 gain:0.581421356237309 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 3/4 ⇜ (25/32 → 51/64) ⇝ 7/8 | note:C4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 3/4 ⇜ (25/32 → 51/64) ⇝ 7/8 | note:Eb4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ (11/14 → 51/64) ⇝ 29/28 | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ (11/14 → 51/64) ⇝ 29/28 | note:74 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (11/14 → 51/64) ⇝ 29/28 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ (11/14 → 51/64) ⇝ 29/28 | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 3/4 ⇜ (51/64 → 13/16) ⇝ 7/8 | note:C4 gain:0.5814213562373098 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 3/4 ⇜ (51/64 → 13/16) ⇝ 7/8 | note:Eb4 gain:0.5814213562373098 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 11/14 ⇜ (51/64 → 13/16) ⇝ 29/28 | note:70 gain:0.05814213562373099 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 11/14 ⇜ (51/64 → 13/16) ⇝ 29/28 | note:74 gain:0.05814213562373099 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 11/14 ⇜ (51/64 → 13/16) ⇝ 29/28 | note:75 gain:0.05814213562373099 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 11/14 ⇜ (51/64 → 13/16) ⇝ 29/28 | note:79 gain:0.05814213562373099 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 3/4 ⇜ (13/16 → 53/64) ⇝ 7/8 | note:C4 gain:0.4399999999999996 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 3/4 ⇜ (13/16 → 53/64) ⇝ 7/8 | note:Eb4 gain:0.4399999999999996 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 11/14 ⇜ (13/16 → 53/64) ⇝ 29/28 | note:70 gain:0.04399999999999996 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 11/14 ⇜ (13/16 → 53/64) ⇝ 29/28 | note:74 gain:0.04399999999999996 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 11/14 ⇜ (13/16 → 53/64) ⇝ 29/28 | note:75 gain:0.04399999999999996 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 11/14 ⇜ (13/16 → 53/64) ⇝ 29/28 | note:79 gain:0.04399999999999996 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 3/4 ⇜ (53/64 → 27/32) ⇝ 7/8 | note:C4 gain:0.2985786437626906 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 3/4 ⇜ (53/64 → 27/32) ⇝ 7/8 | note:Eb4 gain:0.2985786437626906 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 11/14 ⇜ (53/64 → 27/32) ⇝ 29/28 | note:70 gain:0.029857864376269062 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 11/14 ⇜ (53/64 → 27/32) ⇝ 29/28 | note:74 gain:0.029857864376269062 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 11/14 ⇜ (53/64 → 27/32) ⇝ 29/28 | note:75 gain:0.029857864376269062 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 11/14 ⇜ (53/64 → 27/32) ⇝ 29/28 | note:79 gain:0.029857864376269062 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 3/4 ⇜ (27/32 → 55/64) ⇝ 7/8 | note:C4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 3/4 ⇜ (27/32 → 55/64) ⇝ 7/8 | note:Eb4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 11/14 ⇜ (27/32 → 55/64) ⇝ 29/28 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 11/14 ⇜ (27/32 → 55/64) ⇝ 29/28 | note:74 gain:0.024 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 11/14 ⇜ (27/32 → 55/64) ⇝ 29/28 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 11/14 ⇜ (27/32 → 55/64) ⇝ 29/28 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 3/4 ⇜ (55/64 → 7/8) | note:C4 gain:0.29857864376269067 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 3/4 ⇜ (55/64 → 7/8) | note:Eb4 gain:0.29857864376269067 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 11/14 ⇜ (55/64 → 7/8) ⇝ 29/28 | note:70 gain:0.02985786437626907 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 11/14 ⇜ (55/64 → 7/8) ⇝ 29/28 | note:74 gain:0.02985786437626907 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 11/14 ⇜ (55/64 → 7/8) ⇝ 29/28 | note:75 gain:0.02985786437626907 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 11/14 ⇜ (55/64 → 7/8) ⇝ 29/28 | note:79 gain:0.02985786437626907 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 11/14 ⇜ (7/8 → 57/64) ⇝ 29/28 | note:70 gain:0.04399999999999998 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 11/14 ⇜ (7/8 → 57/64) ⇝ 29/28 | note:74 gain:0.04399999999999998 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 11/14 ⇜ (7/8 → 57/64) ⇝ 29/28 | note:75 gain:0.04399999999999998 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 11/14 ⇜ (7/8 → 57/64) ⇝ 29/28 | note:79 gain:0.04399999999999998 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 11/14 ⇜ (57/64 → 29/32) ⇝ 29/28 | note:70 gain:0.0581421356237309 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 11/14 ⇜ (57/64 → 29/32) ⇝ 29/28 | note:74 gain:0.0581421356237309 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 11/14 ⇜ (57/64 → 29/32) ⇝ 29/28 | note:75 gain:0.0581421356237309 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 11/14 ⇜ (57/64 → 29/32) ⇝ 29/28 | note:79 gain:0.0581421356237309 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 11/14 ⇜ (29/32 → 59/64) ⇝ 29/28 | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 11/14 ⇜ (29/32 → 59/64) ⇝ 29/28 | note:74 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 11/14 ⇜ (29/32 → 59/64) ⇝ 29/28 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 11/14 ⇜ (29/32 → 59/64) ⇝ 29/28 | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 11/14 ⇜ (59/64 → 15/16) ⇝ 29/28 | note:70 gain:0.058142135623730995 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 11/14 ⇜ (59/64 → 15/16) ⇝ 29/28 | note:74 gain:0.058142135623730995 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 11/14 ⇜ (59/64 → 15/16) ⇝ 29/28 | note:75 gain:0.058142135623730995 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 11/14 ⇜ (59/64 → 15/16) ⇝ 29/28 | note:79 gain:0.058142135623730995 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 11/14 ⇜ (15/16 → 61/64) ⇝ 29/28 | note:70 gain:0.044000000000000115 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 11/14 ⇜ (15/16 → 61/64) ⇝ 29/28 | note:74 gain:0.044000000000000115 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 11/14 ⇜ (15/16 → 61/64) ⇝ 29/28 | note:75 gain:0.044000000000000115 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 11/14 ⇜ (15/16 → 61/64) ⇝ 29/28 | note:79 gain:0.044000000000000115 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 11/14 ⇜ (61/64 → 31/32) ⇝ 29/28 | note:70 gain:0.02985786437626907 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 11/14 ⇜ (61/64 → 31/32) ⇝ 29/28 | note:74 gain:0.02985786437626907 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 11/14 ⇜ (61/64 → 31/32) ⇝ 29/28 | note:75 gain:0.02985786437626907 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 11/14 ⇜ (61/64 → 31/32) ⇝ 29/28 | note:79 gain:0.02985786437626907 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 11/14 ⇜ (31/32 → 63/64) ⇝ 29/28 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 11/14 ⇜ (31/32 → 63/64) ⇝ 29/28 | note:74 gain:0.024 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 11/14 ⇜ (31/32 → 63/64) ⇝ 29/28 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 11/14 ⇜ (31/32 → 63/64) ⇝ 29/28 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 11/14 ⇜ (63/64 → 1/1) ⇝ 29/28 | note:70 gain:0.029857864376269062 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 11/14 ⇜ (63/64 → 1/1) ⇝ 29/28 | note:74 gain:0.029857864376269062 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 11/14 ⇜ (63/64 → 1/1) ⇝ 29/28 | note:75 gain:0.029857864376269062 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 11/14 ⇜ (63/64 → 1/1) ⇝ 29/28 | note:79 gain:0.029857864376269062 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 11/14 ⇜ (1/1 → 65/64) ⇝ 29/28 | note:70 gain:0.04399999999999996 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 11/14 ⇜ (1/1 → 65/64) ⇝ 29/28 | note:74 gain:0.04399999999999996 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 11/14 ⇜ (1/1 → 65/64) ⇝ 29/28 | note:75 gain:0.04399999999999996 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 11/14 ⇜ (1/1 → 65/64) ⇝ 29/28 | note:79 gain:0.04399999999999996 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ (1/1 → 65/64) ⇝ 5/4 | note:C2 gain:0.4399999999999996 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 11/14 ⇜ (65/64 → 33/32) ⇝ 29/28 | note:70 gain:0.0581421356237309 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 11/14 ⇜ (65/64 → 33/32) ⇝ 29/28 | note:74 gain:0.0581421356237309 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 11/14 ⇜ (65/64 → 33/32) ⇝ 29/28 | note:75 gain:0.0581421356237309 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 11/14 ⇜ (65/64 → 33/32) ⇝ 29/28 | note:79 gain:0.0581421356237309 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 1/1 ⇜ (65/64 → 33/32) ⇝ 5/4 | note:C2 gain:0.581421356237309 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 11/14 ⇜ (33/32 → 29/28) | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 11/14 ⇜ (33/32 → 29/28) | note:74 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 11/14 ⇜ (33/32 → 29/28) | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 11/14 ⇜ (33/32 → 29/28) | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 1/1 ⇜ (33/32 → 67/64) ⇝ 5/4 | note:C2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/1 ⇜ (67/64 → 17/16) ⇝ 5/4 | note:C2 gain:0.58142135623731 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/1 ⇜ (17/16 → 69/64) ⇝ 5/4 | note:C2 gain:0.4399999999999997 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/1 ⇜ (69/64 → 35/32) ⇝ 5/4 | note:C2 gain:0.29857864376269067 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/1 ⇜ (35/32 → 71/64) ⇝ 5/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/1 ⇜ (71/64 → 9/8) ⇝ 5/4 | note:C2 gain:0.29857864376269055 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 1/1 ⇜ (9/8 → 73/64) ⇝ 5/4 | note:C2 gain:0.4399999999999995 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ (9/8 → 73/64) ⇝ 5/4 | note:C4 gain:0.4399999999999995 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ (9/8 → 73/64) ⇝ 5/4 | note:Eb4 gain:0.4399999999999995 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 1/1 ⇜ (73/64 → 37/32) ⇝ 5/4 | note:C2 gain:0.5814213562373087 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 9/8 ⇜ (73/64 → 37/32) ⇝ 5/4 | note:C4 gain:0.5814213562373087 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 9/8 ⇜ (73/64 → 37/32) ⇝ 5/4 | note:Eb4 gain:0.5814213562373087 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 1/1 ⇜ (37/32 → 75/64) ⇝ 5/4 | note:C2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 9/8 ⇜ (37/32 → 75/64) ⇝ 5/4 | note:C4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 9/8 ⇜ (37/32 → 75/64) ⇝ 5/4 | note:Eb4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 1/1 ⇜ (75/64 → 19/16) ⇝ 5/4 | note:C2 gain:0.58142135623731 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 9/8 ⇜ (75/64 → 19/16) ⇝ 5/4 | note:C4 gain:0.58142135623731 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 9/8 ⇜ (75/64 → 19/16) ⇝ 5/4 | note:Eb4 gain:0.58142135623731 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 1/1 ⇜ (19/16 → 77/64) ⇝ 5/4 | note:C2 gain:0.4400000000000011 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 9/8 ⇜ (19/16 → 77/64) ⇝ 5/4 | note:C4 gain:0.4400000000000011 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 9/8 ⇜ (19/16 → 77/64) ⇝ 5/4 | note:Eb4 gain:0.4400000000000011 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 1/1 ⇜ (77/64 → 39/32) ⇝ 5/4 | note:C2 gain:0.2985786437626907 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 9/8 ⇜ (77/64 → 39/32) ⇝ 5/4 | note:C4 gain:0.2985786437626907 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 9/8 ⇜ (77/64 → 39/32) ⇝ 5/4 | note:Eb4 gain:0.2985786437626907 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 1/1 ⇜ (39/32 → 79/64) ⇝ 5/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 9/8 ⇜ (39/32 → 79/64) ⇝ 5/4 | note:C4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 9/8 ⇜ (39/32 → 79/64) ⇝ 5/4 | note:Eb4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 1/1 ⇜ (79/64 → 5/4) | note:C2 gain:0.29857864376269055 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 9/8 ⇜ (79/64 → 5/4) | note:C4 gain:0.29857864376269055 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 9/8 ⇜ (79/64 → 5/4) | note:Eb4 gain:0.29857864376269055 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ (5/4 → 81/64) ⇝ 3/2 | note:Bb3 gain:0.21999999999999975 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ (5/4 → 81/64) ⇝ 3/2 | note:D4 gain:0.21999999999999975 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ (5/4 → 81/64) ⇝ 3/2 | note:Eb4 gain:0.21999999999999975 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ (5/4 → 81/64) ⇝ 3/2 | note:G4 gain:0.21999999999999975 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/4 ⇜ (81/64 → 41/32) ⇝ 3/2 | note:Bb3 gain:0.29071067811865436 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 5/4 ⇜ (81/64 → 41/32) ⇝ 3/2 | note:D4 gain:0.29071067811865436 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 5/4 ⇜ (81/64 → 41/32) ⇝ 3/2 | note:Eb4 gain:0.29071067811865436 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/4 ⇜ (81/64 → 41/32) ⇝ 3/2 | note:G4 gain:0.29071067811865436 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/4 ⇜ (41/32 → 83/64) ⇝ 3/2 | note:Bb3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 5/4 ⇜ (41/32 → 83/64) ⇝ 3/2 | note:D4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 5/4 ⇜ (41/32 → 83/64) ⇝ 3/2 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/4 ⇜ (41/32 → 83/64) ⇝ 3/2 | note:G4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/4 ⇜ (83/64 → 21/16) ⇝ 3/2 | note:Bb3 gain:0.2907106781186545 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 5/4 ⇜ (83/64 → 21/16) ⇝ 3/2 | note:D4 gain:0.2907106781186545 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 5/4 ⇜ (83/64 → 21/16) ⇝ 3/2 | note:Eb4 gain:0.2907106781186545 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/4 ⇜ (83/64 → 21/16) ⇝ 3/2 | note:G4 gain:0.2907106781186545 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/4 ⇜ (21/16 → 85/64) ⇝ 3/2 | note:Bb3 gain:0.2199999999999999 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 5/4 ⇜ (21/16 → 85/64) ⇝ 3/2 | note:D4 gain:0.2199999999999999 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 5/4 ⇜ (21/16 → 85/64) ⇝ 3/2 | note:Eb4 gain:0.2199999999999999 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/4 ⇜ (21/16 → 85/64) ⇝ 3/2 | note:G4 gain:0.2199999999999999 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/4 ⇜ (85/64 → 43/32) ⇝ 3/2 | note:Bb3 gain:0.14928932188134536 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 5/4 ⇜ (85/64 → 43/32) ⇝ 3/2 | note:D4 gain:0.14928932188134536 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 5/4 ⇜ (85/64 → 43/32) ⇝ 3/2 | note:Eb4 gain:0.14928932188134536 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/4 ⇜ (85/64 → 43/32) ⇝ 3/2 | note:G4 gain:0.14928932188134536 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/4 ⇜ (43/32 → 87/64) ⇝ 3/2 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 5/4 ⇜ (43/32 → 87/64) ⇝ 3/2 | note:D4 gain:0.12 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 5/4 ⇜ (43/32 → 87/64) ⇝ 3/2 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/4 ⇜ (43/32 → 87/64) ⇝ 3/2 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/4 ⇜ (87/64 → 11/8) ⇝ 3/2 | note:Bb3 gain:0.14928932188134475 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 5/4 ⇜ (87/64 → 11/8) ⇝ 3/2 | note:D4 gain:0.14928932188134475 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 5/4 ⇜ (87/64 → 11/8) ⇝ 3/2 | note:Eb4 gain:0.14928932188134475 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/4 ⇜ (87/64 → 11/8) ⇝ 3/2 | note:G4 gain:0.14928932188134475 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/4 ⇜ (11/8 → 89/64) ⇝ 3/2 | note:Bb3 gain:0.21999999999999906 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 5/4 ⇜ (11/8 → 89/64) ⇝ 3/2 | note:D4 gain:0.21999999999999906 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 5/4 ⇜ (11/8 → 89/64) ⇝ 3/2 | note:Eb4 gain:0.21999999999999906 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/4 ⇜ (11/8 → 89/64) ⇝ 3/2 | note:G4 gain:0.21999999999999906 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/4 ⇜ (89/64 → 45/32) ⇝ 3/2 | note:Bb3 gain:0.2907106781186549 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 5/4 ⇜ (89/64 → 45/32) ⇝ 3/2 | note:D4 gain:0.2907106781186549 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 5/4 ⇜ (89/64 → 45/32) ⇝ 3/2 | note:Eb4 gain:0.2907106781186549 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/4 ⇜ (89/64 → 45/32) ⇝ 3/2 | note:G4 gain:0.2907106781186549 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/4 ⇜ (45/32 → 91/64) ⇝ 3/2 | note:Bb3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 5/4 ⇜ (45/32 → 91/64) ⇝ 3/2 | note:D4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 5/4 ⇜ (45/32 → 91/64) ⇝ 3/2 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/4 ⇜ (45/32 → 91/64) ⇝ 3/2 | note:G4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/4 ⇜ (91/64 → 23/16) ⇝ 3/2 | note:Bb3 gain:0.290710678118655 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 5/4 ⇜ (91/64 → 23/16) ⇝ 3/2 | note:D4 gain:0.290710678118655 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 5/4 ⇜ (91/64 → 23/16) ⇝ 3/2 | note:Eb4 gain:0.290710678118655 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/4 ⇜ (91/64 → 23/16) ⇝ 3/2 | note:G4 gain:0.290710678118655 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/4 ⇜ (23/16 → 93/64) ⇝ 3/2 | note:Bb3 gain:0.22000000000000064 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 5/4 ⇜ (23/16 → 93/64) ⇝ 3/2 | note:D4 gain:0.22000000000000064 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 5/4 ⇜ (23/16 → 93/64) ⇝ 3/2 | note:Eb4 gain:0.22000000000000064 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/4 ⇜ (23/16 → 93/64) ⇝ 3/2 | note:G4 gain:0.22000000000000064 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/4 ⇜ (93/64 → 47/32) ⇝ 3/2 | note:Bb3 gain:0.1492893218813459 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 5/4 ⇜ (93/64 → 47/32) ⇝ 3/2 | note:D4 gain:0.1492893218813459 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 5/4 ⇜ (93/64 → 47/32) ⇝ 3/2 | note:Eb4 gain:0.1492893218813459 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/4 ⇜ (93/64 → 47/32) ⇝ 3/2 | note:G4 gain:0.1492893218813459 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/4 ⇜ (47/32 → 95/64) ⇝ 3/2 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 5/4 ⇜ (47/32 → 95/64) ⇝ 3/2 | note:D4 gain:0.12 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 5/4 ⇜ (47/32 → 95/64) ⇝ 3/2 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/4 ⇜ (47/32 → 95/64) ⇝ 3/2 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/4 ⇜ (95/64 → 3/2) | note:Bb3 gain:0.14928932188134522 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 5/4 ⇜ (95/64 → 3/2) | note:D4 gain:0.14928932188134522 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 5/4 ⇜ (95/64 → 3/2) | note:Eb4 gain:0.14928932188134522 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/4 ⇜ (95/64 → 3/2) | note:G4 gain:0.14928932188134522 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (3/2 → 97/64) ⇝ 13/8 | note:G4 gain:0.43999999999999945 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (3/2 → 97/64) ⇝ 13/8 | note:Bb4 gain:0.43999999999999945 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ (3/2 → 97/64) ⇝ 7/4 | note:C2 gain:0.43999999999999945 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 3/2 ⇜ (97/64 → 49/32) ⇝ 13/8 | note:G4 gain:0.5814213562373087 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 3/2 ⇜ (97/64 → 49/32) ⇝ 13/8 | note:Bb4 gain:0.5814213562373087 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 3/2 ⇜ (97/64 → 49/32) ⇝ 7/4 | note:C2 gain:0.5814213562373087 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 3/2 ⇜ (49/32 → 99/64) ⇝ 13/8 | note:G4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 3/2 ⇜ (49/32 → 99/64) ⇝ 13/8 | note:Bb4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 3/2 ⇜ (49/32 → 99/64) ⇝ 7/4 | note:C2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ (43/28 → 99/64) ⇝ 25/14 | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ (43/28 → 99/64) ⇝ 25/14 | note:74 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (43/28 → 99/64) ⇝ 25/14 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ (43/28 → 99/64) ⇝ 25/14 | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 3/2 ⇜ (99/64 → 25/16) ⇝ 13/8 | note:G4 gain:0.5814213562373091 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 3/2 ⇜ (99/64 → 25/16) ⇝ 13/8 | note:Bb4 gain:0.5814213562373091 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 3/2 ⇜ (99/64 → 25/16) ⇝ 7/4 | note:C2 gain:0.5814213562373091 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 43/28 ⇜ (99/64 → 25/16) ⇝ 25/14 | note:70 gain:0.05814213562373091 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 43/28 ⇜ (99/64 → 25/16) ⇝ 25/14 | note:74 gain:0.05814213562373091 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 43/28 ⇜ (99/64 → 25/16) ⇝ 25/14 | note:75 gain:0.05814213562373091 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 43/28 ⇜ (99/64 → 25/16) ⇝ 25/14 | note:79 gain:0.05814213562373091 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 3/2 ⇜ (25/16 → 101/64) ⇝ 13/8 | note:G4 gain:0.4399999999999999 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 3/2 ⇜ (25/16 → 101/64) ⇝ 13/8 | note:Bb4 gain:0.4399999999999999 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 3/2 ⇜ (25/16 → 101/64) ⇝ 7/4 | note:C2 gain:0.4399999999999999 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 43/28 ⇜ (25/16 → 101/64) ⇝ 25/14 | note:70 gain:0.04399999999999999 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 43/28 ⇜ (25/16 → 101/64) ⇝ 25/14 | note:74 gain:0.04399999999999999 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 43/28 ⇜ (25/16 → 101/64) ⇝ 25/14 | note:75 gain:0.04399999999999999 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 43/28 ⇜ (25/16 → 101/64) ⇝ 25/14 | note:79 gain:0.04399999999999999 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 3/2 ⇜ (101/64 → 51/32) ⇝ 13/8 | note:G4 gain:0.29857864376269083 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 3/2 ⇜ (101/64 → 51/32) ⇝ 13/8 | note:Bb4 gain:0.29857864376269083 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 3/2 ⇜ (101/64 → 51/32) ⇝ 7/4 | note:C2 gain:0.29857864376269083 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 43/28 ⇜ (101/64 → 51/32) ⇝ 25/14 | note:70 gain:0.029857864376269083 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 43/28 ⇜ (101/64 → 51/32) ⇝ 25/14 | note:74 gain:0.029857864376269083 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 43/28 ⇜ (101/64 → 51/32) ⇝ 25/14 | note:75 gain:0.029857864376269083 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 43/28 ⇜ (101/64 → 51/32) ⇝ 25/14 | note:79 gain:0.029857864376269083 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 3/2 ⇜ (51/32 → 103/64) ⇝ 13/8 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 3/2 ⇜ (51/32 → 103/64) ⇝ 13/8 | note:Bb4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 3/2 ⇜ (51/32 → 103/64) ⇝ 7/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 43/28 ⇜ (51/32 → 103/64) ⇝ 25/14 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 43/28 ⇜ (51/32 → 103/64) ⇝ 25/14 | note:74 gain:0.024 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 43/28 ⇜ (51/32 → 103/64) ⇝ 25/14 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 43/28 ⇜ (51/32 → 103/64) ⇝ 25/14 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 3/2 ⇜ (103/64 → 13/8) | note:G4 gain:0.2985786437626894 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 3/2 ⇜ (103/64 → 13/8) | note:Bb4 gain:0.2985786437626894 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 3/2 ⇜ (103/64 → 13/8) ⇝ 7/4 | note:C2 gain:0.2985786437626894 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 43/28 ⇜ (103/64 → 13/8) ⇝ 25/14 | note:70 gain:0.02985786437626894 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 43/28 ⇜ (103/64 → 13/8) ⇝ 25/14 | note:74 gain:0.02985786437626894 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 43/28 ⇜ (103/64 → 13/8) ⇝ 25/14 | note:75 gain:0.02985786437626894 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 43/28 ⇜ (103/64 → 13/8) ⇝ 25/14 | note:79 gain:0.02985786437626894 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 3/2 ⇜ (13/8 → 105/64) ⇝ 7/4 | note:C2 gain:0.4400000000000008 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 43/28 ⇜ (13/8 → 105/64) ⇝ 25/14 | note:70 gain:0.04400000000000008 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 43/28 ⇜ (13/8 → 105/64) ⇝ 25/14 | note:74 gain:0.04400000000000008 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 43/28 ⇜ (13/8 → 105/64) ⇝ 25/14 | note:75 gain:0.04400000000000008 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 43/28 ⇜ (13/8 → 105/64) ⇝ 25/14 | note:79 gain:0.04400000000000008 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 3/2 ⇜ (105/64 → 53/32) ⇝ 7/4 | note:C2 gain:0.5814213562373096 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 43/28 ⇜ (105/64 → 53/32) ⇝ 25/14 | note:70 gain:0.05814213562373097 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 43/28 ⇜ (105/64 → 53/32) ⇝ 25/14 | note:74 gain:0.05814213562373097 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 43/28 ⇜ (105/64 → 53/32) ⇝ 25/14 | note:75 gain:0.05814213562373097 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 43/28 ⇜ (105/64 → 53/32) ⇝ 25/14 | note:79 gain:0.05814213562373097 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 3/2 ⇜ (53/32 → 107/64) ⇝ 7/4 | note:C2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 43/28 ⇜ (53/32 → 107/64) ⇝ 25/14 | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 43/28 ⇜ (53/32 → 107/64) ⇝ 25/14 | note:74 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 43/28 ⇜ (53/32 → 107/64) ⇝ 25/14 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 43/28 ⇜ (53/32 → 107/64) ⇝ 25/14 | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 3/2 ⇜ (107/64 → 27/16) ⇝ 7/4 | note:C2 gain:0.5814213562373102 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 43/28 ⇜ (107/64 → 27/16) ⇝ 25/14 | note:70 gain:0.05814213562373102 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 43/28 ⇜ (107/64 → 27/16) ⇝ 25/14 | note:74 gain:0.05814213562373102 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 43/28 ⇜ (107/64 → 27/16) ⇝ 25/14 | note:75 gain:0.05814213562373102 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 43/28 ⇜ (107/64 → 27/16) ⇝ 25/14 | note:79 gain:0.05814213562373102 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 3/2 ⇜ (27/16 → 109/64) ⇝ 7/4 | note:C2 gain:0.4400000000000014 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 43/28 ⇜ (27/16 → 109/64) ⇝ 25/14 | note:70 gain:0.04400000000000014 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 43/28 ⇜ (27/16 → 109/64) ⇝ 25/14 | note:74 gain:0.04400000000000014 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 43/28 ⇜ (27/16 → 109/64) ⇝ 25/14 | note:75 gain:0.04400000000000014 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 43/28 ⇜ (27/16 → 109/64) ⇝ 25/14 | note:79 gain:0.04400000000000014 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 3/2 ⇜ (109/64 → 55/32) ⇝ 7/4 | note:C2 gain:0.29857864376269183 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 43/28 ⇜ (109/64 → 55/32) ⇝ 25/14 | note:70 gain:0.029857864376269184 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 43/28 ⇜ (109/64 → 55/32) ⇝ 25/14 | note:74 gain:0.029857864376269184 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 43/28 ⇜ (109/64 → 55/32) ⇝ 25/14 | note:75 gain:0.029857864376269184 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 43/28 ⇜ (109/64 → 55/32) ⇝ 25/14 | note:79 gain:0.029857864376269184 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 3/2 ⇜ (55/32 → 111/64) ⇝ 7/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 43/28 ⇜ (55/32 → 111/64) ⇝ 25/14 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 43/28 ⇜ (55/32 → 111/64) ⇝ 25/14 | note:74 gain:0.024 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 43/28 ⇜ (55/32 → 111/64) ⇝ 25/14 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 43/28 ⇜ (55/32 → 111/64) ⇝ 25/14 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 3/2 ⇜ (111/64 → 7/4) | note:C2 gain:0.2985786437626904 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 43/28 ⇜ (111/64 → 7/4) ⇝ 25/14 | note:70 gain:0.02985786437626904 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 43/28 ⇜ (111/64 → 7/4) ⇝ 25/14 | note:74 gain:0.02985786437626904 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 43/28 ⇜ (111/64 → 7/4) ⇝ 25/14 | note:75 gain:0.02985786437626904 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 43/28 ⇜ (111/64 → 7/4) ⇝ 25/14 | note:79 gain:0.02985786437626904 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 43/28 ⇜ (7/4 → 113/64) ⇝ 25/14 | note:70 gain:0.043999999999999935 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 43/28 ⇜ (7/4 → 113/64) ⇝ 25/14 | note:74 gain:0.043999999999999935 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 43/28 ⇜ (7/4 → 113/64) ⇝ 25/14 | note:75 gain:0.043999999999999935 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 43/28 ⇜ (7/4 → 113/64) ⇝ 25/14 | note:79 gain:0.043999999999999935 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ (7/4 → 113/64) ⇝ 15/8 | note:G4 gain:0.43999999999999934 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (7/4 → 113/64) ⇝ 15/8 | note:Bb4 gain:0.43999999999999934 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ (7/4 → 113/64) ⇝ 2/1 | note:Bb3 gain:0.21999999999999967 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ (7/4 → 113/64) ⇝ 2/1 | note:D4 gain:0.21999999999999967 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ (7/4 → 113/64) ⇝ 2/1 | note:Eb4 gain:0.21999999999999967 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ (7/4 → 113/64) ⇝ 2/1 | note:G4 gain:0.21999999999999967 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 43/28 ⇜ (113/64 → 57/32) ⇝ 25/14 | note:70 gain:0.05814213562373086 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 43/28 ⇜ (113/64 → 57/32) ⇝ 25/14 | note:74 gain:0.05814213562373086 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 43/28 ⇜ (113/64 → 57/32) ⇝ 25/14 | note:75 gain:0.05814213562373086 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 43/28 ⇜ (113/64 → 57/32) ⇝ 25/14 | note:79 gain:0.05814213562373086 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 7/4 ⇜ (113/64 → 57/32) ⇝ 15/8 | note:G4 gain:0.5814213562373086 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 7/4 ⇜ (113/64 → 57/32) ⇝ 15/8 | note:Bb4 gain:0.5814213562373086 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 7/4 ⇜ (113/64 → 57/32) ⇝ 2/1 | note:Bb3 gain:0.2907106781186543 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 7/4 ⇜ (113/64 → 57/32) ⇝ 2/1 | note:D4 gain:0.2907106781186543 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 7/4 ⇜ (113/64 → 57/32) ⇝ 2/1 | note:Eb4 gain:0.2907106781186543 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 7/4 ⇜ (113/64 → 57/32) ⇝ 2/1 | note:G4 gain:0.2907106781186543 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 43/28 ⇜ (57/32 → 25/14) | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 43/28 ⇜ (57/32 → 25/14) | note:74 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 43/28 ⇜ (57/32 → 25/14) | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 43/28 ⇜ (57/32 → 25/14) | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 7/4 ⇜ (57/32 → 115/64) ⇝ 15/8 | note:G4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 7/4 ⇜ (57/32 → 115/64) ⇝ 15/8 | note:Bb4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 7/4 ⇜ (57/32 → 115/64) ⇝ 2/1 | note:Bb3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 7/4 ⇜ (57/32 → 115/64) ⇝ 2/1 | note:D4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 7/4 ⇜ (57/32 → 115/64) ⇝ 2/1 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 7/4 ⇜ (57/32 → 115/64) ⇝ 2/1 | note:G4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 7/4 ⇜ (115/64 → 29/16) ⇝ 15/8 | note:G4 gain:0.5814213562373091 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 7/4 ⇜ (115/64 → 29/16) ⇝ 15/8 | note:Bb4 gain:0.5814213562373091 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 7/4 ⇜ (115/64 → 29/16) ⇝ 2/1 | note:Bb3 gain:0.29071067811865453 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 7/4 ⇜ (115/64 → 29/16) ⇝ 2/1 | note:D4 gain:0.29071067811865453 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 7/4 ⇜ (115/64 → 29/16) ⇝ 2/1 | note:Eb4 gain:0.29071067811865453 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 7/4 ⇜ (115/64 → 29/16) ⇝ 2/1 | note:G4 gain:0.29071067811865453 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 7/4 ⇜ (29/16 → 117/64) ⇝ 15/8 | note:G4 gain:0.44000000000000006 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 7/4 ⇜ (29/16 → 117/64) ⇝ 15/8 | note:Bb4 gain:0.44000000000000006 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 7/4 ⇜ (29/16 → 117/64) ⇝ 2/1 | note:Bb3 gain:0.22000000000000003 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 7/4 ⇜ (29/16 → 117/64) ⇝ 2/1 | note:D4 gain:0.22000000000000003 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 7/4 ⇜ (29/16 → 117/64) ⇝ 2/1 | note:Eb4 gain:0.22000000000000003 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 7/4 ⇜ (29/16 → 117/64) ⇝ 2/1 | note:G4 gain:0.22000000000000003 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 7/4 ⇜ (117/64 → 59/32) ⇝ 15/8 | note:G4 gain:0.2985786437626909 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 7/4 ⇜ (117/64 → 59/32) ⇝ 15/8 | note:Bb4 gain:0.2985786437626909 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 7/4 ⇜ (117/64 → 59/32) ⇝ 2/1 | note:Bb3 gain:0.14928932188134544 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 7/4 ⇜ (117/64 → 59/32) ⇝ 2/1 | note:D4 gain:0.14928932188134544 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 7/4 ⇜ (117/64 → 59/32) ⇝ 2/1 | note:Eb4 gain:0.14928932188134544 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 7/4 ⇜ (117/64 → 59/32) ⇝ 2/1 | note:G4 gain:0.14928932188134544 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 7/4 ⇜ (59/32 → 119/64) ⇝ 15/8 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 7/4 ⇜ (59/32 → 119/64) ⇝ 15/8 | note:Bb4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 7/4 ⇜ (59/32 → 119/64) ⇝ 2/1 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 7/4 ⇜ (59/32 → 119/64) ⇝ 2/1 | note:D4 gain:0.12 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 7/4 ⇜ (59/32 → 119/64) ⇝ 2/1 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 7/4 ⇜ (59/32 → 119/64) ⇝ 2/1 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 7/4 ⇜ (119/64 → 15/8) | note:G4 gain:0.29857864376268933 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 7/4 ⇜ (119/64 → 15/8) | note:Bb4 gain:0.29857864376268933 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 7/4 ⇜ (119/64 → 15/8) ⇝ 2/1 | note:Bb3 gain:0.14928932188134467 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 7/4 ⇜ (119/64 → 15/8) ⇝ 2/1 | note:D4 gain:0.14928932188134467 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 7/4 ⇜ (119/64 → 15/8) ⇝ 2/1 | note:Eb4 gain:0.14928932188134467 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 7/4 ⇜ (119/64 → 15/8) ⇝ 2/1 | note:G4 gain:0.14928932188134467 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 7/4 ⇜ (15/8 → 121/64) ⇝ 2/1 | note:Bb3 gain:0.21999999999999892 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 7/4 ⇜ (15/8 → 121/64) ⇝ 2/1 | note:D4 gain:0.21999999999999892 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 7/4 ⇜ (15/8 → 121/64) ⇝ 2/1 | note:Eb4 gain:0.21999999999999892 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 7/4 ⇜ (15/8 → 121/64) ⇝ 2/1 | note:G4 gain:0.21999999999999892 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 7/4 ⇜ (121/64 → 61/32) ⇝ 2/1 | note:Bb3 gain:0.2907106781186548 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 7/4 ⇜ (121/64 → 61/32) ⇝ 2/1 | note:D4 gain:0.2907106781186548 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 7/4 ⇜ (121/64 → 61/32) ⇝ 2/1 | note:Eb4 gain:0.2907106781186548 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 7/4 ⇜ (121/64 → 61/32) ⇝ 2/1 | note:G4 gain:0.2907106781186548 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 7/4 ⇜ (61/32 → 123/64) ⇝ 2/1 | note:Bb3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 7/4 ⇜ (61/32 → 123/64) ⇝ 2/1 | note:D4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 7/4 ⇜ (61/32 → 123/64) ⇝ 2/1 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 7/4 ⇜ (61/32 → 123/64) ⇝ 2/1 | note:G4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 7/4 ⇜ (123/64 → 31/16) ⇝ 2/1 | note:Bb3 gain:0.2907106781186551 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 7/4 ⇜ (123/64 → 31/16) ⇝ 2/1 | note:D4 gain:0.2907106781186551 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 7/4 ⇜ (123/64 → 31/16) ⇝ 2/1 | note:Eb4 gain:0.2907106781186551 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 7/4 ⇜ (123/64 → 31/16) ⇝ 2/1 | note:G4 gain:0.2907106781186551 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 7/4 ⇜ (31/16 → 125/64) ⇝ 2/1 | note:Bb3 gain:0.22000000000000075 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 7/4 ⇜ (31/16 → 125/64) ⇝ 2/1 | note:D4 gain:0.22000000000000075 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 7/4 ⇜ (31/16 → 125/64) ⇝ 2/1 | note:Eb4 gain:0.22000000000000075 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 7/4 ⇜ (31/16 → 125/64) ⇝ 2/1 | note:G4 gain:0.22000000000000075 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 7/4 ⇜ (125/64 → 63/32) ⇝ 2/1 | note:Bb3 gain:0.14928932188134594 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 7/4 ⇜ (125/64 → 63/32) ⇝ 2/1 | note:D4 gain:0.14928932188134594 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 7/4 ⇜ (125/64 → 63/32) ⇝ 2/1 | note:Eb4 gain:0.14928932188134594 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 7/4 ⇜ (125/64 → 63/32) ⇝ 2/1 | note:G4 gain:0.14928932188134594 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 7/4 ⇜ (63/32 → 127/64) ⇝ 2/1 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 7/4 ⇜ (63/32 → 127/64) ⇝ 2/1 | note:D4 gain:0.12 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 7/4 ⇜ (63/32 → 127/64) ⇝ 2/1 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 7/4 ⇜ (63/32 → 127/64) ⇝ 2/1 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 7/4 ⇜ (127/64 → 2/1) | note:Bb3 gain:0.14928932188134517 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 7/4 ⇜ (127/64 → 2/1) | note:D4 gain:0.14928932188134517 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 7/4 ⇜ (127/64 → 2/1) | note:Eb4 gain:0.14928932188134517 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 7/4 ⇜ (127/64 → 2/1) | note:G4 gain:0.14928932188134517 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (2/1 → 129/64) ⇝ 9/4 | note:F2 gain:0.4399999999999993 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 2/1 ⇜ (129/64 → 65/32) ⇝ 9/4 | note:F2 gain:0.5814213562373086 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 2/1 ⇜ (65/32 → 131/64) ⇝ 9/4 | note:F2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ (57/28 → 131/64) ⇝ 16/7 | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ (57/28 → 131/64) ⇝ 16/7 | note:74 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (57/28 → 131/64) ⇝ 16/7 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ (57/28 → 131/64) ⇝ 16/7 | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 2/1 ⇜ (131/64 → 33/16) ⇝ 9/4 | note:F2 gain:0.5814213562373092 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 57/28 ⇜ (131/64 → 33/16) ⇝ 16/7 | note:70 gain:0.05814213562373092 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 57/28 ⇜ (131/64 → 33/16) ⇝ 16/7 | note:74 gain:0.05814213562373092 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 57/28 ⇜ (131/64 → 33/16) ⇝ 16/7 | note:75 gain:0.05814213562373092 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 57/28 ⇜ (131/64 → 33/16) ⇝ 16/7 | note:79 gain:0.05814213562373092 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 2/1 ⇜ (33/16 → 133/64) ⇝ 9/4 | note:F2 gain:0.44000000000000006 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 57/28 ⇜ (33/16 → 133/64) ⇝ 16/7 | note:70 gain:0.04400000000000001 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 57/28 ⇜ (33/16 → 133/64) ⇝ 16/7 | note:74 gain:0.04400000000000001 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 57/28 ⇜ (33/16 → 133/64) ⇝ 16/7 | note:75 gain:0.04400000000000001 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 57/28 ⇜ (33/16 → 133/64) ⇝ 16/7 | note:79 gain:0.04400000000000001 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 2/1 ⇜ (133/64 → 67/32) ⇝ 9/4 | note:F2 gain:0.2985786437626909 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 57/28 ⇜ (133/64 → 67/32) ⇝ 16/7 | note:70 gain:0.02985786437626909 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 57/28 ⇜ (133/64 → 67/32) ⇝ 16/7 | note:74 gain:0.02985786437626909 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 57/28 ⇜ (133/64 → 67/32) ⇝ 16/7 | note:75 gain:0.02985786437626909 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 57/28 ⇜ (133/64 → 67/32) ⇝ 16/7 | note:79 gain:0.02985786437626909 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 2/1 ⇜ (67/32 → 135/64) ⇝ 9/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 57/28 ⇜ (67/32 → 135/64) ⇝ 16/7 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 57/28 ⇜ (67/32 → 135/64) ⇝ 16/7 | note:74 gain:0.024 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 57/28 ⇜ (67/32 → 135/64) ⇝ 16/7 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 57/28 ⇜ (67/32 → 135/64) ⇝ 16/7 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 2/1 ⇜ (135/64 → 17/8) ⇝ 9/4 | note:F2 gain:0.29857864376268933 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 57/28 ⇜ (135/64 → 17/8) ⇝ 16/7 | note:70 gain:0.029857864376268934 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 57/28 ⇜ (135/64 → 17/8) ⇝ 16/7 | note:74 gain:0.029857864376268934 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 57/28 ⇜ (135/64 → 17/8) ⇝ 16/7 | note:75 gain:0.029857864376268934 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 57/28 ⇜ (135/64 → 17/8) ⇝ 16/7 | note:79 gain:0.029857864376268934 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 2/1 ⇜ (17/8 → 137/64) ⇝ 9/4 | note:F2 gain:0.4400000000000006 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 57/28 ⇜ (17/8 → 137/64) ⇝ 16/7 | note:70 gain:0.04400000000000007 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 57/28 ⇜ (17/8 → 137/64) ⇝ 16/7 | note:74 gain:0.04400000000000007 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 57/28 ⇜ (17/8 → 137/64) ⇝ 16/7 | note:75 gain:0.04400000000000007 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 57/28 ⇜ (17/8 → 137/64) ⇝ 16/7 | note:79 gain:0.04400000000000007 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ (17/8 → 137/64) ⇝ 9/4 | note:F4 gain:0.4400000000000006 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (17/8 → 137/64) ⇝ 9/4 | note:Ab4 gain:0.4400000000000006 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 2/1 ⇜ (137/64 → 69/32) ⇝ 9/4 | note:F2 gain:0.5814213562373095 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 57/28 ⇜ (137/64 → 69/32) ⇝ 16/7 | note:70 gain:0.05814213562373095 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 57/28 ⇜ (137/64 → 69/32) ⇝ 16/7 | note:74 gain:0.05814213562373095 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 57/28 ⇜ (137/64 → 69/32) ⇝ 16/7 | note:75 gain:0.05814213562373095 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 57/28 ⇜ (137/64 → 69/32) ⇝ 16/7 | note:79 gain:0.05814213562373095 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 17/8 ⇜ (137/64 → 69/32) ⇝ 9/4 | note:F4 gain:0.5814213562373095 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 17/8 ⇜ (137/64 → 69/32) ⇝ 9/4 | note:Ab4 gain:0.5814213562373095 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 2/1 ⇜ (69/32 → 139/64) ⇝ 9/4 | note:F2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 57/28 ⇜ (69/32 → 139/64) ⇝ 16/7 | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 57/28 ⇜ (69/32 → 139/64) ⇝ 16/7 | note:74 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 57/28 ⇜ (69/32 → 139/64) ⇝ 16/7 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 57/28 ⇜ (69/32 → 139/64) ⇝ 16/7 | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 17/8 ⇜ (69/32 → 139/64) ⇝ 9/4 | note:F4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 17/8 ⇜ (69/32 → 139/64) ⇝ 9/4 | note:Ab4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 2/1 ⇜ (139/64 → 35/16) ⇝ 9/4 | note:F2 gain:0.5814213562373102 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 57/28 ⇜ (139/64 → 35/16) ⇝ 16/7 | note:70 gain:0.05814213562373102 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 57/28 ⇜ (139/64 → 35/16) ⇝ 16/7 | note:74 gain:0.05814213562373102 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 57/28 ⇜ (139/64 → 35/16) ⇝ 16/7 | note:75 gain:0.05814213562373102 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 57/28 ⇜ (139/64 → 35/16) ⇝ 16/7 | note:79 gain:0.05814213562373102 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 17/8 ⇜ (139/64 → 35/16) ⇝ 9/4 | note:F4 gain:0.5814213562373102 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 17/8 ⇜ (139/64 → 35/16) ⇝ 9/4 | note:Ab4 gain:0.5814213562373102 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 2/1 ⇜ (35/16 → 141/64) ⇝ 9/4 | note:F2 gain:0.44000000000000156 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 57/28 ⇜ (35/16 → 141/64) ⇝ 16/7 | note:70 gain:0.04400000000000016 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 57/28 ⇜ (35/16 → 141/64) ⇝ 16/7 | note:74 gain:0.04400000000000016 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 57/28 ⇜ (35/16 → 141/64) ⇝ 16/7 | note:75 gain:0.04400000000000016 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 57/28 ⇜ (35/16 → 141/64) ⇝ 16/7 | note:79 gain:0.04400000000000016 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 17/8 ⇜ (35/16 → 141/64) ⇝ 9/4 | note:F4 gain:0.44000000000000156 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 17/8 ⇜ (35/16 → 141/64) ⇝ 9/4 | note:Ab4 gain:0.44000000000000156 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 2/1 ⇜ (141/64 → 71/32) ⇝ 9/4 | note:F2 gain:0.298578643762692 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 57/28 ⇜ (141/64 → 71/32) ⇝ 16/7 | note:70 gain:0.0298578643762692 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 57/28 ⇜ (141/64 → 71/32) ⇝ 16/7 | note:74 gain:0.0298578643762692 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 57/28 ⇜ (141/64 → 71/32) ⇝ 16/7 | note:75 gain:0.0298578643762692 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 57/28 ⇜ (141/64 → 71/32) ⇝ 16/7 | note:79 gain:0.0298578643762692 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 17/8 ⇜ (141/64 → 71/32) ⇝ 9/4 | note:F4 gain:0.298578643762692 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 17/8 ⇜ (141/64 → 71/32) ⇝ 9/4 | note:Ab4 gain:0.298578643762692 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 2/1 ⇜ (71/32 → 143/64) ⇝ 9/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 57/28 ⇜ (71/32 → 143/64) ⇝ 16/7 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 57/28 ⇜ (71/32 → 143/64) ⇝ 16/7 | note:74 gain:0.024 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 57/28 ⇜ (71/32 → 143/64) ⇝ 16/7 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 57/28 ⇜ (71/32 → 143/64) ⇝ 16/7 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 17/8 ⇜ (71/32 → 143/64) ⇝ 9/4 | note:F4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 17/8 ⇜ (71/32 → 143/64) ⇝ 9/4 | note:Ab4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 2/1 ⇜ (143/64 → 9/4) | note:F2 gain:0.2985786437626902 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 57/28 ⇜ (143/64 → 9/4) ⇝ 16/7 | note:70 gain:0.029857864376269024 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 57/28 ⇜ (143/64 → 9/4) ⇝ 16/7 | note:74 gain:0.029857864376269024 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 57/28 ⇜ (143/64 → 9/4) ⇝ 16/7 | note:75 gain:0.029857864376269024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 57/28 ⇜ (143/64 → 9/4) ⇝ 16/7 | note:79 gain:0.029857864376269024 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 17/8 ⇜ (143/64 → 9/4) | note:F4 gain:0.2985786437626902 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 17/8 ⇜ (143/64 → 9/4) | note:Ab4 gain:0.2985786437626902 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 57/28 ⇜ (9/4 → 145/64) ⇝ 16/7 | note:70 gain:0.04399999999999992 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 57/28 ⇜ (9/4 → 145/64) ⇝ 16/7 | note:74 gain:0.04399999999999992 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 57/28 ⇜ (9/4 → 145/64) ⇝ 16/7 | note:75 gain:0.04399999999999992 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 57/28 ⇜ (9/4 → 145/64) ⇝ 16/7 | note:79 gain:0.04399999999999992 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 57/28 ⇜ (145/64 → 73/32) ⇝ 16/7 | note:70 gain:0.05814213562373086 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 57/28 ⇜ (145/64 → 73/32) ⇝ 16/7 | note:74 gain:0.05814213562373086 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 57/28 ⇜ (145/64 → 73/32) ⇝ 16/7 | note:75 gain:0.05814213562373086 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 57/28 ⇜ (145/64 → 73/32) ⇝ 16/7 | note:79 gain:0.05814213562373086 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 57/28 ⇜ (73/32 → 16/7) | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 57/28 ⇜ (73/32 → 16/7) | note:74 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 57/28 ⇜ (73/32 → 16/7) | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 57/28 ⇜ (73/32 → 16/7) | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ (5/2 → 161/64) ⇝ 21/8 | note:C5 gain:0.439999999999999 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ (5/2 → 161/64) ⇝ 21/8 | note:Eb5 gain:0.439999999999999 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ (5/2 → 161/64) ⇝ 11/4 | note:Eb4 gain:0.2199999999999995 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ (5/2 → 161/64) ⇝ 11/4 | note:G4 gain:0.2199999999999995 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (5/2 → 161/64) ⇝ 11/4 | note:Ab4 gain:0.2199999999999995 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ (5/2 → 161/64) ⇝ 11/4 | note:C5 gain:0.2199999999999995 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ (5/2 → 161/64) ⇝ 11/4 | note:F2 gain:0.439999999999999 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 5/2 ⇜ (161/64 → 81/32) ⇝ 21/8 | note:C5 gain:0.5814213562373084 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 5/2 ⇜ (161/64 → 81/32) ⇝ 21/8 | note:Eb5 gain:0.5814213562373084 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 5/2 ⇜ (161/64 → 81/32) ⇝ 11/4 | note:Eb4 gain:0.2907106781186542 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/2 ⇜ (161/64 → 81/32) ⇝ 11/4 | note:G4 gain:0.2907106781186542 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/2 ⇜ (161/64 → 81/32) ⇝ 11/4 | note:Ab4 gain:0.2907106781186542 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 5/2 ⇜ (161/64 → 81/32) ⇝ 11/4 | note:C5 gain:0.2907106781186542 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 5/2 ⇜ (161/64 → 81/32) ⇝ 11/4 | note:F2 gain:0.5814213562373084 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 5/2 ⇜ (81/32 → 163/64) ⇝ 21/8 | note:C5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 5/2 ⇜ (81/32 → 163/64) ⇝ 21/8 | note:Eb5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 5/2 ⇜ (81/32 → 163/64) ⇝ 11/4 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/2 ⇜ (81/32 → 163/64) ⇝ 11/4 | note:G4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/2 ⇜ (81/32 → 163/64) ⇝ 11/4 | note:Ab4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 5/2 ⇜ (81/32 → 163/64) ⇝ 11/4 | note:C5 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 5/2 ⇜ (81/32 → 163/64) ⇝ 11/4 | note:F2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 5/2 ⇜ (163/64 → 41/16) ⇝ 21/8 | note:C5 gain:0.5814213562373114 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 5/2 ⇜ (163/64 → 41/16) ⇝ 21/8 | note:Eb5 gain:0.5814213562373114 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 5/2 ⇜ (163/64 → 41/16) ⇝ 11/4 | note:Eb4 gain:0.2907106781186557 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/2 ⇜ (163/64 → 41/16) ⇝ 11/4 | note:G4 gain:0.2907106781186557 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/2 ⇜ (163/64 → 41/16) ⇝ 11/4 | note:Ab4 gain:0.2907106781186557 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 5/2 ⇜ (163/64 → 41/16) ⇝ 11/4 | note:C5 gain:0.2907106781186557 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 5/2 ⇜ (163/64 → 41/16) ⇝ 11/4 | note:F2 gain:0.5814213562373114 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 5/2 ⇜ (41/16 → 165/64) ⇝ 21/8 | note:C5 gain:0.44000000000000317 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 5/2 ⇜ (41/16 → 165/64) ⇝ 21/8 | note:Eb5 gain:0.44000000000000317 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 5/2 ⇜ (41/16 → 165/64) ⇝ 11/4 | note:Eb4 gain:0.22000000000000158 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/2 ⇜ (41/16 → 165/64) ⇝ 11/4 | note:G4 gain:0.22000000000000158 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/2 ⇜ (41/16 → 165/64) ⇝ 11/4 | note:Ab4 gain:0.22000000000000158 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 5/2 ⇜ (41/16 → 165/64) ⇝ 11/4 | note:C5 gain:0.22000000000000158 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 5/2 ⇜ (41/16 → 165/64) ⇝ 11/4 | note:F2 gain:0.44000000000000317 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 5/2 ⇜ (165/64 → 83/32) ⇝ 21/8 | note:C5 gain:0.2985786437626931 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 5/2 ⇜ (165/64 → 83/32) ⇝ 21/8 | note:Eb5 gain:0.2985786437626931 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 5/2 ⇜ (165/64 → 83/32) ⇝ 11/4 | note:Eb4 gain:0.14928932188134655 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/2 ⇜ (165/64 → 83/32) ⇝ 11/4 | note:G4 gain:0.14928932188134655 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/2 ⇜ (165/64 → 83/32) ⇝ 11/4 | note:Ab4 gain:0.14928932188134655 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 5/2 ⇜ (165/64 → 83/32) ⇝ 11/4 | note:C5 gain:0.14928932188134655 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 5/2 ⇜ (165/64 → 83/32) ⇝ 11/4 | note:F2 gain:0.2985786437626931 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 5/2 ⇜ (83/32 → 167/64) ⇝ 21/8 | note:C5 gain:0.24 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 5/2 ⇜ (83/32 → 167/64) ⇝ 21/8 | note:Eb5 gain:0.24 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 5/2 ⇜ (83/32 → 167/64) ⇝ 11/4 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/2 ⇜ (83/32 → 167/64) ⇝ 11/4 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/2 ⇜ (83/32 → 167/64) ⇝ 11/4 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 5/2 ⇜ (83/32 → 167/64) ⇝ 11/4 | note:C5 gain:0.12 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 5/2 ⇜ (83/32 → 167/64) ⇝ 11/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 5/2 ⇜ (167/64 → 21/8) | note:C5 gain:0.29857864376269116 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 5/2 ⇜ (167/64 → 21/8) | note:Eb5 gain:0.29857864376269116 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 5/2 ⇜ (167/64 → 21/8) ⇝ 11/4 | note:Eb4 gain:0.14928932188134558 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/2 ⇜ (167/64 → 21/8) ⇝ 11/4 | note:G4 gain:0.14928932188134558 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/2 ⇜ (167/64 → 21/8) ⇝ 11/4 | note:Ab4 gain:0.14928932188134558 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 5/2 ⇜ (167/64 → 21/8) ⇝ 11/4 | note:C5 gain:0.14928932188134558 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 5/2 ⇜ (167/64 → 21/8) ⇝ 11/4 | note:F2 gain:0.29857864376269116 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 5/2 ⇜ (21/8 → 169/64) ⇝ 11/4 | note:Eb4 gain:0.2200000000000002 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/2 ⇜ (21/8 → 169/64) ⇝ 11/4 | note:G4 gain:0.2200000000000002 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/2 ⇜ (21/8 → 169/64) ⇝ 11/4 | note:Ab4 gain:0.2200000000000002 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 5/2 ⇜ (21/8 → 169/64) ⇝ 11/4 | note:C5 gain:0.2200000000000002 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 5/2 ⇜ (21/8 → 169/64) ⇝ 11/4 | note:F2 gain:0.4400000000000004 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 5/2 ⇜ (169/64 → 85/32) ⇝ 11/4 | note:Eb4 gain:0.29071067811865475 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/2 ⇜ (169/64 → 85/32) ⇝ 11/4 | note:G4 gain:0.29071067811865475 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/2 ⇜ (169/64 → 85/32) ⇝ 11/4 | note:Ab4 gain:0.29071067811865475 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 5/2 ⇜ (169/64 → 85/32) ⇝ 11/4 | note:C5 gain:0.29071067811865475 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 5/2 ⇜ (169/64 → 85/32) ⇝ 11/4 | note:F2 gain:0.5814213562373095 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 5/2 ⇜ (85/32 → 171/64) ⇝ 11/4 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/2 ⇜ (85/32 → 171/64) ⇝ 11/4 | note:G4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/2 ⇜ (85/32 → 171/64) ⇝ 11/4 | note:Ab4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 5/2 ⇜ (85/32 → 171/64) ⇝ 11/4 | note:C5 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 5/2 ⇜ (85/32 → 171/64) ⇝ 11/4 | note:F2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 5/2 ⇜ (171/64 → 43/16) ⇝ 11/4 | note:Eb4 gain:0.2907106781186552 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/2 ⇜ (171/64 → 43/16) ⇝ 11/4 | note:G4 gain:0.2907106781186552 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/2 ⇜ (171/64 → 43/16) ⇝ 11/4 | note:Ab4 gain:0.2907106781186552 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 5/2 ⇜ (171/64 → 43/16) ⇝ 11/4 | note:C5 gain:0.2907106781186552 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 5/2 ⇜ (171/64 → 43/16) ⇝ 11/4 | note:F2 gain:0.5814213562373104 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 5/2 ⇜ (43/16 → 173/64) ⇝ 11/4 | note:Eb4 gain:0.22000000000000092 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/2 ⇜ (43/16 → 173/64) ⇝ 11/4 | note:G4 gain:0.22000000000000092 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/2 ⇜ (43/16 → 173/64) ⇝ 11/4 | note:Ab4 gain:0.22000000000000092 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 5/2 ⇜ (43/16 → 173/64) ⇝ 11/4 | note:C5 gain:0.22000000000000092 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 5/2 ⇜ (43/16 → 173/64) ⇝ 11/4 | note:F2 gain:0.44000000000000183 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 5/2 ⇜ (173/64 → 87/32) ⇝ 11/4 | note:Eb4 gain:0.14928932188134608 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/2 ⇜ (173/64 → 87/32) ⇝ 11/4 | note:G4 gain:0.14928932188134608 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/2 ⇜ (173/64 → 87/32) ⇝ 11/4 | note:Ab4 gain:0.14928932188134608 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 5/2 ⇜ (173/64 → 87/32) ⇝ 11/4 | note:C5 gain:0.14928932188134608 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 5/2 ⇜ (173/64 → 87/32) ⇝ 11/4 | note:F2 gain:0.29857864376269216 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 5/2 ⇜ (87/32 → 175/64) ⇝ 11/4 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/2 ⇜ (87/32 → 175/64) ⇝ 11/4 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/2 ⇜ (87/32 → 175/64) ⇝ 11/4 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 5/2 ⇜ (87/32 → 175/64) ⇝ 11/4 | note:C5 gain:0.12 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 5/2 ⇜ (87/32 → 175/64) ⇝ 11/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 5/2 ⇜ (175/64 → 11/4) | note:Eb4 gain:0.14928932188134406 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/2 ⇜ (175/64 → 11/4) | note:G4 gain:0.14928932188134406 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/2 ⇜ (175/64 → 11/4) | note:Ab4 gain:0.14928932188134406 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 5/2 ⇜ (175/64 → 11/4) | note:C5 gain:0.14928932188134406 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 5/2 ⇜ (175/64 → 11/4) | note:F2 gain:0.2985786437626881 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ (11/4 → 177/64) ⇝ 23/8 | note:F4 gain:0.43999999999999606 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (11/4 → 177/64) ⇝ 23/8 | note:Ab4 gain:0.43999999999999606 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 11/4 ⇜ (177/64 → 89/32) ⇝ 23/8 | note:F4 gain:0.5814213562373104 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 11/4 ⇜ (177/64 → 89/32) ⇝ 23/8 | note:Ab4 gain:0.5814213562373104 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 11/4 ⇜ (89/32 → 179/64) ⇝ 23/8 | note:F4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 11/4 ⇜ (89/32 → 179/64) ⇝ 23/8 | note:Ab4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ (39/14 → 179/64) ⇝ 85/28 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ (39/14 → 179/64) ⇝ 85/28 | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ (39/14 → 179/64) ⇝ 85/28 | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ (39/14 → 179/64) ⇝ 85/28 | note:84 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 11/4 ⇜ (179/64 → 45/16) ⇝ 23/8 | note:F4 gain:0.5814213562373095 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 11/4 ⇜ (179/64 → 45/16) ⇝ 23/8 | note:Ab4 gain:0.5814213562373095 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 39/14 ⇜ (179/64 → 45/16) ⇝ 85/28 | note:75 gain:0.05814213562373095 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 39/14 ⇜ (179/64 → 45/16) ⇝ 85/28 | note:79 gain:0.05814213562373095 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 39/14 ⇜ (179/64 → 45/16) ⇝ 85/28 | note:80 gain:0.05814213562373095 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 39/14 ⇜ (179/64 → 45/16) ⇝ 85/28 | note:84 gain:0.05814213562373095 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 11/4 ⇜ (45/16 → 181/64) ⇝ 23/8 | note:F4 gain:0.4400000000000004 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 11/4 ⇜ (45/16 → 181/64) ⇝ 23/8 | note:Ab4 gain:0.4400000000000004 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 39/14 ⇜ (45/16 → 181/64) ⇝ 85/28 | note:75 gain:0.04400000000000004 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 39/14 ⇜ (45/16 → 181/64) ⇝ 85/28 | note:79 gain:0.04400000000000004 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 39/14 ⇜ (45/16 → 181/64) ⇝ 85/28 | note:80 gain:0.04400000000000004 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 39/14 ⇜ (45/16 → 181/64) ⇝ 85/28 | note:84 gain:0.04400000000000004 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 11/4 ⇜ (181/64 → 91/32) ⇝ 23/8 | note:F4 gain:0.29857864376269116 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 11/4 ⇜ (181/64 → 91/32) ⇝ 23/8 | note:Ab4 gain:0.29857864376269116 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 39/14 ⇜ (181/64 → 91/32) ⇝ 85/28 | note:75 gain:0.029857864376269118 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 39/14 ⇜ (181/64 → 91/32) ⇝ 85/28 | note:79 gain:0.029857864376269118 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 39/14 ⇜ (181/64 → 91/32) ⇝ 85/28 | note:80 gain:0.029857864376269118 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 39/14 ⇜ (181/64 → 91/32) ⇝ 85/28 | note:84 gain:0.029857864376269118 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 11/4 ⇜ (91/32 → 183/64) ⇝ 23/8 | note:F4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 11/4 ⇜ (91/32 → 183/64) ⇝ 23/8 | note:Ab4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 39/14 ⇜ (91/32 → 183/64) ⇝ 85/28 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 39/14 ⇜ (91/32 → 183/64) ⇝ 85/28 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 39/14 ⇜ (91/32 → 183/64) ⇝ 85/28 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 39/14 ⇜ (91/32 → 183/64) ⇝ 85/28 | note:84 gain:0.024 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 11/4 ⇜ (183/64 → 23/8) | note:F4 gain:0.2985786437626891 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 11/4 ⇜ (183/64 → 23/8) | note:Ab4 gain:0.2985786437626891 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 39/14 ⇜ (183/64 → 23/8) ⇝ 85/28 | note:75 gain:0.029857864376268913 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 39/14 ⇜ (183/64 → 23/8) ⇝ 85/28 | note:79 gain:0.029857864376268913 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 39/14 ⇜ (183/64 → 23/8) ⇝ 85/28 | note:80 gain:0.029857864376268913 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 39/14 ⇜ (183/64 → 23/8) ⇝ 85/28 | note:84 gain:0.029857864376268913 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 39/14 ⇜ (23/8 → 185/64) ⇝ 85/28 | note:75 gain:0.043999999999999755 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 39/14 ⇜ (23/8 → 185/64) ⇝ 85/28 | note:79 gain:0.043999999999999755 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 39/14 ⇜ (23/8 → 185/64) ⇝ 85/28 | note:80 gain:0.043999999999999755 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 39/14 ⇜ (23/8 → 185/64) ⇝ 85/28 | note:84 gain:0.043999999999999755 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 39/14 ⇜ (185/64 → 93/32) ⇝ 85/28 | note:75 gain:0.05814213562373073 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 39/14 ⇜ (185/64 → 93/32) ⇝ 85/28 | note:79 gain:0.05814213562373073 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 39/14 ⇜ (185/64 → 93/32) ⇝ 85/28 | note:80 gain:0.05814213562373073 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 39/14 ⇜ (185/64 → 93/32) ⇝ 85/28 | note:84 gain:0.05814213562373073 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 39/14 ⇜ (93/32 → 187/64) ⇝ 85/28 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 39/14 ⇜ (93/32 → 187/64) ⇝ 85/28 | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 39/14 ⇜ (93/32 → 187/64) ⇝ 85/28 | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 39/14 ⇜ (93/32 → 187/64) ⇝ 85/28 | note:84 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 39/14 ⇜ (187/64 → 47/16) ⇝ 85/28 | note:75 gain:0.05814213562373084 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 39/14 ⇜ (187/64 → 47/16) ⇝ 85/28 | note:79 gain:0.05814213562373084 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 39/14 ⇜ (187/64 → 47/16) ⇝ 85/28 | note:80 gain:0.05814213562373084 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 39/14 ⇜ (187/64 → 47/16) ⇝ 85/28 | note:84 gain:0.05814213562373084 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 39/14 ⇜ (47/16 → 189/64) ⇝ 85/28 | note:75 gain:0.0439999999999999 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 39/14 ⇜ (47/16 → 189/64) ⇝ 85/28 | note:79 gain:0.0439999999999999 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 39/14 ⇜ (47/16 → 189/64) ⇝ 85/28 | note:80 gain:0.0439999999999999 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 39/14 ⇜ (47/16 → 189/64) ⇝ 85/28 | note:84 gain:0.0439999999999999 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 39/14 ⇜ (189/64 → 95/32) ⇝ 85/28 | note:75 gain:0.029857864376269024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 39/14 ⇜ (189/64 → 95/32) ⇝ 85/28 | note:79 gain:0.029857864376269024 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 39/14 ⇜ (189/64 → 95/32) ⇝ 85/28 | note:80 gain:0.029857864376269024 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 39/14 ⇜ (189/64 → 95/32) ⇝ 85/28 | note:84 gain:0.029857864376269024 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 39/14 ⇜ (95/32 → 191/64) ⇝ 85/28 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 39/14 ⇜ (95/32 → 191/64) ⇝ 85/28 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 39/14 ⇜ (95/32 → 191/64) ⇝ 85/28 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 39/14 ⇜ (95/32 → 191/64) ⇝ 85/28 | note:84 gain:0.024 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 39/14 ⇜ (191/64 → 3/1) ⇝ 85/28 | note:75 gain:0.029857864376269 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 39/14 ⇜ (191/64 → 3/1) ⇝ 85/28 | note:79 gain:0.029857864376269 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 39/14 ⇜ (191/64 → 3/1) ⇝ 85/28 | note:80 gain:0.029857864376269 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 39/14 ⇜ (191/64 → 3/1) ⇝ 85/28 | note:84 gain:0.029857864376269 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 39/14 ⇜ (3/1 → 193/64) ⇝ 85/28 | note:75 gain:0.043999999999999886 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 39/14 ⇜ (3/1 → 193/64) ⇝ 85/28 | note:79 gain:0.043999999999999886 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 39/14 ⇜ (3/1 → 193/64) ⇝ 85/28 | note:80 gain:0.043999999999999886 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 39/14 ⇜ (3/1 → 193/64) ⇝ 85/28 | note:84 gain:0.043999999999999886 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ (3/1 → 193/64) ⇝ 13/4 | note:F2 gain:0.43999999999999884 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 39/14 ⇜ (193/64 → 97/32) ⇝ 85/28 | note:75 gain:0.05814213562373083 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 39/14 ⇜ (193/64 → 97/32) ⇝ 85/28 | note:79 gain:0.05814213562373083 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 39/14 ⇜ (193/64 → 97/32) ⇝ 85/28 | note:80 gain:0.05814213562373083 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 39/14 ⇜ (193/64 → 97/32) ⇝ 85/28 | note:84 gain:0.05814213562373083 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 3/1 ⇜ (193/64 → 97/32) ⇝ 13/4 | note:F2 gain:0.5814213562373083 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 39/14 ⇜ (97/32 → 85/28) | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 39/14 ⇜ (97/32 → 85/28) | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 39/14 ⇜ (97/32 → 85/28) | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 39/14 ⇜ (97/32 → 85/28) | note:84 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 3/1 ⇜ (97/32 → 195/64) ⇝ 13/4 | note:F2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 3/1 ⇜ (195/64 → 49/16) ⇝ 13/4 | note:F2 gain:0.5814213562373115 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 3/1 ⇜ (49/16 → 197/64) ⇝ 13/4 | note:F2 gain:0.44000000000000333 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 3/1 ⇜ (197/64 → 99/32) ⇝ 13/4 | note:F2 gain:0.2985786437626932 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 3/1 ⇜ (99/32 → 199/64) ⇝ 13/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 3/1 ⇜ (199/64 → 25/8) ⇝ 13/4 | note:F2 gain:0.298578643762691 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 3/1 ⇜ (25/8 → 201/64) ⇝ 13/4 | note:F2 gain:0.4400000000000002 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ (25/8 → 201/64) ⇝ 13/4 | note:F4 gain:0.4400000000000002 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (25/8 → 201/64) ⇝ 13/4 | note:Ab4 gain:0.4400000000000002 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 3/1 ⇜ (201/64 → 101/32) ⇝ 13/4 | note:F2 gain:0.5814213562373093 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 25/8 ⇜ (201/64 → 101/32) ⇝ 13/4 | note:F4 gain:0.5814213562373093 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 25/8 ⇜ (201/64 → 101/32) ⇝ 13/4 | note:Ab4 gain:0.5814213562373093 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 3/1 ⇜ (101/32 → 203/64) ⇝ 13/4 | note:F2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 25/8 ⇜ (101/32 → 203/64) ⇝ 13/4 | note:F4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 25/8 ⇜ (101/32 → 203/64) ⇝ 13/4 | note:Ab4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 3/1 ⇜ (203/64 → 51/16) ⇝ 13/4 | note:F2 gain:0.5814213562373105 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 25/8 ⇜ (203/64 → 51/16) ⇝ 13/4 | note:F4 gain:0.5814213562373105 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 25/8 ⇜ (203/64 → 51/16) ⇝ 13/4 | note:Ab4 gain:0.5814213562373105 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 3/1 ⇜ (51/16 → 205/64) ⇝ 13/4 | note:F2 gain:0.440000000000002 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 25/8 ⇜ (51/16 → 205/64) ⇝ 13/4 | note:F4 gain:0.440000000000002 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 25/8 ⇜ (51/16 → 205/64) ⇝ 13/4 | note:Ab4 gain:0.440000000000002 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 3/1 ⇜ (205/64 → 103/32) ⇝ 13/4 | note:F2 gain:0.2985786437626922 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 25/8 ⇜ (205/64 → 103/32) ⇝ 13/4 | note:F4 gain:0.2985786437626922 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 25/8 ⇜ (205/64 → 103/32) ⇝ 13/4 | note:Ab4 gain:0.2985786437626922 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 3/1 ⇜ (103/32 → 207/64) ⇝ 13/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 25/8 ⇜ (103/32 → 207/64) ⇝ 13/4 | note:F4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 25/8 ⇜ (103/32 → 207/64) ⇝ 13/4 | note:Ab4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 3/1 ⇜ (207/64 → 13/4) | note:F2 gain:0.298578643762688 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 25/8 ⇜ (207/64 → 13/4) | note:F4 gain:0.298578643762688 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 25/8 ⇜ (207/64 → 13/4) | note:Ab4 gain:0.298578643762688 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ (13/4 → 209/64) ⇝ 7/2 | note:Eb4 gain:0.22000000000000078 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ (13/4 → 209/64) ⇝ 7/2 | note:G4 gain:0.22000000000000078 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (13/4 → 209/64) ⇝ 7/2 | note:Ab4 gain:0.22000000000000078 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ (13/4 → 209/64) ⇝ 7/2 | note:C5 gain:0.22000000000000078 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 13/4 ⇜ (209/64 → 105/32) ⇝ 7/2 | note:Eb4 gain:0.2907106781186551 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/4 ⇜ (209/64 → 105/32) ⇝ 7/2 | note:G4 gain:0.2907106781186551 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 13/4 ⇜ (209/64 → 105/32) ⇝ 7/2 | note:Ab4 gain:0.2907106781186551 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/4 ⇜ (209/64 → 105/32) ⇝ 7/2 | note:C5 gain:0.2907106781186551 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 13/4 ⇜ (105/32 → 211/64) ⇝ 7/2 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/4 ⇜ (105/32 → 211/64) ⇝ 7/2 | note:G4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 13/4 ⇜ (105/32 → 211/64) ⇝ 7/2 | note:Ab4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/4 ⇜ (105/32 → 211/64) ⇝ 7/2 | note:C5 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 13/4 ⇜ (211/64 → 53/16) ⇝ 7/2 | note:Eb4 gain:0.29071067811865475 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/4 ⇜ (211/64 → 53/16) ⇝ 7/2 | note:G4 gain:0.29071067811865475 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 13/4 ⇜ (211/64 → 53/16) ⇝ 7/2 | note:Ab4 gain:0.29071067811865475 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/4 ⇜ (211/64 → 53/16) ⇝ 7/2 | note:C5 gain:0.29071067811865475 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 13/4 ⇜ (53/16 → 213/64) ⇝ 7/2 | note:Eb4 gain:0.2200000000000003 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/4 ⇜ (53/16 → 213/64) ⇝ 7/2 | note:G4 gain:0.2200000000000003 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 13/4 ⇜ (53/16 → 213/64) ⇝ 7/2 | note:Ab4 gain:0.2200000000000003 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/4 ⇜ (53/16 → 213/64) ⇝ 7/2 | note:C5 gain:0.2200000000000003 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 13/4 ⇜ (213/64 → 107/32) ⇝ 7/2 | note:Eb4 gain:0.14928932188134564 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/4 ⇜ (213/64 → 107/32) ⇝ 7/2 | note:G4 gain:0.14928932188134564 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 13/4 ⇜ (213/64 → 107/32) ⇝ 7/2 | note:Ab4 gain:0.14928932188134564 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/4 ⇜ (213/64 → 107/32) ⇝ 7/2 | note:C5 gain:0.14928932188134564 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 13/4 ⇜ (107/32 → 215/64) ⇝ 7/2 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/4 ⇜ (107/32 → 215/64) ⇝ 7/2 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 13/4 ⇜ (107/32 → 215/64) ⇝ 7/2 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/4 ⇜ (107/32 → 215/64) ⇝ 7/2 | note:C5 gain:0.12 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 13/4 ⇜ (215/64 → 27/8) ⇝ 7/2 | note:Eb4 gain:0.14928932188134447 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/4 ⇜ (215/64 → 27/8) ⇝ 7/2 | note:G4 gain:0.14928932188134447 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 13/4 ⇜ (215/64 → 27/8) ⇝ 7/2 | note:Ab4 gain:0.14928932188134447 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/4 ⇜ (215/64 → 27/8) ⇝ 7/2 | note:C5 gain:0.14928932188134447 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 13/4 ⇜ (27/8 → 217/64) ⇝ 7/2 | note:Eb4 gain:0.2199999999999986 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/4 ⇜ (27/8 → 217/64) ⇝ 7/2 | note:G4 gain:0.2199999999999986 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 13/4 ⇜ (27/8 → 217/64) ⇝ 7/2 | note:Ab4 gain:0.2199999999999986 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/4 ⇜ (27/8 → 217/64) ⇝ 7/2 | note:C5 gain:0.2199999999999986 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 13/4 ⇜ (217/64 → 109/32) ⇝ 7/2 | note:Eb4 gain:0.2907106781186536 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/4 ⇜ (217/64 → 109/32) ⇝ 7/2 | note:G4 gain:0.2907106781186536 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 13/4 ⇜ (217/64 → 109/32) ⇝ 7/2 | note:Ab4 gain:0.2907106781186536 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/4 ⇜ (217/64 → 109/32) ⇝ 7/2 | note:C5 gain:0.2907106781186536 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 13/4 ⇜ (109/32 → 219/64) ⇝ 7/2 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/4 ⇜ (109/32 → 219/64) ⇝ 7/2 | note:G4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 13/4 ⇜ (109/32 → 219/64) ⇝ 7/2 | note:Ab4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/4 ⇜ (109/32 → 219/64) ⇝ 7/2 | note:C5 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 13/4 ⇜ (219/64 → 55/16) ⇝ 7/2 | note:Eb4 gain:0.2907106781186543 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/4 ⇜ (219/64 → 55/16) ⇝ 7/2 | note:G4 gain:0.2907106781186543 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 13/4 ⇜ (219/64 → 55/16) ⇝ 7/2 | note:Ab4 gain:0.2907106781186543 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/4 ⇜ (219/64 → 55/16) ⇝ 7/2 | note:C5 gain:0.2907106781186543 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 13/4 ⇜ (55/16 → 221/64) ⇝ 7/2 | note:Eb4 gain:0.21999999999999964 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/4 ⇜ (55/16 → 221/64) ⇝ 7/2 | note:G4 gain:0.21999999999999964 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 13/4 ⇜ (55/16 → 221/64) ⇝ 7/2 | note:Ab4 gain:0.21999999999999964 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/4 ⇜ (55/16 → 221/64) ⇝ 7/2 | note:C5 gain:0.21999999999999964 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 13/4 ⇜ (221/64 → 111/32) ⇝ 7/2 | note:Eb4 gain:0.14928932188134517 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/4 ⇜ (221/64 → 111/32) ⇝ 7/2 | note:G4 gain:0.14928932188134517 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 13/4 ⇜ (221/64 → 111/32) ⇝ 7/2 | note:Ab4 gain:0.14928932188134517 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/4 ⇜ (221/64 → 111/32) ⇝ 7/2 | note:C5 gain:0.14928932188134517 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 13/4 ⇜ (111/32 → 223/64) ⇝ 7/2 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/4 ⇜ (111/32 → 223/64) ⇝ 7/2 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 13/4 ⇜ (111/32 → 223/64) ⇝ 7/2 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/4 ⇜ (111/32 → 223/64) ⇝ 7/2 | note:C5 gain:0.12 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 13/4 ⇜ (223/64 → 7/2) | note:Eb4 gain:0.14928932188134497 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/4 ⇜ (223/64 → 7/2) | note:G4 gain:0.14928932188134497 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 13/4 ⇜ (223/64 → 7/2) | note:Ab4 gain:0.14928932188134497 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/4 ⇜ (223/64 → 7/2) | note:C5 gain:0.14928932188134497 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ (7/2 → 225/64) ⇝ 29/8 | note:C5 gain:0.4399999999999986 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ (7/2 → 225/64) ⇝ 29/8 | note:Eb5 gain:0.4399999999999986 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ (7/2 → 225/64) ⇝ 15/4 | note:F2 gain:0.4399999999999986 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 7/2 ⇜ (225/64 → 113/32) ⇝ 29/8 | note:C5 gain:0.5814213562373082 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 7/2 ⇜ (225/64 → 113/32) ⇝ 29/8 | note:Eb5 gain:0.5814213562373082 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 7/2 ⇜ (225/64 → 113/32) ⇝ 15/4 | note:F2 gain:0.5814213562373082 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 7/2 ⇜ (113/32 → 227/64) ⇝ 29/8 | note:C5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 7/2 ⇜ (113/32 → 227/64) ⇝ 29/8 | note:Eb5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 7/2 ⇜ (113/32 → 227/64) ⇝ 15/4 | note:F2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ (99/28 → 227/64) ⇝ 53/14 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ (99/28 → 227/64) ⇝ 53/14 | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ (99/28 → 227/64) ⇝ 53/14 | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ (99/28 → 227/64) ⇝ 53/14 | note:84 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 7/2 ⇜ (227/64 → 57/16) ⇝ 29/8 | note:C5 gain:0.5814213562373116 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 7/2 ⇜ (227/64 → 57/16) ⇝ 29/8 | note:Eb5 gain:0.5814213562373116 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 7/2 ⇜ (227/64 → 57/16) ⇝ 15/4 | note:F2 gain:0.5814213562373116 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 99/28 ⇜ (227/64 → 57/16) ⇝ 53/14 | note:75 gain:0.05814213562373116 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 99/28 ⇜ (227/64 → 57/16) ⇝ 53/14 | note:79 gain:0.05814213562373116 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 99/28 ⇜ (227/64 → 57/16) ⇝ 53/14 | note:80 gain:0.05814213562373116 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 99/28 ⇜ (227/64 → 57/16) ⇝ 53/14 | note:84 gain:0.05814213562373116 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 7/2 ⇜ (57/16 → 229/64) ⇝ 29/8 | note:C5 gain:0.4400000000000035 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 7/2 ⇜ (57/16 → 229/64) ⇝ 29/8 | note:Eb5 gain:0.4400000000000035 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 7/2 ⇜ (57/16 → 229/64) ⇝ 15/4 | note:F2 gain:0.4400000000000035 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 99/28 ⇜ (57/16 → 229/64) ⇝ 53/14 | note:75 gain:0.04400000000000035 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 99/28 ⇜ (57/16 → 229/64) ⇝ 53/14 | note:79 gain:0.04400000000000035 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 99/28 ⇜ (57/16 → 229/64) ⇝ 53/14 | note:80 gain:0.04400000000000035 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 99/28 ⇜ (57/16 → 229/64) ⇝ 53/14 | note:84 gain:0.04400000000000035 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 7/2 ⇜ (229/64 → 115/32) ⇝ 29/8 | note:C5 gain:0.2985786437626934 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 7/2 ⇜ (229/64 → 115/32) ⇝ 29/8 | note:Eb5 gain:0.2985786437626934 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 7/2 ⇜ (229/64 → 115/32) ⇝ 15/4 | note:F2 gain:0.2985786437626934 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 99/28 ⇜ (229/64 → 115/32) ⇝ 53/14 | note:75 gain:0.02985786437626934 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 99/28 ⇜ (229/64 → 115/32) ⇝ 53/14 | note:79 gain:0.02985786437626934 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 99/28 ⇜ (229/64 → 115/32) ⇝ 53/14 | note:80 gain:0.02985786437626934 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 99/28 ⇜ (229/64 → 115/32) ⇝ 53/14 | note:84 gain:0.02985786437626934 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 7/2 ⇜ (115/32 → 231/64) ⇝ 29/8 | note:C5 gain:0.24 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 7/2 ⇜ (115/32 → 231/64) ⇝ 29/8 | note:Eb5 gain:0.24 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 7/2 ⇜ (115/32 → 231/64) ⇝ 15/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 99/28 ⇜ (115/32 → 231/64) ⇝ 53/14 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 99/28 ⇜ (115/32 → 231/64) ⇝ 53/14 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 99/28 ⇜ (115/32 → 231/64) ⇝ 53/14 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 99/28 ⇜ (115/32 → 231/64) ⇝ 53/14 | note:84 gain:0.024 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 7/2 ⇜ (231/64 → 29/8) | note:C5 gain:0.2985786437626909 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 7/2 ⇜ (231/64 → 29/8) | note:Eb5 gain:0.2985786437626909 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 7/2 ⇜ (231/64 → 29/8) ⇝ 15/4 | note:F2 gain:0.2985786437626909 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 99/28 ⇜ (231/64 → 29/8) ⇝ 53/14 | note:75 gain:0.02985786437626909 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 99/28 ⇜ (231/64 → 29/8) ⇝ 53/14 | note:79 gain:0.02985786437626909 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 99/28 ⇜ (231/64 → 29/8) ⇝ 53/14 | note:80 gain:0.02985786437626909 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 99/28 ⇜ (231/64 → 29/8) ⇝ 53/14 | note:84 gain:0.02985786437626909 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 7/2 ⇜ (29/8 → 233/64) ⇝ 15/4 | note:F2 gain:0.44000000000000006 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 99/28 ⇜ (29/8 → 233/64) ⇝ 53/14 | note:75 gain:0.04400000000000001 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 99/28 ⇜ (29/8 → 233/64) ⇝ 53/14 | note:79 gain:0.04400000000000001 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 99/28 ⇜ (29/8 → 233/64) ⇝ 53/14 | note:80 gain:0.04400000000000001 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 99/28 ⇜ (29/8 → 233/64) ⇝ 53/14 | note:84 gain:0.04400000000000001 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 7/2 ⇜ (233/64 → 117/32) ⇝ 15/4 | note:F2 gain:0.5814213562373091 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 99/28 ⇜ (233/64 → 117/32) ⇝ 53/14 | note:75 gain:0.05814213562373091 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 99/28 ⇜ (233/64 → 117/32) ⇝ 53/14 | note:79 gain:0.05814213562373091 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 99/28 ⇜ (233/64 → 117/32) ⇝ 53/14 | note:80 gain:0.05814213562373091 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 99/28 ⇜ (233/64 → 117/32) ⇝ 53/14 | note:84 gain:0.05814213562373091 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 7/2 ⇜ (117/32 → 235/64) ⇝ 15/4 | note:F2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 99/28 ⇜ (117/32 → 235/64) ⇝ 53/14 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 99/28 ⇜ (117/32 → 235/64) ⇝ 53/14 | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 99/28 ⇜ (117/32 → 235/64) ⇝ 53/14 | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 99/28 ⇜ (117/32 → 235/64) ⇝ 53/14 | note:84 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 7/2 ⇜ (235/64 → 59/16) ⇝ 15/4 | note:F2 gain:0.5814213562373107 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 99/28 ⇜ (235/64 → 59/16) ⇝ 53/14 | note:75 gain:0.05814213562373108 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 99/28 ⇜ (235/64 → 59/16) ⇝ 53/14 | note:79 gain:0.05814213562373108 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 99/28 ⇜ (235/64 → 59/16) ⇝ 53/14 | note:80 gain:0.05814213562373108 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 99/28 ⇜ (235/64 → 59/16) ⇝ 53/14 | note:84 gain:0.05814213562373108 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 7/2 ⇜ (59/16 → 237/64) ⇝ 15/4 | note:F2 gain:0.44000000000000217 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 99/28 ⇜ (59/16 → 237/64) ⇝ 53/14 | note:75 gain:0.04400000000000022 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 99/28 ⇜ (59/16 → 237/64) ⇝ 53/14 | note:79 gain:0.04400000000000022 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 99/28 ⇜ (59/16 → 237/64) ⇝ 53/14 | note:80 gain:0.04400000000000022 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 99/28 ⇜ (59/16 → 237/64) ⇝ 53/14 | note:84 gain:0.04400000000000022 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 7/2 ⇜ (237/64 → 119/32) ⇝ 15/4 | note:F2 gain:0.29857864376269244 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 99/28 ⇜ (237/64 → 119/32) ⇝ 53/14 | note:75 gain:0.029857864376269246 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 99/28 ⇜ (237/64 → 119/32) ⇝ 53/14 | note:79 gain:0.029857864376269246 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 99/28 ⇜ (237/64 → 119/32) ⇝ 53/14 | note:80 gain:0.029857864376269246 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 99/28 ⇜ (237/64 → 119/32) ⇝ 53/14 | note:84 gain:0.029857864376269246 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 7/2 ⇜ (119/32 → 239/64) ⇝ 15/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 99/28 ⇜ (119/32 → 239/64) ⇝ 53/14 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 99/28 ⇜ (119/32 → 239/64) ⇝ 53/14 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 99/28 ⇜ (119/32 → 239/64) ⇝ 53/14 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 99/28 ⇜ (119/32 → 239/64) ⇝ 53/14 | note:84 gain:0.024 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 7/2 ⇜ (239/64 → 15/4) | note:F2 gain:0.2985786437626878 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 99/28 ⇜ (239/64 → 15/4) ⇝ 53/14 | note:75 gain:0.029857864376268778 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 99/28 ⇜ (239/64 → 15/4) ⇝ 53/14 | note:79 gain:0.029857864376268778 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 99/28 ⇜ (239/64 → 15/4) ⇝ 53/14 | note:80 gain:0.029857864376268778 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 99/28 ⇜ (239/64 → 15/4) ⇝ 53/14 | note:84 gain:0.029857864376268778 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 99/28 ⇜ (15/4 → 241/64) ⇝ 53/14 | note:75 gain:0.043999999999999574 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 99/28 ⇜ (15/4 → 241/64) ⇝ 53/14 | note:79 gain:0.043999999999999574 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 99/28 ⇜ (15/4 → 241/64) ⇝ 53/14 | note:80 gain:0.043999999999999574 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 99/28 ⇜ (15/4 → 241/64) ⇝ 53/14 | note:84 gain:0.043999999999999574 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ (15/4 → 241/64) ⇝ 31/8 | note:C5 gain:0.43999999999999573 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ (15/4 → 241/64) ⇝ 31/8 | note:Eb5 gain:0.43999999999999573 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ (15/4 → 241/64) ⇝ 4/1 | note:Eb4 gain:0.21999999999999786 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ (15/4 → 241/64) ⇝ 4/1 | note:G4 gain:0.21999999999999786 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (15/4 → 241/64) ⇝ 4/1 | note:Ab4 gain:0.21999999999999786 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ (15/4 → 241/64) ⇝ 4/1 | note:C5 gain:0.21999999999999786 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 99/28 ⇜ (241/64 → 121/32) ⇝ 53/14 | note:75 gain:0.05814213562373102 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 99/28 ⇜ (241/64 → 121/32) ⇝ 53/14 | note:79 gain:0.05814213562373102 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 99/28 ⇜ (241/64 → 121/32) ⇝ 53/14 | note:80 gain:0.05814213562373102 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 99/28 ⇜ (241/64 → 121/32) ⇝ 53/14 | note:84 gain:0.05814213562373102 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 15/4 ⇜ (241/64 → 121/32) ⇝ 31/8 | note:C5 gain:0.5814213562373102 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 15/4 ⇜ (241/64 → 121/32) ⇝ 31/8 | note:Eb5 gain:0.5814213562373102 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 15/4 ⇜ (241/64 → 121/32) ⇝ 4/1 | note:Eb4 gain:0.2907106781186551 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 15/4 ⇜ (241/64 → 121/32) ⇝ 4/1 | note:G4 gain:0.2907106781186551 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 15/4 ⇜ (241/64 → 121/32) ⇝ 4/1 | note:Ab4 gain:0.2907106781186551 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 15/4 ⇜ (241/64 → 121/32) ⇝ 4/1 | note:C5 gain:0.2907106781186551 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 99/28 ⇜ (121/32 → 53/14) | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 99/28 ⇜ (121/32 → 53/14) | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 99/28 ⇜ (121/32 → 53/14) | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 99/28 ⇜ (121/32 → 53/14) | note:84 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 15/4 ⇜ (121/32 → 243/64) ⇝ 31/8 | note:C5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 15/4 ⇜ (121/32 → 243/64) ⇝ 31/8 | note:Eb5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 15/4 ⇜ (121/32 → 243/64) ⇝ 4/1 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 15/4 ⇜ (121/32 → 243/64) ⇝ 4/1 | note:G4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 15/4 ⇜ (121/32 → 243/64) ⇝ 4/1 | note:Ab4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 15/4 ⇜ (121/32 → 243/64) ⇝ 4/1 | note:C5 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 15/4 ⇜ (243/64 → 61/16) ⇝ 31/8 | note:C5 gain:0.5814213562373096 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 15/4 ⇜ (243/64 → 61/16) ⇝ 31/8 | note:Eb5 gain:0.5814213562373096 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 15/4 ⇜ (243/64 → 61/16) ⇝ 4/1 | note:Eb4 gain:0.2907106781186548 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 15/4 ⇜ (243/64 → 61/16) ⇝ 4/1 | note:G4 gain:0.2907106781186548 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 15/4 ⇜ (243/64 → 61/16) ⇝ 4/1 | note:Ab4 gain:0.2907106781186548 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 15/4 ⇜ (243/64 → 61/16) ⇝ 4/1 | note:C5 gain:0.2907106781186548 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 15/4 ⇜ (61/16 → 245/64) ⇝ 31/8 | note:C5 gain:0.4400000000000008 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 15/4 ⇜ (61/16 → 245/64) ⇝ 31/8 | note:Eb5 gain:0.4400000000000008 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 15/4 ⇜ (61/16 → 245/64) ⇝ 4/1 | note:Eb4 gain:0.2200000000000004 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 15/4 ⇜ (61/16 → 245/64) ⇝ 4/1 | note:G4 gain:0.2200000000000004 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 15/4 ⇜ (61/16 → 245/64) ⇝ 4/1 | note:Ab4 gain:0.2200000000000004 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 15/4 ⇜ (61/16 → 245/64) ⇝ 4/1 | note:C5 gain:0.2200000000000004 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 15/4 ⇜ (245/64 → 123/32) ⇝ 31/8 | note:C5 gain:0.29857864376269144 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 15/4 ⇜ (245/64 → 123/32) ⇝ 31/8 | note:Eb5 gain:0.29857864376269144 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 15/4 ⇜ (245/64 → 123/32) ⇝ 4/1 | note:Eb4 gain:0.14928932188134572 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 15/4 ⇜ (245/64 → 123/32) ⇝ 4/1 | note:G4 gain:0.14928932188134572 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 15/4 ⇜ (245/64 → 123/32) ⇝ 4/1 | note:Ab4 gain:0.14928932188134572 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 15/4 ⇜ (245/64 → 123/32) ⇝ 4/1 | note:C5 gain:0.14928932188134572 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 15/4 ⇜ (123/32 → 247/64) ⇝ 31/8 | note:C5 gain:0.24 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 15/4 ⇜ (123/32 → 247/64) ⇝ 31/8 | note:Eb5 gain:0.24 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 15/4 ⇜ (123/32 → 247/64) ⇝ 4/1 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 15/4 ⇜ (123/32 → 247/64) ⇝ 4/1 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 15/4 ⇜ (123/32 → 247/64) ⇝ 4/1 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 15/4 ⇜ (123/32 → 247/64) ⇝ 4/1 | note:C5 gain:0.12 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 15/4 ⇜ (247/64 → 31/8) | note:C5 gain:0.2985786437626888 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 15/4 ⇜ (247/64 → 31/8) | note:Eb5 gain:0.2985786437626888 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 15/4 ⇜ (247/64 → 31/8) ⇝ 4/1 | note:Eb4 gain:0.1492893218813444 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 15/4 ⇜ (247/64 → 31/8) ⇝ 4/1 | note:G4 gain:0.1492893218813444 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 15/4 ⇜ (247/64 → 31/8) ⇝ 4/1 | note:Ab4 gain:0.1492893218813444 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 15/4 ⇜ (247/64 → 31/8) ⇝ 4/1 | note:C5 gain:0.1492893218813444 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 15/4 ⇜ (31/8 → 249/64) ⇝ 4/1 | note:Eb4 gain:0.21999999999999853 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 15/4 ⇜ (31/8 → 249/64) ⇝ 4/1 | note:G4 gain:0.21999999999999853 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 15/4 ⇜ (31/8 → 249/64) ⇝ 4/1 | note:Ab4 gain:0.21999999999999853 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 15/4 ⇜ (31/8 → 249/64) ⇝ 4/1 | note:C5 gain:0.21999999999999853 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 15/4 ⇜ (249/64 → 125/32) ⇝ 4/1 | note:Eb4 gain:0.29071067811865353 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 15/4 ⇜ (249/64 → 125/32) ⇝ 4/1 | note:G4 gain:0.29071067811865353 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 15/4 ⇜ (249/64 → 125/32) ⇝ 4/1 | note:Ab4 gain:0.29071067811865353 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 15/4 ⇜ (249/64 → 125/32) ⇝ 4/1 | note:C5 gain:0.29071067811865353 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 15/4 ⇜ (125/32 → 251/64) ⇝ 4/1 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 15/4 ⇜ (125/32 → 251/64) ⇝ 4/1 | note:G4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 15/4 ⇜ (125/32 → 251/64) ⇝ 4/1 | note:Ab4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 15/4 ⇜ (125/32 → 251/64) ⇝ 4/1 | note:C5 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 15/4 ⇜ (251/64 → 63/16) ⇝ 4/1 | note:Eb4 gain:0.29071067811865436 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 15/4 ⇜ (251/64 → 63/16) ⇝ 4/1 | note:G4 gain:0.29071067811865436 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 15/4 ⇜ (251/64 → 63/16) ⇝ 4/1 | note:Ab4 gain:0.29071067811865436 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 15/4 ⇜ (251/64 → 63/16) ⇝ 4/1 | note:C5 gain:0.29071067811865436 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 15/4 ⇜ (63/16 → 253/64) ⇝ 4/1 | note:Eb4 gain:0.21999999999999972 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 15/4 ⇜ (63/16 → 253/64) ⇝ 4/1 | note:G4 gain:0.21999999999999972 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 15/4 ⇜ (63/16 → 253/64) ⇝ 4/1 | note:Ab4 gain:0.21999999999999972 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 15/4 ⇜ (63/16 → 253/64) ⇝ 4/1 | note:C5 gain:0.21999999999999972 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 15/4 ⇜ (253/64 → 127/32) ⇝ 4/1 | note:Eb4 gain:0.14928932188134522 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 15/4 ⇜ (253/64 → 127/32) ⇝ 4/1 | note:G4 gain:0.14928932188134522 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 15/4 ⇜ (253/64 → 127/32) ⇝ 4/1 | note:Ab4 gain:0.14928932188134522 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 15/4 ⇜ (253/64 → 127/32) ⇝ 4/1 | note:C5 gain:0.14928932188134522 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 15/4 ⇜ (127/32 → 255/64) ⇝ 4/1 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 15/4 ⇜ (127/32 → 255/64) ⇝ 4/1 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 15/4 ⇜ (127/32 → 255/64) ⇝ 4/1 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 15/4 ⇜ (127/32 → 255/64) ⇝ 4/1 | note:C5 gain:0.12 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 15/4 ⇜ (255/64 → 4/1) | note:Eb4 gain:0.1492893218813449 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 15/4 ⇜ (255/64 → 4/1) | note:G4 gain:0.1492893218813449 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 15/4 ⇜ (255/64 → 4/1) | note:Ab4 gain:0.1492893218813449 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 15/4 ⇜ (255/64 → 4/1) | note:C5 gain:0.1492893218813449 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ (4/1 → 257/64) ⇝ 17/4 | note:G2 gain:0.43999999999999845 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 4/1 ⇜ (257/64 → 129/32) ⇝ 17/4 | note:G2 gain:0.5814213562373081 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 4/1 ⇜ (129/32 → 259/64) ⇝ 17/4 | note:G2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ (113/28 → 259/64) ⇝ 30/7 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ (113/28 → 259/64) ⇝ 30/7 | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ (113/28 → 259/64) ⇝ 30/7 | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ (113/28 → 259/64) ⇝ 30/7 | note:84 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 4/1 ⇜ (259/64 → 65/16) ⇝ 17/4 | note:G2 gain:0.5814213562373117 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 113/28 ⇜ (259/64 → 65/16) ⇝ 30/7 | note:75 gain:0.058142135623731175 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 113/28 ⇜ (259/64 → 65/16) ⇝ 30/7 | note:79 gain:0.058142135623731175 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 113/28 ⇜ (259/64 → 65/16) ⇝ 30/7 | note:80 gain:0.058142135623731175 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 113/28 ⇜ (259/64 → 65/16) ⇝ 30/7 | note:84 gain:0.058142135623731175 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 4/1 ⇜ (65/16 → 261/64) ⇝ 17/4 | note:G2 gain:0.4400000000000038 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 113/28 ⇜ (65/16 → 261/64) ⇝ 30/7 | note:75 gain:0.04400000000000038 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 113/28 ⇜ (65/16 → 261/64) ⇝ 30/7 | note:79 gain:0.04400000000000038 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 113/28 ⇜ (65/16 → 261/64) ⇝ 30/7 | note:80 gain:0.04400000000000038 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 113/28 ⇜ (65/16 → 261/64) ⇝ 30/7 | note:84 gain:0.04400000000000038 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 4/1 ⇜ (261/64 → 131/32) ⇝ 17/4 | note:G2 gain:0.2985786437626935 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 113/28 ⇜ (261/64 → 131/32) ⇝ 30/7 | note:75 gain:0.02985786437626935 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 113/28 ⇜ (261/64 → 131/32) ⇝ 30/7 | note:79 gain:0.02985786437626935 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 113/28 ⇜ (261/64 → 131/32) ⇝ 30/7 | note:80 gain:0.02985786437626935 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 113/28 ⇜ (261/64 → 131/32) ⇝ 30/7 | note:84 gain:0.02985786437626935 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 4/1 ⇜ (131/32 → 263/64) ⇝ 17/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 113/28 ⇜ (131/32 → 263/64) ⇝ 30/7 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 113/28 ⇜ (131/32 → 263/64) ⇝ 30/7 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 113/28 ⇜ (131/32 → 263/64) ⇝ 30/7 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 113/28 ⇜ (131/32 → 263/64) ⇝ 30/7 | note:84 gain:0.024 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 4/1 ⇜ (263/64 → 33/8) ⇝ 17/4 | note:G2 gain:0.2985786437626907 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 113/28 ⇜ (263/64 → 33/8) ⇝ 30/7 | note:75 gain:0.029857864376269073 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 113/28 ⇜ (263/64 → 33/8) ⇝ 30/7 | note:79 gain:0.029857864376269073 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 113/28 ⇜ (263/64 → 33/8) ⇝ 30/7 | note:80 gain:0.029857864376269073 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 113/28 ⇜ (263/64 → 33/8) ⇝ 30/7 | note:84 gain:0.029857864376269073 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 4/1 ⇜ (33/8 → 265/64) ⇝ 17/4 | note:G2 gain:0.4399999999999998 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 113/28 ⇜ (33/8 → 265/64) ⇝ 30/7 | note:75 gain:0.043999999999999984 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 113/28 ⇜ (33/8 → 265/64) ⇝ 30/7 | note:79 gain:0.043999999999999984 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 113/28 ⇜ (33/8 → 265/64) ⇝ 30/7 | note:80 gain:0.043999999999999984 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 113/28 ⇜ (33/8 → 265/64) ⇝ 30/7 | note:84 gain:0.043999999999999984 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ (33/8 → 265/64) ⇝ 17/4 | note:G4 gain:0.4399999999999998 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (33/8 → 265/64) ⇝ 17/4 | note:Bb4 gain:0.4399999999999998 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 4/1 ⇜ (265/64 → 133/32) ⇝ 17/4 | note:G2 gain:0.581421356237309 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 113/28 ⇜ (265/64 → 133/32) ⇝ 30/7 | note:75 gain:0.0581421356237309 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 113/28 ⇜ (265/64 → 133/32) ⇝ 30/7 | note:79 gain:0.0581421356237309 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 113/28 ⇜ (265/64 → 133/32) ⇝ 30/7 | note:80 gain:0.0581421356237309 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 113/28 ⇜ (265/64 → 133/32) ⇝ 30/7 | note:84 gain:0.0581421356237309 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 33/8 ⇜ (265/64 → 133/32) ⇝ 17/4 | note:G4 gain:0.581421356237309 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 33/8 ⇜ (265/64 → 133/32) ⇝ 17/4 | note:Bb4 gain:0.581421356237309 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 4/1 ⇜ (133/32 → 267/64) ⇝ 17/4 | note:G2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 113/28 ⇜ (133/32 → 267/64) ⇝ 30/7 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 113/28 ⇜ (133/32 → 267/64) ⇝ 30/7 | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 113/28 ⇜ (133/32 → 267/64) ⇝ 30/7 | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 113/28 ⇜ (133/32 → 267/64) ⇝ 30/7 | note:84 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 33/8 ⇜ (133/32 → 267/64) ⇝ 17/4 | note:G4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 33/8 ⇜ (133/32 → 267/64) ⇝ 17/4 | note:Bb4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 4/1 ⇜ (267/64 → 67/16) ⇝ 17/4 | note:G2 gain:0.5814213562373108 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 113/28 ⇜ (267/64 → 67/16) ⇝ 30/7 | note:75 gain:0.058142135623731085 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 113/28 ⇜ (267/64 → 67/16) ⇝ 30/7 | note:79 gain:0.058142135623731085 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 113/28 ⇜ (267/64 → 67/16) ⇝ 30/7 | note:80 gain:0.058142135623731085 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 113/28 ⇜ (267/64 → 67/16) ⇝ 30/7 | note:84 gain:0.058142135623731085 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 33/8 ⇜ (267/64 → 67/16) ⇝ 17/4 | note:G4 gain:0.5814213562373108 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 33/8 ⇜ (267/64 → 67/16) ⇝ 17/4 | note:Bb4 gain:0.5814213562373108 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 4/1 ⇜ (67/16 → 269/64) ⇝ 17/4 | note:G2 gain:0.4400000000000024 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 113/28 ⇜ (67/16 → 269/64) ⇝ 30/7 | note:75 gain:0.04400000000000024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 113/28 ⇜ (67/16 → 269/64) ⇝ 30/7 | note:79 gain:0.04400000000000024 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 113/28 ⇜ (67/16 → 269/64) ⇝ 30/7 | note:80 gain:0.04400000000000024 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 113/28 ⇜ (67/16 → 269/64) ⇝ 30/7 | note:84 gain:0.04400000000000024 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 33/8 ⇜ (67/16 → 269/64) ⇝ 17/4 | note:G4 gain:0.4400000000000024 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 33/8 ⇜ (67/16 → 269/64) ⇝ 17/4 | note:Bb4 gain:0.4400000000000024 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 4/1 ⇜ (269/64 → 135/32) ⇝ 17/4 | note:G2 gain:0.2985786437626925 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 113/28 ⇜ (269/64 → 135/32) ⇝ 30/7 | note:75 gain:0.02985786437626925 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 113/28 ⇜ (269/64 → 135/32) ⇝ 30/7 | note:79 gain:0.02985786437626925 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 113/28 ⇜ (269/64 → 135/32) ⇝ 30/7 | note:80 gain:0.02985786437626925 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 113/28 ⇜ (269/64 → 135/32) ⇝ 30/7 | note:84 gain:0.02985786437626925 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 33/8 ⇜ (269/64 → 135/32) ⇝ 17/4 | note:G4 gain:0.2985786437626925 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 33/8 ⇜ (269/64 → 135/32) ⇝ 17/4 | note:Bb4 gain:0.2985786437626925 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 4/1 ⇜ (135/32 → 271/64) ⇝ 17/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 113/28 ⇜ (135/32 → 271/64) ⇝ 30/7 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 113/28 ⇜ (135/32 → 271/64) ⇝ 30/7 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 113/28 ⇜ (135/32 → 271/64) ⇝ 30/7 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 113/28 ⇜ (135/32 → 271/64) ⇝ 30/7 | note:84 gain:0.024 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 33/8 ⇜ (135/32 → 271/64) ⇝ 17/4 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 33/8 ⇜ (135/32 → 271/64) ⇝ 17/4 | note:Bb4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 4/1 ⇜ (271/64 → 17/4) | note:G2 gain:0.2985786437626877 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 113/28 ⇜ (271/64 → 17/4) ⇝ 30/7 | note:75 gain:0.029857864376268774 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 113/28 ⇜ (271/64 → 17/4) ⇝ 30/7 | note:79 gain:0.029857864376268774 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 113/28 ⇜ (271/64 → 17/4) ⇝ 30/7 | note:80 gain:0.029857864376268774 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 113/28 ⇜ (271/64 → 17/4) ⇝ 30/7 | note:84 gain:0.029857864376268774 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 33/8 ⇜ (271/64 → 17/4) | note:G4 gain:0.2985786437626877 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 33/8 ⇜ (271/64 → 17/4) | note:Bb4 gain:0.2985786437626877 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 113/28 ⇜ (17/4 → 273/64) ⇝ 30/7 | note:75 gain:0.044000000000000115 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 113/28 ⇜ (17/4 → 273/64) ⇝ 30/7 | note:79 gain:0.044000000000000115 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 113/28 ⇜ (17/4 → 273/64) ⇝ 30/7 | note:80 gain:0.044000000000000115 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 113/28 ⇜ (17/4 → 273/64) ⇝ 30/7 | note:84 gain:0.044000000000000115 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 113/28 ⇜ (273/64 → 137/32) ⇝ 30/7 | note:75 gain:0.058142135623730995 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 113/28 ⇜ (273/64 → 137/32) ⇝ 30/7 | note:79 gain:0.058142135623730995 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 113/28 ⇜ (273/64 → 137/32) ⇝ 30/7 | note:80 gain:0.058142135623730995 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 113/28 ⇜ (273/64 → 137/32) ⇝ 30/7 | note:84 gain:0.058142135623730995 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 113/28 ⇜ (137/32 → 30/7) | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 113/28 ⇜ (137/32 → 30/7) | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 113/28 ⇜ (137/32 → 30/7) | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 113/28 ⇜ (137/32 → 30/7) | note:84 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ (9/2 → 289/64) ⇝ 37/8 | note:D5 gain:0.4399999999999983 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (9/2 → 289/64) ⇝ 37/8 | note:F5 gain:0.4399999999999983 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ (9/2 → 289/64) ⇝ 19/4 | note:B3 gain:0.21999999999999914 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ (9/2 → 289/64) ⇝ 19/4 | note:E4 gain:0.21999999999999914 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (9/2 → 289/64) ⇝ 19/4 | note:F4 gain:0.21999999999999914 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (9/2 → 289/64) ⇝ 19/4 | note:A4 gain:0.21999999999999914 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (9/2 → 289/64) ⇝ 19/4 | note:G2 gain:0.4399999999999983 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 9/2 ⇜ (289/64 → 145/32) ⇝ 37/8 | note:D5 gain:0.5814213562373078 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 9/2 ⇜ (289/64 → 145/32) ⇝ 37/8 | note:F5 gain:0.5814213562373078 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 9/2 ⇜ (289/64 → 145/32) ⇝ 19/4 | note:B3 gain:0.2907106781186539 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 9/2 ⇜ (289/64 → 145/32) ⇝ 19/4 | note:E4 gain:0.2907106781186539 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 9/2 ⇜ (289/64 → 145/32) ⇝ 19/4 | note:F4 gain:0.2907106781186539 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 9/2 ⇜ (289/64 → 145/32) ⇝ 19/4 | note:A4 gain:0.2907106781186539 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 9/2 ⇜ (289/64 → 145/32) ⇝ 19/4 | note:G2 gain:0.5814213562373078 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 9/2 ⇜ (145/32 → 291/64) ⇝ 37/8 | note:D5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 9/2 ⇜ (145/32 → 291/64) ⇝ 37/8 | note:F5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 9/2 ⇜ (145/32 → 291/64) ⇝ 19/4 | note:B3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 9/2 ⇜ (145/32 → 291/64) ⇝ 19/4 | note:E4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 9/2 ⇜ (145/32 → 291/64) ⇝ 19/4 | note:F4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 9/2 ⇜ (145/32 → 291/64) ⇝ 19/4 | note:A4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 9/2 ⇜ (145/32 → 291/64) ⇝ 19/4 | note:G2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 9/2 ⇜ (291/64 → 73/16) ⇝ 37/8 | note:D5 gain:0.581421356237312 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 9/2 ⇜ (291/64 → 73/16) ⇝ 37/8 | note:F5 gain:0.581421356237312 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 9/2 ⇜ (291/64 → 73/16) ⇝ 19/4 | note:B3 gain:0.290710678118656 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 9/2 ⇜ (291/64 → 73/16) ⇝ 19/4 | note:E4 gain:0.290710678118656 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 9/2 ⇜ (291/64 → 73/16) ⇝ 19/4 | note:F4 gain:0.290710678118656 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 9/2 ⇜ (291/64 → 73/16) ⇝ 19/4 | note:A4 gain:0.290710678118656 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 9/2 ⇜ (291/64 → 73/16) ⇝ 19/4 | note:G2 gain:0.581421356237312 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 9/2 ⇜ (73/16 → 293/64) ⇝ 37/8 | note:D5 gain:0.44000000000000394 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 9/2 ⇜ (73/16 → 293/64) ⇝ 37/8 | note:F5 gain:0.44000000000000394 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 9/2 ⇜ (73/16 → 293/64) ⇝ 19/4 | note:B3 gain:0.22000000000000197 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 9/2 ⇜ (73/16 → 293/64) ⇝ 19/4 | note:E4 gain:0.22000000000000197 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 9/2 ⇜ (73/16 → 293/64) ⇝ 19/4 | note:F4 gain:0.22000000000000197 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 9/2 ⇜ (73/16 → 293/64) ⇝ 19/4 | note:A4 gain:0.22000000000000197 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 9/2 ⇜ (73/16 → 293/64) ⇝ 19/4 | note:G2 gain:0.44000000000000394 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 9/2 ⇜ (293/64 → 147/32) ⇝ 37/8 | note:D5 gain:0.29857864376269366 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 9/2 ⇜ (293/64 → 147/32) ⇝ 37/8 | note:F5 gain:0.29857864376269366 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 9/2 ⇜ (293/64 → 147/32) ⇝ 19/4 | note:B3 gain:0.14928932188134683 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 9/2 ⇜ (293/64 → 147/32) ⇝ 19/4 | note:E4 gain:0.14928932188134683 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 9/2 ⇜ (293/64 → 147/32) ⇝ 19/4 | note:F4 gain:0.14928932188134683 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 9/2 ⇜ (293/64 → 147/32) ⇝ 19/4 | note:A4 gain:0.14928932188134683 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 9/2 ⇜ (293/64 → 147/32) ⇝ 19/4 | note:G2 gain:0.29857864376269366 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 9/2 ⇜ (147/32 → 295/64) ⇝ 37/8 | note:D5 gain:0.24 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 9/2 ⇜ (147/32 → 295/64) ⇝ 37/8 | note:F5 gain:0.24 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 9/2 ⇜ (147/32 → 295/64) ⇝ 19/4 | note:B3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 9/2 ⇜ (147/32 → 295/64) ⇝ 19/4 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 9/2 ⇜ (147/32 → 295/64) ⇝ 19/4 | note:F4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 9/2 ⇜ (147/32 → 295/64) ⇝ 19/4 | note:A4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 9/2 ⇜ (147/32 → 295/64) ⇝ 19/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 9/2 ⇜ (295/64 → 37/8) | note:D5 gain:0.2985786437626906 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 9/2 ⇜ (295/64 → 37/8) | note:F5 gain:0.2985786437626906 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 9/2 ⇜ (295/64 → 37/8) ⇝ 19/4 | note:B3 gain:0.1492893218813453 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 9/2 ⇜ (295/64 → 37/8) ⇝ 19/4 | note:E4 gain:0.1492893218813453 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 9/2 ⇜ (295/64 → 37/8) ⇝ 19/4 | note:F4 gain:0.1492893218813453 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 9/2 ⇜ (295/64 → 37/8) ⇝ 19/4 | note:A4 gain:0.1492893218813453 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 9/2 ⇜ (295/64 → 37/8) ⇝ 19/4 | note:G2 gain:0.2985786437626906 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 9/2 ⇜ (37/8 → 297/64) ⇝ 19/4 | note:B3 gain:0.2199999999999998 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 9/2 ⇜ (37/8 → 297/64) ⇝ 19/4 | note:E4 gain:0.2199999999999998 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 9/2 ⇜ (37/8 → 297/64) ⇝ 19/4 | note:F4 gain:0.2199999999999998 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 9/2 ⇜ (37/8 → 297/64) ⇝ 19/4 | note:A4 gain:0.2199999999999998 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 9/2 ⇜ (37/8 → 297/64) ⇝ 19/4 | note:G2 gain:0.4399999999999996 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 9/2 ⇜ (297/64 → 149/32) ⇝ 19/4 | note:B3 gain:0.2907106781186545 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 9/2 ⇜ (297/64 → 149/32) ⇝ 19/4 | note:E4 gain:0.2907106781186545 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 9/2 ⇜ (297/64 → 149/32) ⇝ 19/4 | note:F4 gain:0.2907106781186545 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 9/2 ⇜ (297/64 → 149/32) ⇝ 19/4 | note:A4 gain:0.2907106781186545 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 9/2 ⇜ (297/64 → 149/32) ⇝ 19/4 | note:G2 gain:0.581421356237309 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 9/2 ⇜ (149/32 → 299/64) ⇝ 19/4 | note:B3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 9/2 ⇜ (149/32 → 299/64) ⇝ 19/4 | note:E4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 9/2 ⇜ (149/32 → 299/64) ⇝ 19/4 | note:F4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 9/2 ⇜ (149/32 → 299/64) ⇝ 19/4 | note:A4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 9/2 ⇜ (149/32 → 299/64) ⇝ 19/4 | note:G2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 9/2 ⇜ (299/64 → 75/16) ⇝ 19/4 | note:B3 gain:0.2907106781186554 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 9/2 ⇜ (299/64 → 75/16) ⇝ 19/4 | note:E4 gain:0.2907106781186554 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 9/2 ⇜ (299/64 → 75/16) ⇝ 19/4 | note:F4 gain:0.2907106781186554 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 9/2 ⇜ (299/64 → 75/16) ⇝ 19/4 | note:A4 gain:0.2907106781186554 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 9/2 ⇜ (299/64 → 75/16) ⇝ 19/4 | note:G2 gain:0.5814213562373108 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 9/2 ⇜ (75/16 → 301/64) ⇝ 19/4 | note:B3 gain:0.22000000000000128 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 9/2 ⇜ (75/16 → 301/64) ⇝ 19/4 | note:E4 gain:0.22000000000000128 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 9/2 ⇜ (75/16 → 301/64) ⇝ 19/4 | note:F4 gain:0.22000000000000128 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 9/2 ⇜ (75/16 → 301/64) ⇝ 19/4 | note:A4 gain:0.22000000000000128 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 9/2 ⇜ (75/16 → 301/64) ⇝ 19/4 | note:G2 gain:0.44000000000000256 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 9/2 ⇜ (301/64 → 151/32) ⇝ 19/4 | note:B3 gain:0.14928932188134633 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 9/2 ⇜ (301/64 → 151/32) ⇝ 19/4 | note:E4 gain:0.14928932188134633 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 9/2 ⇜ (301/64 → 151/32) ⇝ 19/4 | note:F4 gain:0.14928932188134633 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 9/2 ⇜ (301/64 → 151/32) ⇝ 19/4 | note:A4 gain:0.14928932188134633 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 9/2 ⇜ (301/64 → 151/32) ⇝ 19/4 | note:G2 gain:0.29857864376269266 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 9/2 ⇜ (151/32 → 303/64) ⇝ 19/4 | note:B3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 9/2 ⇜ (151/32 → 303/64) ⇝ 19/4 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 9/2 ⇜ (151/32 → 303/64) ⇝ 19/4 | note:F4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 9/2 ⇜ (151/32 → 303/64) ⇝ 19/4 | note:A4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 9/2 ⇜ (151/32 → 303/64) ⇝ 19/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 9/2 ⇜ (303/64 → 19/4) | note:B3 gain:0.14928932188134378 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 9/2 ⇜ (303/64 → 19/4) | note:E4 gain:0.14928932188134378 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 9/2 ⇜ (303/64 → 19/4) | note:F4 gain:0.14928932188134378 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 9/2 ⇜ (303/64 → 19/4) | note:A4 gain:0.14928932188134378 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 9/2 ⇜ (303/64 → 19/4) | note:G2 gain:0.29857864376268756 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ (19/4 → 305/64) ⇝ 39/8 | note:G4 gain:0.4399999999999953 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (19/4 → 305/64) ⇝ 39/8 | note:Bb4 gain:0.4399999999999953 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 19/4 ⇜ (305/64 → 153/32) ⇝ 39/8 | note:G4 gain:0.5814213562373098 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 19/4 ⇜ (305/64 → 153/32) ⇝ 39/8 | note:Bb4 gain:0.5814213562373098 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 19/4 ⇜ (153/32 → 307/64) ⇝ 39/8 | note:G4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 19/4 ⇜ (153/32 → 307/64) ⇝ 39/8 | note:Bb4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ (67/14 → 307/64) ⇝ 141/28 | note:71 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ (67/14 → 307/64) ⇝ 141/28 | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ (67/14 → 307/64) ⇝ 141/28 | note:77 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ (67/14 → 307/64) ⇝ 141/28 | note:81 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 19/4 ⇜ (307/64 → 77/16) ⇝ 39/8 | note:G4 gain:0.58142135623731 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 19/4 ⇜ (307/64 → 77/16) ⇝ 39/8 | note:Bb4 gain:0.58142135623731 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 67/14 ⇜ (307/64 → 77/16) ⇝ 141/28 | note:71 gain:0.058142135623730995 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 67/14 ⇜ (307/64 → 77/16) ⇝ 141/28 | note:76 gain:0.058142135623730995 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 67/14 ⇜ (307/64 → 77/16) ⇝ 141/28 | note:77 gain:0.058142135623730995 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 67/14 ⇜ (307/64 → 77/16) ⇝ 141/28 | note:81 gain:0.058142135623730995 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 19/4 ⇜ (77/16 → 309/64) ⇝ 39/8 | note:G4 gain:0.4400000000000011 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 19/4 ⇜ (77/16 → 309/64) ⇝ 39/8 | note:Bb4 gain:0.4400000000000011 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 67/14 ⇜ (77/16 → 309/64) ⇝ 141/28 | note:71 gain:0.044000000000000115 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 67/14 ⇜ (77/16 → 309/64) ⇝ 141/28 | note:76 gain:0.044000000000000115 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 67/14 ⇜ (77/16 → 309/64) ⇝ 141/28 | note:77 gain:0.044000000000000115 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 67/14 ⇜ (77/16 → 309/64) ⇝ 141/28 | note:81 gain:0.044000000000000115 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 19/4 ⇜ (309/64 → 155/32) ⇝ 39/8 | note:G4 gain:0.2985786437626917 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 19/4 ⇜ (309/64 → 155/32) ⇝ 39/8 | note:Bb4 gain:0.2985786437626917 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 67/14 ⇜ (309/64 → 155/32) ⇝ 141/28 | note:71 gain:0.029857864376269173 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 67/14 ⇜ (309/64 → 155/32) ⇝ 141/28 | note:76 gain:0.029857864376269173 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 67/14 ⇜ (309/64 → 155/32) ⇝ 141/28 | note:77 gain:0.029857864376269173 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 67/14 ⇜ (309/64 → 155/32) ⇝ 141/28 | note:81 gain:0.029857864376269173 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 19/4 ⇜ (155/32 → 311/64) ⇝ 39/8 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 19/4 ⇜ (155/32 → 311/64) ⇝ 39/8 | note:Bb4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 67/14 ⇜ (155/32 → 311/64) ⇝ 141/28 | note:71 gain:0.024 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 67/14 ⇜ (155/32 → 311/64) ⇝ 141/28 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 67/14 ⇜ (155/32 → 311/64) ⇝ 141/28 | note:77 gain:0.024 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", + "[ (0/1 → 1/64) ⇝ 1/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 0/1 ⇜ (1/64 → 1/32) ⇝ 1/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 0/1 ⇜ (1/32 → 3/64) ⇝ 1/4 | note:C2 gain:0.64 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ (1/28 → 3/64) ⇝ 2/7 | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ (1/28 → 3/64) ⇝ 2/7 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ (1/28 → 3/64) ⇝ 2/7 | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ (1/28 → 3/64) ⇝ 2/7 | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 0/1 ⇜ (3/64 → 1/16) ⇝ 1/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/28 ⇜ (3/64 → 1/16) ⇝ 2/7 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 1/28 ⇜ (3/64 → 1/16) ⇝ 2/7 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 1/28 ⇜ (3/64 → 1/16) ⇝ 2/7 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 1/28 ⇜ (3/64 → 1/16) ⇝ 2/7 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 0/1 ⇜ (1/16 → 5/64) ⇝ 1/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/28 ⇜ (1/16 → 5/64) ⇝ 2/7 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 1/28 ⇜ (1/16 → 5/64) ⇝ 2/7 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 1/28 ⇜ (1/16 → 5/64) ⇝ 2/7 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 1/28 ⇜ (1/16 → 5/64) ⇝ 2/7 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 0/1 ⇜ (5/64 → 3/32) ⇝ 1/4 | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/28 ⇜ (5/64 → 3/32) ⇝ 2/7 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 1/28 ⇜ (5/64 → 3/32) ⇝ 2/7 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 1/28 ⇜ (5/64 → 3/32) ⇝ 2/7 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 1/28 ⇜ (5/64 → 3/32) ⇝ 2/7 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 0/1 ⇜ (3/32 → 7/64) ⇝ 1/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/28 ⇜ (3/32 → 7/64) ⇝ 2/7 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 1/28 ⇜ (3/32 → 7/64) ⇝ 2/7 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 1/28 ⇜ (3/32 → 7/64) ⇝ 2/7 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 1/28 ⇜ (3/32 → 7/64) ⇝ 2/7 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 0/1 ⇜ (7/64 → 1/8) ⇝ 1/4 | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/28 ⇜ (7/64 → 1/8) ⇝ 2/7 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 1/28 ⇜ (7/64 → 1/8) ⇝ 2/7 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 1/28 ⇜ (7/64 → 1/8) ⇝ 2/7 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 1/28 ⇜ (7/64 → 1/8) ⇝ 2/7 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 0/1 ⇜ (1/8 → 9/64) ⇝ 1/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/28 ⇜ (1/8 → 9/64) ⇝ 2/7 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 1/28 ⇜ (1/8 → 9/64) ⇝ 2/7 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 1/28 ⇜ (1/8 → 9/64) ⇝ 2/7 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 1/28 ⇜ (1/8 → 9/64) ⇝ 2/7 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ (1/8 → 9/64) ⇝ 1/4 | note:C4 gain:0.44 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ (1/8 → 9/64) ⇝ 1/4 | note:Eb4 gain:0.44 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 0/1 ⇜ (9/64 → 5/32) ⇝ 1/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/28 ⇜ (9/64 → 5/32) ⇝ 2/7 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 1/28 ⇜ (9/64 → 5/32) ⇝ 2/7 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 1/28 ⇜ (9/64 → 5/32) ⇝ 2/7 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 1/28 ⇜ (9/64 → 5/32) ⇝ 2/7 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 1/8 ⇜ (9/64 → 5/32) ⇝ 1/4 | note:C4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 1/8 ⇜ (9/64 → 5/32) ⇝ 1/4 | note:Eb4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 0/1 ⇜ (5/32 → 11/64) ⇝ 1/4 | note:C2 gain:0.64 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/28 ⇜ (5/32 → 11/64) ⇝ 2/7 | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 1/28 ⇜ (5/32 → 11/64) ⇝ 2/7 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 1/28 ⇜ (5/32 → 11/64) ⇝ 2/7 | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 1/28 ⇜ (5/32 → 11/64) ⇝ 2/7 | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 1/8 ⇜ (5/32 → 11/64) ⇝ 1/4 | note:C4 gain:0.64 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 1/8 ⇜ (5/32 → 11/64) ⇝ 1/4 | note:Eb4 gain:0.64 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 0/1 ⇜ (11/64 → 3/16) ⇝ 1/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/28 ⇜ (11/64 → 3/16) ⇝ 2/7 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 1/28 ⇜ (11/64 → 3/16) ⇝ 2/7 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 1/28 ⇜ (11/64 → 3/16) ⇝ 2/7 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 1/28 ⇜ (11/64 → 3/16) ⇝ 2/7 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 1/8 ⇜ (11/64 → 3/16) ⇝ 1/4 | note:C4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 1/8 ⇜ (11/64 → 3/16) ⇝ 1/4 | note:Eb4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 0/1 ⇜ (3/16 → 13/64) ⇝ 1/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/28 ⇜ (3/16 → 13/64) ⇝ 2/7 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 1/28 ⇜ (3/16 → 13/64) ⇝ 2/7 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 1/28 ⇜ (3/16 → 13/64) ⇝ 2/7 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 1/28 ⇜ (3/16 → 13/64) ⇝ 2/7 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 1/8 ⇜ (3/16 → 13/64) ⇝ 1/4 | note:C4 gain:0.44 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 1/8 ⇜ (3/16 → 13/64) ⇝ 1/4 | note:Eb4 gain:0.44 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 0/1 ⇜ (13/64 → 7/32) ⇝ 1/4 | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/28 ⇜ (13/64 → 7/32) ⇝ 2/7 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 1/28 ⇜ (13/64 → 7/32) ⇝ 2/7 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 1/28 ⇜ (13/64 → 7/32) ⇝ 2/7 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 1/28 ⇜ (13/64 → 7/32) ⇝ 2/7 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 1/8 ⇜ (13/64 → 7/32) ⇝ 1/4 | note:C4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 1/8 ⇜ (13/64 → 7/32) ⇝ 1/4 | note:Eb4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 0/1 ⇜ (7/32 → 15/64) ⇝ 1/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/28 ⇜ (7/32 → 15/64) ⇝ 2/7 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 1/28 ⇜ (7/32 → 15/64) ⇝ 2/7 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 1/28 ⇜ (7/32 → 15/64) ⇝ 2/7 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 1/28 ⇜ (7/32 → 15/64) ⇝ 2/7 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 1/8 ⇜ (7/32 → 15/64) ⇝ 1/4 | note:C4 gain:0.24 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 1/8 ⇜ (7/32 → 15/64) ⇝ 1/4 | note:Eb4 gain:0.24 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 0/1 ⇜ (15/64 → 1/4) | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/28 ⇜ (15/64 → 1/4) ⇝ 2/7 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 1/28 ⇜ (15/64 → 1/4) ⇝ 2/7 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 1/28 ⇜ (15/64 → 1/4) ⇝ 2/7 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 1/28 ⇜ (15/64 → 1/4) ⇝ 2/7 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 1/8 ⇜ (15/64 → 1/4) | note:C4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 1/8 ⇜ (15/64 → 1/4) | note:Eb4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 1/28 ⇜ (1/4 → 17/64) ⇝ 2/7 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 1/28 ⇜ (1/4 → 17/64) ⇝ 2/7 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 1/28 ⇜ (1/4 → 17/64) ⇝ 2/7 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 1/28 ⇜ (1/4 → 17/64) ⇝ 2/7 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 1/28 ⇜ (17/64 → 9/32) ⇝ 2/7 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 1/28 ⇜ (17/64 → 9/32) ⇝ 2/7 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 1/28 ⇜ (17/64 → 9/32) ⇝ 2/7 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 1/28 ⇜ (17/64 → 9/32) ⇝ 2/7 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 1/28 ⇜ (9/32 → 2/7) | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 1/28 ⇜ (9/32 → 2/7) | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 1/28 ⇜ (9/32 → 2/7) | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 1/28 ⇜ (9/32 → 2/7) | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ (1/2 → 33/64) ⇝ 5/8 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (1/2 → 33/64) ⇝ 5/8 | note:Bb4 gain:0.44 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ (1/2 → 33/64) ⇝ 3/4 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ (1/2 → 33/64) ⇝ 3/4 | note:D4 gain:0.22 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ (1/2 → 33/64) ⇝ 3/4 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ (1/2 → 33/64) ⇝ 3/4 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (1/2 → 33/64) ⇝ 3/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/2 ⇜ (33/64 → 17/32) ⇝ 5/8 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 1/2 ⇜ (33/64 → 17/32) ⇝ 5/8 | note:Bb4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 1/2 ⇜ (33/64 → 17/32) ⇝ 3/4 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 1/2 ⇜ (33/64 → 17/32) ⇝ 3/4 | note:D4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 1/2 ⇜ (33/64 → 17/32) ⇝ 3/4 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 1/2 ⇜ (33/64 → 17/32) ⇝ 3/4 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 1/2 ⇜ (33/64 → 17/32) ⇝ 3/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/2 ⇜ (17/32 → 35/64) ⇝ 5/8 | note:G4 gain:0.64 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 1/2 ⇜ (17/32 → 35/64) ⇝ 5/8 | note:Bb4 gain:0.64 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 1/2 ⇜ (17/32 → 35/64) ⇝ 3/4 | note:Bb3 gain:0.32 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 1/2 ⇜ (17/32 → 35/64) ⇝ 3/4 | note:D4 gain:0.32 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 1/2 ⇜ (17/32 → 35/64) ⇝ 3/4 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 1/2 ⇜ (17/32 → 35/64) ⇝ 3/4 | note:G4 gain:0.32 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 1/2 ⇜ (17/32 → 35/64) ⇝ 3/4 | note:C2 gain:0.64 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/2 ⇜ (35/64 → 9/16) ⇝ 5/8 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 1/2 ⇜ (35/64 → 9/16) ⇝ 5/8 | note:Bb4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 1/2 ⇜ (35/64 → 9/16) ⇝ 3/4 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 1/2 ⇜ (35/64 → 9/16) ⇝ 3/4 | note:D4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 1/2 ⇜ (35/64 → 9/16) ⇝ 3/4 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 1/2 ⇜ (35/64 → 9/16) ⇝ 3/4 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 1/2 ⇜ (35/64 → 9/16) ⇝ 3/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/2 ⇜ (9/16 → 37/64) ⇝ 5/8 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 1/2 ⇜ (9/16 → 37/64) ⇝ 5/8 | note:Bb4 gain:0.44 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 1/2 ⇜ (9/16 → 37/64) ⇝ 3/4 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 1/2 ⇜ (9/16 → 37/64) ⇝ 3/4 | note:D4 gain:0.22 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 1/2 ⇜ (9/16 → 37/64) ⇝ 3/4 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 1/2 ⇜ (9/16 → 37/64) ⇝ 3/4 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 1/2 ⇜ (9/16 → 37/64) ⇝ 3/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/2 ⇜ (37/64 → 19/32) ⇝ 5/8 | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 1/2 ⇜ (37/64 → 19/32) ⇝ 5/8 | note:Bb4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 1/2 ⇜ (37/64 → 19/32) ⇝ 3/4 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 1/2 ⇜ (37/64 → 19/32) ⇝ 3/4 | note:D4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 1/2 ⇜ (37/64 → 19/32) ⇝ 3/4 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 1/2 ⇜ (37/64 → 19/32) ⇝ 3/4 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 1/2 ⇜ (37/64 → 19/32) ⇝ 3/4 | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/2 ⇜ (19/32 → 39/64) ⇝ 5/8 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 1/2 ⇜ (19/32 → 39/64) ⇝ 5/8 | note:Bb4 gain:0.24 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 1/2 ⇜ (19/32 → 39/64) ⇝ 3/4 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 1/2 ⇜ (19/32 → 39/64) ⇝ 3/4 | note:D4 gain:0.12 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 1/2 ⇜ (19/32 → 39/64) ⇝ 3/4 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 1/2 ⇜ (19/32 → 39/64) ⇝ 3/4 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 1/2 ⇜ (19/32 → 39/64) ⇝ 3/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/2 ⇜ (39/64 → 5/8) | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 1/2 ⇜ (39/64 → 5/8) | note:Bb4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 1/2 ⇜ (39/64 → 5/8) ⇝ 3/4 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 1/2 ⇜ (39/64 → 5/8) ⇝ 3/4 | note:D4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 1/2 ⇜ (39/64 → 5/8) ⇝ 3/4 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 1/2 ⇜ (39/64 → 5/8) ⇝ 3/4 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 1/2 ⇜ (39/64 → 5/8) ⇝ 3/4 | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/2 ⇜ (5/8 → 41/64) ⇝ 3/4 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 1/2 ⇜ (5/8 → 41/64) ⇝ 3/4 | note:D4 gain:0.22 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 1/2 ⇜ (5/8 → 41/64) ⇝ 3/4 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 1/2 ⇜ (5/8 → 41/64) ⇝ 3/4 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 1/2 ⇜ (5/8 → 41/64) ⇝ 3/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/2 ⇜ (41/64 → 21/32) ⇝ 3/4 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 1/2 ⇜ (41/64 → 21/32) ⇝ 3/4 | note:D4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 1/2 ⇜ (41/64 → 21/32) ⇝ 3/4 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 1/2 ⇜ (41/64 → 21/32) ⇝ 3/4 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 1/2 ⇜ (41/64 → 21/32) ⇝ 3/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/2 ⇜ (21/32 → 43/64) ⇝ 3/4 | note:Bb3 gain:0.32 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 1/2 ⇜ (21/32 → 43/64) ⇝ 3/4 | note:D4 gain:0.32 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 1/2 ⇜ (21/32 → 43/64) ⇝ 3/4 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 1/2 ⇜ (21/32 → 43/64) ⇝ 3/4 | note:G4 gain:0.32 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 1/2 ⇜ (21/32 → 43/64) ⇝ 3/4 | note:C2 gain:0.64 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/2 ⇜ (43/64 → 11/16) ⇝ 3/4 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 1/2 ⇜ (43/64 → 11/16) ⇝ 3/4 | note:D4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 1/2 ⇜ (43/64 → 11/16) ⇝ 3/4 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 1/2 ⇜ (43/64 → 11/16) ⇝ 3/4 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 1/2 ⇜ (43/64 → 11/16) ⇝ 3/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/2 ⇜ (11/16 → 45/64) ⇝ 3/4 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 1/2 ⇜ (11/16 → 45/64) ⇝ 3/4 | note:D4 gain:0.22 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 1/2 ⇜ (11/16 → 45/64) ⇝ 3/4 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 1/2 ⇜ (11/16 → 45/64) ⇝ 3/4 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 1/2 ⇜ (11/16 → 45/64) ⇝ 3/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/2 ⇜ (45/64 → 23/32) ⇝ 3/4 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 1/2 ⇜ (45/64 → 23/32) ⇝ 3/4 | note:D4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 1/2 ⇜ (45/64 → 23/32) ⇝ 3/4 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 1/2 ⇜ (45/64 → 23/32) ⇝ 3/4 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 1/2 ⇜ (45/64 → 23/32) ⇝ 3/4 | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/2 ⇜ (23/32 → 47/64) ⇝ 3/4 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 1/2 ⇜ (23/32 → 47/64) ⇝ 3/4 | note:D4 gain:0.12 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 1/2 ⇜ (23/32 → 47/64) ⇝ 3/4 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 1/2 ⇜ (23/32 → 47/64) ⇝ 3/4 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 1/2 ⇜ (23/32 → 47/64) ⇝ 3/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/2 ⇜ (47/64 → 3/4) | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 1/2 ⇜ (47/64 → 3/4) | note:D4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 1/2 ⇜ (47/64 → 3/4) | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 1/2 ⇜ (47/64 → 3/4) | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 1/2 ⇜ (47/64 → 3/4) | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ (3/4 → 49/64) ⇝ 7/8 | note:C4 gain:0.44 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ (3/4 → 49/64) ⇝ 7/8 | note:Eb4 gain:0.44 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 3/4 ⇜ (49/64 → 25/32) ⇝ 7/8 | note:C4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 3/4 ⇜ (49/64 → 25/32) ⇝ 7/8 | note:Eb4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 3/4 ⇜ (25/32 → 51/64) ⇝ 7/8 | note:C4 gain:0.64 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 3/4 ⇜ (25/32 → 51/64) ⇝ 7/8 | note:Eb4 gain:0.64 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ (11/14 → 51/64) ⇝ 29/28 | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ (11/14 → 51/64) ⇝ 29/28 | note:74 gain:0.064 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ (11/14 → 51/64) ⇝ 29/28 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ (11/14 → 51/64) ⇝ 29/28 | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 3/4 ⇜ (51/64 → 13/16) ⇝ 7/8 | note:C4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 3/4 ⇜ (51/64 → 13/16) ⇝ 7/8 | note:Eb4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 11/14 ⇜ (51/64 → 13/16) ⇝ 29/28 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 11/14 ⇜ (51/64 → 13/16) ⇝ 29/28 | note:74 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 11/14 ⇜ (51/64 → 13/16) ⇝ 29/28 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 11/14 ⇜ (51/64 → 13/16) ⇝ 29/28 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 3/4 ⇜ (13/16 → 53/64) ⇝ 7/8 | note:C4 gain:0.44 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 3/4 ⇜ (13/16 → 53/64) ⇝ 7/8 | note:Eb4 gain:0.44 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 11/14 ⇜ (13/16 → 53/64) ⇝ 29/28 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 11/14 ⇜ (13/16 → 53/64) ⇝ 29/28 | note:74 gain:0.044 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 11/14 ⇜ (13/16 → 53/64) ⇝ 29/28 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 11/14 ⇜ (13/16 → 53/64) ⇝ 29/28 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 3/4 ⇜ (53/64 → 27/32) ⇝ 7/8 | note:C4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 3/4 ⇜ (53/64 → 27/32) ⇝ 7/8 | note:Eb4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 11/14 ⇜ (53/64 → 27/32) ⇝ 29/28 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 11/14 ⇜ (53/64 → 27/32) ⇝ 29/28 | note:74 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 11/14 ⇜ (53/64 → 27/32) ⇝ 29/28 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 11/14 ⇜ (53/64 → 27/32) ⇝ 29/28 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 3/4 ⇜ (27/32 → 55/64) ⇝ 7/8 | note:C4 gain:0.24 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 3/4 ⇜ (27/32 → 55/64) ⇝ 7/8 | note:Eb4 gain:0.24 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 11/14 ⇜ (27/32 → 55/64) ⇝ 29/28 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 11/14 ⇜ (27/32 → 55/64) ⇝ 29/28 | note:74 gain:0.024 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 11/14 ⇜ (27/32 → 55/64) ⇝ 29/28 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 11/14 ⇜ (27/32 → 55/64) ⇝ 29/28 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 3/4 ⇜ (55/64 → 7/8) | note:C4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 3/4 ⇜ (55/64 → 7/8) | note:Eb4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 11/14 ⇜ (55/64 → 7/8) ⇝ 29/28 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 11/14 ⇜ (55/64 → 7/8) ⇝ 29/28 | note:74 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 11/14 ⇜ (55/64 → 7/8) ⇝ 29/28 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 11/14 ⇜ (55/64 → 7/8) ⇝ 29/28 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 11/14 ⇜ (7/8 → 57/64) ⇝ 29/28 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 11/14 ⇜ (7/8 → 57/64) ⇝ 29/28 | note:74 gain:0.044 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 11/14 ⇜ (7/8 → 57/64) ⇝ 29/28 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 11/14 ⇜ (7/8 → 57/64) ⇝ 29/28 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 11/14 ⇜ (57/64 → 29/32) ⇝ 29/28 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 11/14 ⇜ (57/64 → 29/32) ⇝ 29/28 | note:74 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 11/14 ⇜ (57/64 → 29/32) ⇝ 29/28 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 11/14 ⇜ (57/64 → 29/32) ⇝ 29/28 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 11/14 ⇜ (29/32 → 59/64) ⇝ 29/28 | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 11/14 ⇜ (29/32 → 59/64) ⇝ 29/28 | note:74 gain:0.064 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 11/14 ⇜ (29/32 → 59/64) ⇝ 29/28 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 11/14 ⇜ (29/32 → 59/64) ⇝ 29/28 | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 11/14 ⇜ (59/64 → 15/16) ⇝ 29/28 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 11/14 ⇜ (59/64 → 15/16) ⇝ 29/28 | note:74 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 11/14 ⇜ (59/64 → 15/16) ⇝ 29/28 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 11/14 ⇜ (59/64 → 15/16) ⇝ 29/28 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 11/14 ⇜ (15/16 → 61/64) ⇝ 29/28 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 11/14 ⇜ (15/16 → 61/64) ⇝ 29/28 | note:74 gain:0.044 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 11/14 ⇜ (15/16 → 61/64) ⇝ 29/28 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 11/14 ⇜ (15/16 → 61/64) ⇝ 29/28 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 11/14 ⇜ (61/64 → 31/32) ⇝ 29/28 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 11/14 ⇜ (61/64 → 31/32) ⇝ 29/28 | note:74 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 11/14 ⇜ (61/64 → 31/32) ⇝ 29/28 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 11/14 ⇜ (61/64 → 31/32) ⇝ 29/28 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 11/14 ⇜ (31/32 → 63/64) ⇝ 29/28 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 11/14 ⇜ (31/32 → 63/64) ⇝ 29/28 | note:74 gain:0.024 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 11/14 ⇜ (31/32 → 63/64) ⇝ 29/28 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 11/14 ⇜ (31/32 → 63/64) ⇝ 29/28 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 11/14 ⇜ (63/64 → 1/1) ⇝ 29/28 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 11/14 ⇜ (63/64 → 1/1) ⇝ 29/28 | note:74 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 11/14 ⇜ (63/64 → 1/1) ⇝ 29/28 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 11/14 ⇜ (63/64 → 1/1) ⇝ 29/28 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 11/14 ⇜ (1/1 → 65/64) ⇝ 29/28 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 11/14 ⇜ (1/1 → 65/64) ⇝ 29/28 | note:74 gain:0.044 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 11/14 ⇜ (1/1 → 65/64) ⇝ 29/28 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 11/14 ⇜ (1/1 → 65/64) ⇝ 29/28 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ (1/1 → 65/64) ⇝ 5/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 11/14 ⇜ (65/64 → 33/32) ⇝ 29/28 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 11/14 ⇜ (65/64 → 33/32) ⇝ 29/28 | note:74 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 11/14 ⇜ (65/64 → 33/32) ⇝ 29/28 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 11/14 ⇜ (65/64 → 33/32) ⇝ 29/28 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 1/1 ⇜ (65/64 → 33/32) ⇝ 5/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 11/14 ⇜ (33/32 → 29/28) | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 11/14 ⇜ (33/32 → 29/28) | note:74 gain:0.064 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 11/14 ⇜ (33/32 → 29/28) | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 11/14 ⇜ (33/32 → 29/28) | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 1/1 ⇜ (33/32 → 67/64) ⇝ 5/4 | note:C2 gain:0.64 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/1 ⇜ (67/64 → 17/16) ⇝ 5/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/1 ⇜ (17/16 → 69/64) ⇝ 5/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/1 ⇜ (69/64 → 35/32) ⇝ 5/4 | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/1 ⇜ (35/32 → 71/64) ⇝ 5/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/1 ⇜ (71/64 → 9/8) ⇝ 5/4 | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 1/1 ⇜ (9/8 → 73/64) ⇝ 5/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ (9/8 → 73/64) ⇝ 5/4 | note:C4 gain:0.44 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ (9/8 → 73/64) ⇝ 5/4 | note:Eb4 gain:0.44 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 1/1 ⇜ (73/64 → 37/32) ⇝ 5/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 9/8 ⇜ (73/64 → 37/32) ⇝ 5/4 | note:C4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 9/8 ⇜ (73/64 → 37/32) ⇝ 5/4 | note:Eb4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 1/1 ⇜ (37/32 → 75/64) ⇝ 5/4 | note:C2 gain:0.64 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 9/8 ⇜ (37/32 → 75/64) ⇝ 5/4 | note:C4 gain:0.64 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 9/8 ⇜ (37/32 → 75/64) ⇝ 5/4 | note:Eb4 gain:0.64 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 1/1 ⇜ (75/64 → 19/16) ⇝ 5/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 9/8 ⇜ (75/64 → 19/16) ⇝ 5/4 | note:C4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 9/8 ⇜ (75/64 → 19/16) ⇝ 5/4 | note:Eb4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 1/1 ⇜ (19/16 → 77/64) ⇝ 5/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 9/8 ⇜ (19/16 → 77/64) ⇝ 5/4 | note:C4 gain:0.44 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 9/8 ⇜ (19/16 → 77/64) ⇝ 5/4 | note:Eb4 gain:0.44 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 1/1 ⇜ (77/64 → 39/32) ⇝ 5/4 | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 9/8 ⇜ (77/64 → 39/32) ⇝ 5/4 | note:C4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 9/8 ⇜ (77/64 → 39/32) ⇝ 5/4 | note:Eb4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 1/1 ⇜ (39/32 → 79/64) ⇝ 5/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 9/8 ⇜ (39/32 → 79/64) ⇝ 5/4 | note:C4 gain:0.24 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 9/8 ⇜ (39/32 → 79/64) ⇝ 5/4 | note:Eb4 gain:0.24 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 1/1 ⇜ (79/64 → 5/4) | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 9/8 ⇜ (79/64 → 5/4) | note:C4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 9/8 ⇜ (79/64 → 5/4) | note:Eb4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ (5/4 → 81/64) ⇝ 3/2 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ (5/4 → 81/64) ⇝ 3/2 | note:D4 gain:0.22 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ (5/4 → 81/64) ⇝ 3/2 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ (5/4 → 81/64) ⇝ 3/2 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/4 ⇜ (81/64 → 41/32) ⇝ 3/2 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 5/4 ⇜ (81/64 → 41/32) ⇝ 3/2 | note:D4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 5/4 ⇜ (81/64 → 41/32) ⇝ 3/2 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/4 ⇜ (81/64 → 41/32) ⇝ 3/2 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/4 ⇜ (41/32 → 83/64) ⇝ 3/2 | note:Bb3 gain:0.32 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 5/4 ⇜ (41/32 → 83/64) ⇝ 3/2 | note:D4 gain:0.32 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 5/4 ⇜ (41/32 → 83/64) ⇝ 3/2 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/4 ⇜ (41/32 → 83/64) ⇝ 3/2 | note:G4 gain:0.32 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/4 ⇜ (83/64 → 21/16) ⇝ 3/2 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 5/4 ⇜ (83/64 → 21/16) ⇝ 3/2 | note:D4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 5/4 ⇜ (83/64 → 21/16) ⇝ 3/2 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/4 ⇜ (83/64 → 21/16) ⇝ 3/2 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/4 ⇜ (21/16 → 85/64) ⇝ 3/2 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 5/4 ⇜ (21/16 → 85/64) ⇝ 3/2 | note:D4 gain:0.22 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 5/4 ⇜ (21/16 → 85/64) ⇝ 3/2 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/4 ⇜ (21/16 → 85/64) ⇝ 3/2 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/4 ⇜ (85/64 → 43/32) ⇝ 3/2 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 5/4 ⇜ (85/64 → 43/32) ⇝ 3/2 | note:D4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 5/4 ⇜ (85/64 → 43/32) ⇝ 3/2 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/4 ⇜ (85/64 → 43/32) ⇝ 3/2 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/4 ⇜ (43/32 → 87/64) ⇝ 3/2 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 5/4 ⇜ (43/32 → 87/64) ⇝ 3/2 | note:D4 gain:0.12 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 5/4 ⇜ (43/32 → 87/64) ⇝ 3/2 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/4 ⇜ (43/32 → 87/64) ⇝ 3/2 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/4 ⇜ (87/64 → 11/8) ⇝ 3/2 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 5/4 ⇜ (87/64 → 11/8) ⇝ 3/2 | note:D4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 5/4 ⇜ (87/64 → 11/8) ⇝ 3/2 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/4 ⇜ (87/64 → 11/8) ⇝ 3/2 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/4 ⇜ (11/8 → 89/64) ⇝ 3/2 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 5/4 ⇜ (11/8 → 89/64) ⇝ 3/2 | note:D4 gain:0.22 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 5/4 ⇜ (11/8 → 89/64) ⇝ 3/2 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/4 ⇜ (11/8 → 89/64) ⇝ 3/2 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/4 ⇜ (89/64 → 45/32) ⇝ 3/2 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 5/4 ⇜ (89/64 → 45/32) ⇝ 3/2 | note:D4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 5/4 ⇜ (89/64 → 45/32) ⇝ 3/2 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/4 ⇜ (89/64 → 45/32) ⇝ 3/2 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/4 ⇜ (45/32 → 91/64) ⇝ 3/2 | note:Bb3 gain:0.32 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 5/4 ⇜ (45/32 → 91/64) ⇝ 3/2 | note:D4 gain:0.32 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 5/4 ⇜ (45/32 → 91/64) ⇝ 3/2 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/4 ⇜ (45/32 → 91/64) ⇝ 3/2 | note:G4 gain:0.32 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/4 ⇜ (91/64 → 23/16) ⇝ 3/2 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 5/4 ⇜ (91/64 → 23/16) ⇝ 3/2 | note:D4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 5/4 ⇜ (91/64 → 23/16) ⇝ 3/2 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/4 ⇜ (91/64 → 23/16) ⇝ 3/2 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/4 ⇜ (23/16 → 93/64) ⇝ 3/2 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 5/4 ⇜ (23/16 → 93/64) ⇝ 3/2 | note:D4 gain:0.22 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 5/4 ⇜ (23/16 → 93/64) ⇝ 3/2 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/4 ⇜ (23/16 → 93/64) ⇝ 3/2 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/4 ⇜ (93/64 → 47/32) ⇝ 3/2 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 5/4 ⇜ (93/64 → 47/32) ⇝ 3/2 | note:D4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 5/4 ⇜ (93/64 → 47/32) ⇝ 3/2 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/4 ⇜ (93/64 → 47/32) ⇝ 3/2 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/4 ⇜ (47/32 → 95/64) ⇝ 3/2 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 5/4 ⇜ (47/32 → 95/64) ⇝ 3/2 | note:D4 gain:0.12 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 5/4 ⇜ (47/32 → 95/64) ⇝ 3/2 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/4 ⇜ (47/32 → 95/64) ⇝ 3/2 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/4 ⇜ (95/64 → 3/2) | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 5/4 ⇜ (95/64 → 3/2) | note:D4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 5/4 ⇜ (95/64 → 3/2) | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/4 ⇜ (95/64 → 3/2) | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (3/2 → 97/64) ⇝ 13/8 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (3/2 → 97/64) ⇝ 13/8 | note:Bb4 gain:0.44 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ (3/2 → 97/64) ⇝ 7/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 3/2 ⇜ (97/64 → 49/32) ⇝ 13/8 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 3/2 ⇜ (97/64 → 49/32) ⇝ 13/8 | note:Bb4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 3/2 ⇜ (97/64 → 49/32) ⇝ 7/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 3/2 ⇜ (49/32 → 99/64) ⇝ 13/8 | note:G4 gain:0.64 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 3/2 ⇜ (49/32 → 99/64) ⇝ 13/8 | note:Bb4 gain:0.64 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 3/2 ⇜ (49/32 → 99/64) ⇝ 7/4 | note:C2 gain:0.64 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ (43/28 → 99/64) ⇝ 25/14 | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ (43/28 → 99/64) ⇝ 25/14 | note:74 gain:0.064 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ (43/28 → 99/64) ⇝ 25/14 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ (43/28 → 99/64) ⇝ 25/14 | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 3/2 ⇜ (99/64 → 25/16) ⇝ 13/8 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 3/2 ⇜ (99/64 → 25/16) ⇝ 13/8 | note:Bb4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 3/2 ⇜ (99/64 → 25/16) ⇝ 7/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 43/28 ⇜ (99/64 → 25/16) ⇝ 25/14 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 43/28 ⇜ (99/64 → 25/16) ⇝ 25/14 | note:74 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 43/28 ⇜ (99/64 → 25/16) ⇝ 25/14 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 43/28 ⇜ (99/64 → 25/16) ⇝ 25/14 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 3/2 ⇜ (25/16 → 101/64) ⇝ 13/8 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 3/2 ⇜ (25/16 → 101/64) ⇝ 13/8 | note:Bb4 gain:0.44 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 3/2 ⇜ (25/16 → 101/64) ⇝ 7/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 43/28 ⇜ (25/16 → 101/64) ⇝ 25/14 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 43/28 ⇜ (25/16 → 101/64) ⇝ 25/14 | note:74 gain:0.044 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 43/28 ⇜ (25/16 → 101/64) ⇝ 25/14 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 43/28 ⇜ (25/16 → 101/64) ⇝ 25/14 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 3/2 ⇜ (101/64 → 51/32) ⇝ 13/8 | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 3/2 ⇜ (101/64 → 51/32) ⇝ 13/8 | note:Bb4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 3/2 ⇜ (101/64 → 51/32) ⇝ 7/4 | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 43/28 ⇜ (101/64 → 51/32) ⇝ 25/14 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 43/28 ⇜ (101/64 → 51/32) ⇝ 25/14 | note:74 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 43/28 ⇜ (101/64 → 51/32) ⇝ 25/14 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 43/28 ⇜ (101/64 → 51/32) ⇝ 25/14 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 3/2 ⇜ (51/32 → 103/64) ⇝ 13/8 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 3/2 ⇜ (51/32 → 103/64) ⇝ 13/8 | note:Bb4 gain:0.24 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 3/2 ⇜ (51/32 → 103/64) ⇝ 7/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 43/28 ⇜ (51/32 → 103/64) ⇝ 25/14 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 43/28 ⇜ (51/32 → 103/64) ⇝ 25/14 | note:74 gain:0.024 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 43/28 ⇜ (51/32 → 103/64) ⇝ 25/14 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 43/28 ⇜ (51/32 → 103/64) ⇝ 25/14 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 3/2 ⇜ (103/64 → 13/8) | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 3/2 ⇜ (103/64 → 13/8) | note:Bb4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 3/2 ⇜ (103/64 → 13/8) ⇝ 7/4 | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 43/28 ⇜ (103/64 → 13/8) ⇝ 25/14 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 43/28 ⇜ (103/64 → 13/8) ⇝ 25/14 | note:74 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 43/28 ⇜ (103/64 → 13/8) ⇝ 25/14 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 43/28 ⇜ (103/64 → 13/8) ⇝ 25/14 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 3/2 ⇜ (13/8 → 105/64) ⇝ 7/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 43/28 ⇜ (13/8 → 105/64) ⇝ 25/14 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 43/28 ⇜ (13/8 → 105/64) ⇝ 25/14 | note:74 gain:0.044 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 43/28 ⇜ (13/8 → 105/64) ⇝ 25/14 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 43/28 ⇜ (13/8 → 105/64) ⇝ 25/14 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 3/2 ⇜ (105/64 → 53/32) ⇝ 7/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 43/28 ⇜ (105/64 → 53/32) ⇝ 25/14 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 43/28 ⇜ (105/64 → 53/32) ⇝ 25/14 | note:74 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 43/28 ⇜ (105/64 → 53/32) ⇝ 25/14 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 43/28 ⇜ (105/64 → 53/32) ⇝ 25/14 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 3/2 ⇜ (53/32 → 107/64) ⇝ 7/4 | note:C2 gain:0.64 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 43/28 ⇜ (53/32 → 107/64) ⇝ 25/14 | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 43/28 ⇜ (53/32 → 107/64) ⇝ 25/14 | note:74 gain:0.064 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 43/28 ⇜ (53/32 → 107/64) ⇝ 25/14 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 43/28 ⇜ (53/32 → 107/64) ⇝ 25/14 | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 3/2 ⇜ (107/64 → 27/16) ⇝ 7/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 43/28 ⇜ (107/64 → 27/16) ⇝ 25/14 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 43/28 ⇜ (107/64 → 27/16) ⇝ 25/14 | note:74 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 43/28 ⇜ (107/64 → 27/16) ⇝ 25/14 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 43/28 ⇜ (107/64 → 27/16) ⇝ 25/14 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 3/2 ⇜ (27/16 → 109/64) ⇝ 7/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 43/28 ⇜ (27/16 → 109/64) ⇝ 25/14 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 43/28 ⇜ (27/16 → 109/64) ⇝ 25/14 | note:74 gain:0.044 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 43/28 ⇜ (27/16 → 109/64) ⇝ 25/14 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 43/28 ⇜ (27/16 → 109/64) ⇝ 25/14 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 3/2 ⇜ (109/64 → 55/32) ⇝ 7/4 | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 43/28 ⇜ (109/64 → 55/32) ⇝ 25/14 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 43/28 ⇜ (109/64 → 55/32) ⇝ 25/14 | note:74 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 43/28 ⇜ (109/64 → 55/32) ⇝ 25/14 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 43/28 ⇜ (109/64 → 55/32) ⇝ 25/14 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 3/2 ⇜ (55/32 → 111/64) ⇝ 7/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 43/28 ⇜ (55/32 → 111/64) ⇝ 25/14 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 43/28 ⇜ (55/32 → 111/64) ⇝ 25/14 | note:74 gain:0.024 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 43/28 ⇜ (55/32 → 111/64) ⇝ 25/14 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 43/28 ⇜ (55/32 → 111/64) ⇝ 25/14 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 3/2 ⇜ (111/64 → 7/4) | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 43/28 ⇜ (111/64 → 7/4) ⇝ 25/14 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 43/28 ⇜ (111/64 → 7/4) ⇝ 25/14 | note:74 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 43/28 ⇜ (111/64 → 7/4) ⇝ 25/14 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 43/28 ⇜ (111/64 → 7/4) ⇝ 25/14 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 43/28 ⇜ (7/4 → 113/64) ⇝ 25/14 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 43/28 ⇜ (7/4 → 113/64) ⇝ 25/14 | note:74 gain:0.044 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 43/28 ⇜ (7/4 → 113/64) ⇝ 25/14 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 43/28 ⇜ (7/4 → 113/64) ⇝ 25/14 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ (7/4 → 113/64) ⇝ 15/8 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (7/4 → 113/64) ⇝ 15/8 | note:Bb4 gain:0.44 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ (7/4 → 113/64) ⇝ 2/1 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ (7/4 → 113/64) ⇝ 2/1 | note:D4 gain:0.22 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ (7/4 → 113/64) ⇝ 2/1 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ (7/4 → 113/64) ⇝ 2/1 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 43/28 ⇜ (113/64 → 57/32) ⇝ 25/14 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 43/28 ⇜ (113/64 → 57/32) ⇝ 25/14 | note:74 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 43/28 ⇜ (113/64 → 57/32) ⇝ 25/14 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 43/28 ⇜ (113/64 → 57/32) ⇝ 25/14 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 7/4 ⇜ (113/64 → 57/32) ⇝ 15/8 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 7/4 ⇜ (113/64 → 57/32) ⇝ 15/8 | note:Bb4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 7/4 ⇜ (113/64 → 57/32) ⇝ 2/1 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 7/4 ⇜ (113/64 → 57/32) ⇝ 2/1 | note:D4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 7/4 ⇜ (113/64 → 57/32) ⇝ 2/1 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 7/4 ⇜ (113/64 → 57/32) ⇝ 2/1 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 43/28 ⇜ (57/32 → 25/14) | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 43/28 ⇜ (57/32 → 25/14) | note:74 gain:0.064 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 43/28 ⇜ (57/32 → 25/14) | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 43/28 ⇜ (57/32 → 25/14) | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 7/4 ⇜ (57/32 → 115/64) ⇝ 15/8 | note:G4 gain:0.64 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 7/4 ⇜ (57/32 → 115/64) ⇝ 15/8 | note:Bb4 gain:0.64 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 7/4 ⇜ (57/32 → 115/64) ⇝ 2/1 | note:Bb3 gain:0.32 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 7/4 ⇜ (57/32 → 115/64) ⇝ 2/1 | note:D4 gain:0.32 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 7/4 ⇜ (57/32 → 115/64) ⇝ 2/1 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 7/4 ⇜ (57/32 → 115/64) ⇝ 2/1 | note:G4 gain:0.32 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 7/4 ⇜ (115/64 → 29/16) ⇝ 15/8 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 7/4 ⇜ (115/64 → 29/16) ⇝ 15/8 | note:Bb4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 7/4 ⇜ (115/64 → 29/16) ⇝ 2/1 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 7/4 ⇜ (115/64 → 29/16) ⇝ 2/1 | note:D4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 7/4 ⇜ (115/64 → 29/16) ⇝ 2/1 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 7/4 ⇜ (115/64 → 29/16) ⇝ 2/1 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 7/4 ⇜ (29/16 → 117/64) ⇝ 15/8 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 7/4 ⇜ (29/16 → 117/64) ⇝ 15/8 | note:Bb4 gain:0.44 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 7/4 ⇜ (29/16 → 117/64) ⇝ 2/1 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 7/4 ⇜ (29/16 → 117/64) ⇝ 2/1 | note:D4 gain:0.22 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 7/4 ⇜ (29/16 → 117/64) ⇝ 2/1 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 7/4 ⇜ (29/16 → 117/64) ⇝ 2/1 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 7/4 ⇜ (117/64 → 59/32) ⇝ 15/8 | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 7/4 ⇜ (117/64 → 59/32) ⇝ 15/8 | note:Bb4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 7/4 ⇜ (117/64 → 59/32) ⇝ 2/1 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 7/4 ⇜ (117/64 → 59/32) ⇝ 2/1 | note:D4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 7/4 ⇜ (117/64 → 59/32) ⇝ 2/1 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 7/4 ⇜ (117/64 → 59/32) ⇝ 2/1 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 7/4 ⇜ (59/32 → 119/64) ⇝ 15/8 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 7/4 ⇜ (59/32 → 119/64) ⇝ 15/8 | note:Bb4 gain:0.24 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 7/4 ⇜ (59/32 → 119/64) ⇝ 2/1 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 7/4 ⇜ (59/32 → 119/64) ⇝ 2/1 | note:D4 gain:0.12 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 7/4 ⇜ (59/32 → 119/64) ⇝ 2/1 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 7/4 ⇜ (59/32 → 119/64) ⇝ 2/1 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 7/4 ⇜ (119/64 → 15/8) | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 7/4 ⇜ (119/64 → 15/8) | note:Bb4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 7/4 ⇜ (119/64 → 15/8) ⇝ 2/1 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 7/4 ⇜ (119/64 → 15/8) ⇝ 2/1 | note:D4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 7/4 ⇜ (119/64 → 15/8) ⇝ 2/1 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 7/4 ⇜ (119/64 → 15/8) ⇝ 2/1 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 7/4 ⇜ (15/8 → 121/64) ⇝ 2/1 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 7/4 ⇜ (15/8 → 121/64) ⇝ 2/1 | note:D4 gain:0.22 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 7/4 ⇜ (15/8 → 121/64) ⇝ 2/1 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 7/4 ⇜ (15/8 → 121/64) ⇝ 2/1 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 7/4 ⇜ (121/64 → 61/32) ⇝ 2/1 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 7/4 ⇜ (121/64 → 61/32) ⇝ 2/1 | note:D4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 7/4 ⇜ (121/64 → 61/32) ⇝ 2/1 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 7/4 ⇜ (121/64 → 61/32) ⇝ 2/1 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 7/4 ⇜ (61/32 → 123/64) ⇝ 2/1 | note:Bb3 gain:0.32 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 7/4 ⇜ (61/32 → 123/64) ⇝ 2/1 | note:D4 gain:0.32 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 7/4 ⇜ (61/32 → 123/64) ⇝ 2/1 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 7/4 ⇜ (61/32 → 123/64) ⇝ 2/1 | note:G4 gain:0.32 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 7/4 ⇜ (123/64 → 31/16) ⇝ 2/1 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 7/4 ⇜ (123/64 → 31/16) ⇝ 2/1 | note:D4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 7/4 ⇜ (123/64 → 31/16) ⇝ 2/1 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 7/4 ⇜ (123/64 → 31/16) ⇝ 2/1 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 7/4 ⇜ (31/16 → 125/64) ⇝ 2/1 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 7/4 ⇜ (31/16 → 125/64) ⇝ 2/1 | note:D4 gain:0.22 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 7/4 ⇜ (31/16 → 125/64) ⇝ 2/1 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 7/4 ⇜ (31/16 → 125/64) ⇝ 2/1 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 7/4 ⇜ (125/64 → 63/32) ⇝ 2/1 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 7/4 ⇜ (125/64 → 63/32) ⇝ 2/1 | note:D4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 7/4 ⇜ (125/64 → 63/32) ⇝ 2/1 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 7/4 ⇜ (125/64 → 63/32) ⇝ 2/1 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 7/4 ⇜ (63/32 → 127/64) ⇝ 2/1 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 7/4 ⇜ (63/32 → 127/64) ⇝ 2/1 | note:D4 gain:0.12 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 7/4 ⇜ (63/32 → 127/64) ⇝ 2/1 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 7/4 ⇜ (63/32 → 127/64) ⇝ 2/1 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 7/4 ⇜ (127/64 → 2/1) | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 7/4 ⇜ (127/64 → 2/1) | note:D4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 7/4 ⇜ (127/64 → 2/1) | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 7/4 ⇜ (127/64 → 2/1) | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (2/1 → 129/64) ⇝ 9/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 2/1 ⇜ (129/64 → 65/32) ⇝ 9/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 2/1 ⇜ (65/32 → 131/64) ⇝ 9/4 | note:F2 gain:0.64 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ (57/28 → 131/64) ⇝ 16/7 | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ (57/28 → 131/64) ⇝ 16/7 | note:74 gain:0.064 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ (57/28 → 131/64) ⇝ 16/7 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ (57/28 → 131/64) ⇝ 16/7 | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 2/1 ⇜ (131/64 → 33/16) ⇝ 9/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 57/28 ⇜ (131/64 → 33/16) ⇝ 16/7 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 57/28 ⇜ (131/64 → 33/16) ⇝ 16/7 | note:74 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 57/28 ⇜ (131/64 → 33/16) ⇝ 16/7 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 57/28 ⇜ (131/64 → 33/16) ⇝ 16/7 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 2/1 ⇜ (33/16 → 133/64) ⇝ 9/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 57/28 ⇜ (33/16 → 133/64) ⇝ 16/7 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 57/28 ⇜ (33/16 → 133/64) ⇝ 16/7 | note:74 gain:0.044 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 57/28 ⇜ (33/16 → 133/64) ⇝ 16/7 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 57/28 ⇜ (33/16 → 133/64) ⇝ 16/7 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 2/1 ⇜ (133/64 → 67/32) ⇝ 9/4 | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 57/28 ⇜ (133/64 → 67/32) ⇝ 16/7 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 57/28 ⇜ (133/64 → 67/32) ⇝ 16/7 | note:74 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 57/28 ⇜ (133/64 → 67/32) ⇝ 16/7 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 57/28 ⇜ (133/64 → 67/32) ⇝ 16/7 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 2/1 ⇜ (67/32 → 135/64) ⇝ 9/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 57/28 ⇜ (67/32 → 135/64) ⇝ 16/7 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 57/28 ⇜ (67/32 → 135/64) ⇝ 16/7 | note:74 gain:0.024 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 57/28 ⇜ (67/32 → 135/64) ⇝ 16/7 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 57/28 ⇜ (67/32 → 135/64) ⇝ 16/7 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 2/1 ⇜ (135/64 → 17/8) ⇝ 9/4 | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 57/28 ⇜ (135/64 → 17/8) ⇝ 16/7 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 57/28 ⇜ (135/64 → 17/8) ⇝ 16/7 | note:74 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 57/28 ⇜ (135/64 → 17/8) ⇝ 16/7 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 57/28 ⇜ (135/64 → 17/8) ⇝ 16/7 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 2/1 ⇜ (17/8 → 137/64) ⇝ 9/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 57/28 ⇜ (17/8 → 137/64) ⇝ 16/7 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 57/28 ⇜ (17/8 → 137/64) ⇝ 16/7 | note:74 gain:0.044 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 57/28 ⇜ (17/8 → 137/64) ⇝ 16/7 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 57/28 ⇜ (17/8 → 137/64) ⇝ 16/7 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ (17/8 → 137/64) ⇝ 9/4 | note:F4 gain:0.44 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ (17/8 → 137/64) ⇝ 9/4 | note:Ab4 gain:0.44 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 2/1 ⇜ (137/64 → 69/32) ⇝ 9/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 57/28 ⇜ (137/64 → 69/32) ⇝ 16/7 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 57/28 ⇜ (137/64 → 69/32) ⇝ 16/7 | note:74 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 57/28 ⇜ (137/64 → 69/32) ⇝ 16/7 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 57/28 ⇜ (137/64 → 69/32) ⇝ 16/7 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 17/8 ⇜ (137/64 → 69/32) ⇝ 9/4 | note:F4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 17/8 ⇜ (137/64 → 69/32) ⇝ 9/4 | note:Ab4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 2/1 ⇜ (69/32 → 139/64) ⇝ 9/4 | note:F2 gain:0.64 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 57/28 ⇜ (69/32 → 139/64) ⇝ 16/7 | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 57/28 ⇜ (69/32 → 139/64) ⇝ 16/7 | note:74 gain:0.064 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 57/28 ⇜ (69/32 → 139/64) ⇝ 16/7 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 57/28 ⇜ (69/32 → 139/64) ⇝ 16/7 | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 17/8 ⇜ (69/32 → 139/64) ⇝ 9/4 | note:F4 gain:0.64 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 17/8 ⇜ (69/32 → 139/64) ⇝ 9/4 | note:Ab4 gain:0.64 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 2/1 ⇜ (139/64 → 35/16) ⇝ 9/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 57/28 ⇜ (139/64 → 35/16) ⇝ 16/7 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 57/28 ⇜ (139/64 → 35/16) ⇝ 16/7 | note:74 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 57/28 ⇜ (139/64 → 35/16) ⇝ 16/7 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 57/28 ⇜ (139/64 → 35/16) ⇝ 16/7 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 17/8 ⇜ (139/64 → 35/16) ⇝ 9/4 | note:F4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 17/8 ⇜ (139/64 → 35/16) ⇝ 9/4 | note:Ab4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 2/1 ⇜ (35/16 → 141/64) ⇝ 9/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 57/28 ⇜ (35/16 → 141/64) ⇝ 16/7 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 57/28 ⇜ (35/16 → 141/64) ⇝ 16/7 | note:74 gain:0.044 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 57/28 ⇜ (35/16 → 141/64) ⇝ 16/7 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 57/28 ⇜ (35/16 → 141/64) ⇝ 16/7 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 17/8 ⇜ (35/16 → 141/64) ⇝ 9/4 | note:F4 gain:0.44 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 17/8 ⇜ (35/16 → 141/64) ⇝ 9/4 | note:Ab4 gain:0.44 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 2/1 ⇜ (141/64 → 71/32) ⇝ 9/4 | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 57/28 ⇜ (141/64 → 71/32) ⇝ 16/7 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 57/28 ⇜ (141/64 → 71/32) ⇝ 16/7 | note:74 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 57/28 ⇜ (141/64 → 71/32) ⇝ 16/7 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 57/28 ⇜ (141/64 → 71/32) ⇝ 16/7 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 17/8 ⇜ (141/64 → 71/32) ⇝ 9/4 | note:F4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 17/8 ⇜ (141/64 → 71/32) ⇝ 9/4 | note:Ab4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 2/1 ⇜ (71/32 → 143/64) ⇝ 9/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 57/28 ⇜ (71/32 → 143/64) ⇝ 16/7 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 57/28 ⇜ (71/32 → 143/64) ⇝ 16/7 | note:74 gain:0.024 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 57/28 ⇜ (71/32 → 143/64) ⇝ 16/7 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 57/28 ⇜ (71/32 → 143/64) ⇝ 16/7 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 17/8 ⇜ (71/32 → 143/64) ⇝ 9/4 | note:F4 gain:0.24 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 17/8 ⇜ (71/32 → 143/64) ⇝ 9/4 | note:Ab4 gain:0.24 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 2/1 ⇜ (143/64 → 9/4) | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 57/28 ⇜ (143/64 → 9/4) ⇝ 16/7 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 57/28 ⇜ (143/64 → 9/4) ⇝ 16/7 | note:74 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 57/28 ⇜ (143/64 → 9/4) ⇝ 16/7 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 57/28 ⇜ (143/64 → 9/4) ⇝ 16/7 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 17/8 ⇜ (143/64 → 9/4) | note:F4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 17/8 ⇜ (143/64 → 9/4) | note:Ab4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 57/28 ⇜ (9/4 → 145/64) ⇝ 16/7 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 57/28 ⇜ (9/4 → 145/64) ⇝ 16/7 | note:74 gain:0.044 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 57/28 ⇜ (9/4 → 145/64) ⇝ 16/7 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 57/28 ⇜ (9/4 → 145/64) ⇝ 16/7 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 57/28 ⇜ (145/64 → 73/32) ⇝ 16/7 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 57/28 ⇜ (145/64 → 73/32) ⇝ 16/7 | note:74 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 57/28 ⇜ (145/64 → 73/32) ⇝ 16/7 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 57/28 ⇜ (145/64 → 73/32) ⇝ 16/7 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 57/28 ⇜ (73/32 → 16/7) | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 57/28 ⇜ (73/32 → 16/7) | note:74 gain:0.064 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 57/28 ⇜ (73/32 → 16/7) | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 57/28 ⇜ (73/32 → 16/7) | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ (5/2 → 161/64) ⇝ 21/8 | note:C5 gain:0.44 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ (5/2 → 161/64) ⇝ 21/8 | note:Eb5 gain:0.44 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ (5/2 → 161/64) ⇝ 11/4 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ (5/2 → 161/64) ⇝ 11/4 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (5/2 → 161/64) ⇝ 11/4 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ (5/2 → 161/64) ⇝ 11/4 | note:C5 gain:0.22 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ (5/2 → 161/64) ⇝ 11/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 5/2 ⇜ (161/64 → 81/32) ⇝ 21/8 | note:C5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 5/2 ⇜ (161/64 → 81/32) ⇝ 21/8 | note:Eb5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 5/2 ⇜ (161/64 → 81/32) ⇝ 11/4 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/2 ⇜ (161/64 → 81/32) ⇝ 11/4 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/2 ⇜ (161/64 → 81/32) ⇝ 11/4 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 5/2 ⇜ (161/64 → 81/32) ⇝ 11/4 | note:C5 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 5/2 ⇜ (161/64 → 81/32) ⇝ 11/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 5/2 ⇜ (81/32 → 163/64) ⇝ 21/8 | note:C5 gain:0.64 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 5/2 ⇜ (81/32 → 163/64) ⇝ 21/8 | note:Eb5 gain:0.64 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 5/2 ⇜ (81/32 → 163/64) ⇝ 11/4 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/2 ⇜ (81/32 → 163/64) ⇝ 11/4 | note:G4 gain:0.32 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/2 ⇜ (81/32 → 163/64) ⇝ 11/4 | note:Ab4 gain:0.32 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 5/2 ⇜ (81/32 → 163/64) ⇝ 11/4 | note:C5 gain:0.32 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 5/2 ⇜ (81/32 → 163/64) ⇝ 11/4 | note:F2 gain:0.64 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 5/2 ⇜ (163/64 → 41/16) ⇝ 21/8 | note:C5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 5/2 ⇜ (163/64 → 41/16) ⇝ 21/8 | note:Eb5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 5/2 ⇜ (163/64 → 41/16) ⇝ 11/4 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/2 ⇜ (163/64 → 41/16) ⇝ 11/4 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/2 ⇜ (163/64 → 41/16) ⇝ 11/4 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 5/2 ⇜ (163/64 → 41/16) ⇝ 11/4 | note:C5 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 5/2 ⇜ (163/64 → 41/16) ⇝ 11/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 5/2 ⇜ (41/16 → 165/64) ⇝ 21/8 | note:C5 gain:0.44 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 5/2 ⇜ (41/16 → 165/64) ⇝ 21/8 | note:Eb5 gain:0.44 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 5/2 ⇜ (41/16 → 165/64) ⇝ 11/4 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/2 ⇜ (41/16 → 165/64) ⇝ 11/4 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/2 ⇜ (41/16 → 165/64) ⇝ 11/4 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 5/2 ⇜ (41/16 → 165/64) ⇝ 11/4 | note:C5 gain:0.22 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 5/2 ⇜ (41/16 → 165/64) ⇝ 11/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 5/2 ⇜ (165/64 → 83/32) ⇝ 21/8 | note:C5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 5/2 ⇜ (165/64 → 83/32) ⇝ 21/8 | note:Eb5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 5/2 ⇜ (165/64 → 83/32) ⇝ 11/4 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/2 ⇜ (165/64 → 83/32) ⇝ 11/4 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/2 ⇜ (165/64 → 83/32) ⇝ 11/4 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 5/2 ⇜ (165/64 → 83/32) ⇝ 11/4 | note:C5 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 5/2 ⇜ (165/64 → 83/32) ⇝ 11/4 | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 5/2 ⇜ (83/32 → 167/64) ⇝ 21/8 | note:C5 gain:0.24 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 5/2 ⇜ (83/32 → 167/64) ⇝ 21/8 | note:Eb5 gain:0.24 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 5/2 ⇜ (83/32 → 167/64) ⇝ 11/4 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/2 ⇜ (83/32 → 167/64) ⇝ 11/4 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/2 ⇜ (83/32 → 167/64) ⇝ 11/4 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 5/2 ⇜ (83/32 → 167/64) ⇝ 11/4 | note:C5 gain:0.12 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 5/2 ⇜ (83/32 → 167/64) ⇝ 11/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 5/2 ⇜ (167/64 → 21/8) | note:C5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 5/2 ⇜ (167/64 → 21/8) | note:Eb5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 5/2 ⇜ (167/64 → 21/8) ⇝ 11/4 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/2 ⇜ (167/64 → 21/8) ⇝ 11/4 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/2 ⇜ (167/64 → 21/8) ⇝ 11/4 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 5/2 ⇜ (167/64 → 21/8) ⇝ 11/4 | note:C5 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 5/2 ⇜ (167/64 → 21/8) ⇝ 11/4 | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 5/2 ⇜ (21/8 → 169/64) ⇝ 11/4 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/2 ⇜ (21/8 → 169/64) ⇝ 11/4 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/2 ⇜ (21/8 → 169/64) ⇝ 11/4 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 5/2 ⇜ (21/8 → 169/64) ⇝ 11/4 | note:C5 gain:0.22 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 5/2 ⇜ (21/8 → 169/64) ⇝ 11/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 5/2 ⇜ (169/64 → 85/32) ⇝ 11/4 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/2 ⇜ (169/64 → 85/32) ⇝ 11/4 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/2 ⇜ (169/64 → 85/32) ⇝ 11/4 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 5/2 ⇜ (169/64 → 85/32) ⇝ 11/4 | note:C5 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 5/2 ⇜ (169/64 → 85/32) ⇝ 11/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 5/2 ⇜ (85/32 → 171/64) ⇝ 11/4 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/2 ⇜ (85/32 → 171/64) ⇝ 11/4 | note:G4 gain:0.32 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/2 ⇜ (85/32 → 171/64) ⇝ 11/4 | note:Ab4 gain:0.32 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 5/2 ⇜ (85/32 → 171/64) ⇝ 11/4 | note:C5 gain:0.32 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 5/2 ⇜ (85/32 → 171/64) ⇝ 11/4 | note:F2 gain:0.64 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 5/2 ⇜ (171/64 → 43/16) ⇝ 11/4 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/2 ⇜ (171/64 → 43/16) ⇝ 11/4 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/2 ⇜ (171/64 → 43/16) ⇝ 11/4 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 5/2 ⇜ (171/64 → 43/16) ⇝ 11/4 | note:C5 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 5/2 ⇜ (171/64 → 43/16) ⇝ 11/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 5/2 ⇜ (43/16 → 173/64) ⇝ 11/4 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/2 ⇜ (43/16 → 173/64) ⇝ 11/4 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/2 ⇜ (43/16 → 173/64) ⇝ 11/4 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 5/2 ⇜ (43/16 → 173/64) ⇝ 11/4 | note:C5 gain:0.22 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 5/2 ⇜ (43/16 → 173/64) ⇝ 11/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 5/2 ⇜ (173/64 → 87/32) ⇝ 11/4 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/2 ⇜ (173/64 → 87/32) ⇝ 11/4 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/2 ⇜ (173/64 → 87/32) ⇝ 11/4 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 5/2 ⇜ (173/64 → 87/32) ⇝ 11/4 | note:C5 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 5/2 ⇜ (173/64 → 87/32) ⇝ 11/4 | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 5/2 ⇜ (87/32 → 175/64) ⇝ 11/4 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/2 ⇜ (87/32 → 175/64) ⇝ 11/4 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/2 ⇜ (87/32 → 175/64) ⇝ 11/4 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 5/2 ⇜ (87/32 → 175/64) ⇝ 11/4 | note:C5 gain:0.12 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 5/2 ⇜ (87/32 → 175/64) ⇝ 11/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 5/2 ⇜ (175/64 → 11/4) | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/2 ⇜ (175/64 → 11/4) | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/2 ⇜ (175/64 → 11/4) | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 5/2 ⇜ (175/64 → 11/4) | note:C5 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 5/2 ⇜ (175/64 → 11/4) | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ (11/4 → 177/64) ⇝ 23/8 | note:F4 gain:0.44 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ (11/4 → 177/64) ⇝ 23/8 | note:Ab4 gain:0.44 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 11/4 ⇜ (177/64 → 89/32) ⇝ 23/8 | note:F4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 11/4 ⇜ (177/64 → 89/32) ⇝ 23/8 | note:Ab4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 11/4 ⇜ (89/32 → 179/64) ⇝ 23/8 | note:F4 gain:0.64 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 11/4 ⇜ (89/32 → 179/64) ⇝ 23/8 | note:Ab4 gain:0.64 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ (39/14 → 179/64) ⇝ 85/28 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ (39/14 → 179/64) ⇝ 85/28 | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ (39/14 → 179/64) ⇝ 85/28 | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ (39/14 → 179/64) ⇝ 85/28 | note:84 gain:0.064 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 11/4 ⇜ (179/64 → 45/16) ⇝ 23/8 | note:F4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 11/4 ⇜ (179/64 → 45/16) ⇝ 23/8 | note:Ab4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 39/14 ⇜ (179/64 → 45/16) ⇝ 85/28 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 39/14 ⇜ (179/64 → 45/16) ⇝ 85/28 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 39/14 ⇜ (179/64 → 45/16) ⇝ 85/28 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 39/14 ⇜ (179/64 → 45/16) ⇝ 85/28 | note:84 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 11/4 ⇜ (45/16 → 181/64) ⇝ 23/8 | note:F4 gain:0.44 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 11/4 ⇜ (45/16 → 181/64) ⇝ 23/8 | note:Ab4 gain:0.44 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 39/14 ⇜ (45/16 → 181/64) ⇝ 85/28 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 39/14 ⇜ (45/16 → 181/64) ⇝ 85/28 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 39/14 ⇜ (45/16 → 181/64) ⇝ 85/28 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 39/14 ⇜ (45/16 → 181/64) ⇝ 85/28 | note:84 gain:0.044 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 11/4 ⇜ (181/64 → 91/32) ⇝ 23/8 | note:F4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 11/4 ⇜ (181/64 → 91/32) ⇝ 23/8 | note:Ab4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 39/14 ⇜ (181/64 → 91/32) ⇝ 85/28 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 39/14 ⇜ (181/64 → 91/32) ⇝ 85/28 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 39/14 ⇜ (181/64 → 91/32) ⇝ 85/28 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 39/14 ⇜ (181/64 → 91/32) ⇝ 85/28 | note:84 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 11/4 ⇜ (91/32 → 183/64) ⇝ 23/8 | note:F4 gain:0.24 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 11/4 ⇜ (91/32 → 183/64) ⇝ 23/8 | note:Ab4 gain:0.24 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 39/14 ⇜ (91/32 → 183/64) ⇝ 85/28 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 39/14 ⇜ (91/32 → 183/64) ⇝ 85/28 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 39/14 ⇜ (91/32 → 183/64) ⇝ 85/28 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 39/14 ⇜ (91/32 → 183/64) ⇝ 85/28 | note:84 gain:0.024 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 11/4 ⇜ (183/64 → 23/8) | note:F4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 11/4 ⇜ (183/64 → 23/8) | note:Ab4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 39/14 ⇜ (183/64 → 23/8) ⇝ 85/28 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 39/14 ⇜ (183/64 → 23/8) ⇝ 85/28 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 39/14 ⇜ (183/64 → 23/8) ⇝ 85/28 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 39/14 ⇜ (183/64 → 23/8) ⇝ 85/28 | note:84 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 39/14 ⇜ (23/8 → 185/64) ⇝ 85/28 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 39/14 ⇜ (23/8 → 185/64) ⇝ 85/28 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 39/14 ⇜ (23/8 → 185/64) ⇝ 85/28 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 39/14 ⇜ (23/8 → 185/64) ⇝ 85/28 | note:84 gain:0.044 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 39/14 ⇜ (185/64 → 93/32) ⇝ 85/28 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 39/14 ⇜ (185/64 → 93/32) ⇝ 85/28 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 39/14 ⇜ (185/64 → 93/32) ⇝ 85/28 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 39/14 ⇜ (185/64 → 93/32) ⇝ 85/28 | note:84 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 39/14 ⇜ (93/32 → 187/64) ⇝ 85/28 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 39/14 ⇜ (93/32 → 187/64) ⇝ 85/28 | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 39/14 ⇜ (93/32 → 187/64) ⇝ 85/28 | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 39/14 ⇜ (93/32 → 187/64) ⇝ 85/28 | note:84 gain:0.064 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 39/14 ⇜ (187/64 → 47/16) ⇝ 85/28 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 39/14 ⇜ (187/64 → 47/16) ⇝ 85/28 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 39/14 ⇜ (187/64 → 47/16) ⇝ 85/28 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 39/14 ⇜ (187/64 → 47/16) ⇝ 85/28 | note:84 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 39/14 ⇜ (47/16 → 189/64) ⇝ 85/28 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 39/14 ⇜ (47/16 → 189/64) ⇝ 85/28 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 39/14 ⇜ (47/16 → 189/64) ⇝ 85/28 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 39/14 ⇜ (47/16 → 189/64) ⇝ 85/28 | note:84 gain:0.044 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 39/14 ⇜ (189/64 → 95/32) ⇝ 85/28 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 39/14 ⇜ (189/64 → 95/32) ⇝ 85/28 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 39/14 ⇜ (189/64 → 95/32) ⇝ 85/28 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 39/14 ⇜ (189/64 → 95/32) ⇝ 85/28 | note:84 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 39/14 ⇜ (95/32 → 191/64) ⇝ 85/28 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 39/14 ⇜ (95/32 → 191/64) ⇝ 85/28 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 39/14 ⇜ (95/32 → 191/64) ⇝ 85/28 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 39/14 ⇜ (95/32 → 191/64) ⇝ 85/28 | note:84 gain:0.024 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 39/14 ⇜ (191/64 → 3/1) ⇝ 85/28 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 39/14 ⇜ (191/64 → 3/1) ⇝ 85/28 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 39/14 ⇜ (191/64 → 3/1) ⇝ 85/28 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 39/14 ⇜ (191/64 → 3/1) ⇝ 85/28 | note:84 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 39/14 ⇜ (3/1 → 193/64) ⇝ 85/28 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 39/14 ⇜ (3/1 → 193/64) ⇝ 85/28 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 39/14 ⇜ (3/1 → 193/64) ⇝ 85/28 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 39/14 ⇜ (3/1 → 193/64) ⇝ 85/28 | note:84 gain:0.044 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ (3/1 → 193/64) ⇝ 13/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 39/14 ⇜ (193/64 → 97/32) ⇝ 85/28 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 39/14 ⇜ (193/64 → 97/32) ⇝ 85/28 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 39/14 ⇜ (193/64 → 97/32) ⇝ 85/28 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 39/14 ⇜ (193/64 → 97/32) ⇝ 85/28 | note:84 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 3/1 ⇜ (193/64 → 97/32) ⇝ 13/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 39/14 ⇜ (97/32 → 85/28) | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 39/14 ⇜ (97/32 → 85/28) | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 39/14 ⇜ (97/32 → 85/28) | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 39/14 ⇜ (97/32 → 85/28) | note:84 gain:0.064 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 3/1 ⇜ (97/32 → 195/64) ⇝ 13/4 | note:F2 gain:0.64 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 3/1 ⇜ (195/64 → 49/16) ⇝ 13/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 3/1 ⇜ (49/16 → 197/64) ⇝ 13/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 3/1 ⇜ (197/64 → 99/32) ⇝ 13/4 | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 3/1 ⇜ (99/32 → 199/64) ⇝ 13/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 3/1 ⇜ (199/64 → 25/8) ⇝ 13/4 | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 3/1 ⇜ (25/8 → 201/64) ⇝ 13/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ (25/8 → 201/64) ⇝ 13/4 | note:F4 gain:0.44 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ (25/8 → 201/64) ⇝ 13/4 | note:Ab4 gain:0.44 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 3/1 ⇜ (201/64 → 101/32) ⇝ 13/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 25/8 ⇜ (201/64 → 101/32) ⇝ 13/4 | note:F4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 25/8 ⇜ (201/64 → 101/32) ⇝ 13/4 | note:Ab4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 3/1 ⇜ (101/32 → 203/64) ⇝ 13/4 | note:F2 gain:0.64 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 25/8 ⇜ (101/32 → 203/64) ⇝ 13/4 | note:F4 gain:0.64 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 25/8 ⇜ (101/32 → 203/64) ⇝ 13/4 | note:Ab4 gain:0.64 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 3/1 ⇜ (203/64 → 51/16) ⇝ 13/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 25/8 ⇜ (203/64 → 51/16) ⇝ 13/4 | note:F4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 25/8 ⇜ (203/64 → 51/16) ⇝ 13/4 | note:Ab4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 3/1 ⇜ (51/16 → 205/64) ⇝ 13/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 25/8 ⇜ (51/16 → 205/64) ⇝ 13/4 | note:F4 gain:0.44 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 25/8 ⇜ (51/16 → 205/64) ⇝ 13/4 | note:Ab4 gain:0.44 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 3/1 ⇜ (205/64 → 103/32) ⇝ 13/4 | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 25/8 ⇜ (205/64 → 103/32) ⇝ 13/4 | note:F4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 25/8 ⇜ (205/64 → 103/32) ⇝ 13/4 | note:Ab4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 3/1 ⇜ (103/32 → 207/64) ⇝ 13/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 25/8 ⇜ (103/32 → 207/64) ⇝ 13/4 | note:F4 gain:0.24 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 25/8 ⇜ (103/32 → 207/64) ⇝ 13/4 | note:Ab4 gain:0.24 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 3/1 ⇜ (207/64 → 13/4) | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 25/8 ⇜ (207/64 → 13/4) | note:F4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 25/8 ⇜ (207/64 → 13/4) | note:Ab4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ (13/4 → 209/64) ⇝ 7/2 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ (13/4 → 209/64) ⇝ 7/2 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (13/4 → 209/64) ⇝ 7/2 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ (13/4 → 209/64) ⇝ 7/2 | note:C5 gain:0.22 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 13/4 ⇜ (209/64 → 105/32) ⇝ 7/2 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/4 ⇜ (209/64 → 105/32) ⇝ 7/2 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 13/4 ⇜ (209/64 → 105/32) ⇝ 7/2 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/4 ⇜ (209/64 → 105/32) ⇝ 7/2 | note:C5 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 13/4 ⇜ (105/32 → 211/64) ⇝ 7/2 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/4 ⇜ (105/32 → 211/64) ⇝ 7/2 | note:G4 gain:0.32 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 13/4 ⇜ (105/32 → 211/64) ⇝ 7/2 | note:Ab4 gain:0.32 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/4 ⇜ (105/32 → 211/64) ⇝ 7/2 | note:C5 gain:0.32 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 13/4 ⇜ (211/64 → 53/16) ⇝ 7/2 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/4 ⇜ (211/64 → 53/16) ⇝ 7/2 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 13/4 ⇜ (211/64 → 53/16) ⇝ 7/2 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/4 ⇜ (211/64 → 53/16) ⇝ 7/2 | note:C5 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 13/4 ⇜ (53/16 → 213/64) ⇝ 7/2 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/4 ⇜ (53/16 → 213/64) ⇝ 7/2 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 13/4 ⇜ (53/16 → 213/64) ⇝ 7/2 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/4 ⇜ (53/16 → 213/64) ⇝ 7/2 | note:C5 gain:0.22 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 13/4 ⇜ (213/64 → 107/32) ⇝ 7/2 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/4 ⇜ (213/64 → 107/32) ⇝ 7/2 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 13/4 ⇜ (213/64 → 107/32) ⇝ 7/2 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/4 ⇜ (213/64 → 107/32) ⇝ 7/2 | note:C5 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 13/4 ⇜ (107/32 → 215/64) ⇝ 7/2 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/4 ⇜ (107/32 → 215/64) ⇝ 7/2 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 13/4 ⇜ (107/32 → 215/64) ⇝ 7/2 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/4 ⇜ (107/32 → 215/64) ⇝ 7/2 | note:C5 gain:0.12 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 13/4 ⇜ (215/64 → 27/8) ⇝ 7/2 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/4 ⇜ (215/64 → 27/8) ⇝ 7/2 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 13/4 ⇜ (215/64 → 27/8) ⇝ 7/2 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/4 ⇜ (215/64 → 27/8) ⇝ 7/2 | note:C5 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 13/4 ⇜ (27/8 → 217/64) ⇝ 7/2 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/4 ⇜ (27/8 → 217/64) ⇝ 7/2 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 13/4 ⇜ (27/8 → 217/64) ⇝ 7/2 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/4 ⇜ (27/8 → 217/64) ⇝ 7/2 | note:C5 gain:0.22 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 13/4 ⇜ (217/64 → 109/32) ⇝ 7/2 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/4 ⇜ (217/64 → 109/32) ⇝ 7/2 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 13/4 ⇜ (217/64 → 109/32) ⇝ 7/2 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/4 ⇜ (217/64 → 109/32) ⇝ 7/2 | note:C5 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 13/4 ⇜ (109/32 → 219/64) ⇝ 7/2 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/4 ⇜ (109/32 → 219/64) ⇝ 7/2 | note:G4 gain:0.32 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 13/4 ⇜ (109/32 → 219/64) ⇝ 7/2 | note:Ab4 gain:0.32 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/4 ⇜ (109/32 → 219/64) ⇝ 7/2 | note:C5 gain:0.32 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 13/4 ⇜ (219/64 → 55/16) ⇝ 7/2 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/4 ⇜ (219/64 → 55/16) ⇝ 7/2 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 13/4 ⇜ (219/64 → 55/16) ⇝ 7/2 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/4 ⇜ (219/64 → 55/16) ⇝ 7/2 | note:C5 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 13/4 ⇜ (55/16 → 221/64) ⇝ 7/2 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/4 ⇜ (55/16 → 221/64) ⇝ 7/2 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 13/4 ⇜ (55/16 → 221/64) ⇝ 7/2 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/4 ⇜ (55/16 → 221/64) ⇝ 7/2 | note:C5 gain:0.22 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 13/4 ⇜ (221/64 → 111/32) ⇝ 7/2 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/4 ⇜ (221/64 → 111/32) ⇝ 7/2 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 13/4 ⇜ (221/64 → 111/32) ⇝ 7/2 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/4 ⇜ (221/64 → 111/32) ⇝ 7/2 | note:C5 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 13/4 ⇜ (111/32 → 223/64) ⇝ 7/2 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/4 ⇜ (111/32 → 223/64) ⇝ 7/2 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 13/4 ⇜ (111/32 → 223/64) ⇝ 7/2 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/4 ⇜ (111/32 → 223/64) ⇝ 7/2 | note:C5 gain:0.12 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 13/4 ⇜ (223/64 → 7/2) | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/4 ⇜ (223/64 → 7/2) | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 13/4 ⇜ (223/64 → 7/2) | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/4 ⇜ (223/64 → 7/2) | note:C5 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ (7/2 → 225/64) ⇝ 29/8 | note:C5 gain:0.44 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ (7/2 → 225/64) ⇝ 29/8 | note:Eb5 gain:0.44 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ (7/2 → 225/64) ⇝ 15/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 7/2 ⇜ (225/64 → 113/32) ⇝ 29/8 | note:C5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 7/2 ⇜ (225/64 → 113/32) ⇝ 29/8 | note:Eb5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 7/2 ⇜ (225/64 → 113/32) ⇝ 15/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 7/2 ⇜ (113/32 → 227/64) ⇝ 29/8 | note:C5 gain:0.64 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 7/2 ⇜ (113/32 → 227/64) ⇝ 29/8 | note:Eb5 gain:0.64 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 7/2 ⇜ (113/32 → 227/64) ⇝ 15/4 | note:F2 gain:0.64 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ (99/28 → 227/64) ⇝ 53/14 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ (99/28 → 227/64) ⇝ 53/14 | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ (99/28 → 227/64) ⇝ 53/14 | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ (99/28 → 227/64) ⇝ 53/14 | note:84 gain:0.064 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 7/2 ⇜ (227/64 → 57/16) ⇝ 29/8 | note:C5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 7/2 ⇜ (227/64 → 57/16) ⇝ 29/8 | note:Eb5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 7/2 ⇜ (227/64 → 57/16) ⇝ 15/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 99/28 ⇜ (227/64 → 57/16) ⇝ 53/14 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 99/28 ⇜ (227/64 → 57/16) ⇝ 53/14 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 99/28 ⇜ (227/64 → 57/16) ⇝ 53/14 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 99/28 ⇜ (227/64 → 57/16) ⇝ 53/14 | note:84 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 7/2 ⇜ (57/16 → 229/64) ⇝ 29/8 | note:C5 gain:0.44 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 7/2 ⇜ (57/16 → 229/64) ⇝ 29/8 | note:Eb5 gain:0.44 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 7/2 ⇜ (57/16 → 229/64) ⇝ 15/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 99/28 ⇜ (57/16 → 229/64) ⇝ 53/14 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 99/28 ⇜ (57/16 → 229/64) ⇝ 53/14 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 99/28 ⇜ (57/16 → 229/64) ⇝ 53/14 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 99/28 ⇜ (57/16 → 229/64) ⇝ 53/14 | note:84 gain:0.044 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 7/2 ⇜ (229/64 → 115/32) ⇝ 29/8 | note:C5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 7/2 ⇜ (229/64 → 115/32) ⇝ 29/8 | note:Eb5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 7/2 ⇜ (229/64 → 115/32) ⇝ 15/4 | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 99/28 ⇜ (229/64 → 115/32) ⇝ 53/14 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 99/28 ⇜ (229/64 → 115/32) ⇝ 53/14 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 99/28 ⇜ (229/64 → 115/32) ⇝ 53/14 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 99/28 ⇜ (229/64 → 115/32) ⇝ 53/14 | note:84 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 7/2 ⇜ (115/32 → 231/64) ⇝ 29/8 | note:C5 gain:0.24 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 7/2 ⇜ (115/32 → 231/64) ⇝ 29/8 | note:Eb5 gain:0.24 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 7/2 ⇜ (115/32 → 231/64) ⇝ 15/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 99/28 ⇜ (115/32 → 231/64) ⇝ 53/14 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 99/28 ⇜ (115/32 → 231/64) ⇝ 53/14 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 99/28 ⇜ (115/32 → 231/64) ⇝ 53/14 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 99/28 ⇜ (115/32 → 231/64) ⇝ 53/14 | note:84 gain:0.024 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 7/2 ⇜ (231/64 → 29/8) | note:C5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 7/2 ⇜ (231/64 → 29/8) | note:Eb5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 7/2 ⇜ (231/64 → 29/8) ⇝ 15/4 | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 99/28 ⇜ (231/64 → 29/8) ⇝ 53/14 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 99/28 ⇜ (231/64 → 29/8) ⇝ 53/14 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 99/28 ⇜ (231/64 → 29/8) ⇝ 53/14 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 99/28 ⇜ (231/64 → 29/8) ⇝ 53/14 | note:84 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 7/2 ⇜ (29/8 → 233/64) ⇝ 15/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 99/28 ⇜ (29/8 → 233/64) ⇝ 53/14 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 99/28 ⇜ (29/8 → 233/64) ⇝ 53/14 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 99/28 ⇜ (29/8 → 233/64) ⇝ 53/14 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 99/28 ⇜ (29/8 → 233/64) ⇝ 53/14 | note:84 gain:0.044 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 7/2 ⇜ (233/64 → 117/32) ⇝ 15/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 99/28 ⇜ (233/64 → 117/32) ⇝ 53/14 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 99/28 ⇜ (233/64 → 117/32) ⇝ 53/14 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 99/28 ⇜ (233/64 → 117/32) ⇝ 53/14 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 99/28 ⇜ (233/64 → 117/32) ⇝ 53/14 | note:84 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 7/2 ⇜ (117/32 → 235/64) ⇝ 15/4 | note:F2 gain:0.64 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 99/28 ⇜ (117/32 → 235/64) ⇝ 53/14 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 99/28 ⇜ (117/32 → 235/64) ⇝ 53/14 | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 99/28 ⇜ (117/32 → 235/64) ⇝ 53/14 | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 99/28 ⇜ (117/32 → 235/64) ⇝ 53/14 | note:84 gain:0.064 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 7/2 ⇜ (235/64 → 59/16) ⇝ 15/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 99/28 ⇜ (235/64 → 59/16) ⇝ 53/14 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 99/28 ⇜ (235/64 → 59/16) ⇝ 53/14 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 99/28 ⇜ (235/64 → 59/16) ⇝ 53/14 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 99/28 ⇜ (235/64 → 59/16) ⇝ 53/14 | note:84 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 7/2 ⇜ (59/16 → 237/64) ⇝ 15/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 99/28 ⇜ (59/16 → 237/64) ⇝ 53/14 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 99/28 ⇜ (59/16 → 237/64) ⇝ 53/14 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 99/28 ⇜ (59/16 → 237/64) ⇝ 53/14 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 99/28 ⇜ (59/16 → 237/64) ⇝ 53/14 | note:84 gain:0.044 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 7/2 ⇜ (237/64 → 119/32) ⇝ 15/4 | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 99/28 ⇜ (237/64 → 119/32) ⇝ 53/14 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 99/28 ⇜ (237/64 → 119/32) ⇝ 53/14 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 99/28 ⇜ (237/64 → 119/32) ⇝ 53/14 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 99/28 ⇜ (237/64 → 119/32) ⇝ 53/14 | note:84 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 7/2 ⇜ (119/32 → 239/64) ⇝ 15/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 99/28 ⇜ (119/32 → 239/64) ⇝ 53/14 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 99/28 ⇜ (119/32 → 239/64) ⇝ 53/14 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 99/28 ⇜ (119/32 → 239/64) ⇝ 53/14 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 99/28 ⇜ (119/32 → 239/64) ⇝ 53/14 | note:84 gain:0.024 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 7/2 ⇜ (239/64 → 15/4) | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 99/28 ⇜ (239/64 → 15/4) ⇝ 53/14 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 99/28 ⇜ (239/64 → 15/4) ⇝ 53/14 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 99/28 ⇜ (239/64 → 15/4) ⇝ 53/14 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 99/28 ⇜ (239/64 → 15/4) ⇝ 53/14 | note:84 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 99/28 ⇜ (15/4 → 241/64) ⇝ 53/14 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 99/28 ⇜ (15/4 → 241/64) ⇝ 53/14 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 99/28 ⇜ (15/4 → 241/64) ⇝ 53/14 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 99/28 ⇜ (15/4 → 241/64) ⇝ 53/14 | note:84 gain:0.044 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ (15/4 → 241/64) ⇝ 31/8 | note:C5 gain:0.44 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ (15/4 → 241/64) ⇝ 31/8 | note:Eb5 gain:0.44 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ (15/4 → 241/64) ⇝ 4/1 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ (15/4 → 241/64) ⇝ 4/1 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (15/4 → 241/64) ⇝ 4/1 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ (15/4 → 241/64) ⇝ 4/1 | note:C5 gain:0.22 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 99/28 ⇜ (241/64 → 121/32) ⇝ 53/14 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 99/28 ⇜ (241/64 → 121/32) ⇝ 53/14 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 99/28 ⇜ (241/64 → 121/32) ⇝ 53/14 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 99/28 ⇜ (241/64 → 121/32) ⇝ 53/14 | note:84 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 15/4 ⇜ (241/64 → 121/32) ⇝ 31/8 | note:C5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 15/4 ⇜ (241/64 → 121/32) ⇝ 31/8 | note:Eb5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 15/4 ⇜ (241/64 → 121/32) ⇝ 4/1 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 15/4 ⇜ (241/64 → 121/32) ⇝ 4/1 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 15/4 ⇜ (241/64 → 121/32) ⇝ 4/1 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 15/4 ⇜ (241/64 → 121/32) ⇝ 4/1 | note:C5 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 99/28 ⇜ (121/32 → 53/14) | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 99/28 ⇜ (121/32 → 53/14) | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 99/28 ⇜ (121/32 → 53/14) | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 99/28 ⇜ (121/32 → 53/14) | note:84 gain:0.064 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 15/4 ⇜ (121/32 → 243/64) ⇝ 31/8 | note:C5 gain:0.64 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 15/4 ⇜ (121/32 → 243/64) ⇝ 31/8 | note:Eb5 gain:0.64 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 15/4 ⇜ (121/32 → 243/64) ⇝ 4/1 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 15/4 ⇜ (121/32 → 243/64) ⇝ 4/1 | note:G4 gain:0.32 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 15/4 ⇜ (121/32 → 243/64) ⇝ 4/1 | note:Ab4 gain:0.32 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 15/4 ⇜ (121/32 → 243/64) ⇝ 4/1 | note:C5 gain:0.32 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 15/4 ⇜ (243/64 → 61/16) ⇝ 31/8 | note:C5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 15/4 ⇜ (243/64 → 61/16) ⇝ 31/8 | note:Eb5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 15/4 ⇜ (243/64 → 61/16) ⇝ 4/1 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 15/4 ⇜ (243/64 → 61/16) ⇝ 4/1 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 15/4 ⇜ (243/64 → 61/16) ⇝ 4/1 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 15/4 ⇜ (243/64 → 61/16) ⇝ 4/1 | note:C5 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 15/4 ⇜ (61/16 → 245/64) ⇝ 31/8 | note:C5 gain:0.44 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 15/4 ⇜ (61/16 → 245/64) ⇝ 31/8 | note:Eb5 gain:0.44 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 15/4 ⇜ (61/16 → 245/64) ⇝ 4/1 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 15/4 ⇜ (61/16 → 245/64) ⇝ 4/1 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 15/4 ⇜ (61/16 → 245/64) ⇝ 4/1 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 15/4 ⇜ (61/16 → 245/64) ⇝ 4/1 | note:C5 gain:0.22 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 15/4 ⇜ (245/64 → 123/32) ⇝ 31/8 | note:C5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 15/4 ⇜ (245/64 → 123/32) ⇝ 31/8 | note:Eb5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 15/4 ⇜ (245/64 → 123/32) ⇝ 4/1 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 15/4 ⇜ (245/64 → 123/32) ⇝ 4/1 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 15/4 ⇜ (245/64 → 123/32) ⇝ 4/1 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 15/4 ⇜ (245/64 → 123/32) ⇝ 4/1 | note:C5 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 15/4 ⇜ (123/32 → 247/64) ⇝ 31/8 | note:C5 gain:0.24 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 15/4 ⇜ (123/32 → 247/64) ⇝ 31/8 | note:Eb5 gain:0.24 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 15/4 ⇜ (123/32 → 247/64) ⇝ 4/1 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 15/4 ⇜ (123/32 → 247/64) ⇝ 4/1 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 15/4 ⇜ (123/32 → 247/64) ⇝ 4/1 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 15/4 ⇜ (123/32 → 247/64) ⇝ 4/1 | note:C5 gain:0.12 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 15/4 ⇜ (247/64 → 31/8) | note:C5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 15/4 ⇜ (247/64 → 31/8) | note:Eb5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 15/4 ⇜ (247/64 → 31/8) ⇝ 4/1 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 15/4 ⇜ (247/64 → 31/8) ⇝ 4/1 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 15/4 ⇜ (247/64 → 31/8) ⇝ 4/1 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 15/4 ⇜ (247/64 → 31/8) ⇝ 4/1 | note:C5 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 15/4 ⇜ (31/8 → 249/64) ⇝ 4/1 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 15/4 ⇜ (31/8 → 249/64) ⇝ 4/1 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 15/4 ⇜ (31/8 → 249/64) ⇝ 4/1 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 15/4 ⇜ (31/8 → 249/64) ⇝ 4/1 | note:C5 gain:0.22 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 15/4 ⇜ (249/64 → 125/32) ⇝ 4/1 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 15/4 ⇜ (249/64 → 125/32) ⇝ 4/1 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 15/4 ⇜ (249/64 → 125/32) ⇝ 4/1 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 15/4 ⇜ (249/64 → 125/32) ⇝ 4/1 | note:C5 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 15/4 ⇜ (125/32 → 251/64) ⇝ 4/1 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 15/4 ⇜ (125/32 → 251/64) ⇝ 4/1 | note:G4 gain:0.32 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 15/4 ⇜ (125/32 → 251/64) ⇝ 4/1 | note:Ab4 gain:0.32 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 15/4 ⇜ (125/32 → 251/64) ⇝ 4/1 | note:C5 gain:0.32 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 15/4 ⇜ (251/64 → 63/16) ⇝ 4/1 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 15/4 ⇜ (251/64 → 63/16) ⇝ 4/1 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 15/4 ⇜ (251/64 → 63/16) ⇝ 4/1 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 15/4 ⇜ (251/64 → 63/16) ⇝ 4/1 | note:C5 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 15/4 ⇜ (63/16 → 253/64) ⇝ 4/1 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 15/4 ⇜ (63/16 → 253/64) ⇝ 4/1 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 15/4 ⇜ (63/16 → 253/64) ⇝ 4/1 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 15/4 ⇜ (63/16 → 253/64) ⇝ 4/1 | note:C5 gain:0.22 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 15/4 ⇜ (253/64 → 127/32) ⇝ 4/1 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 15/4 ⇜ (253/64 → 127/32) ⇝ 4/1 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 15/4 ⇜ (253/64 → 127/32) ⇝ 4/1 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 15/4 ⇜ (253/64 → 127/32) ⇝ 4/1 | note:C5 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 15/4 ⇜ (127/32 → 255/64) ⇝ 4/1 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 15/4 ⇜ (127/32 → 255/64) ⇝ 4/1 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 15/4 ⇜ (127/32 → 255/64) ⇝ 4/1 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 15/4 ⇜ (127/32 → 255/64) ⇝ 4/1 | note:C5 gain:0.12 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 15/4 ⇜ (255/64 → 4/1) | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 15/4 ⇜ (255/64 → 4/1) | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 15/4 ⇜ (255/64 → 4/1) | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 15/4 ⇜ (255/64 → 4/1) | note:C5 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ (4/1 → 257/64) ⇝ 17/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 4/1 ⇜ (257/64 → 129/32) ⇝ 17/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 4/1 ⇜ (129/32 → 259/64) ⇝ 17/4 | note:G2 gain:0.64 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ (113/28 → 259/64) ⇝ 30/7 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ (113/28 → 259/64) ⇝ 30/7 | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ (113/28 → 259/64) ⇝ 30/7 | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ (113/28 → 259/64) ⇝ 30/7 | note:84 gain:0.064 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 4/1 ⇜ (259/64 → 65/16) ⇝ 17/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 113/28 ⇜ (259/64 → 65/16) ⇝ 30/7 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 113/28 ⇜ (259/64 → 65/16) ⇝ 30/7 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 113/28 ⇜ (259/64 → 65/16) ⇝ 30/7 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 113/28 ⇜ (259/64 → 65/16) ⇝ 30/7 | note:84 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 4/1 ⇜ (65/16 → 261/64) ⇝ 17/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 113/28 ⇜ (65/16 → 261/64) ⇝ 30/7 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 113/28 ⇜ (65/16 → 261/64) ⇝ 30/7 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 113/28 ⇜ (65/16 → 261/64) ⇝ 30/7 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 113/28 ⇜ (65/16 → 261/64) ⇝ 30/7 | note:84 gain:0.044 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 4/1 ⇜ (261/64 → 131/32) ⇝ 17/4 | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 113/28 ⇜ (261/64 → 131/32) ⇝ 30/7 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 113/28 ⇜ (261/64 → 131/32) ⇝ 30/7 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 113/28 ⇜ (261/64 → 131/32) ⇝ 30/7 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 113/28 ⇜ (261/64 → 131/32) ⇝ 30/7 | note:84 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 4/1 ⇜ (131/32 → 263/64) ⇝ 17/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 113/28 ⇜ (131/32 → 263/64) ⇝ 30/7 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 113/28 ⇜ (131/32 → 263/64) ⇝ 30/7 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 113/28 ⇜ (131/32 → 263/64) ⇝ 30/7 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 113/28 ⇜ (131/32 → 263/64) ⇝ 30/7 | note:84 gain:0.024 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 4/1 ⇜ (263/64 → 33/8) ⇝ 17/4 | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 113/28 ⇜ (263/64 → 33/8) ⇝ 30/7 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 113/28 ⇜ (263/64 → 33/8) ⇝ 30/7 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 113/28 ⇜ (263/64 → 33/8) ⇝ 30/7 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 113/28 ⇜ (263/64 → 33/8) ⇝ 30/7 | note:84 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 4/1 ⇜ (33/8 → 265/64) ⇝ 17/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 113/28 ⇜ (33/8 → 265/64) ⇝ 30/7 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 113/28 ⇜ (33/8 → 265/64) ⇝ 30/7 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 113/28 ⇜ (33/8 → 265/64) ⇝ 30/7 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 113/28 ⇜ (33/8 → 265/64) ⇝ 30/7 | note:84 gain:0.044 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ (33/8 → 265/64) ⇝ 17/4 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (33/8 → 265/64) ⇝ 17/4 | note:Bb4 gain:0.44 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 4/1 ⇜ (265/64 → 133/32) ⇝ 17/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 113/28 ⇜ (265/64 → 133/32) ⇝ 30/7 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 113/28 ⇜ (265/64 → 133/32) ⇝ 30/7 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 113/28 ⇜ (265/64 → 133/32) ⇝ 30/7 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 113/28 ⇜ (265/64 → 133/32) ⇝ 30/7 | note:84 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 33/8 ⇜ (265/64 → 133/32) ⇝ 17/4 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 33/8 ⇜ (265/64 → 133/32) ⇝ 17/4 | note:Bb4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 4/1 ⇜ (133/32 → 267/64) ⇝ 17/4 | note:G2 gain:0.64 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 113/28 ⇜ (133/32 → 267/64) ⇝ 30/7 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 113/28 ⇜ (133/32 → 267/64) ⇝ 30/7 | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 113/28 ⇜ (133/32 → 267/64) ⇝ 30/7 | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 113/28 ⇜ (133/32 → 267/64) ⇝ 30/7 | note:84 gain:0.064 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 33/8 ⇜ (133/32 → 267/64) ⇝ 17/4 | note:G4 gain:0.64 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 33/8 ⇜ (133/32 → 267/64) ⇝ 17/4 | note:Bb4 gain:0.64 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 4/1 ⇜ (267/64 → 67/16) ⇝ 17/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 113/28 ⇜ (267/64 → 67/16) ⇝ 30/7 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 113/28 ⇜ (267/64 → 67/16) ⇝ 30/7 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 113/28 ⇜ (267/64 → 67/16) ⇝ 30/7 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 113/28 ⇜ (267/64 → 67/16) ⇝ 30/7 | note:84 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 33/8 ⇜ (267/64 → 67/16) ⇝ 17/4 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 33/8 ⇜ (267/64 → 67/16) ⇝ 17/4 | note:Bb4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 4/1 ⇜ (67/16 → 269/64) ⇝ 17/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 113/28 ⇜ (67/16 → 269/64) ⇝ 30/7 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 113/28 ⇜ (67/16 → 269/64) ⇝ 30/7 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 113/28 ⇜ (67/16 → 269/64) ⇝ 30/7 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 113/28 ⇜ (67/16 → 269/64) ⇝ 30/7 | note:84 gain:0.044 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 33/8 ⇜ (67/16 → 269/64) ⇝ 17/4 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 33/8 ⇜ (67/16 → 269/64) ⇝ 17/4 | note:Bb4 gain:0.44 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 4/1 ⇜ (269/64 → 135/32) ⇝ 17/4 | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 113/28 ⇜ (269/64 → 135/32) ⇝ 30/7 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 113/28 ⇜ (269/64 → 135/32) ⇝ 30/7 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 113/28 ⇜ (269/64 → 135/32) ⇝ 30/7 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 113/28 ⇜ (269/64 → 135/32) ⇝ 30/7 | note:84 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 33/8 ⇜ (269/64 → 135/32) ⇝ 17/4 | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 33/8 ⇜ (269/64 → 135/32) ⇝ 17/4 | note:Bb4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 4/1 ⇜ (135/32 → 271/64) ⇝ 17/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 113/28 ⇜ (135/32 → 271/64) ⇝ 30/7 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 113/28 ⇜ (135/32 → 271/64) ⇝ 30/7 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 113/28 ⇜ (135/32 → 271/64) ⇝ 30/7 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 113/28 ⇜ (135/32 → 271/64) ⇝ 30/7 | note:84 gain:0.024 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 33/8 ⇜ (135/32 → 271/64) ⇝ 17/4 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 33/8 ⇜ (135/32 → 271/64) ⇝ 17/4 | note:Bb4 gain:0.24 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 4/1 ⇜ (271/64 → 17/4) | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 113/28 ⇜ (271/64 → 17/4) ⇝ 30/7 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 113/28 ⇜ (271/64 → 17/4) ⇝ 30/7 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 113/28 ⇜ (271/64 → 17/4) ⇝ 30/7 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 113/28 ⇜ (271/64 → 17/4) ⇝ 30/7 | note:84 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 33/8 ⇜ (271/64 → 17/4) | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 33/8 ⇜ (271/64 → 17/4) | note:Bb4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 113/28 ⇜ (17/4 → 273/64) ⇝ 30/7 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 113/28 ⇜ (17/4 → 273/64) ⇝ 30/7 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 113/28 ⇜ (17/4 → 273/64) ⇝ 30/7 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 113/28 ⇜ (17/4 → 273/64) ⇝ 30/7 | note:84 gain:0.044 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 113/28 ⇜ (273/64 → 137/32) ⇝ 30/7 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 113/28 ⇜ (273/64 → 137/32) ⇝ 30/7 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 113/28 ⇜ (273/64 → 137/32) ⇝ 30/7 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 113/28 ⇜ (273/64 → 137/32) ⇝ 30/7 | note:84 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 113/28 ⇜ (137/32 → 30/7) | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 113/28 ⇜ (137/32 → 30/7) | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 113/28 ⇜ (137/32 → 30/7) | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 113/28 ⇜ (137/32 → 30/7) | note:84 gain:0.064 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ (9/2 → 289/64) ⇝ 37/8 | note:D5 gain:0.44 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ (9/2 → 289/64) ⇝ 37/8 | note:F5 gain:0.44 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ (9/2 → 289/64) ⇝ 19/4 | note:B3 gain:0.22 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ (9/2 → 289/64) ⇝ 19/4 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (9/2 → 289/64) ⇝ 19/4 | note:F4 gain:0.22 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ (9/2 → 289/64) ⇝ 19/4 | note:A4 gain:0.22 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ (9/2 → 289/64) ⇝ 19/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 9/2 ⇜ (289/64 → 145/32) ⇝ 37/8 | note:D5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 9/2 ⇜ (289/64 → 145/32) ⇝ 37/8 | note:F5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 9/2 ⇜ (289/64 → 145/32) ⇝ 19/4 | note:B3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 9/2 ⇜ (289/64 → 145/32) ⇝ 19/4 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 9/2 ⇜ (289/64 → 145/32) ⇝ 19/4 | note:F4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 9/2 ⇜ (289/64 → 145/32) ⇝ 19/4 | note:A4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 9/2 ⇜ (289/64 → 145/32) ⇝ 19/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 9/2 ⇜ (145/32 → 291/64) ⇝ 37/8 | note:D5 gain:0.64 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 9/2 ⇜ (145/32 → 291/64) ⇝ 37/8 | note:F5 gain:0.64 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 9/2 ⇜ (145/32 → 291/64) ⇝ 19/4 | note:B3 gain:0.32 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 9/2 ⇜ (145/32 → 291/64) ⇝ 19/4 | note:E4 gain:0.32 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 9/2 ⇜ (145/32 → 291/64) ⇝ 19/4 | note:F4 gain:0.32 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 9/2 ⇜ (145/32 → 291/64) ⇝ 19/4 | note:A4 gain:0.32 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 9/2 ⇜ (145/32 → 291/64) ⇝ 19/4 | note:G2 gain:0.64 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 9/2 ⇜ (291/64 → 73/16) ⇝ 37/8 | note:D5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 9/2 ⇜ (291/64 → 73/16) ⇝ 37/8 | note:F5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 9/2 ⇜ (291/64 → 73/16) ⇝ 19/4 | note:B3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 9/2 ⇜ (291/64 → 73/16) ⇝ 19/4 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 9/2 ⇜ (291/64 → 73/16) ⇝ 19/4 | note:F4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 9/2 ⇜ (291/64 → 73/16) ⇝ 19/4 | note:A4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 9/2 ⇜ (291/64 → 73/16) ⇝ 19/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 9/2 ⇜ (73/16 → 293/64) ⇝ 37/8 | note:D5 gain:0.44 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 9/2 ⇜ (73/16 → 293/64) ⇝ 37/8 | note:F5 gain:0.44 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 9/2 ⇜ (73/16 → 293/64) ⇝ 19/4 | note:B3 gain:0.22 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 9/2 ⇜ (73/16 → 293/64) ⇝ 19/4 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 9/2 ⇜ (73/16 → 293/64) ⇝ 19/4 | note:F4 gain:0.22 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 9/2 ⇜ (73/16 → 293/64) ⇝ 19/4 | note:A4 gain:0.22 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 9/2 ⇜ (73/16 → 293/64) ⇝ 19/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 9/2 ⇜ (293/64 → 147/32) ⇝ 37/8 | note:D5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 9/2 ⇜ (293/64 → 147/32) ⇝ 37/8 | note:F5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 9/2 ⇜ (293/64 → 147/32) ⇝ 19/4 | note:B3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 9/2 ⇜ (293/64 → 147/32) ⇝ 19/4 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 9/2 ⇜ (293/64 → 147/32) ⇝ 19/4 | note:F4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 9/2 ⇜ (293/64 → 147/32) ⇝ 19/4 | note:A4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 9/2 ⇜ (293/64 → 147/32) ⇝ 19/4 | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 9/2 ⇜ (147/32 → 295/64) ⇝ 37/8 | note:D5 gain:0.24 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 9/2 ⇜ (147/32 → 295/64) ⇝ 37/8 | note:F5 gain:0.24 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 9/2 ⇜ (147/32 → 295/64) ⇝ 19/4 | note:B3 gain:0.12 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 9/2 ⇜ (147/32 → 295/64) ⇝ 19/4 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 9/2 ⇜ (147/32 → 295/64) ⇝ 19/4 | note:F4 gain:0.12 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 9/2 ⇜ (147/32 → 295/64) ⇝ 19/4 | note:A4 gain:0.12 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 9/2 ⇜ (147/32 → 295/64) ⇝ 19/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 9/2 ⇜ (295/64 → 37/8) | note:D5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 9/2 ⇜ (295/64 → 37/8) | note:F5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 9/2 ⇜ (295/64 → 37/8) ⇝ 19/4 | note:B3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 9/2 ⇜ (295/64 → 37/8) ⇝ 19/4 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 9/2 ⇜ (295/64 → 37/8) ⇝ 19/4 | note:F4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 9/2 ⇜ (295/64 → 37/8) ⇝ 19/4 | note:A4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 9/2 ⇜ (295/64 → 37/8) ⇝ 19/4 | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 9/2 ⇜ (37/8 → 297/64) ⇝ 19/4 | note:B3 gain:0.22 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 9/2 ⇜ (37/8 → 297/64) ⇝ 19/4 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 9/2 ⇜ (37/8 → 297/64) ⇝ 19/4 | note:F4 gain:0.22 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 9/2 ⇜ (37/8 → 297/64) ⇝ 19/4 | note:A4 gain:0.22 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 9/2 ⇜ (37/8 → 297/64) ⇝ 19/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 9/2 ⇜ (297/64 → 149/32) ⇝ 19/4 | note:B3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 9/2 ⇜ (297/64 → 149/32) ⇝ 19/4 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 9/2 ⇜ (297/64 → 149/32) ⇝ 19/4 | note:F4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 9/2 ⇜ (297/64 → 149/32) ⇝ 19/4 | note:A4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 9/2 ⇜ (297/64 → 149/32) ⇝ 19/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 9/2 ⇜ (149/32 → 299/64) ⇝ 19/4 | note:B3 gain:0.32 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 9/2 ⇜ (149/32 → 299/64) ⇝ 19/4 | note:E4 gain:0.32 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 9/2 ⇜ (149/32 → 299/64) ⇝ 19/4 | note:F4 gain:0.32 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 9/2 ⇜ (149/32 → 299/64) ⇝ 19/4 | note:A4 gain:0.32 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 9/2 ⇜ (149/32 → 299/64) ⇝ 19/4 | note:G2 gain:0.64 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 9/2 ⇜ (299/64 → 75/16) ⇝ 19/4 | note:B3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 9/2 ⇜ (299/64 → 75/16) ⇝ 19/4 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 9/2 ⇜ (299/64 → 75/16) ⇝ 19/4 | note:F4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 9/2 ⇜ (299/64 → 75/16) ⇝ 19/4 | note:A4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 9/2 ⇜ (299/64 → 75/16) ⇝ 19/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 9/2 ⇜ (75/16 → 301/64) ⇝ 19/4 | note:B3 gain:0.22 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 9/2 ⇜ (75/16 → 301/64) ⇝ 19/4 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 9/2 ⇜ (75/16 → 301/64) ⇝ 19/4 | note:F4 gain:0.22 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 9/2 ⇜ (75/16 → 301/64) ⇝ 19/4 | note:A4 gain:0.22 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 9/2 ⇜ (75/16 → 301/64) ⇝ 19/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 9/2 ⇜ (301/64 → 151/32) ⇝ 19/4 | note:B3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 9/2 ⇜ (301/64 → 151/32) ⇝ 19/4 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 9/2 ⇜ (301/64 → 151/32) ⇝ 19/4 | note:F4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 9/2 ⇜ (301/64 → 151/32) ⇝ 19/4 | note:A4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 9/2 ⇜ (301/64 → 151/32) ⇝ 19/4 | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 9/2 ⇜ (151/32 → 303/64) ⇝ 19/4 | note:B3 gain:0.12 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 9/2 ⇜ (151/32 → 303/64) ⇝ 19/4 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 9/2 ⇜ (151/32 → 303/64) ⇝ 19/4 | note:F4 gain:0.12 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 9/2 ⇜ (151/32 → 303/64) ⇝ 19/4 | note:A4 gain:0.12 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 9/2 ⇜ (151/32 → 303/64) ⇝ 19/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 9/2 ⇜ (303/64 → 19/4) | note:B3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 9/2 ⇜ (303/64 → 19/4) | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 9/2 ⇜ (303/64 → 19/4) | note:F4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 9/2 ⇜ (303/64 → 19/4) | note:A4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 9/2 ⇜ (303/64 → 19/4) | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ (19/4 → 305/64) ⇝ 39/8 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (19/4 → 305/64) ⇝ 39/8 | note:Bb4 gain:0.44 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 19/4 ⇜ (305/64 → 153/32) ⇝ 39/8 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 19/4 ⇜ (305/64 → 153/32) ⇝ 39/8 | note:Bb4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 19/4 ⇜ (153/32 → 307/64) ⇝ 39/8 | note:G4 gain:0.64 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 19/4 ⇜ (153/32 → 307/64) ⇝ 39/8 | note:Bb4 gain:0.64 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ (67/14 → 307/64) ⇝ 141/28 | note:71 gain:0.064 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ (67/14 → 307/64) ⇝ 141/28 | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ (67/14 → 307/64) ⇝ 141/28 | note:77 gain:0.064 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ (67/14 → 307/64) ⇝ 141/28 | note:81 gain:0.064 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 19/4 ⇜ (307/64 → 77/16) ⇝ 39/8 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 19/4 ⇜ (307/64 → 77/16) ⇝ 39/8 | note:Bb4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 67/14 ⇜ (307/64 → 77/16) ⇝ 141/28 | note:71 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 67/14 ⇜ (307/64 → 77/16) ⇝ 141/28 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 67/14 ⇜ (307/64 → 77/16) ⇝ 141/28 | note:77 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 67/14 ⇜ (307/64 → 77/16) ⇝ 141/28 | note:81 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 19/4 ⇜ (77/16 → 309/64) ⇝ 39/8 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 19/4 ⇜ (77/16 → 309/64) ⇝ 39/8 | note:Bb4 gain:0.44 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 67/14 ⇜ (77/16 → 309/64) ⇝ 141/28 | note:71 gain:0.044 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 67/14 ⇜ (77/16 → 309/64) ⇝ 141/28 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 67/14 ⇜ (77/16 → 309/64) ⇝ 141/28 | note:77 gain:0.044 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 67/14 ⇜ (77/16 → 309/64) ⇝ 141/28 | note:81 gain:0.044 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 19/4 ⇜ (309/64 → 155/32) ⇝ 39/8 | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 19/4 ⇜ (309/64 → 155/32) ⇝ 39/8 | note:Bb4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 67/14 ⇜ (309/64 → 155/32) ⇝ 141/28 | note:71 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 67/14 ⇜ (309/64 → 155/32) ⇝ 141/28 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 67/14 ⇜ (309/64 → 155/32) ⇝ 141/28 | note:77 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 67/14 ⇜ (309/64 → 155/32) ⇝ 141/28 | note:81 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 19/4 ⇜ (155/32 → 311/64) ⇝ 39/8 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 19/4 ⇜ (155/32 → 311/64) ⇝ 39/8 | note:Bb4 gain:0.24 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 67/14 ⇜ (155/32 → 311/64) ⇝ 141/28 | note:71 gain:0.024 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 67/14 ⇜ (155/32 → 311/64) ⇝ 141/28 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 67/14 ⇜ (155/32 → 311/64) ⇝ 141/28 | note:77 gain:0.024 clip:1 s:piano release:0.1 pan:0.606481481481 ]", "[ 67/14 ⇜ (155/32 → 311/64) ⇝ 141/28 | note:81 gain:0.024 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 19/4 ⇜ (311/64 → 39/8) | note:G4 gain:0.2985786437626885 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 19/4 ⇜ (311/64 → 39/8) | note:Bb4 gain:0.2985786437626885 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 67/14 ⇜ (311/64 → 39/8) ⇝ 141/28 | note:71 gain:0.02985786437626885 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 67/14 ⇜ (311/64 → 39/8) ⇝ 141/28 | note:76 gain:0.02985786437626885 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 67/14 ⇜ (311/64 → 39/8) ⇝ 141/28 | note:77 gain:0.02985786437626885 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 67/14 ⇜ (311/64 → 39/8) ⇝ 141/28 | note:81 gain:0.02985786437626885 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 67/14 ⇜ (39/8 → 313/64) ⇝ 141/28 | note:71 gain:0.04399999999999967 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 67/14 ⇜ (39/8 → 313/64) ⇝ 141/28 | note:76 gain:0.04399999999999967 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 67/14 ⇜ (39/8 → 313/64) ⇝ 141/28 | note:77 gain:0.04399999999999967 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 67/14 ⇜ (39/8 → 313/64) ⇝ 141/28 | note:81 gain:0.04399999999999967 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 67/14 ⇜ (313/64 → 157/32) ⇝ 141/28 | note:71 gain:0.05814213562373069 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 67/14 ⇜ (313/64 → 157/32) ⇝ 141/28 | note:76 gain:0.05814213562373069 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 67/14 ⇜ (313/64 → 157/32) ⇝ 141/28 | note:77 gain:0.05814213562373069 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 67/14 ⇜ (313/64 → 157/32) ⇝ 141/28 | note:81 gain:0.05814213562373069 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 67/14 ⇜ (157/32 → 315/64) ⇝ 141/28 | note:71 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 67/14 ⇜ (157/32 → 315/64) ⇝ 141/28 | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 67/14 ⇜ (157/32 → 315/64) ⇝ 141/28 | note:77 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 67/14 ⇜ (157/32 → 315/64) ⇝ 141/28 | note:81 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 67/14 ⇜ (315/64 → 79/16) ⇝ 141/28 | note:71 gain:0.0581421356237309 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 67/14 ⇜ (315/64 → 79/16) ⇝ 141/28 | note:76 gain:0.0581421356237309 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 67/14 ⇜ (315/64 → 79/16) ⇝ 141/28 | note:77 gain:0.0581421356237309 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 67/14 ⇜ (315/64 → 79/16) ⇝ 141/28 | note:81 gain:0.0581421356237309 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 67/14 ⇜ (79/16 → 317/64) ⇝ 141/28 | note:71 gain:0.043999999999999984 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 67/14 ⇜ (79/16 → 317/64) ⇝ 141/28 | note:76 gain:0.043999999999999984 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 67/14 ⇜ (79/16 → 317/64) ⇝ 141/28 | note:77 gain:0.043999999999999984 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 67/14 ⇜ (79/16 → 317/64) ⇝ 141/28 | note:81 gain:0.043999999999999984 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 67/14 ⇜ (317/64 → 159/32) ⇝ 141/28 | note:71 gain:0.029857864376269073 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 67/14 ⇜ (317/64 → 159/32) ⇝ 141/28 | note:76 gain:0.029857864376269073 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 67/14 ⇜ (317/64 → 159/32) ⇝ 141/28 | note:77 gain:0.029857864376269073 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 67/14 ⇜ (317/64 → 159/32) ⇝ 141/28 | note:81 gain:0.029857864376269073 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 67/14 ⇜ (159/32 → 319/64) ⇝ 141/28 | note:71 gain:0.024 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 67/14 ⇜ (159/32 → 319/64) ⇝ 141/28 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 67/14 ⇜ (159/32 → 319/64) ⇝ 141/28 | note:77 gain:0.024 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", + "[ 19/4 ⇜ (311/64 → 39/8) | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 19/4 ⇜ (311/64 → 39/8) | note:Bb4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 67/14 ⇜ (311/64 → 39/8) ⇝ 141/28 | note:71 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 67/14 ⇜ (311/64 → 39/8) ⇝ 141/28 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 67/14 ⇜ (311/64 → 39/8) ⇝ 141/28 | note:77 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 67/14 ⇜ (311/64 → 39/8) ⇝ 141/28 | note:81 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 67/14 ⇜ (39/8 → 313/64) ⇝ 141/28 | note:71 gain:0.044 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 67/14 ⇜ (39/8 → 313/64) ⇝ 141/28 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 67/14 ⇜ (39/8 → 313/64) ⇝ 141/28 | note:77 gain:0.044 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 67/14 ⇜ (39/8 → 313/64) ⇝ 141/28 | note:81 gain:0.044 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 67/14 ⇜ (313/64 → 157/32) ⇝ 141/28 | note:71 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 67/14 ⇜ (313/64 → 157/32) ⇝ 141/28 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 67/14 ⇜ (313/64 → 157/32) ⇝ 141/28 | note:77 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 67/14 ⇜ (313/64 → 157/32) ⇝ 141/28 | note:81 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 67/14 ⇜ (157/32 → 315/64) ⇝ 141/28 | note:71 gain:0.064 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 67/14 ⇜ (157/32 → 315/64) ⇝ 141/28 | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 67/14 ⇜ (157/32 → 315/64) ⇝ 141/28 | note:77 gain:0.064 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 67/14 ⇜ (157/32 → 315/64) ⇝ 141/28 | note:81 gain:0.064 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 67/14 ⇜ (315/64 → 79/16) ⇝ 141/28 | note:71 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 67/14 ⇜ (315/64 → 79/16) ⇝ 141/28 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 67/14 ⇜ (315/64 → 79/16) ⇝ 141/28 | note:77 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 67/14 ⇜ (315/64 → 79/16) ⇝ 141/28 | note:81 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 67/14 ⇜ (79/16 → 317/64) ⇝ 141/28 | note:71 gain:0.044 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 67/14 ⇜ (79/16 → 317/64) ⇝ 141/28 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 67/14 ⇜ (79/16 → 317/64) ⇝ 141/28 | note:77 gain:0.044 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 67/14 ⇜ (79/16 → 317/64) ⇝ 141/28 | note:81 gain:0.044 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 67/14 ⇜ (317/64 → 159/32) ⇝ 141/28 | note:71 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 67/14 ⇜ (317/64 → 159/32) ⇝ 141/28 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 67/14 ⇜ (317/64 → 159/32) ⇝ 141/28 | note:77 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 67/14 ⇜ (317/64 → 159/32) ⇝ 141/28 | note:81 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 67/14 ⇜ (159/32 → 319/64) ⇝ 141/28 | note:71 gain:0.024 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 67/14 ⇜ (159/32 → 319/64) ⇝ 141/28 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 67/14 ⇜ (159/32 → 319/64) ⇝ 141/28 | note:77 gain:0.024 clip:1 s:piano release:0.1 pan:0.606481481481 ]", "[ 67/14 ⇜ (159/32 → 319/64) ⇝ 141/28 | note:81 gain:0.024 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 67/14 ⇜ (319/64 → 5/1) ⇝ 141/28 | note:71 gain:0.02985786437626895 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 67/14 ⇜ (319/64 → 5/1) ⇝ 141/28 | note:76 gain:0.02985786437626895 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 67/14 ⇜ (319/64 → 5/1) ⇝ 141/28 | note:77 gain:0.02985786437626895 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 67/14 ⇜ (319/64 → 5/1) ⇝ 141/28 | note:81 gain:0.02985786437626895 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 67/14 ⇜ (5/1 → 321/64) ⇝ 141/28 | note:71 gain:0.04399999999999982 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 67/14 ⇜ (5/1 → 321/64) ⇝ 141/28 | note:76 gain:0.04399999999999982 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 67/14 ⇜ (5/1 → 321/64) ⇝ 141/28 | note:77 gain:0.04399999999999982 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 67/14 ⇜ (5/1 → 321/64) ⇝ 141/28 | note:81 gain:0.04399999999999982 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ (5/1 → 321/64) ⇝ 21/4 | note:G2 gain:0.4399999999999981 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 67/14 ⇜ (321/64 → 161/32) ⇝ 141/28 | note:71 gain:0.05814213562373077 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 67/14 ⇜ (321/64 → 161/32) ⇝ 141/28 | note:76 gain:0.05814213562373077 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 67/14 ⇜ (321/64 → 161/32) ⇝ 141/28 | note:77 gain:0.05814213562373077 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 67/14 ⇜ (321/64 → 161/32) ⇝ 141/28 | note:81 gain:0.05814213562373077 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 5/1 ⇜ (321/64 → 161/32) ⇝ 21/4 | note:G2 gain:0.5814213562373077 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 67/14 ⇜ (161/32 → 141/28) | note:71 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 67/14 ⇜ (161/32 → 141/28) | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 67/14 ⇜ (161/32 → 141/28) | note:77 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 67/14 ⇜ (161/32 → 141/28) | note:81 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 5/1 ⇜ (161/32 → 323/64) ⇝ 21/4 | note:G2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 5/1 ⇜ (323/64 → 81/16) ⇝ 21/4 | note:G2 gain:0.5814213562373121 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 5/1 ⇜ (81/16 → 325/64) ⇝ 21/4 | note:G2 gain:0.44000000000000417 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 5/1 ⇜ (325/64 → 163/32) ⇝ 21/4 | note:G2 gain:0.2985786437626938 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 5/1 ⇜ (163/32 → 327/64) ⇝ 21/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 5/1 ⇜ (327/64 → 41/8) ⇝ 21/4 | note:G2 gain:0.29857864376269044 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 5/1 ⇜ (41/8 → 329/64) ⇝ 21/4 | note:G2 gain:0.43999999999999373 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ (41/8 → 329/64) ⇝ 21/4 | note:G4 gain:0.43999999999999373 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (41/8 → 329/64) ⇝ 21/4 | note:Bb4 gain:0.43999999999999373 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 5/1 ⇜ (329/64 → 165/32) ⇝ 21/4 | note:G2 gain:0.5814213562373087 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 41/8 ⇜ (329/64 → 165/32) ⇝ 21/4 | note:G4 gain:0.5814213562373087 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 41/8 ⇜ (329/64 → 165/32) ⇝ 21/4 | note:Bb4 gain:0.5814213562373087 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 5/1 ⇜ (165/32 → 331/64) ⇝ 21/4 | note:G2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 41/8 ⇜ (165/32 → 331/64) ⇝ 21/4 | note:G4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 41/8 ⇜ (165/32 → 331/64) ⇝ 21/4 | note:Bb4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 5/1 ⇜ (331/64 → 83/16) ⇝ 21/4 | note:G2 gain:0.5814213562373111 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 41/8 ⇜ (331/64 → 83/16) ⇝ 21/4 | note:G4 gain:0.5814213562373111 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 41/8 ⇜ (331/64 → 83/16) ⇝ 21/4 | note:Bb4 gain:0.5814213562373111 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 5/1 ⇜ (83/16 → 333/64) ⇝ 21/4 | note:G2 gain:0.43999999999999706 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 41/8 ⇜ (83/16 → 333/64) ⇝ 21/4 | note:G4 gain:0.43999999999999706 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 41/8 ⇜ (83/16 → 333/64) ⇝ 21/4 | note:Bb4 gain:0.43999999999999706 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 5/1 ⇜ (333/64 → 167/32) ⇝ 21/4 | note:G2 gain:0.29857864376269283 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 41/8 ⇜ (333/64 → 167/32) ⇝ 21/4 | note:G4 gain:0.29857864376269283 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 41/8 ⇜ (333/64 → 167/32) ⇝ 21/4 | note:Bb4 gain:0.29857864376269283 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 5/1 ⇜ (167/32 → 335/64) ⇝ 21/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 41/8 ⇜ (167/32 → 335/64) ⇝ 21/4 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 41/8 ⇜ (167/32 → 335/64) ⇝ 21/4 | note:Bb4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 5/1 ⇜ (335/64 → 21/4) | note:G2 gain:0.2985786437626874 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 41/8 ⇜ (335/64 → 21/4) | note:G4 gain:0.2985786437626874 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 41/8 ⇜ (335/64 → 21/4) | note:Bb4 gain:0.2985786437626874 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ (21/4 → 337/64) ⇝ 11/2 | note:B3 gain:0.2200000000000004 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ (21/4 → 337/64) ⇝ 11/2 | note:E4 gain:0.2200000000000004 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (21/4 → 337/64) ⇝ 11/2 | note:F4 gain:0.2200000000000004 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (21/4 → 337/64) ⇝ 11/2 | note:A4 gain:0.2200000000000004 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 21/4 ⇜ (337/64 → 169/32) ⇝ 11/2 | note:B3 gain:0.29071067811865287 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 21/4 ⇜ (337/64 → 169/32) ⇝ 11/2 | note:E4 gain:0.29071067811865287 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 21/4 ⇜ (337/64 → 169/32) ⇝ 11/2 | note:F4 gain:0.29071067811865287 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 21/4 ⇜ (337/64 → 169/32) ⇝ 11/2 | note:A4 gain:0.29071067811865287 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 21/4 ⇜ (169/32 → 339/64) ⇝ 11/2 | note:B3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 21/4 ⇜ (169/32 → 339/64) ⇝ 11/2 | note:E4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 21/4 ⇜ (169/32 → 339/64) ⇝ 11/2 | note:F4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 21/4 ⇜ (169/32 → 339/64) ⇝ 11/2 | note:A4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 21/4 ⇜ (339/64 → 85/16) ⇝ 11/2 | note:B3 gain:0.29071067811865703 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 21/4 ⇜ (339/64 → 85/16) ⇝ 11/2 | note:E4 gain:0.29071067811865703 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 21/4 ⇜ (339/64 → 85/16) ⇝ 11/2 | note:F4 gain:0.29071067811865703 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 21/4 ⇜ (339/64 → 85/16) ⇝ 11/2 | note:A4 gain:0.29071067811865703 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 21/4 ⇜ (85/16 → 341/64) ⇝ 11/2 | note:B3 gain:0.2200000000000007 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 21/4 ⇜ (85/16 → 341/64) ⇝ 11/2 | note:E4 gain:0.2200000000000007 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 21/4 ⇜ (85/16 → 341/64) ⇝ 11/2 | note:F4 gain:0.2200000000000007 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 21/4 ⇜ (85/16 → 341/64) ⇝ 11/2 | note:A4 gain:0.2200000000000007 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 21/4 ⇜ (341/64 → 171/32) ⇝ 11/2 | note:B3 gain:0.14928932188134794 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 21/4 ⇜ (341/64 → 171/32) ⇝ 11/2 | note:E4 gain:0.14928932188134794 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 21/4 ⇜ (341/64 → 171/32) ⇝ 11/2 | note:F4 gain:0.14928932188134794 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 21/4 ⇜ (341/64 → 171/32) ⇝ 11/2 | note:A4 gain:0.14928932188134794 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 21/4 ⇜ (171/32 → 343/64) ⇝ 11/2 | note:B3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 21/4 ⇜ (171/32 → 343/64) ⇝ 11/2 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 21/4 ⇜ (171/32 → 343/64) ⇝ 11/2 | note:F4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 21/4 ⇜ (171/32 → 343/64) ⇝ 11/2 | note:A4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 21/4 ⇜ (343/64 → 43/8) ⇝ 11/2 | note:B3 gain:0.14928932188134622 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 21/4 ⇜ (343/64 → 43/8) ⇝ 11/2 | note:E4 gain:0.14928932188134622 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 21/4 ⇜ (343/64 → 43/8) ⇝ 11/2 | note:F4 gain:0.14928932188134622 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 21/4 ⇜ (343/64 → 43/8) ⇝ 11/2 | note:A4 gain:0.14928932188134622 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 21/4 ⇜ (43/8 → 345/64) ⇝ 11/2 | note:B3 gain:0.21999999999999825 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 21/4 ⇜ (43/8 → 345/64) ⇝ 11/2 | note:E4 gain:0.21999999999999825 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 21/4 ⇜ (43/8 → 345/64) ⇝ 11/2 | note:F4 gain:0.21999999999999825 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 21/4 ⇜ (43/8 → 345/64) ⇝ 11/2 | note:A4 gain:0.21999999999999825 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 21/4 ⇜ (345/64 → 173/32) ⇝ 11/2 | note:B3 gain:0.29071067811865536 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 21/4 ⇜ (345/64 → 173/32) ⇝ 11/2 | note:E4 gain:0.29071067811865536 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 21/4 ⇜ (345/64 → 173/32) ⇝ 11/2 | note:F4 gain:0.29071067811865536 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 21/4 ⇜ (345/64 → 173/32) ⇝ 11/2 | note:A4 gain:0.29071067811865536 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 21/4 ⇜ (173/32 → 347/64) ⇝ 11/2 | note:B3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 21/4 ⇜ (173/32 → 347/64) ⇝ 11/2 | note:E4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 21/4 ⇜ (173/32 → 347/64) ⇝ 11/2 | note:F4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 21/4 ⇜ (173/32 → 347/64) ⇝ 11/2 | note:A4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 21/4 ⇜ (347/64 → 87/16) ⇝ 11/2 | note:B3 gain:0.29071067811865453 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 21/4 ⇜ (347/64 → 87/16) ⇝ 11/2 | note:E4 gain:0.29071067811865453 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 21/4 ⇜ (347/64 → 87/16) ⇝ 11/2 | note:F4 gain:0.29071067811865453 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 21/4 ⇜ (347/64 → 87/16) ⇝ 11/2 | note:A4 gain:0.29071067811865453 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 21/4 ⇜ (87/16 → 349/64) ⇝ 11/2 | note:B3 gain:0.22000000000000286 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 21/4 ⇜ (87/16 → 349/64) ⇝ 11/2 | note:E4 gain:0.22000000000000286 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 21/4 ⇜ (87/16 → 349/64) ⇝ 11/2 | note:F4 gain:0.22000000000000286 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 21/4 ⇜ (87/16 → 349/64) ⇝ 11/2 | note:A4 gain:0.22000000000000286 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 21/4 ⇜ (349/64 → 175/32) ⇝ 11/2 | note:B3 gain:0.14928932188134544 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 21/4 ⇜ (349/64 → 175/32) ⇝ 11/2 | note:E4 gain:0.14928932188134544 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 21/4 ⇜ (349/64 → 175/32) ⇝ 11/2 | note:F4 gain:0.14928932188134544 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 21/4 ⇜ (349/64 → 175/32) ⇝ 11/2 | note:A4 gain:0.14928932188134544 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 21/4 ⇜ (175/32 → 351/64) ⇝ 11/2 | note:B3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 21/4 ⇜ (175/32 → 351/64) ⇝ 11/2 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 21/4 ⇜ (175/32 → 351/64) ⇝ 11/2 | note:F4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 21/4 ⇜ (175/32 → 351/64) ⇝ 11/2 | note:A4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 21/4 ⇜ (351/64 → 11/2) | note:B3 gain:0.14928932188134467 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 21/4 ⇜ (351/64 → 11/2) | note:E4 gain:0.14928932188134467 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 21/4 ⇜ (351/64 → 11/2) | note:F4 gain:0.14928932188134467 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 21/4 ⇜ (351/64 → 11/2) | note:A4 gain:0.14928932188134467 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (11/2 → 353/64) ⇝ 45/8 | note:D5 gain:0.4399999999999922 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (11/2 → 353/64) ⇝ 45/8 | note:F5 gain:0.4399999999999922 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ (11/2 → 353/64) ⇝ 23/4 | note:G2 gain:0.4399999999999922 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 11/2 ⇜ (353/64 → 177/32) ⇝ 45/8 | note:D5 gain:0.5814213562373077 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 11/2 ⇜ (353/64 → 177/32) ⇝ 45/8 | note:F5 gain:0.5814213562373077 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 11/2 ⇜ (353/64 → 177/32) ⇝ 23/4 | note:G2 gain:0.5814213562373077 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 11/2 ⇜ (177/32 → 355/64) ⇝ 45/8 | note:D5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 11/2 ⇜ (177/32 → 355/64) ⇝ 45/8 | note:F5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 11/2 ⇜ (177/32 → 355/64) ⇝ 23/4 | note:G2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ (155/28 → 355/64) ⇝ 81/14 | note:71 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ (155/28 → 355/64) ⇝ 81/14 | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ (155/28 → 355/64) ⇝ 81/14 | note:77 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ (155/28 → 355/64) ⇝ 81/14 | note:81 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 11/2 ⇜ (355/64 → 89/16) ⇝ 45/8 | note:D5 gain:0.5814213562373122 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 11/2 ⇜ (355/64 → 89/16) ⇝ 45/8 | note:F5 gain:0.5814213562373122 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 11/2 ⇜ (355/64 → 89/16) ⇝ 23/4 | note:G2 gain:0.5814213562373122 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 155/28 ⇜ (355/64 → 89/16) ⇝ 81/14 | note:71 gain:0.05814213562373122 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 155/28 ⇜ (355/64 → 89/16) ⇝ 81/14 | note:76 gain:0.05814213562373122 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 155/28 ⇜ (355/64 → 89/16) ⇝ 81/14 | note:77 gain:0.05814213562373122 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 155/28 ⇜ (355/64 → 89/16) ⇝ 81/14 | note:81 gain:0.05814213562373122 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 11/2 ⇜ (89/16 → 357/64) ⇝ 45/8 | note:D5 gain:0.4399999999999986 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 11/2 ⇜ (89/16 → 357/64) ⇝ 45/8 | note:F5 gain:0.4399999999999986 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 11/2 ⇜ (89/16 → 357/64) ⇝ 23/4 | note:G2 gain:0.4399999999999986 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 155/28 ⇜ (89/16 → 357/64) ⇝ 81/14 | note:71 gain:0.043999999999999866 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 155/28 ⇜ (89/16 → 357/64) ⇝ 81/14 | note:76 gain:0.043999999999999866 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 155/28 ⇜ (89/16 → 357/64) ⇝ 81/14 | note:77 gain:0.043999999999999866 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 155/28 ⇜ (89/16 → 357/64) ⇝ 81/14 | note:81 gain:0.043999999999999866 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 11/2 ⇜ (357/64 → 179/32) ⇝ 45/8 | note:D5 gain:0.29857864376269394 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 11/2 ⇜ (357/64 → 179/32) ⇝ 45/8 | note:F5 gain:0.29857864376269394 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 11/2 ⇜ (357/64 → 179/32) ⇝ 23/4 | note:G2 gain:0.29857864376269394 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 155/28 ⇜ (357/64 → 179/32) ⇝ 81/14 | note:71 gain:0.029857864376269395 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 155/28 ⇜ (357/64 → 179/32) ⇝ 81/14 | note:76 gain:0.029857864376269395 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 155/28 ⇜ (357/64 → 179/32) ⇝ 81/14 | note:77 gain:0.029857864376269395 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 155/28 ⇜ (357/64 → 179/32) ⇝ 81/14 | note:81 gain:0.029857864376269395 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 11/2 ⇜ (179/32 → 359/64) ⇝ 45/8 | note:D5 gain:0.24 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 11/2 ⇜ (179/32 → 359/64) ⇝ 45/8 | note:F5 gain:0.24 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 11/2 ⇜ (179/32 → 359/64) ⇝ 23/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 155/28 ⇜ (179/32 → 359/64) ⇝ 81/14 | note:71 gain:0.024 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 155/28 ⇜ (179/32 → 359/64) ⇝ 81/14 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 155/28 ⇜ (179/32 → 359/64) ⇝ 81/14 | note:77 gain:0.024 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", + "[ 67/14 ⇜ (319/64 → 5/1) ⇝ 141/28 | note:71 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 67/14 ⇜ (319/64 → 5/1) ⇝ 141/28 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 67/14 ⇜ (319/64 → 5/1) ⇝ 141/28 | note:77 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 67/14 ⇜ (319/64 → 5/1) ⇝ 141/28 | note:81 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 67/14 ⇜ (5/1 → 321/64) ⇝ 141/28 | note:71 gain:0.044 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 67/14 ⇜ (5/1 → 321/64) ⇝ 141/28 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 67/14 ⇜ (5/1 → 321/64) ⇝ 141/28 | note:77 gain:0.044 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 67/14 ⇜ (5/1 → 321/64) ⇝ 141/28 | note:81 gain:0.044 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ (5/1 → 321/64) ⇝ 21/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 67/14 ⇜ (321/64 → 161/32) ⇝ 141/28 | note:71 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 67/14 ⇜ (321/64 → 161/32) ⇝ 141/28 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 67/14 ⇜ (321/64 → 161/32) ⇝ 141/28 | note:77 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 67/14 ⇜ (321/64 → 161/32) ⇝ 141/28 | note:81 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 5/1 ⇜ (321/64 → 161/32) ⇝ 21/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 67/14 ⇜ (161/32 → 141/28) | note:71 gain:0.064 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 67/14 ⇜ (161/32 → 141/28) | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 67/14 ⇜ (161/32 → 141/28) | note:77 gain:0.064 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 67/14 ⇜ (161/32 → 141/28) | note:81 gain:0.064 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 5/1 ⇜ (161/32 → 323/64) ⇝ 21/4 | note:G2 gain:0.64 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 5/1 ⇜ (323/64 → 81/16) ⇝ 21/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 5/1 ⇜ (81/16 → 325/64) ⇝ 21/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 5/1 ⇜ (325/64 → 163/32) ⇝ 21/4 | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 5/1 ⇜ (163/32 → 327/64) ⇝ 21/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 5/1 ⇜ (327/64 → 41/8) ⇝ 21/4 | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 5/1 ⇜ (41/8 → 329/64) ⇝ 21/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ (41/8 → 329/64) ⇝ 21/4 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (41/8 → 329/64) ⇝ 21/4 | note:Bb4 gain:0.44 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 5/1 ⇜ (329/64 → 165/32) ⇝ 21/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 41/8 ⇜ (329/64 → 165/32) ⇝ 21/4 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 41/8 ⇜ (329/64 → 165/32) ⇝ 21/4 | note:Bb4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 5/1 ⇜ (165/32 → 331/64) ⇝ 21/4 | note:G2 gain:0.64 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 41/8 ⇜ (165/32 → 331/64) ⇝ 21/4 | note:G4 gain:0.64 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 41/8 ⇜ (165/32 → 331/64) ⇝ 21/4 | note:Bb4 gain:0.64 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 5/1 ⇜ (331/64 → 83/16) ⇝ 21/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 41/8 ⇜ (331/64 → 83/16) ⇝ 21/4 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 41/8 ⇜ (331/64 → 83/16) ⇝ 21/4 | note:Bb4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 5/1 ⇜ (83/16 → 333/64) ⇝ 21/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 41/8 ⇜ (83/16 → 333/64) ⇝ 21/4 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 41/8 ⇜ (83/16 → 333/64) ⇝ 21/4 | note:Bb4 gain:0.44 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 5/1 ⇜ (333/64 → 167/32) ⇝ 21/4 | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 41/8 ⇜ (333/64 → 167/32) ⇝ 21/4 | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 41/8 ⇜ (333/64 → 167/32) ⇝ 21/4 | note:Bb4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 5/1 ⇜ (167/32 → 335/64) ⇝ 21/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 41/8 ⇜ (167/32 → 335/64) ⇝ 21/4 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 41/8 ⇜ (167/32 → 335/64) ⇝ 21/4 | note:Bb4 gain:0.24 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 5/1 ⇜ (335/64 → 21/4) | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 41/8 ⇜ (335/64 → 21/4) | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 41/8 ⇜ (335/64 → 21/4) | note:Bb4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ (21/4 → 337/64) ⇝ 11/2 | note:B3 gain:0.22 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ (21/4 → 337/64) ⇝ 11/2 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (21/4 → 337/64) ⇝ 11/2 | note:F4 gain:0.22 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ (21/4 → 337/64) ⇝ 11/2 | note:A4 gain:0.22 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 21/4 ⇜ (337/64 → 169/32) ⇝ 11/2 | note:B3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 21/4 ⇜ (337/64 → 169/32) ⇝ 11/2 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 21/4 ⇜ (337/64 → 169/32) ⇝ 11/2 | note:F4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 21/4 ⇜ (337/64 → 169/32) ⇝ 11/2 | note:A4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 21/4 ⇜ (169/32 → 339/64) ⇝ 11/2 | note:B3 gain:0.32 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 21/4 ⇜ (169/32 → 339/64) ⇝ 11/2 | note:E4 gain:0.32 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 21/4 ⇜ (169/32 → 339/64) ⇝ 11/2 | note:F4 gain:0.32 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 21/4 ⇜ (169/32 → 339/64) ⇝ 11/2 | note:A4 gain:0.32 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 21/4 ⇜ (339/64 → 85/16) ⇝ 11/2 | note:B3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 21/4 ⇜ (339/64 → 85/16) ⇝ 11/2 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 21/4 ⇜ (339/64 → 85/16) ⇝ 11/2 | note:F4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 21/4 ⇜ (339/64 → 85/16) ⇝ 11/2 | note:A4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 21/4 ⇜ (85/16 → 341/64) ⇝ 11/2 | note:B3 gain:0.22 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 21/4 ⇜ (85/16 → 341/64) ⇝ 11/2 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 21/4 ⇜ (85/16 → 341/64) ⇝ 11/2 | note:F4 gain:0.22 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 21/4 ⇜ (85/16 → 341/64) ⇝ 11/2 | note:A4 gain:0.22 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 21/4 ⇜ (341/64 → 171/32) ⇝ 11/2 | note:B3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 21/4 ⇜ (341/64 → 171/32) ⇝ 11/2 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 21/4 ⇜ (341/64 → 171/32) ⇝ 11/2 | note:F4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 21/4 ⇜ (341/64 → 171/32) ⇝ 11/2 | note:A4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 21/4 ⇜ (171/32 → 343/64) ⇝ 11/2 | note:B3 gain:0.12 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 21/4 ⇜ (171/32 → 343/64) ⇝ 11/2 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 21/4 ⇜ (171/32 → 343/64) ⇝ 11/2 | note:F4 gain:0.12 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 21/4 ⇜ (171/32 → 343/64) ⇝ 11/2 | note:A4 gain:0.12 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 21/4 ⇜ (343/64 → 43/8) ⇝ 11/2 | note:B3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 21/4 ⇜ (343/64 → 43/8) ⇝ 11/2 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 21/4 ⇜ (343/64 → 43/8) ⇝ 11/2 | note:F4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 21/4 ⇜ (343/64 → 43/8) ⇝ 11/2 | note:A4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 21/4 ⇜ (43/8 → 345/64) ⇝ 11/2 | note:B3 gain:0.22 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 21/4 ⇜ (43/8 → 345/64) ⇝ 11/2 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 21/4 ⇜ (43/8 → 345/64) ⇝ 11/2 | note:F4 gain:0.22 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 21/4 ⇜ (43/8 → 345/64) ⇝ 11/2 | note:A4 gain:0.22 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 21/4 ⇜ (345/64 → 173/32) ⇝ 11/2 | note:B3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 21/4 ⇜ (345/64 → 173/32) ⇝ 11/2 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 21/4 ⇜ (345/64 → 173/32) ⇝ 11/2 | note:F4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 21/4 ⇜ (345/64 → 173/32) ⇝ 11/2 | note:A4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 21/4 ⇜ (173/32 → 347/64) ⇝ 11/2 | note:B3 gain:0.32 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 21/4 ⇜ (173/32 → 347/64) ⇝ 11/2 | note:E4 gain:0.32 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 21/4 ⇜ (173/32 → 347/64) ⇝ 11/2 | note:F4 gain:0.32 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 21/4 ⇜ (173/32 → 347/64) ⇝ 11/2 | note:A4 gain:0.32 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 21/4 ⇜ (347/64 → 87/16) ⇝ 11/2 | note:B3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 21/4 ⇜ (347/64 → 87/16) ⇝ 11/2 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 21/4 ⇜ (347/64 → 87/16) ⇝ 11/2 | note:F4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 21/4 ⇜ (347/64 → 87/16) ⇝ 11/2 | note:A4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 21/4 ⇜ (87/16 → 349/64) ⇝ 11/2 | note:B3 gain:0.22 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 21/4 ⇜ (87/16 → 349/64) ⇝ 11/2 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 21/4 ⇜ (87/16 → 349/64) ⇝ 11/2 | note:F4 gain:0.22 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 21/4 ⇜ (87/16 → 349/64) ⇝ 11/2 | note:A4 gain:0.22 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 21/4 ⇜ (349/64 → 175/32) ⇝ 11/2 | note:B3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 21/4 ⇜ (349/64 → 175/32) ⇝ 11/2 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 21/4 ⇜ (349/64 → 175/32) ⇝ 11/2 | note:F4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 21/4 ⇜ (349/64 → 175/32) ⇝ 11/2 | note:A4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 21/4 ⇜ (175/32 → 351/64) ⇝ 11/2 | note:B3 gain:0.12 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 21/4 ⇜ (175/32 → 351/64) ⇝ 11/2 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 21/4 ⇜ (175/32 → 351/64) ⇝ 11/2 | note:F4 gain:0.12 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 21/4 ⇜ (175/32 → 351/64) ⇝ 11/2 | note:A4 gain:0.12 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 21/4 ⇜ (351/64 → 11/2) | note:B3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 21/4 ⇜ (351/64 → 11/2) | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 21/4 ⇜ (351/64 → 11/2) | note:F4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 21/4 ⇜ (351/64 → 11/2) | note:A4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ (11/2 → 353/64) ⇝ 45/8 | note:D5 gain:0.44 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ (11/2 → 353/64) ⇝ 45/8 | note:F5 gain:0.44 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ (11/2 → 353/64) ⇝ 23/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 11/2 ⇜ (353/64 → 177/32) ⇝ 45/8 | note:D5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 11/2 ⇜ (353/64 → 177/32) ⇝ 45/8 | note:F5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 11/2 ⇜ (353/64 → 177/32) ⇝ 23/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 11/2 ⇜ (177/32 → 355/64) ⇝ 45/8 | note:D5 gain:0.64 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 11/2 ⇜ (177/32 → 355/64) ⇝ 45/8 | note:F5 gain:0.64 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 11/2 ⇜ (177/32 → 355/64) ⇝ 23/4 | note:G2 gain:0.64 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ (155/28 → 355/64) ⇝ 81/14 | note:71 gain:0.064 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ (155/28 → 355/64) ⇝ 81/14 | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ (155/28 → 355/64) ⇝ 81/14 | note:77 gain:0.064 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ (155/28 → 355/64) ⇝ 81/14 | note:81 gain:0.064 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 11/2 ⇜ (355/64 → 89/16) ⇝ 45/8 | note:D5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 11/2 ⇜ (355/64 → 89/16) ⇝ 45/8 | note:F5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 11/2 ⇜ (355/64 → 89/16) ⇝ 23/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 155/28 ⇜ (355/64 → 89/16) ⇝ 81/14 | note:71 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 155/28 ⇜ (355/64 → 89/16) ⇝ 81/14 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 155/28 ⇜ (355/64 → 89/16) ⇝ 81/14 | note:77 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 155/28 ⇜ (355/64 → 89/16) ⇝ 81/14 | note:81 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 11/2 ⇜ (89/16 → 357/64) ⇝ 45/8 | note:D5 gain:0.44 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 11/2 ⇜ (89/16 → 357/64) ⇝ 45/8 | note:F5 gain:0.44 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 11/2 ⇜ (89/16 → 357/64) ⇝ 23/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 155/28 ⇜ (89/16 → 357/64) ⇝ 81/14 | note:71 gain:0.044 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 155/28 ⇜ (89/16 → 357/64) ⇝ 81/14 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 155/28 ⇜ (89/16 → 357/64) ⇝ 81/14 | note:77 gain:0.044 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 155/28 ⇜ (89/16 → 357/64) ⇝ 81/14 | note:81 gain:0.044 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 11/2 ⇜ (357/64 → 179/32) ⇝ 45/8 | note:D5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 11/2 ⇜ (357/64 → 179/32) ⇝ 45/8 | note:F5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 11/2 ⇜ (357/64 → 179/32) ⇝ 23/4 | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 155/28 ⇜ (357/64 → 179/32) ⇝ 81/14 | note:71 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 155/28 ⇜ (357/64 → 179/32) ⇝ 81/14 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 155/28 ⇜ (357/64 → 179/32) ⇝ 81/14 | note:77 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 155/28 ⇜ (357/64 → 179/32) ⇝ 81/14 | note:81 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 11/2 ⇜ (179/32 → 359/64) ⇝ 45/8 | note:D5 gain:0.24 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 11/2 ⇜ (179/32 → 359/64) ⇝ 45/8 | note:F5 gain:0.24 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 11/2 ⇜ (179/32 → 359/64) ⇝ 23/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 155/28 ⇜ (179/32 → 359/64) ⇝ 81/14 | note:71 gain:0.024 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 155/28 ⇜ (179/32 → 359/64) ⇝ 81/14 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 155/28 ⇜ (179/32 → 359/64) ⇝ 81/14 | note:77 gain:0.024 clip:1 s:piano release:0.1 pan:0.606481481481 ]", "[ 155/28 ⇜ (179/32 → 359/64) ⇝ 81/14 | note:81 gain:0.024 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 11/2 ⇜ (359/64 → 45/8) | note:D5 gain:0.2985786437626863 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 11/2 ⇜ (359/64 → 45/8) | note:F5 gain:0.2985786437626863 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 11/2 ⇜ (359/64 → 45/8) ⇝ 23/4 | note:G2 gain:0.2985786437626863 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 155/28 ⇜ (359/64 → 45/8) ⇝ 81/14 | note:71 gain:0.02985786437626863 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 155/28 ⇜ (359/64 → 45/8) ⇝ 81/14 | note:76 gain:0.02985786437626863 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 155/28 ⇜ (359/64 → 45/8) ⇝ 81/14 | note:77 gain:0.02985786437626863 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 155/28 ⇜ (359/64 → 45/8) ⇝ 81/14 | note:81 gain:0.02985786437626863 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 11/2 ⇜ (45/8 → 361/64) ⇝ 23/4 | note:G2 gain:0.4399999999999993 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 155/28 ⇜ (45/8 → 361/64) ⇝ 81/14 | note:71 gain:0.04399999999999993 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 155/28 ⇜ (45/8 → 361/64) ⇝ 81/14 | note:76 gain:0.04399999999999993 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 155/28 ⇜ (45/8 → 361/64) ⇝ 81/14 | note:77 gain:0.04399999999999993 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 155/28 ⇜ (45/8 → 361/64) ⇝ 81/14 | note:81 gain:0.04399999999999993 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 11/2 ⇜ (361/64 → 181/32) ⇝ 23/4 | note:G2 gain:0.5814213562373046 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 155/28 ⇜ (361/64 → 181/32) ⇝ 81/14 | note:71 gain:0.05814213562373047 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 155/28 ⇜ (361/64 → 181/32) ⇝ 81/14 | note:76 gain:0.05814213562373047 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 155/28 ⇜ (361/64 → 181/32) ⇝ 81/14 | note:77 gain:0.05814213562373047 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 155/28 ⇜ (361/64 → 181/32) ⇝ 81/14 | note:81 gain:0.05814213562373047 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 11/2 ⇜ (181/32 → 363/64) ⇝ 23/4 | note:G2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 155/28 ⇜ (181/32 → 363/64) ⇝ 81/14 | note:71 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 155/28 ⇜ (181/32 → 363/64) ⇝ 81/14 | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 155/28 ⇜ (181/32 → 363/64) ⇝ 81/14 | note:77 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 155/28 ⇜ (181/32 → 363/64) ⇝ 81/14 | note:81 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 11/2 ⇜ (363/64 → 91/16) ⇝ 23/4 | note:G2 gain:0.5814213562373072 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 155/28 ⇜ (363/64 → 91/16) ⇝ 81/14 | note:71 gain:0.05814213562373072 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 155/28 ⇜ (363/64 → 91/16) ⇝ 81/14 | note:76 gain:0.05814213562373072 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 155/28 ⇜ (363/64 → 91/16) ⇝ 81/14 | note:77 gain:0.05814213562373072 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 155/28 ⇜ (363/64 → 91/16) ⇝ 81/14 | note:81 gain:0.05814213562373072 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 11/2 ⇜ (91/16 → 365/64) ⇝ 23/4 | note:G2 gain:0.4400000000000029 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 155/28 ⇜ (91/16 → 365/64) ⇝ 81/14 | note:71 gain:0.04400000000000029 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 155/28 ⇜ (91/16 → 365/64) ⇝ 81/14 | note:76 gain:0.04400000000000029 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 155/28 ⇜ (91/16 → 365/64) ⇝ 81/14 | note:77 gain:0.04400000000000029 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 155/28 ⇜ (91/16 → 365/64) ⇝ 81/14 | note:81 gain:0.04400000000000029 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 11/2 ⇜ (365/64 → 183/32) ⇝ 23/4 | note:G2 gain:0.29857864376268894 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 155/28 ⇜ (365/64 → 183/32) ⇝ 81/14 | note:71 gain:0.029857864376268896 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 155/28 ⇜ (365/64 → 183/32) ⇝ 81/14 | note:76 gain:0.029857864376268896 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 155/28 ⇜ (365/64 → 183/32) ⇝ 81/14 | note:77 gain:0.029857864376268896 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 155/28 ⇜ (365/64 → 183/32) ⇝ 81/14 | note:81 gain:0.029857864376268896 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 11/2 ⇜ (183/32 → 367/64) ⇝ 23/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 155/28 ⇜ (183/32 → 367/64) ⇝ 81/14 | note:71 gain:0.024 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 155/28 ⇜ (183/32 → 367/64) ⇝ 81/14 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 155/28 ⇜ (183/32 → 367/64) ⇝ 81/14 | note:77 gain:0.024 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", + "[ 11/2 ⇜ (359/64 → 45/8) | note:D5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 11/2 ⇜ (359/64 → 45/8) | note:F5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 11/2 ⇜ (359/64 → 45/8) ⇝ 23/4 | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 155/28 ⇜ (359/64 → 45/8) ⇝ 81/14 | note:71 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 155/28 ⇜ (359/64 → 45/8) ⇝ 81/14 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 155/28 ⇜ (359/64 → 45/8) ⇝ 81/14 | note:77 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 155/28 ⇜ (359/64 → 45/8) ⇝ 81/14 | note:81 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 11/2 ⇜ (45/8 → 361/64) ⇝ 23/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 155/28 ⇜ (45/8 → 361/64) ⇝ 81/14 | note:71 gain:0.044 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 155/28 ⇜ (45/8 → 361/64) ⇝ 81/14 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 155/28 ⇜ (45/8 → 361/64) ⇝ 81/14 | note:77 gain:0.044 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 155/28 ⇜ (45/8 → 361/64) ⇝ 81/14 | note:81 gain:0.044 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 11/2 ⇜ (361/64 → 181/32) ⇝ 23/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 155/28 ⇜ (361/64 → 181/32) ⇝ 81/14 | note:71 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 155/28 ⇜ (361/64 → 181/32) ⇝ 81/14 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 155/28 ⇜ (361/64 → 181/32) ⇝ 81/14 | note:77 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 155/28 ⇜ (361/64 → 181/32) ⇝ 81/14 | note:81 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 11/2 ⇜ (181/32 → 363/64) ⇝ 23/4 | note:G2 gain:0.64 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 155/28 ⇜ (181/32 → 363/64) ⇝ 81/14 | note:71 gain:0.064 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 155/28 ⇜ (181/32 → 363/64) ⇝ 81/14 | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 155/28 ⇜ (181/32 → 363/64) ⇝ 81/14 | note:77 gain:0.064 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 155/28 ⇜ (181/32 → 363/64) ⇝ 81/14 | note:81 gain:0.064 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 11/2 ⇜ (363/64 → 91/16) ⇝ 23/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 155/28 ⇜ (363/64 → 91/16) ⇝ 81/14 | note:71 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 155/28 ⇜ (363/64 → 91/16) ⇝ 81/14 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 155/28 ⇜ (363/64 → 91/16) ⇝ 81/14 | note:77 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 155/28 ⇜ (363/64 → 91/16) ⇝ 81/14 | note:81 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 11/2 ⇜ (91/16 → 365/64) ⇝ 23/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 155/28 ⇜ (91/16 → 365/64) ⇝ 81/14 | note:71 gain:0.044 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 155/28 ⇜ (91/16 → 365/64) ⇝ 81/14 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 155/28 ⇜ (91/16 → 365/64) ⇝ 81/14 | note:77 gain:0.044 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 155/28 ⇜ (91/16 → 365/64) ⇝ 81/14 | note:81 gain:0.044 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 11/2 ⇜ (365/64 → 183/32) ⇝ 23/4 | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 155/28 ⇜ (365/64 → 183/32) ⇝ 81/14 | note:71 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 155/28 ⇜ (365/64 → 183/32) ⇝ 81/14 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 155/28 ⇜ (365/64 → 183/32) ⇝ 81/14 | note:77 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 155/28 ⇜ (365/64 → 183/32) ⇝ 81/14 | note:81 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 11/2 ⇜ (183/32 → 367/64) ⇝ 23/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 155/28 ⇜ (183/32 → 367/64) ⇝ 81/14 | note:71 gain:0.024 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 155/28 ⇜ (183/32 → 367/64) ⇝ 81/14 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 155/28 ⇜ (183/32 → 367/64) ⇝ 81/14 | note:77 gain:0.024 clip:1 s:piano release:0.1 pan:0.606481481481 ]", "[ 155/28 ⇜ (183/32 → 367/64) ⇝ 81/14 | note:81 gain:0.024 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 11/2 ⇜ (367/64 → 23/4) | note:G2 gain:0.2985786437626913 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 155/28 ⇜ (367/64 → 23/4) ⇝ 81/14 | note:71 gain:0.02985786437626913 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 155/28 ⇜ (367/64 → 23/4) ⇝ 81/14 | note:76 gain:0.02985786437626913 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 155/28 ⇜ (367/64 → 23/4) ⇝ 81/14 | note:77 gain:0.02985786437626913 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 155/28 ⇜ (367/64 → 23/4) ⇝ 81/14 | note:81 gain:0.02985786437626913 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 155/28 ⇜ (23/4 → 369/64) ⇝ 81/14 | note:71 gain:0.04399999999999949 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 155/28 ⇜ (23/4 → 369/64) ⇝ 81/14 | note:76 gain:0.04399999999999949 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 155/28 ⇜ (23/4 → 369/64) ⇝ 81/14 | note:77 gain:0.04399999999999949 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 155/28 ⇜ (23/4 → 369/64) ⇝ 81/14 | note:81 gain:0.04399999999999949 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ (23/4 → 369/64) ⇝ 47/8 | note:D5 gain:0.4399999999999949 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (23/4 → 369/64) ⇝ 47/8 | note:F5 gain:0.4399999999999949 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ (23/4 → 369/64) ⇝ 6/1 | note:B3 gain:0.21999999999999745 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ (23/4 → 369/64) ⇝ 6/1 | note:E4 gain:0.21999999999999745 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (23/4 → 369/64) ⇝ 6/1 | note:F4 gain:0.21999999999999745 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (23/4 → 369/64) ⇝ 6/1 | note:A4 gain:0.21999999999999745 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 155/28 ⇜ (369/64 → 185/32) ⇝ 81/14 | note:71 gain:0.05814213562373095 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 155/28 ⇜ (369/64 → 185/32) ⇝ 81/14 | note:76 gain:0.05814213562373095 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 155/28 ⇜ (369/64 → 185/32) ⇝ 81/14 | note:77 gain:0.05814213562373095 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 155/28 ⇜ (369/64 → 185/32) ⇝ 81/14 | note:81 gain:0.05814213562373095 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 23/4 ⇜ (369/64 → 185/32) ⇝ 47/8 | note:D5 gain:0.5814213562373095 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 23/4 ⇜ (369/64 → 185/32) ⇝ 47/8 | note:F5 gain:0.5814213562373095 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 23/4 ⇜ (369/64 → 185/32) ⇝ 6/1 | note:B3 gain:0.29071067811865475 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 23/4 ⇜ (369/64 → 185/32) ⇝ 6/1 | note:E4 gain:0.29071067811865475 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 23/4 ⇜ (369/64 → 185/32) ⇝ 6/1 | note:F4 gain:0.29071067811865475 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 23/4 ⇜ (369/64 → 185/32) ⇝ 6/1 | note:A4 gain:0.29071067811865475 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 155/28 ⇜ (185/32 → 81/14) | note:71 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 155/28 ⇜ (185/32 → 81/14) | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 155/28 ⇜ (185/32 → 81/14) | note:77 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 155/28 ⇜ (185/32 → 81/14) | note:81 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 23/4 ⇜ (185/32 → 371/64) ⇝ 47/8 | note:D5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 23/4 ⇜ (185/32 → 371/64) ⇝ 47/8 | note:F5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 23/4 ⇜ (185/32 → 371/64) ⇝ 6/1 | note:B3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 23/4 ⇜ (185/32 → 371/64) ⇝ 6/1 | note:E4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 23/4 ⇜ (185/32 → 371/64) ⇝ 6/1 | note:F4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 23/4 ⇜ (185/32 → 371/64) ⇝ 6/1 | note:A4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 23/4 ⇜ (371/64 → 93/16) ⇝ 47/8 | note:D5 gain:0.5814213562373102 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 23/4 ⇜ (371/64 → 93/16) ⇝ 47/8 | note:F5 gain:0.5814213562373102 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 23/4 ⇜ (371/64 → 93/16) ⇝ 6/1 | note:B3 gain:0.2907106781186551 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 23/4 ⇜ (371/64 → 93/16) ⇝ 6/1 | note:E4 gain:0.2907106781186551 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 23/4 ⇜ (371/64 → 93/16) ⇝ 6/1 | note:F4 gain:0.2907106781186551 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 23/4 ⇜ (371/64 → 93/16) ⇝ 6/1 | note:A4 gain:0.2907106781186551 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 23/4 ⇜ (93/16 → 373/64) ⇝ 47/8 | note:D5 gain:0.4400000000000073 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 23/4 ⇜ (93/16 → 373/64) ⇝ 47/8 | note:F5 gain:0.4400000000000073 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 23/4 ⇜ (93/16 → 373/64) ⇝ 6/1 | note:B3 gain:0.22000000000000364 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 23/4 ⇜ (93/16 → 373/64) ⇝ 6/1 | note:E4 gain:0.22000000000000364 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 23/4 ⇜ (93/16 → 373/64) ⇝ 6/1 | note:F4 gain:0.22000000000000364 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 23/4 ⇜ (93/16 → 373/64) ⇝ 6/1 | note:A4 gain:0.22000000000000364 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 23/4 ⇜ (373/64 → 187/32) ⇝ 47/8 | note:D5 gain:0.298578643762692 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 23/4 ⇜ (373/64 → 187/32) ⇝ 47/8 | note:F5 gain:0.298578643762692 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 23/4 ⇜ (373/64 → 187/32) ⇝ 6/1 | note:B3 gain:0.149289321881346 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 23/4 ⇜ (373/64 → 187/32) ⇝ 6/1 | note:E4 gain:0.149289321881346 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 23/4 ⇜ (373/64 → 187/32) ⇝ 6/1 | note:F4 gain:0.149289321881346 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 23/4 ⇜ (373/64 → 187/32) ⇝ 6/1 | note:A4 gain:0.149289321881346 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 23/4 ⇜ (187/32 → 375/64) ⇝ 47/8 | note:D5 gain:0.24 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 23/4 ⇜ (187/32 → 375/64) ⇝ 47/8 | note:F5 gain:0.24 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 23/4 ⇜ (187/32 → 375/64) ⇝ 6/1 | note:B3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 23/4 ⇜ (187/32 → 375/64) ⇝ 6/1 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 23/4 ⇜ (187/32 → 375/64) ⇝ 6/1 | note:F4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 23/4 ⇜ (187/32 → 375/64) ⇝ 6/1 | note:A4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 23/4 ⇜ (375/64 → 47/8) | note:D5 gain:0.2985786437626882 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 23/4 ⇜ (375/64 → 47/8) | note:F5 gain:0.2985786437626882 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 23/4 ⇜ (375/64 → 47/8) ⇝ 6/1 | note:B3 gain:0.1492893218813441 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 23/4 ⇜ (375/64 → 47/8) ⇝ 6/1 | note:E4 gain:0.1492893218813441 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 23/4 ⇜ (375/64 → 47/8) ⇝ 6/1 | note:F4 gain:0.1492893218813441 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 23/4 ⇜ (375/64 → 47/8) ⇝ 6/1 | note:A4 gain:0.1492893218813441 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 23/4 ⇜ (47/8 → 377/64) ⇝ 6/1 | note:B3 gain:0.220000000000001 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 23/4 ⇜ (47/8 → 377/64) ⇝ 6/1 | note:E4 gain:0.220000000000001 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 23/4 ⇜ (47/8 → 377/64) ⇝ 6/1 | note:F4 gain:0.220000000000001 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 23/4 ⇜ (47/8 → 377/64) ⇝ 6/1 | note:A4 gain:0.220000000000001 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 23/4 ⇜ (377/64 → 189/32) ⇝ 6/1 | note:B3 gain:0.2907106781186532 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 23/4 ⇜ (377/64 → 189/32) ⇝ 6/1 | note:E4 gain:0.2907106781186532 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 23/4 ⇜ (377/64 → 189/32) ⇝ 6/1 | note:F4 gain:0.2907106781186532 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 23/4 ⇜ (377/64 → 189/32) ⇝ 6/1 | note:A4 gain:0.2907106781186532 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 23/4 ⇜ (189/32 → 379/64) ⇝ 6/1 | note:B3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 23/4 ⇜ (189/32 → 379/64) ⇝ 6/1 | note:E4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 23/4 ⇜ (189/32 → 379/64) ⇝ 6/1 | note:F4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 23/4 ⇜ (189/32 → 379/64) ⇝ 6/1 | note:A4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 23/4 ⇜ (379/64 → 95/16) ⇝ 6/1 | note:B3 gain:0.2907106781186567 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 23/4 ⇜ (379/64 → 95/16) ⇝ 6/1 | note:E4 gain:0.2907106781186567 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 23/4 ⇜ (379/64 → 95/16) ⇝ 6/1 | note:F4 gain:0.2907106781186567 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 23/4 ⇜ (379/64 → 95/16) ⇝ 6/1 | note:A4 gain:0.2907106781186567 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 23/4 ⇜ (95/16 → 381/64) ⇝ 6/1 | note:B3 gain:0.2200000000000001 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 23/4 ⇜ (95/16 → 381/64) ⇝ 6/1 | note:E4 gain:0.2200000000000001 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 23/4 ⇜ (95/16 → 381/64) ⇝ 6/1 | note:F4 gain:0.2200000000000001 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 23/4 ⇜ (95/16 → 381/64) ⇝ 6/1 | note:A4 gain:0.2200000000000001 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 23/4 ⇜ (381/64 → 191/32) ⇝ 6/1 | note:B3 gain:0.14928932188134753 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 23/4 ⇜ (381/64 → 191/32) ⇝ 6/1 | note:E4 gain:0.14928932188134753 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 23/4 ⇜ (381/64 → 191/32) ⇝ 6/1 | note:F4 gain:0.14928932188134753 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 23/4 ⇜ (381/64 → 191/32) ⇝ 6/1 | note:A4 gain:0.14928932188134753 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 23/4 ⇜ (191/32 → 383/64) ⇝ 6/1 | note:B3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 23/4 ⇜ (191/32 → 383/64) ⇝ 6/1 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 23/4 ⇜ (191/32 → 383/64) ⇝ 6/1 | note:F4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 23/4 ⇜ (191/32 → 383/64) ⇝ 6/1 | note:A4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 23/4 ⇜ (383/64 → 6/1) | note:B3 gain:0.1492893218813426 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 23/4 ⇜ (383/64 → 6/1) | note:E4 gain:0.1492893218813426 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 23/4 ⇜ (383/64 → 6/1) | note:F4 gain:0.1492893218813426 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 23/4 ⇜ (383/64 → 6/1) | note:A4 gain:0.1492893218813426 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (6/1 → 385/64) ⇝ 25/4 | note:F#2 gain:0.43999999999999767 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 6/1 ⇜ (385/64 → 193/32) ⇝ 25/4 | note:F#2 gain:0.5814213562373115 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 6/1 ⇜ (193/32 → 387/64) ⇝ 25/4 | note:F#2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ (169/28 → 387/64) ⇝ 44/7 | note:71 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ (169/28 → 387/64) ⇝ 44/7 | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ (169/28 → 387/64) ⇝ 44/7 | note:77 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ (169/28 → 387/64) ⇝ 44/7 | note:81 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 6/1 ⇜ (387/64 → 97/16) ⇝ 25/4 | note:F#2 gain:0.5814213562373083 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 169/28 ⇜ (387/64 → 97/16) ⇝ 44/7 | note:71 gain:0.05814213562373083 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 169/28 ⇜ (387/64 → 97/16) ⇝ 44/7 | note:76 gain:0.05814213562373083 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 169/28 ⇜ (387/64 → 97/16) ⇝ 44/7 | note:77 gain:0.05814213562373083 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 169/28 ⇜ (387/64 → 97/16) ⇝ 44/7 | note:81 gain:0.05814213562373083 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 6/1 ⇜ (97/16 → 389/64) ⇝ 25/4 | note:F#2 gain:0.4400000000000045 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 169/28 ⇜ (97/16 → 389/64) ⇝ 44/7 | note:71 gain:0.044000000000000455 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 169/28 ⇜ (97/16 → 389/64) ⇝ 44/7 | note:76 gain:0.044000000000000455 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 169/28 ⇜ (97/16 → 389/64) ⇝ 44/7 | note:77 gain:0.044000000000000455 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 169/28 ⇜ (97/16 → 389/64) ⇝ 44/7 | note:81 gain:0.044000000000000455 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 6/1 ⇜ (389/64 → 195/32) ⇝ 25/4 | note:F#2 gain:0.29857864376269 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 169/28 ⇜ (389/64 → 195/32) ⇝ 44/7 | note:71 gain:0.029857864376269 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 169/28 ⇜ (389/64 → 195/32) ⇝ 44/7 | note:76 gain:0.029857864376269 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 169/28 ⇜ (389/64 → 195/32) ⇝ 44/7 | note:77 gain:0.029857864376269 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 169/28 ⇜ (389/64 → 195/32) ⇝ 44/7 | note:81 gain:0.029857864376269 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 6/1 ⇜ (195/32 → 391/64) ⇝ 25/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 169/28 ⇜ (195/32 → 391/64) ⇝ 44/7 | note:71 gain:0.024 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 169/28 ⇜ (195/32 → 391/64) ⇝ 44/7 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 169/28 ⇜ (195/32 → 391/64) ⇝ 44/7 | note:77 gain:0.024 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", + "[ 11/2 ⇜ (367/64 → 23/4) | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 155/28 ⇜ (367/64 → 23/4) ⇝ 81/14 | note:71 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 155/28 ⇜ (367/64 → 23/4) ⇝ 81/14 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 155/28 ⇜ (367/64 → 23/4) ⇝ 81/14 | note:77 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 155/28 ⇜ (367/64 → 23/4) ⇝ 81/14 | note:81 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 155/28 ⇜ (23/4 → 369/64) ⇝ 81/14 | note:71 gain:0.044 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 155/28 ⇜ (23/4 → 369/64) ⇝ 81/14 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 155/28 ⇜ (23/4 → 369/64) ⇝ 81/14 | note:77 gain:0.044 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 155/28 ⇜ (23/4 → 369/64) ⇝ 81/14 | note:81 gain:0.044 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ (23/4 → 369/64) ⇝ 47/8 | note:D5 gain:0.44 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ (23/4 → 369/64) ⇝ 47/8 | note:F5 gain:0.44 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ (23/4 → 369/64) ⇝ 6/1 | note:B3 gain:0.22 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ (23/4 → 369/64) ⇝ 6/1 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (23/4 → 369/64) ⇝ 6/1 | note:F4 gain:0.22 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ (23/4 → 369/64) ⇝ 6/1 | note:A4 gain:0.22 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 155/28 ⇜ (369/64 → 185/32) ⇝ 81/14 | note:71 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 155/28 ⇜ (369/64 → 185/32) ⇝ 81/14 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 155/28 ⇜ (369/64 → 185/32) ⇝ 81/14 | note:77 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 155/28 ⇜ (369/64 → 185/32) ⇝ 81/14 | note:81 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 23/4 ⇜ (369/64 → 185/32) ⇝ 47/8 | note:D5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 23/4 ⇜ (369/64 → 185/32) ⇝ 47/8 | note:F5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 23/4 ⇜ (369/64 → 185/32) ⇝ 6/1 | note:B3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 23/4 ⇜ (369/64 → 185/32) ⇝ 6/1 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 23/4 ⇜ (369/64 → 185/32) ⇝ 6/1 | note:F4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 23/4 ⇜ (369/64 → 185/32) ⇝ 6/1 | note:A4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 155/28 ⇜ (185/32 → 81/14) | note:71 gain:0.064 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 155/28 ⇜ (185/32 → 81/14) | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 155/28 ⇜ (185/32 → 81/14) | note:77 gain:0.064 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 155/28 ⇜ (185/32 → 81/14) | note:81 gain:0.064 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 23/4 ⇜ (185/32 → 371/64) ⇝ 47/8 | note:D5 gain:0.64 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 23/4 ⇜ (185/32 → 371/64) ⇝ 47/8 | note:F5 gain:0.64 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 23/4 ⇜ (185/32 → 371/64) ⇝ 6/1 | note:B3 gain:0.32 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 23/4 ⇜ (185/32 → 371/64) ⇝ 6/1 | note:E4 gain:0.32 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 23/4 ⇜ (185/32 → 371/64) ⇝ 6/1 | note:F4 gain:0.32 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 23/4 ⇜ (185/32 → 371/64) ⇝ 6/1 | note:A4 gain:0.32 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 23/4 ⇜ (371/64 → 93/16) ⇝ 47/8 | note:D5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 23/4 ⇜ (371/64 → 93/16) ⇝ 47/8 | note:F5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 23/4 ⇜ (371/64 → 93/16) ⇝ 6/1 | note:B3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 23/4 ⇜ (371/64 → 93/16) ⇝ 6/1 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 23/4 ⇜ (371/64 → 93/16) ⇝ 6/1 | note:F4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 23/4 ⇜ (371/64 → 93/16) ⇝ 6/1 | note:A4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 23/4 ⇜ (93/16 → 373/64) ⇝ 47/8 | note:D5 gain:0.44 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 23/4 ⇜ (93/16 → 373/64) ⇝ 47/8 | note:F5 gain:0.44 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 23/4 ⇜ (93/16 → 373/64) ⇝ 6/1 | note:B3 gain:0.22 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 23/4 ⇜ (93/16 → 373/64) ⇝ 6/1 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 23/4 ⇜ (93/16 → 373/64) ⇝ 6/1 | note:F4 gain:0.22 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 23/4 ⇜ (93/16 → 373/64) ⇝ 6/1 | note:A4 gain:0.22 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 23/4 ⇜ (373/64 → 187/32) ⇝ 47/8 | note:D5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 23/4 ⇜ (373/64 → 187/32) ⇝ 47/8 | note:F5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 23/4 ⇜ (373/64 → 187/32) ⇝ 6/1 | note:B3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 23/4 ⇜ (373/64 → 187/32) ⇝ 6/1 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 23/4 ⇜ (373/64 → 187/32) ⇝ 6/1 | note:F4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 23/4 ⇜ (373/64 → 187/32) ⇝ 6/1 | note:A4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 23/4 ⇜ (187/32 → 375/64) ⇝ 47/8 | note:D5 gain:0.24 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 23/4 ⇜ (187/32 → 375/64) ⇝ 47/8 | note:F5 gain:0.24 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 23/4 ⇜ (187/32 → 375/64) ⇝ 6/1 | note:B3 gain:0.12 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 23/4 ⇜ (187/32 → 375/64) ⇝ 6/1 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 23/4 ⇜ (187/32 → 375/64) ⇝ 6/1 | note:F4 gain:0.12 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 23/4 ⇜ (187/32 → 375/64) ⇝ 6/1 | note:A4 gain:0.12 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 23/4 ⇜ (375/64 → 47/8) | note:D5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 23/4 ⇜ (375/64 → 47/8) | note:F5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 23/4 ⇜ (375/64 → 47/8) ⇝ 6/1 | note:B3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 23/4 ⇜ (375/64 → 47/8) ⇝ 6/1 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 23/4 ⇜ (375/64 → 47/8) ⇝ 6/1 | note:F4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 23/4 ⇜ (375/64 → 47/8) ⇝ 6/1 | note:A4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 23/4 ⇜ (47/8 → 377/64) ⇝ 6/1 | note:B3 gain:0.22 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 23/4 ⇜ (47/8 → 377/64) ⇝ 6/1 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 23/4 ⇜ (47/8 → 377/64) ⇝ 6/1 | note:F4 gain:0.22 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 23/4 ⇜ (47/8 → 377/64) ⇝ 6/1 | note:A4 gain:0.22 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 23/4 ⇜ (377/64 → 189/32) ⇝ 6/1 | note:B3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 23/4 ⇜ (377/64 → 189/32) ⇝ 6/1 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 23/4 ⇜ (377/64 → 189/32) ⇝ 6/1 | note:F4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 23/4 ⇜ (377/64 → 189/32) ⇝ 6/1 | note:A4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 23/4 ⇜ (189/32 → 379/64) ⇝ 6/1 | note:B3 gain:0.32 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 23/4 ⇜ (189/32 → 379/64) ⇝ 6/1 | note:E4 gain:0.32 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 23/4 ⇜ (189/32 → 379/64) ⇝ 6/1 | note:F4 gain:0.32 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 23/4 ⇜ (189/32 → 379/64) ⇝ 6/1 | note:A4 gain:0.32 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 23/4 ⇜ (379/64 → 95/16) ⇝ 6/1 | note:B3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 23/4 ⇜ (379/64 → 95/16) ⇝ 6/1 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 23/4 ⇜ (379/64 → 95/16) ⇝ 6/1 | note:F4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 23/4 ⇜ (379/64 → 95/16) ⇝ 6/1 | note:A4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 23/4 ⇜ (95/16 → 381/64) ⇝ 6/1 | note:B3 gain:0.22 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 23/4 ⇜ (95/16 → 381/64) ⇝ 6/1 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 23/4 ⇜ (95/16 → 381/64) ⇝ 6/1 | note:F4 gain:0.22 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 23/4 ⇜ (95/16 → 381/64) ⇝ 6/1 | note:A4 gain:0.22 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 23/4 ⇜ (381/64 → 191/32) ⇝ 6/1 | note:B3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 23/4 ⇜ (381/64 → 191/32) ⇝ 6/1 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 23/4 ⇜ (381/64 → 191/32) ⇝ 6/1 | note:F4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 23/4 ⇜ (381/64 → 191/32) ⇝ 6/1 | note:A4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 23/4 ⇜ (191/32 → 383/64) ⇝ 6/1 | note:B3 gain:0.12 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 23/4 ⇜ (191/32 → 383/64) ⇝ 6/1 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 23/4 ⇜ (191/32 → 383/64) ⇝ 6/1 | note:F4 gain:0.12 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 23/4 ⇜ (191/32 → 383/64) ⇝ 6/1 | note:A4 gain:0.12 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 23/4 ⇜ (383/64 → 6/1) | note:B3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 23/4 ⇜ (383/64 → 6/1) | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 23/4 ⇜ (383/64 → 6/1) | note:F4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 23/4 ⇜ (383/64 → 6/1) | note:A4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ (6/1 → 385/64) ⇝ 25/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 6/1 ⇜ (385/64 → 193/32) ⇝ 25/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 6/1 ⇜ (193/32 → 387/64) ⇝ 25/4 | note:F#2 gain:0.64 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ (169/28 → 387/64) ⇝ 44/7 | note:71 gain:0.064 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ (169/28 → 387/64) ⇝ 44/7 | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ (169/28 → 387/64) ⇝ 44/7 | note:77 gain:0.064 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ (169/28 → 387/64) ⇝ 44/7 | note:81 gain:0.064 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 6/1 ⇜ (387/64 → 97/16) ⇝ 25/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 169/28 ⇜ (387/64 → 97/16) ⇝ 44/7 | note:71 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 169/28 ⇜ (387/64 → 97/16) ⇝ 44/7 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 169/28 ⇜ (387/64 → 97/16) ⇝ 44/7 | note:77 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 169/28 ⇜ (387/64 → 97/16) ⇝ 44/7 | note:81 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 6/1 ⇜ (97/16 → 389/64) ⇝ 25/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 169/28 ⇜ (97/16 → 389/64) ⇝ 44/7 | note:71 gain:0.044 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 169/28 ⇜ (97/16 → 389/64) ⇝ 44/7 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 169/28 ⇜ (97/16 → 389/64) ⇝ 44/7 | note:77 gain:0.044 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 169/28 ⇜ (97/16 → 389/64) ⇝ 44/7 | note:81 gain:0.044 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 6/1 ⇜ (389/64 → 195/32) ⇝ 25/4 | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 169/28 ⇜ (389/64 → 195/32) ⇝ 44/7 | note:71 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 169/28 ⇜ (389/64 → 195/32) ⇝ 44/7 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 169/28 ⇜ (389/64 → 195/32) ⇝ 44/7 | note:77 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 169/28 ⇜ (389/64 → 195/32) ⇝ 44/7 | note:81 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 6/1 ⇜ (195/32 → 391/64) ⇝ 25/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 169/28 ⇜ (195/32 → 391/64) ⇝ 44/7 | note:71 gain:0.024 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 169/28 ⇜ (195/32 → 391/64) ⇝ 44/7 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 169/28 ⇜ (195/32 → 391/64) ⇝ 44/7 | note:77 gain:0.024 clip:1 s:piano release:0.1 pan:0.606481481481 ]", "[ 169/28 ⇜ (195/32 → 391/64) ⇝ 44/7 | note:81 gain:0.024 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 6/1 ⇜ (391/64 → 49/8) ⇝ 25/4 | note:F#2 gain:0.2985786437626902 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 169/28 ⇜ (391/64 → 49/8) ⇝ 44/7 | note:71 gain:0.029857864376269024 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 169/28 ⇜ (391/64 → 49/8) ⇝ 44/7 | note:76 gain:0.029857864376269024 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 169/28 ⇜ (391/64 → 49/8) ⇝ 44/7 | note:77 gain:0.029857864376269024 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 169/28 ⇜ (391/64 → 49/8) ⇝ 44/7 | note:81 gain:0.029857864376269024 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 6/1 ⇜ (49/8 → 393/64) ⇝ 25/4 | note:F#2 gain:0.4399999999999933 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 169/28 ⇜ (49/8 → 393/64) ⇝ 44/7 | note:71 gain:0.04399999999999933 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 169/28 ⇜ (49/8 → 393/64) ⇝ 44/7 | note:76 gain:0.04399999999999933 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 169/28 ⇜ (49/8 → 393/64) ⇝ 44/7 | note:77 gain:0.04399999999999933 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 169/28 ⇜ (49/8 → 393/64) ⇝ 44/7 | note:81 gain:0.04399999999999933 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ (49/8 → 393/64) ⇝ 25/4 | note:F#4 gain:0.4399999999999933 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ (49/8 → 393/64) ⇝ 25/4 | note:A#4 gain:0.4399999999999933 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 6/1 ⇜ (393/64 → 197/32) ⇝ 25/4 | note:F#2 gain:0.5814213562373084 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 169/28 ⇜ (393/64 → 197/32) ⇝ 44/7 | note:71 gain:0.05814213562373084 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 169/28 ⇜ (393/64 → 197/32) ⇝ 44/7 | note:76 gain:0.05814213562373084 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 169/28 ⇜ (393/64 → 197/32) ⇝ 44/7 | note:77 gain:0.05814213562373084 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 169/28 ⇜ (393/64 → 197/32) ⇝ 44/7 | note:81 gain:0.05814213562373084 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 49/8 ⇜ (393/64 → 197/32) ⇝ 25/4 | note:F#4 gain:0.5814213562373084 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 49/8 ⇜ (393/64 → 197/32) ⇝ 25/4 | note:A#4 gain:0.5814213562373084 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 6/1 ⇜ (197/32 → 395/64) ⇝ 25/4 | note:F#2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 169/28 ⇜ (197/32 → 395/64) ⇝ 44/7 | note:71 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 169/28 ⇜ (197/32 → 395/64) ⇝ 44/7 | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 169/28 ⇜ (197/32 → 395/64) ⇝ 44/7 | note:77 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 169/28 ⇜ (197/32 → 395/64) ⇝ 44/7 | note:81 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 49/8 ⇜ (197/32 → 395/64) ⇝ 25/4 | note:F#4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 49/8 ⇜ (197/32 → 395/64) ⇝ 25/4 | note:A#4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 6/1 ⇜ (395/64 → 99/16) ⇝ 25/4 | note:F#2 gain:0.5814213562373114 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 169/28 ⇜ (395/64 → 99/16) ⇝ 44/7 | note:71 gain:0.05814213562373114 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 169/28 ⇜ (395/64 → 99/16) ⇝ 44/7 | note:76 gain:0.05814213562373114 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 169/28 ⇜ (395/64 → 99/16) ⇝ 44/7 | note:77 gain:0.05814213562373114 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 169/28 ⇜ (395/64 → 99/16) ⇝ 44/7 | note:81 gain:0.05814213562373114 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 49/8 ⇜ (395/64 → 99/16) ⇝ 25/4 | note:F#4 gain:0.5814213562373114 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 49/8 ⇜ (395/64 → 99/16) ⇝ 25/4 | note:A#4 gain:0.5814213562373114 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 6/1 ⇜ (99/16 → 397/64) ⇝ 25/4 | note:F#2 gain:0.4399999999999975 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 169/28 ⇜ (99/16 → 397/64) ⇝ 44/7 | note:71 gain:0.043999999999999755 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 169/28 ⇜ (99/16 → 397/64) ⇝ 44/7 | note:76 gain:0.043999999999999755 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 169/28 ⇜ (99/16 → 397/64) ⇝ 44/7 | note:77 gain:0.043999999999999755 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 169/28 ⇜ (99/16 → 397/64) ⇝ 44/7 | note:81 gain:0.043999999999999755 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 49/8 ⇜ (99/16 → 397/64) ⇝ 25/4 | note:F#4 gain:0.4399999999999975 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 49/8 ⇜ (99/16 → 397/64) ⇝ 25/4 | note:A#4 gain:0.4399999999999975 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 6/1 ⇜ (397/64 → 199/32) ⇝ 25/4 | note:F#2 gain:0.2985786437626931 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 169/28 ⇜ (397/64 → 199/32) ⇝ 44/7 | note:71 gain:0.029857864376269312 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 169/28 ⇜ (397/64 → 199/32) ⇝ 44/7 | note:76 gain:0.029857864376269312 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 169/28 ⇜ (397/64 → 199/32) ⇝ 44/7 | note:77 gain:0.029857864376269312 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 169/28 ⇜ (397/64 → 199/32) ⇝ 44/7 | note:81 gain:0.029857864376269312 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 49/8 ⇜ (397/64 → 199/32) ⇝ 25/4 | note:F#4 gain:0.2985786437626931 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 49/8 ⇜ (397/64 → 199/32) ⇝ 25/4 | note:A#4 gain:0.2985786437626931 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 6/1 ⇜ (199/32 → 399/64) ⇝ 25/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 169/28 ⇜ (199/32 → 399/64) ⇝ 44/7 | note:71 gain:0.024 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 169/28 ⇜ (199/32 → 399/64) ⇝ 44/7 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 169/28 ⇜ (199/32 → 399/64) ⇝ 44/7 | note:77 gain:0.024 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", + "[ 6/1 ⇜ (391/64 → 49/8) ⇝ 25/4 | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 169/28 ⇜ (391/64 → 49/8) ⇝ 44/7 | note:71 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 169/28 ⇜ (391/64 → 49/8) ⇝ 44/7 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 169/28 ⇜ (391/64 → 49/8) ⇝ 44/7 | note:77 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 169/28 ⇜ (391/64 → 49/8) ⇝ 44/7 | note:81 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 6/1 ⇜ (49/8 → 393/64) ⇝ 25/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 169/28 ⇜ (49/8 → 393/64) ⇝ 44/7 | note:71 gain:0.044 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 169/28 ⇜ (49/8 → 393/64) ⇝ 44/7 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 169/28 ⇜ (49/8 → 393/64) ⇝ 44/7 | note:77 gain:0.044 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 169/28 ⇜ (49/8 → 393/64) ⇝ 44/7 | note:81 gain:0.044 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ (49/8 → 393/64) ⇝ 25/4 | note:F#4 gain:0.44 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ (49/8 → 393/64) ⇝ 25/4 | note:A#4 gain:0.44 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 6/1 ⇜ (393/64 → 197/32) ⇝ 25/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 169/28 ⇜ (393/64 → 197/32) ⇝ 44/7 | note:71 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 169/28 ⇜ (393/64 → 197/32) ⇝ 44/7 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 169/28 ⇜ (393/64 → 197/32) ⇝ 44/7 | note:77 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 169/28 ⇜ (393/64 → 197/32) ⇝ 44/7 | note:81 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 49/8 ⇜ (393/64 → 197/32) ⇝ 25/4 | note:F#4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 49/8 ⇜ (393/64 → 197/32) ⇝ 25/4 | note:A#4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 6/1 ⇜ (197/32 → 395/64) ⇝ 25/4 | note:F#2 gain:0.64 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 169/28 ⇜ (197/32 → 395/64) ⇝ 44/7 | note:71 gain:0.064 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 169/28 ⇜ (197/32 → 395/64) ⇝ 44/7 | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 169/28 ⇜ (197/32 → 395/64) ⇝ 44/7 | note:77 gain:0.064 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 169/28 ⇜ (197/32 → 395/64) ⇝ 44/7 | note:81 gain:0.064 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 49/8 ⇜ (197/32 → 395/64) ⇝ 25/4 | note:F#4 gain:0.64 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 49/8 ⇜ (197/32 → 395/64) ⇝ 25/4 | note:A#4 gain:0.64 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 6/1 ⇜ (395/64 → 99/16) ⇝ 25/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 169/28 ⇜ (395/64 → 99/16) ⇝ 44/7 | note:71 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 169/28 ⇜ (395/64 → 99/16) ⇝ 44/7 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 169/28 ⇜ (395/64 → 99/16) ⇝ 44/7 | note:77 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 169/28 ⇜ (395/64 → 99/16) ⇝ 44/7 | note:81 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 49/8 ⇜ (395/64 → 99/16) ⇝ 25/4 | note:F#4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 49/8 ⇜ (395/64 → 99/16) ⇝ 25/4 | note:A#4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 6/1 ⇜ (99/16 → 397/64) ⇝ 25/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 169/28 ⇜ (99/16 → 397/64) ⇝ 44/7 | note:71 gain:0.044 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 169/28 ⇜ (99/16 → 397/64) ⇝ 44/7 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 169/28 ⇜ (99/16 → 397/64) ⇝ 44/7 | note:77 gain:0.044 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 169/28 ⇜ (99/16 → 397/64) ⇝ 44/7 | note:81 gain:0.044 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 49/8 ⇜ (99/16 → 397/64) ⇝ 25/4 | note:F#4 gain:0.44 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 49/8 ⇜ (99/16 → 397/64) ⇝ 25/4 | note:A#4 gain:0.44 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 6/1 ⇜ (397/64 → 199/32) ⇝ 25/4 | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 169/28 ⇜ (397/64 → 199/32) ⇝ 44/7 | note:71 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 169/28 ⇜ (397/64 → 199/32) ⇝ 44/7 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 169/28 ⇜ (397/64 → 199/32) ⇝ 44/7 | note:77 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 169/28 ⇜ (397/64 → 199/32) ⇝ 44/7 | note:81 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 49/8 ⇜ (397/64 → 199/32) ⇝ 25/4 | note:F#4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 49/8 ⇜ (397/64 → 199/32) ⇝ 25/4 | note:A#4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 6/1 ⇜ (199/32 → 399/64) ⇝ 25/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 169/28 ⇜ (199/32 → 399/64) ⇝ 44/7 | note:71 gain:0.024 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 169/28 ⇜ (199/32 → 399/64) ⇝ 44/7 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 169/28 ⇜ (199/32 → 399/64) ⇝ 44/7 | note:77 gain:0.024 clip:1 s:piano release:0.1 pan:0.606481481481 ]", "[ 169/28 ⇜ (199/32 → 399/64) ⇝ 44/7 | note:81 gain:0.024 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 49/8 ⇜ (199/32 → 399/64) ⇝ 25/4 | note:F#4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 49/8 ⇜ (199/32 → 399/64) ⇝ 25/4 | note:A#4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 6/1 ⇜ (399/64 → 25/4) | note:F#2 gain:0.2985786437626871 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 169/28 ⇜ (399/64 → 25/4) ⇝ 44/7 | note:71 gain:0.029857864376268712 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 169/28 ⇜ (399/64 → 25/4) ⇝ 44/7 | note:76 gain:0.029857864376268712 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 169/28 ⇜ (399/64 → 25/4) ⇝ 44/7 | note:77 gain:0.029857864376268712 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 169/28 ⇜ (399/64 → 25/4) ⇝ 44/7 | note:81 gain:0.029857864376268712 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 49/8 ⇜ (399/64 → 25/4) | note:F#4 gain:0.2985786437626871 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 49/8 ⇜ (399/64 → 25/4) | note:A#4 gain:0.2985786437626871 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 169/28 ⇜ (25/4 → 401/64) ⇝ 44/7 | note:71 gain:0.04400000000000004 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 169/28 ⇜ (25/4 → 401/64) ⇝ 44/7 | note:76 gain:0.04400000000000004 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 169/28 ⇜ (25/4 → 401/64) ⇝ 44/7 | note:77 gain:0.04400000000000004 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 169/28 ⇜ (25/4 → 401/64) ⇝ 44/7 | note:81 gain:0.04400000000000004 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 169/28 ⇜ (401/64 → 201/32) ⇝ 44/7 | note:71 gain:0.058142135623730544 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 169/28 ⇜ (401/64 → 201/32) ⇝ 44/7 | note:76 gain:0.058142135623730544 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 169/28 ⇜ (401/64 → 201/32) ⇝ 44/7 | note:77 gain:0.058142135623730544 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 169/28 ⇜ (401/64 → 201/32) ⇝ 44/7 | note:81 gain:0.058142135623730544 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 169/28 ⇜ (201/32 → 44/7) | note:71 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 169/28 ⇜ (201/32 → 44/7) | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 169/28 ⇜ (201/32 → 44/7) | note:77 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 169/28 ⇜ (201/32 → 44/7) | note:81 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ (13/2 → 417/64) ⇝ 53/8 | note:C#5 gain:0.44000000000000317 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ (13/2 → 417/64) ⇝ 53/8 | note:E5 gain:0.44000000000000317 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ (13/2 → 417/64) ⇝ 27/4 | note:Bb3 gain:0.22000000000000158 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ (13/2 → 417/64) ⇝ 27/4 | note:Eb4 gain:0.22000000000000158 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ (13/2 → 417/64) ⇝ 27/4 | note:E4 gain:0.22000000000000158 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (13/2 → 417/64) ⇝ 27/4 | note:Ab4 gain:0.22000000000000158 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ (13/2 → 417/64) ⇝ 27/4 | note:F#2 gain:0.44000000000000317 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 13/2 ⇜ (417/64 → 209/32) ⇝ 53/8 | note:C#5 gain:0.5814213562373073 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 13/2 ⇜ (417/64 → 209/32) ⇝ 53/8 | note:E5 gain:0.5814213562373073 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 13/2 ⇜ (417/64 → 209/32) ⇝ 27/4 | note:Bb3 gain:0.29071067811865364 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 13/2 ⇜ (417/64 → 209/32) ⇝ 27/4 | note:Eb4 gain:0.29071067811865364 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/2 ⇜ (417/64 → 209/32) ⇝ 27/4 | note:E4 gain:0.29071067811865364 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 13/2 ⇜ (417/64 → 209/32) ⇝ 27/4 | note:Ab4 gain:0.29071067811865364 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/2 ⇜ (417/64 → 209/32) ⇝ 27/4 | note:F#2 gain:0.5814213562373073 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 13/2 ⇜ (209/32 → 419/64) ⇝ 53/8 | note:C#5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 13/2 ⇜ (209/32 → 419/64) ⇝ 53/8 | note:E5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 13/2 ⇜ (209/32 → 419/64) ⇝ 27/4 | note:Bb3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 13/2 ⇜ (209/32 → 419/64) ⇝ 27/4 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/2 ⇜ (209/32 → 419/64) ⇝ 27/4 | note:E4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 13/2 ⇜ (209/32 → 419/64) ⇝ 27/4 | note:Ab4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/2 ⇜ (209/32 → 419/64) ⇝ 27/4 | note:F#2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 13/2 ⇜ (419/64 → 105/16) ⇝ 53/8 | note:C#5 gain:0.5814213562373125 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 13/2 ⇜ (419/64 → 105/16) ⇝ 53/8 | note:E5 gain:0.5814213562373125 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 13/2 ⇜ (419/64 → 105/16) ⇝ 27/4 | note:Bb3 gain:0.29071067811865625 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 13/2 ⇜ (419/64 → 105/16) ⇝ 27/4 | note:Eb4 gain:0.29071067811865625 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/2 ⇜ (419/64 → 105/16) ⇝ 27/4 | note:E4 gain:0.29071067811865625 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 13/2 ⇜ (419/64 → 105/16) ⇝ 27/4 | note:Ab4 gain:0.29071067811865625 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/2 ⇜ (419/64 → 105/16) ⇝ 27/4 | note:F#2 gain:0.5814213562373125 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 13/2 ⇜ (105/16 → 421/64) ⇝ 53/8 | note:C#5 gain:0.439999999999999 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 13/2 ⇜ (105/16 → 421/64) ⇝ 53/8 | note:E5 gain:0.439999999999999 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 13/2 ⇜ (105/16 → 421/64) ⇝ 27/4 | note:Bb3 gain:0.2199999999999995 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 13/2 ⇜ (105/16 → 421/64) ⇝ 27/4 | note:Eb4 gain:0.2199999999999995 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/2 ⇜ (105/16 → 421/64) ⇝ 27/4 | note:E4 gain:0.2199999999999995 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 13/2 ⇜ (105/16 → 421/64) ⇝ 27/4 | note:Ab4 gain:0.2199999999999995 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/2 ⇜ (105/16 → 421/64) ⇝ 27/4 | note:F#2 gain:0.439999999999999 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 13/2 ⇜ (421/64 → 211/32) ⇝ 53/8 | note:C#5 gain:0.2985786437626942 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 13/2 ⇜ (421/64 → 211/32) ⇝ 53/8 | note:E5 gain:0.2985786437626942 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 13/2 ⇜ (421/64 → 211/32) ⇝ 27/4 | note:Bb3 gain:0.1492893218813471 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 13/2 ⇜ (421/64 → 211/32) ⇝ 27/4 | note:Eb4 gain:0.1492893218813471 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/2 ⇜ (421/64 → 211/32) ⇝ 27/4 | note:E4 gain:0.1492893218813471 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 13/2 ⇜ (421/64 → 211/32) ⇝ 27/4 | note:Ab4 gain:0.1492893218813471 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/2 ⇜ (421/64 → 211/32) ⇝ 27/4 | note:F#2 gain:0.2985786437626942 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 13/2 ⇜ (211/32 → 423/64) ⇝ 53/8 | note:C#5 gain:0.24 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 13/2 ⇜ (211/32 → 423/64) ⇝ 53/8 | note:E5 gain:0.24 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 13/2 ⇜ (211/32 → 423/64) ⇝ 27/4 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 13/2 ⇜ (211/32 → 423/64) ⇝ 27/4 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/2 ⇜ (211/32 → 423/64) ⇝ 27/4 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 13/2 ⇜ (211/32 → 423/64) ⇝ 27/4 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/2 ⇜ (211/32 → 423/64) ⇝ 27/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 13/2 ⇜ (423/64 → 53/8) | note:C#5 gain:0.298578643762686 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 13/2 ⇜ (423/64 → 53/8) | note:E5 gain:0.298578643762686 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 13/2 ⇜ (423/64 → 53/8) ⇝ 27/4 | note:Bb3 gain:0.149289321881343 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 13/2 ⇜ (423/64 → 53/8) ⇝ 27/4 | note:Eb4 gain:0.149289321881343 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/2 ⇜ (423/64 → 53/8) ⇝ 27/4 | note:E4 gain:0.149289321881343 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 13/2 ⇜ (423/64 → 53/8) ⇝ 27/4 | note:Ab4 gain:0.149289321881343 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/2 ⇜ (423/64 → 53/8) ⇝ 27/4 | note:F#2 gain:0.298578643762686 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 13/2 ⇜ (53/8 → 425/64) ⇝ 27/4 | note:Bb3 gain:0.21999999999999942 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 13/2 ⇜ (53/8 → 425/64) ⇝ 27/4 | note:Eb4 gain:0.21999999999999942 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/2 ⇜ (53/8 → 425/64) ⇝ 27/4 | note:E4 gain:0.21999999999999942 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 13/2 ⇜ (53/8 → 425/64) ⇝ 27/4 | note:Ab4 gain:0.21999999999999942 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/2 ⇜ (53/8 → 425/64) ⇝ 27/4 | note:F#2 gain:0.43999999999999884 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 13/2 ⇜ (425/64 → 213/32) ⇝ 27/4 | note:Bb3 gain:0.29071067811865214 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 13/2 ⇜ (425/64 → 213/32) ⇝ 27/4 | note:Eb4 gain:0.29071067811865214 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/2 ⇜ (425/64 → 213/32) ⇝ 27/4 | note:E4 gain:0.29071067811865214 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 13/2 ⇜ (425/64 → 213/32) ⇝ 27/4 | note:Ab4 gain:0.29071067811865214 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/2 ⇜ (425/64 → 213/32) ⇝ 27/4 | note:F#2 gain:0.5814213562373043 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 13/2 ⇜ (213/32 → 427/64) ⇝ 27/4 | note:Bb3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 13/2 ⇜ (213/32 → 427/64) ⇝ 27/4 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/2 ⇜ (213/32 → 427/64) ⇝ 27/4 | note:E4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 13/2 ⇜ (213/32 → 427/64) ⇝ 27/4 | note:Ab4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/2 ⇜ (213/32 → 427/64) ⇝ 27/4 | note:F#2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 13/2 ⇜ (427/64 → 107/16) ⇝ 27/4 | note:Bb3 gain:0.29071067811865375 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 13/2 ⇜ (427/64 → 107/16) ⇝ 27/4 | note:Eb4 gain:0.29071067811865375 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/2 ⇜ (427/64 → 107/16) ⇝ 27/4 | note:E4 gain:0.29071067811865375 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 13/2 ⇜ (427/64 → 107/16) ⇝ 27/4 | note:Ab4 gain:0.29071067811865375 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/2 ⇜ (427/64 → 107/16) ⇝ 27/4 | note:F#2 gain:0.5814213562373075 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 13/2 ⇜ (107/16 → 429/64) ⇝ 27/4 | note:Bb3 gain:0.22000000000000167 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 13/2 ⇜ (107/16 → 429/64) ⇝ 27/4 | note:Eb4 gain:0.22000000000000167 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/2 ⇜ (107/16 → 429/64) ⇝ 27/4 | note:E4 gain:0.22000000000000167 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 13/2 ⇜ (107/16 → 429/64) ⇝ 27/4 | note:Ab4 gain:0.22000000000000167 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/2 ⇜ (107/16 → 429/64) ⇝ 27/4 | note:F#2 gain:0.44000000000000333 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 13/2 ⇜ (429/64 → 215/32) ⇝ 27/4 | note:Bb3 gain:0.1492893218813446 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 13/2 ⇜ (429/64 → 215/32) ⇝ 27/4 | note:Eb4 gain:0.1492893218813446 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/2 ⇜ (429/64 → 215/32) ⇝ 27/4 | note:E4 gain:0.1492893218813446 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 13/2 ⇜ (429/64 → 215/32) ⇝ 27/4 | note:Ab4 gain:0.1492893218813446 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/2 ⇜ (429/64 → 215/32) ⇝ 27/4 | note:F#2 gain:0.2985786437626892 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 13/2 ⇜ (215/32 → 431/64) ⇝ 27/4 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 13/2 ⇜ (215/32 → 431/64) ⇝ 27/4 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/2 ⇜ (215/32 → 431/64) ⇝ 27/4 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 13/2 ⇜ (215/32 → 431/64) ⇝ 27/4 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/2 ⇜ (215/32 → 431/64) ⇝ 27/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 13/2 ⇜ (431/64 → 27/4) | note:Bb3 gain:0.1492893218813455 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 13/2 ⇜ (431/64 → 27/4) | note:Eb4 gain:0.1492893218813455 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/2 ⇜ (431/64 → 27/4) | note:E4 gain:0.1492893218813455 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 13/2 ⇜ (431/64 → 27/4) | note:Ab4 gain:0.1492893218813455 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 13/2 ⇜ (431/64 → 27/4) | note:F#2 gain:0.298578643762691 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ (27/4 → 433/64) ⇝ 55/8 | note:F#4 gain:0.43999999999999456 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ (27/4 → 433/64) ⇝ 55/8 | note:A#4 gain:0.43999999999999456 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 27/4 ⇜ (433/64 → 217/32) ⇝ 55/8 | note:F#4 gain:0.5814213562373093 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 27/4 ⇜ (433/64 → 217/32) ⇝ 55/8 | note:A#4 gain:0.5814213562373093 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 27/4 ⇜ (217/32 → 435/64) ⇝ 55/8 | note:F#4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 27/4 ⇜ (217/32 → 435/64) ⇝ 55/8 | note:A#4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ (95/14 → 435/64) ⇝ 197/28 | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ (95/14 → 435/64) ⇝ 197/28 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ (95/14 → 435/64) ⇝ 197/28 | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ (95/14 → 435/64) ⇝ 197/28 | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 27/4 ⇜ (435/64 → 109/16) ⇝ 55/8 | note:F#4 gain:0.5814213562373105 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 27/4 ⇜ (435/64 → 109/16) ⇝ 55/8 | note:A#4 gain:0.5814213562373105 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 95/14 ⇜ (435/64 → 109/16) ⇝ 197/28 | note:70 gain:0.05814213562373105 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 95/14 ⇜ (435/64 → 109/16) ⇝ 197/28 | note:75 gain:0.05814213562373105 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 95/14 ⇜ (435/64 → 109/16) ⇝ 197/28 | note:76 gain:0.05814213562373105 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 95/14 ⇜ (435/64 → 109/16) ⇝ 197/28 | note:80 gain:0.05814213562373105 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 27/4 ⇜ (109/16 → 437/64) ⇝ 55/8 | note:F#4 gain:0.4400000000000077 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 27/4 ⇜ (109/16 → 437/64) ⇝ 55/8 | note:A#4 gain:0.4400000000000077 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 95/14 ⇜ (109/16 → 437/64) ⇝ 197/28 | note:70 gain:0.044000000000000775 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 95/14 ⇜ (109/16 → 437/64) ⇝ 197/28 | note:75 gain:0.044000000000000775 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 95/14 ⇜ (109/16 → 437/64) ⇝ 197/28 | note:76 gain:0.044000000000000775 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 95/14 ⇜ (109/16 → 437/64) ⇝ 197/28 | note:80 gain:0.044000000000000775 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 27/4 ⇜ (437/64 → 219/32) ⇝ 55/8 | note:F#4 gain:0.2985786437626922 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 27/4 ⇜ (437/64 → 219/32) ⇝ 55/8 | note:A#4 gain:0.2985786437626922 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 95/14 ⇜ (437/64 → 219/32) ⇝ 197/28 | note:70 gain:0.029857864376269222 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 95/14 ⇜ (437/64 → 219/32) ⇝ 197/28 | note:75 gain:0.029857864376269222 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 95/14 ⇜ (437/64 → 219/32) ⇝ 197/28 | note:76 gain:0.029857864376269222 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 95/14 ⇜ (437/64 → 219/32) ⇝ 197/28 | note:80 gain:0.029857864376269222 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 27/4 ⇜ (219/32 → 439/64) ⇝ 55/8 | note:F#4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 27/4 ⇜ (219/32 → 439/64) ⇝ 55/8 | note:A#4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 95/14 ⇜ (219/32 → 439/64) ⇝ 197/28 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 95/14 ⇜ (219/32 → 439/64) ⇝ 197/28 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 95/14 ⇜ (219/32 → 439/64) ⇝ 197/28 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 95/14 ⇜ (219/32 → 439/64) ⇝ 197/28 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 27/4 ⇜ (439/64 → 55/8) | note:F#4 gain:0.298578643762688 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 27/4 ⇜ (439/64 → 55/8) | note:A#4 gain:0.298578643762688 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 95/14 ⇜ (439/64 → 55/8) ⇝ 197/28 | note:70 gain:0.029857864376268802 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 95/14 ⇜ (439/64 → 55/8) ⇝ 197/28 | note:75 gain:0.029857864376268802 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 95/14 ⇜ (439/64 → 55/8) ⇝ 197/28 | note:76 gain:0.029857864376268802 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 95/14 ⇜ (439/64 → 55/8) ⇝ 197/28 | note:80 gain:0.029857864376268802 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 95/14 ⇜ (55/8 → 441/64) ⇝ 197/28 | note:70 gain:0.04400000000000016 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 95/14 ⇜ (55/8 → 441/64) ⇝ 197/28 | note:75 gain:0.04400000000000016 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 95/14 ⇜ (55/8 → 441/64) ⇝ 197/28 | note:76 gain:0.04400000000000016 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 95/14 ⇜ (55/8 → 441/64) ⇝ 197/28 | note:80 gain:0.04400000000000016 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 95/14 ⇜ (441/64 → 221/32) ⇝ 197/28 | note:70 gain:0.058142135623730634 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 95/14 ⇜ (441/64 → 221/32) ⇝ 197/28 | note:75 gain:0.058142135623730634 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 95/14 ⇜ (441/64 → 221/32) ⇝ 197/28 | note:76 gain:0.058142135623730634 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 95/14 ⇜ (441/64 → 221/32) ⇝ 197/28 | note:80 gain:0.058142135623730634 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 95/14 ⇜ (221/32 → 443/64) ⇝ 197/28 | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 95/14 ⇜ (221/32 → 443/64) ⇝ 197/28 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 95/14 ⇜ (221/32 → 443/64) ⇝ 197/28 | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 95/14 ⇜ (221/32 → 443/64) ⇝ 197/28 | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 95/14 ⇜ (443/64 → 111/16) ⇝ 197/28 | note:70 gain:0.058142135623731356 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 95/14 ⇜ (443/64 → 111/16) ⇝ 197/28 | note:75 gain:0.058142135623731356 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 95/14 ⇜ (443/64 → 111/16) ⇝ 197/28 | note:76 gain:0.058142135623731356 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 95/14 ⇜ (443/64 → 111/16) ⇝ 197/28 | note:80 gain:0.058142135623731356 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 95/14 ⇜ (111/16 → 445/64) ⇝ 197/28 | note:70 gain:0.04400000000000007 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 95/14 ⇜ (111/16 → 445/64) ⇝ 197/28 | note:75 gain:0.04400000000000007 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 95/14 ⇜ (111/16 → 445/64) ⇝ 197/28 | note:76 gain:0.04400000000000007 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 95/14 ⇜ (111/16 → 445/64) ⇝ 197/28 | note:80 gain:0.04400000000000007 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 95/14 ⇜ (445/64 → 223/32) ⇝ 197/28 | note:70 gain:0.029857864376269534 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 95/14 ⇜ (445/64 → 223/32) ⇝ 197/28 | note:75 gain:0.029857864376269534 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 95/14 ⇜ (445/64 → 223/32) ⇝ 197/28 | note:76 gain:0.029857864376269534 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 95/14 ⇜ (445/64 → 223/32) ⇝ 197/28 | note:80 gain:0.029857864376269534 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 95/14 ⇜ (223/32 → 447/64) ⇝ 197/28 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 95/14 ⇜ (223/32 → 447/64) ⇝ 197/28 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 95/14 ⇜ (223/32 → 447/64) ⇝ 197/28 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 95/14 ⇜ (223/32 → 447/64) ⇝ 197/28 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 95/14 ⇜ (447/64 → 7/1) ⇝ 197/28 | note:70 gain:0.02985786437626849 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 95/14 ⇜ (447/64 → 7/1) ⇝ 197/28 | note:75 gain:0.02985786437626849 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 95/14 ⇜ (447/64 → 7/1) ⇝ 197/28 | note:76 gain:0.02985786437626849 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 95/14 ⇜ (447/64 → 7/1) ⇝ 197/28 | note:80 gain:0.02985786437626849 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 95/14 ⇜ (7/1 → 449/64) ⇝ 197/28 | note:70 gain:0.04399999999999973 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 95/14 ⇜ (7/1 → 449/64) ⇝ 197/28 | note:75 gain:0.04399999999999973 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 95/14 ⇜ (7/1 → 449/64) ⇝ 197/28 | note:76 gain:0.04399999999999973 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 95/14 ⇜ (7/1 → 449/64) ⇝ 197/28 | note:80 gain:0.04399999999999973 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ (7/1 → 449/64) ⇝ 29/4 | note:F#2 gain:0.4399999999999972 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 95/14 ⇜ (449/64 → 225/32) ⇝ 197/28 | note:70 gain:0.058142135623731134 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 95/14 ⇜ (449/64 → 225/32) ⇝ 197/28 | note:75 gain:0.058142135623731134 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 95/14 ⇜ (449/64 → 225/32) ⇝ 197/28 | note:76 gain:0.058142135623731134 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 95/14 ⇜ (449/64 → 225/32) ⇝ 197/28 | note:80 gain:0.058142135623731134 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 7/1 ⇜ (449/64 → 225/32) ⇝ 29/4 | note:F#2 gain:0.5814213562373113 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 95/14 ⇜ (225/32 → 197/28) | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 95/14 ⇜ (225/32 → 197/28) | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 95/14 ⇜ (225/32 → 197/28) | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 95/14 ⇜ (225/32 → 197/28) | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 7/1 ⇜ (225/32 → 451/64) ⇝ 29/4 | note:F#2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 7/1 ⇜ (451/64 → 113/16) ⇝ 29/4 | note:F#2 gain:0.5814213562373086 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 7/1 ⇜ (113/16 → 453/64) ⇝ 29/4 | note:F#2 gain:0.44000000000000483 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 7/1 ⇜ (453/64 → 227/32) ⇝ 29/4 | note:F#2 gain:0.29857864376269033 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 7/1 ⇜ (227/32 → 455/64) ⇝ 29/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 7/1 ⇜ (455/64 → 57/8) ⇝ 29/4 | note:F#2 gain:0.29857864376268994 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 7/1 ⇜ (57/8 → 457/64) ⇝ 29/4 | note:F#2 gain:0.43999999999999295 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ (57/8 → 457/64) ⇝ 29/4 | note:F#4 gain:0.43999999999999295 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ (57/8 → 457/64) ⇝ 29/4 | note:A#4 gain:0.43999999999999295 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 7/1 ⇜ (457/64 → 229/32) ⇝ 29/4 | note:F#2 gain:0.5814213562373082 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 57/8 ⇜ (457/64 → 229/32) ⇝ 29/4 | note:F#4 gain:0.5814213562373082 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 57/8 ⇜ (457/64 → 229/32) ⇝ 29/4 | note:A#4 gain:0.5814213562373082 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 7/1 ⇜ (229/32 → 459/64) ⇝ 29/4 | note:F#2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 57/8 ⇜ (229/32 → 459/64) ⇝ 29/4 | note:F#4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 57/8 ⇜ (229/32 → 459/64) ⇝ 29/4 | note:A#4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 7/1 ⇜ (459/64 → 115/16) ⇝ 29/4 | note:F#2 gain:0.5814213562373116 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 57/8 ⇜ (459/64 → 115/16) ⇝ 29/4 | note:F#4 gain:0.5814213562373116 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 57/8 ⇜ (459/64 → 115/16) ⇝ 29/4 | note:A#4 gain:0.5814213562373116 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 7/1 ⇜ (115/16 → 461/64) ⇝ 29/4 | note:F#2 gain:0.43999999999999784 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 57/8 ⇜ (115/16 → 461/64) ⇝ 29/4 | note:F#4 gain:0.43999999999999784 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 57/8 ⇜ (115/16 → 461/64) ⇝ 29/4 | note:A#4 gain:0.43999999999999784 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 7/1 ⇜ (461/64 → 231/32) ⇝ 29/4 | note:F#2 gain:0.2985786437626934 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 57/8 ⇜ (461/64 → 231/32) ⇝ 29/4 | note:F#4 gain:0.2985786437626934 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 57/8 ⇜ (461/64 → 231/32) ⇝ 29/4 | note:A#4 gain:0.2985786437626934 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 7/1 ⇜ (231/32 → 463/64) ⇝ 29/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 57/8 ⇜ (231/32 → 463/64) ⇝ 29/4 | note:F#4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 57/8 ⇜ (231/32 → 463/64) ⇝ 29/4 | note:A#4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 7/1 ⇜ (463/64 → 29/4) | note:F#2 gain:0.2985786437626869 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 57/8 ⇜ (463/64 → 29/4) | note:F#4 gain:0.2985786437626869 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 57/8 ⇜ (463/64 → 29/4) | note:A#4 gain:0.2985786437626869 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ (29/4 → 465/64) ⇝ 15/2 | note:Bb3 gain:0.22000000000000003 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ (29/4 → 465/64) ⇝ 15/2 | note:Eb4 gain:0.22000000000000003 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ (29/4 → 465/64) ⇝ 15/2 | note:E4 gain:0.22000000000000003 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (29/4 → 465/64) ⇝ 15/2 | note:Ab4 gain:0.22000000000000003 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/4 ⇜ (465/64 → 233/32) ⇝ 15/2 | note:Bb3 gain:0.2907106781186526 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/4 ⇜ (465/64 → 233/32) ⇝ 15/2 | note:Eb4 gain:0.2907106781186526 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/4 ⇜ (465/64 → 233/32) ⇝ 15/2 | note:E4 gain:0.2907106781186526 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/4 ⇜ (465/64 → 233/32) ⇝ 15/2 | note:Ab4 gain:0.2907106781186526 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/4 ⇜ (233/32 → 467/64) ⇝ 15/2 | note:Bb3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/4 ⇜ (233/32 → 467/64) ⇝ 15/2 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/4 ⇜ (233/32 → 467/64) ⇝ 15/2 | note:E4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/4 ⇜ (233/32 → 467/64) ⇝ 15/2 | note:Ab4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/4 ⇜ (467/64 → 117/16) ⇝ 15/2 | note:Bb3 gain:0.2907106781186573 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/4 ⇜ (467/64 → 117/16) ⇝ 15/2 | note:Eb4 gain:0.2907106781186573 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/4 ⇜ (467/64 → 117/16) ⇝ 15/2 | note:E4 gain:0.2907106781186573 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/4 ⇜ (467/64 → 117/16) ⇝ 15/2 | note:Ab4 gain:0.2907106781186573 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/4 ⇜ (117/16 → 469/64) ⇝ 15/2 | note:Bb3 gain:0.22000000000000108 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/4 ⇜ (117/16 → 469/64) ⇝ 15/2 | note:Eb4 gain:0.22000000000000108 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/4 ⇜ (117/16 → 469/64) ⇝ 15/2 | note:E4 gain:0.22000000000000108 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/4 ⇜ (117/16 → 469/64) ⇝ 15/2 | note:Ab4 gain:0.22000000000000108 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/4 ⇜ (469/64 → 235/32) ⇝ 15/2 | note:Bb3 gain:0.14928932188134822 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/4 ⇜ (469/64 → 235/32) ⇝ 15/2 | note:Eb4 gain:0.14928932188134822 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/4 ⇜ (469/64 → 235/32) ⇝ 15/2 | note:E4 gain:0.14928932188134822 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/4 ⇜ (469/64 → 235/32) ⇝ 15/2 | note:Ab4 gain:0.14928932188134822 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/4 ⇜ (235/32 → 471/64) ⇝ 15/2 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/4 ⇜ (235/32 → 471/64) ⇝ 15/2 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/4 ⇜ (235/32 → 471/64) ⇝ 15/2 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/4 ⇜ (235/32 → 471/64) ⇝ 15/2 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/4 ⇜ (471/64 → 59/8) ⇝ 15/2 | note:Bb3 gain:0.14928932188134592 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/4 ⇜ (471/64 → 59/8) ⇝ 15/2 | note:Eb4 gain:0.14928932188134592 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/4 ⇜ (471/64 → 59/8) ⇝ 15/2 | note:E4 gain:0.14928932188134592 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/4 ⇜ (471/64 → 59/8) ⇝ 15/2 | note:Ab4 gain:0.14928932188134592 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/4 ⇜ (59/8 → 473/64) ⇝ 15/2 | note:Bb3 gain:0.21999999999999786 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/4 ⇜ (59/8 → 473/64) ⇝ 15/2 | note:Eb4 gain:0.21999999999999786 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/4 ⇜ (59/8 → 473/64) ⇝ 15/2 | note:E4 gain:0.21999999999999786 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/4 ⇜ (59/8 → 473/64) ⇝ 15/2 | note:Ab4 gain:0.21999999999999786 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/4 ⇜ (473/64 → 237/32) ⇝ 15/2 | note:Bb3 gain:0.2907106781186551 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/4 ⇜ (473/64 → 237/32) ⇝ 15/2 | note:Eb4 gain:0.2907106781186551 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/4 ⇜ (473/64 → 237/32) ⇝ 15/2 | note:E4 gain:0.2907106781186551 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/4 ⇜ (473/64 → 237/32) ⇝ 15/2 | note:Ab4 gain:0.2907106781186551 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/4 ⇜ (237/32 → 475/64) ⇝ 15/2 | note:Bb3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/4 ⇜ (237/32 → 475/64) ⇝ 15/2 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/4 ⇜ (237/32 → 475/64) ⇝ 15/2 | note:E4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/4 ⇜ (237/32 → 475/64) ⇝ 15/2 | note:Ab4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/4 ⇜ (475/64 → 119/16) ⇝ 15/2 | note:Bb3 gain:0.2907106781186548 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/4 ⇜ (475/64 → 119/16) ⇝ 15/2 | note:Eb4 gain:0.2907106781186548 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/4 ⇜ (475/64 → 119/16) ⇝ 15/2 | note:E4 gain:0.2907106781186548 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/4 ⇜ (475/64 → 119/16) ⇝ 15/2 | note:Ab4 gain:0.2907106781186548 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/4 ⇜ (119/16 → 477/64) ⇝ 15/2 | note:Bb3 gain:0.22000000000000322 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/4 ⇜ (119/16 → 477/64) ⇝ 15/2 | note:Eb4 gain:0.22000000000000322 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/4 ⇜ (119/16 → 477/64) ⇝ 15/2 | note:E4 gain:0.22000000000000322 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/4 ⇜ (119/16 → 477/64) ⇝ 15/2 | note:Ab4 gain:0.22000000000000322 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/4 ⇜ (477/64 → 239/32) ⇝ 15/2 | note:Bb3 gain:0.14928932188134572 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/4 ⇜ (477/64 → 239/32) ⇝ 15/2 | note:Eb4 gain:0.14928932188134572 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/4 ⇜ (477/64 → 239/32) ⇝ 15/2 | note:E4 gain:0.14928932188134572 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/4 ⇜ (477/64 → 239/32) ⇝ 15/2 | note:Ab4 gain:0.14928932188134572 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/4 ⇜ (239/32 → 479/64) ⇝ 15/2 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/4 ⇜ (239/32 → 479/64) ⇝ 15/2 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/4 ⇜ (239/32 → 479/64) ⇝ 15/2 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/4 ⇜ (239/32 → 479/64) ⇝ 15/2 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/4 ⇜ (479/64 → 15/2) | note:Bb3 gain:0.1492893218813444 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/4 ⇜ (479/64 → 15/2) | note:Eb4 gain:0.1492893218813444 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/4 ⇜ (479/64 → 15/2) | note:E4 gain:0.1492893218813444 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/4 ⇜ (479/64 → 15/2) | note:Ab4 gain:0.1492893218813444 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ (15/2 → 481/64) ⇝ 61/8 | note:C#5 gain:0.43999999999999134 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ (15/2 → 481/64) ⇝ 61/8 | note:E5 gain:0.43999999999999134 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ (15/2 → 481/64) ⇝ 31/4 | note:F#2 gain:0.43999999999999134 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 15/2 ⇜ (481/64 → 241/32) ⇝ 61/8 | note:C#5 gain:0.5814213562373071 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 15/2 ⇜ (481/64 → 241/32) ⇝ 61/8 | note:E5 gain:0.5814213562373071 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 15/2 ⇜ (481/64 → 241/32) ⇝ 31/4 | note:F#2 gain:0.5814213562373071 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 15/2 ⇜ (241/32 → 483/64) ⇝ 61/8 | note:C#5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 15/2 ⇜ (241/32 → 483/64) ⇝ 61/8 | note:E5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 15/2 ⇜ (241/32 → 483/64) ⇝ 31/4 | note:F#2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ (211/28 → 483/64) ⇝ 109/14 | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ (211/28 → 483/64) ⇝ 109/14 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ (211/28 → 483/64) ⇝ 109/14 | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ (211/28 → 483/64) ⇝ 109/14 | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 15/2 ⇜ (483/64 → 121/16) ⇝ 61/8 | note:C#5 gain:0.5814213562373127 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 15/2 ⇜ (483/64 → 121/16) ⇝ 61/8 | note:E5 gain:0.5814213562373127 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 15/2 ⇜ (483/64 → 121/16) ⇝ 31/4 | note:F#2 gain:0.5814213562373127 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 211/28 ⇜ (483/64 → 121/16) ⇝ 109/14 | note:70 gain:0.05814213562373127 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 211/28 ⇜ (483/64 → 121/16) ⇝ 109/14 | note:75 gain:0.05814213562373127 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 211/28 ⇜ (483/64 → 121/16) ⇝ 109/14 | note:76 gain:0.05814213562373127 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 211/28 ⇜ (483/64 → 121/16) ⇝ 109/14 | note:80 gain:0.05814213562373127 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 15/2 ⇜ (121/16 → 485/64) ⇝ 61/8 | note:C#5 gain:0.43999999999999945 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 15/2 ⇜ (121/16 → 485/64) ⇝ 61/8 | note:E5 gain:0.43999999999999945 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 15/2 ⇜ (121/16 → 485/64) ⇝ 31/4 | note:F#2 gain:0.43999999999999945 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 211/28 ⇜ (121/16 → 485/64) ⇝ 109/14 | note:70 gain:0.04399999999999995 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 211/28 ⇜ (121/16 → 485/64) ⇝ 109/14 | note:75 gain:0.04399999999999995 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 211/28 ⇜ (121/16 → 485/64) ⇝ 109/14 | note:76 gain:0.04399999999999995 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 211/28 ⇜ (121/16 → 485/64) ⇝ 109/14 | note:80 gain:0.04399999999999995 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 15/2 ⇜ (485/64 → 243/32) ⇝ 61/8 | note:C#5 gain:0.29857864376269444 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 15/2 ⇜ (485/64 → 243/32) ⇝ 61/8 | note:E5 gain:0.29857864376269444 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 15/2 ⇜ (485/64 → 243/32) ⇝ 31/4 | note:F#2 gain:0.29857864376269444 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 211/28 ⇜ (485/64 → 243/32) ⇝ 109/14 | note:70 gain:0.029857864376269444 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 211/28 ⇜ (485/64 → 243/32) ⇝ 109/14 | note:75 gain:0.029857864376269444 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 211/28 ⇜ (485/64 → 243/32) ⇝ 109/14 | note:76 gain:0.029857864376269444 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 211/28 ⇜ (485/64 → 243/32) ⇝ 109/14 | note:80 gain:0.029857864376269444 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 15/2 ⇜ (243/32 → 487/64) ⇝ 61/8 | note:C#5 gain:0.24 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 15/2 ⇜ (243/32 → 487/64) ⇝ 61/8 | note:E5 gain:0.24 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 15/2 ⇜ (243/32 → 487/64) ⇝ 31/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 211/28 ⇜ (243/32 → 487/64) ⇝ 109/14 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 211/28 ⇜ (243/32 → 487/64) ⇝ 109/14 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 211/28 ⇜ (243/32 → 487/64) ⇝ 109/14 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 211/28 ⇜ (243/32 → 487/64) ⇝ 109/14 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 15/2 ⇜ (487/64 → 61/8) | note:C#5 gain:0.2985786437626858 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 15/2 ⇜ (487/64 → 61/8) | note:E5 gain:0.2985786437626858 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 15/2 ⇜ (487/64 → 61/8) ⇝ 31/4 | note:F#2 gain:0.2985786437626858 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 211/28 ⇜ (487/64 → 61/8) ⇝ 109/14 | note:70 gain:0.02985786437626858 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 211/28 ⇜ (487/64 → 61/8) ⇝ 109/14 | note:75 gain:0.02985786437626858 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 211/28 ⇜ (487/64 → 61/8) ⇝ 109/14 | note:76 gain:0.02985786437626858 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 211/28 ⇜ (487/64 → 61/8) ⇝ 109/14 | note:80 gain:0.02985786437626858 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 15/2 ⇜ (61/8 → 489/64) ⇝ 31/4 | note:F#2 gain:0.43999999999999845 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 211/28 ⇜ (61/8 → 489/64) ⇝ 109/14 | note:70 gain:0.043999999999999845 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 211/28 ⇜ (61/8 → 489/64) ⇝ 109/14 | note:75 gain:0.043999999999999845 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 211/28 ⇜ (61/8 → 489/64) ⇝ 109/14 | note:76 gain:0.043999999999999845 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 211/28 ⇜ (61/8 → 489/64) ⇝ 109/14 | note:80 gain:0.043999999999999845 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 15/2 ⇜ (489/64 → 245/32) ⇝ 31/4 | note:F#2 gain:0.581421356237304 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 211/28 ⇜ (489/64 → 245/32) ⇝ 109/14 | note:70 gain:0.0581421356237304 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 211/28 ⇜ (489/64 → 245/32) ⇝ 109/14 | note:75 gain:0.0581421356237304 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 211/28 ⇜ (489/64 → 245/32) ⇝ 109/14 | note:76 gain:0.0581421356237304 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 211/28 ⇜ (489/64 → 245/32) ⇝ 109/14 | note:80 gain:0.0581421356237304 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 15/2 ⇜ (245/32 → 491/64) ⇝ 31/4 | note:F#2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 211/28 ⇜ (245/32 → 491/64) ⇝ 109/14 | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 211/28 ⇜ (245/32 → 491/64) ⇝ 109/14 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 211/28 ⇜ (245/32 → 491/64) ⇝ 109/14 | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 211/28 ⇜ (245/32 → 491/64) ⇝ 109/14 | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 15/2 ⇜ (491/64 → 123/16) ⇝ 31/4 | note:F#2 gain:0.5814213562373077 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 211/28 ⇜ (491/64 → 123/16) ⇝ 109/14 | note:70 gain:0.05814213562373077 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 211/28 ⇜ (491/64 → 123/16) ⇝ 109/14 | note:75 gain:0.05814213562373077 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 211/28 ⇜ (491/64 → 123/16) ⇝ 109/14 | note:76 gain:0.05814213562373077 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 211/28 ⇜ (491/64 → 123/16) ⇝ 109/14 | note:80 gain:0.05814213562373077 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 15/2 ⇜ (123/16 → 493/64) ⇝ 31/4 | note:F#2 gain:0.4400000000000038 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 211/28 ⇜ (123/16 → 493/64) ⇝ 109/14 | note:70 gain:0.04400000000000038 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 211/28 ⇜ (123/16 → 493/64) ⇝ 109/14 | note:75 gain:0.04400000000000038 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 211/28 ⇜ (123/16 → 493/64) ⇝ 109/14 | note:76 gain:0.04400000000000038 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 211/28 ⇜ (123/16 → 493/64) ⇝ 109/14 | note:80 gain:0.04400000000000038 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 15/2 ⇜ (493/64 → 247/32) ⇝ 31/4 | note:F#2 gain:0.2985786437626895 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 211/28 ⇜ (493/64 → 247/32) ⇝ 109/14 | note:70 gain:0.02985786437626895 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 211/28 ⇜ (493/64 → 247/32) ⇝ 109/14 | note:75 gain:0.02985786437626895 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 211/28 ⇜ (493/64 → 247/32) ⇝ 109/14 | note:76 gain:0.02985786437626895 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 211/28 ⇜ (493/64 → 247/32) ⇝ 109/14 | note:80 gain:0.02985786437626895 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 15/2 ⇜ (247/32 → 495/64) ⇝ 31/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 211/28 ⇜ (247/32 → 495/64) ⇝ 109/14 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 211/28 ⇜ (247/32 → 495/64) ⇝ 109/14 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 211/28 ⇜ (247/32 → 495/64) ⇝ 109/14 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 211/28 ⇜ (247/32 → 495/64) ⇝ 109/14 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 15/2 ⇜ (495/64 → 31/4) | note:F#2 gain:0.2985786437626907 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 211/28 ⇜ (495/64 → 31/4) ⇝ 109/14 | note:70 gain:0.029857864376269073 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 211/28 ⇜ (495/64 → 31/4) ⇝ 109/14 | note:75 gain:0.029857864376269073 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 211/28 ⇜ (495/64 → 31/4) ⇝ 109/14 | note:76 gain:0.029857864376269073 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 211/28 ⇜ (495/64 → 31/4) ⇝ 109/14 | note:80 gain:0.029857864376269073 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 211/28 ⇜ (31/4 → 497/64) ⇝ 109/14 | note:70 gain:0.043999999999999415 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 211/28 ⇜ (31/4 → 497/64) ⇝ 109/14 | note:75 gain:0.043999999999999415 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 211/28 ⇜ (31/4 → 497/64) ⇝ 109/14 | note:76 gain:0.043999999999999415 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 211/28 ⇜ (31/4 → 497/64) ⇝ 109/14 | note:80 gain:0.043999999999999415 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ (31/4 → 497/64) ⇝ 63/8 | note:C#5 gain:0.4399999999999941 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ (31/4 → 497/64) ⇝ 63/8 | note:E5 gain:0.4399999999999941 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ (31/4 → 497/64) ⇝ 8/1 | note:Bb3 gain:0.21999999999999706 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ (31/4 → 497/64) ⇝ 8/1 | note:Eb4 gain:0.21999999999999706 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ (31/4 → 497/64) ⇝ 8/1 | note:E4 gain:0.21999999999999706 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (31/4 → 497/64) ⇝ 8/1 | note:Ab4 gain:0.21999999999999706 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 211/28 ⇜ (497/64 → 249/32) ⇝ 109/14 | note:70 gain:0.0581421356237309 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 211/28 ⇜ (497/64 → 249/32) ⇝ 109/14 | note:75 gain:0.0581421356237309 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 211/28 ⇜ (497/64 → 249/32) ⇝ 109/14 | note:76 gain:0.0581421356237309 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 211/28 ⇜ (497/64 → 249/32) ⇝ 109/14 | note:80 gain:0.0581421356237309 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 31/4 ⇜ (497/64 → 249/32) ⇝ 63/8 | note:C#5 gain:0.581421356237309 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 31/4 ⇜ (497/64 → 249/32) ⇝ 63/8 | note:E5 gain:0.581421356237309 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 31/4 ⇜ (497/64 → 249/32) ⇝ 8/1 | note:Bb3 gain:0.2907106781186545 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 31/4 ⇜ (497/64 → 249/32) ⇝ 8/1 | note:Eb4 gain:0.2907106781186545 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 31/4 ⇜ (497/64 → 249/32) ⇝ 8/1 | note:E4 gain:0.2907106781186545 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 31/4 ⇜ (497/64 → 249/32) ⇝ 8/1 | note:Ab4 gain:0.2907106781186545 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 211/28 ⇜ (249/32 → 109/14) | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 211/28 ⇜ (249/32 → 109/14) | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 211/28 ⇜ (249/32 → 109/14) | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 211/28 ⇜ (249/32 → 109/14) | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 31/4 ⇜ (249/32 → 499/64) ⇝ 63/8 | note:C#5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 31/4 ⇜ (249/32 → 499/64) ⇝ 63/8 | note:E5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 31/4 ⇜ (249/32 → 499/64) ⇝ 8/1 | note:Bb3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 31/4 ⇜ (249/32 → 499/64) ⇝ 8/1 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 31/4 ⇜ (249/32 → 499/64) ⇝ 8/1 | note:E4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 31/4 ⇜ (249/32 → 499/64) ⇝ 8/1 | note:Ab4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 31/4 ⇜ (499/64 → 125/16) ⇝ 63/8 | note:C#5 gain:0.5814213562373108 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 31/4 ⇜ (499/64 → 125/16) ⇝ 63/8 | note:E5 gain:0.5814213562373108 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 31/4 ⇜ (499/64 → 125/16) ⇝ 8/1 | note:Bb3 gain:0.2907106781186554 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 31/4 ⇜ (499/64 → 125/16) ⇝ 8/1 | note:Eb4 gain:0.2907106781186554 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 31/4 ⇜ (499/64 → 125/16) ⇝ 8/1 | note:E4 gain:0.2907106781186554 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 31/4 ⇜ (499/64 → 125/16) ⇝ 8/1 | note:Ab4 gain:0.2907106781186554 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 31/4 ⇜ (125/16 → 501/64) ⇝ 63/8 | note:C#5 gain:0.44000000000000805 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 31/4 ⇜ (125/16 → 501/64) ⇝ 63/8 | note:E5 gain:0.44000000000000805 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 31/4 ⇜ (125/16 → 501/64) ⇝ 8/1 | note:Bb3 gain:0.22000000000000403 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 31/4 ⇜ (125/16 → 501/64) ⇝ 8/1 | note:Eb4 gain:0.22000000000000403 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 31/4 ⇜ (125/16 → 501/64) ⇝ 8/1 | note:E4 gain:0.22000000000000403 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 31/4 ⇜ (125/16 → 501/64) ⇝ 8/1 | note:Ab4 gain:0.22000000000000403 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 31/4 ⇜ (501/64 → 251/32) ⇝ 63/8 | note:C#5 gain:0.2985786437626925 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 31/4 ⇜ (501/64 → 251/32) ⇝ 63/8 | note:E5 gain:0.2985786437626925 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 31/4 ⇜ (501/64 → 251/32) ⇝ 8/1 | note:Bb3 gain:0.14928932188134625 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 31/4 ⇜ (501/64 → 251/32) ⇝ 8/1 | note:Eb4 gain:0.14928932188134625 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 31/4 ⇜ (501/64 → 251/32) ⇝ 8/1 | note:E4 gain:0.14928932188134625 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 31/4 ⇜ (501/64 → 251/32) ⇝ 8/1 | note:Ab4 gain:0.14928932188134625 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 31/4 ⇜ (251/32 → 503/64) ⇝ 63/8 | note:C#5 gain:0.24 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 31/4 ⇜ (251/32 → 503/64) ⇝ 63/8 | note:E5 gain:0.24 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 31/4 ⇜ (251/32 → 503/64) ⇝ 8/1 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 31/4 ⇜ (251/32 → 503/64) ⇝ 8/1 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 31/4 ⇜ (251/32 → 503/64) ⇝ 8/1 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 31/4 ⇜ (251/32 → 503/64) ⇝ 8/1 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 31/4 ⇜ (503/64 → 63/8) | note:C#5 gain:0.2985786437626877 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 31/4 ⇜ (503/64 → 63/8) | note:E5 gain:0.2985786437626877 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 31/4 ⇜ (503/64 → 63/8) ⇝ 8/1 | note:Bb3 gain:0.14928932188134386 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 31/4 ⇜ (503/64 → 63/8) ⇝ 8/1 | note:Eb4 gain:0.14928932188134386 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 31/4 ⇜ (503/64 → 63/8) ⇝ 8/1 | note:E4 gain:0.14928932188134386 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 31/4 ⇜ (503/64 → 63/8) ⇝ 8/1 | note:Ab4 gain:0.14928932188134386 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 31/4 ⇜ (63/8 → 505/64) ⇝ 8/1 | note:Bb3 gain:0.2200000000000006 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 31/4 ⇜ (63/8 → 505/64) ⇝ 8/1 | note:Eb4 gain:0.2200000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 31/4 ⇜ (63/8 → 505/64) ⇝ 8/1 | note:E4 gain:0.2200000000000006 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 31/4 ⇜ (63/8 → 505/64) ⇝ 8/1 | note:Ab4 gain:0.2200000000000006 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 31/4 ⇜ (505/64 → 253/32) ⇝ 8/1 | note:Bb3 gain:0.290710678118653 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 31/4 ⇜ (505/64 → 253/32) ⇝ 8/1 | note:Eb4 gain:0.290710678118653 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 31/4 ⇜ (505/64 → 253/32) ⇝ 8/1 | note:E4 gain:0.290710678118653 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 31/4 ⇜ (505/64 → 253/32) ⇝ 8/1 | note:Ab4 gain:0.290710678118653 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 31/4 ⇜ (253/32 → 507/64) ⇝ 8/1 | note:Bb3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 31/4 ⇜ (253/32 → 507/64) ⇝ 8/1 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 31/4 ⇜ (253/32 → 507/64) ⇝ 8/1 | note:E4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 31/4 ⇜ (253/32 → 507/64) ⇝ 8/1 | note:Ab4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 31/4 ⇜ (507/64 → 127/16) ⇝ 8/1 | note:Bb3 gain:0.290710678118657 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 31/4 ⇜ (507/64 → 127/16) ⇝ 8/1 | note:Eb4 gain:0.290710678118657 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 31/4 ⇜ (507/64 → 127/16) ⇝ 8/1 | note:E4 gain:0.290710678118657 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 31/4 ⇜ (507/64 → 127/16) ⇝ 8/1 | note:Ab4 gain:0.290710678118657 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 31/4 ⇜ (127/16 → 509/64) ⇝ 8/1 | note:Bb3 gain:0.22000000000000047 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 31/4 ⇜ (127/16 → 509/64) ⇝ 8/1 | note:Eb4 gain:0.22000000000000047 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 31/4 ⇜ (127/16 → 509/64) ⇝ 8/1 | note:E4 gain:0.22000000000000047 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 31/4 ⇜ (127/16 → 509/64) ⇝ 8/1 | note:Ab4 gain:0.22000000000000047 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 31/4 ⇜ (509/64 → 255/32) ⇝ 8/1 | note:Bb3 gain:0.1492893218813478 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 31/4 ⇜ (509/64 → 255/32) ⇝ 8/1 | note:Eb4 gain:0.1492893218813478 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 31/4 ⇜ (509/64 → 255/32) ⇝ 8/1 | note:E4 gain:0.1492893218813478 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 31/4 ⇜ (509/64 → 255/32) ⇝ 8/1 | note:Ab4 gain:0.1492893218813478 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 31/4 ⇜ (255/32 → 511/64) ⇝ 8/1 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 31/4 ⇜ (255/32 → 511/64) ⇝ 8/1 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 31/4 ⇜ (255/32 → 511/64) ⇝ 8/1 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 31/4 ⇜ (255/32 → 511/64) ⇝ 8/1 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 31/4 ⇜ (511/64 → 8/1) | note:Bb3 gain:0.14928932188134234 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 31/4 ⇜ (511/64 → 8/1) | note:Eb4 gain:0.14928932188134234 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 31/4 ⇜ (511/64 → 8/1) | note:E4 gain:0.14928932188134234 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 31/4 ⇜ (511/64 → 8/1) | note:Ab4 gain:0.14928932188134234 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ (8/1 → 513/64) ⇝ 33/4 | note:C2 gain:0.43999999999999684 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 8/1 ⇜ (513/64 → 257/32) ⇝ 33/4 | note:C2 gain:0.5814213562373108 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 8/1 ⇜ (257/32 → 515/64) ⇝ 33/4 | note:C2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ (225/28 → 515/64) ⇝ 58/7 | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ (225/28 → 515/64) ⇝ 58/7 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ (225/28 → 515/64) ⇝ 58/7 | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ (225/28 → 515/64) ⇝ 58/7 | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 8/1 ⇜ (515/64 → 129/16) ⇝ 33/4 | note:C2 gain:0.581421356237309 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 225/28 ⇜ (515/64 → 129/16) ⇝ 58/7 | note:70 gain:0.0581421356237309 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 225/28 ⇜ (515/64 → 129/16) ⇝ 58/7 | note:75 gain:0.0581421356237309 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 225/28 ⇜ (515/64 → 129/16) ⇝ 58/7 | note:76 gain:0.0581421356237309 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 225/28 ⇜ (515/64 → 129/16) ⇝ 58/7 | note:80 gain:0.0581421356237309 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 8/1 ⇜ (129/16 → 517/64) ⇝ 33/4 | note:C2 gain:0.4400000000000053 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 225/28 ⇜ (129/16 → 517/64) ⇝ 58/7 | note:70 gain:0.04400000000000053 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 225/28 ⇜ (129/16 → 517/64) ⇝ 58/7 | note:75 gain:0.04400000000000053 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 225/28 ⇜ (129/16 → 517/64) ⇝ 58/7 | note:76 gain:0.04400000000000053 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 225/28 ⇜ (129/16 → 517/64) ⇝ 58/7 | note:80 gain:0.04400000000000053 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 8/1 ⇜ (517/64 → 259/32) ⇝ 33/4 | note:C2 gain:0.2985786437626906 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 225/28 ⇜ (517/64 → 259/32) ⇝ 58/7 | note:70 gain:0.029857864376269062 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 225/28 ⇜ (517/64 → 259/32) ⇝ 58/7 | note:75 gain:0.029857864376269062 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 225/28 ⇜ (517/64 → 259/32) ⇝ 58/7 | note:76 gain:0.029857864376269062 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 225/28 ⇜ (517/64 → 259/32) ⇝ 58/7 | note:80 gain:0.029857864376269062 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 8/1 ⇜ (259/32 → 519/64) ⇝ 33/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 225/28 ⇜ (259/32 → 519/64) ⇝ 58/7 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 225/28 ⇜ (259/32 → 519/64) ⇝ 58/7 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 225/28 ⇜ (259/32 → 519/64) ⇝ 58/7 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 225/28 ⇜ (259/32 → 519/64) ⇝ 58/7 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 8/1 ⇜ (519/64 → 65/8) ⇝ 33/4 | note:C2 gain:0.2985786437626896 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 225/28 ⇜ (519/64 → 65/8) ⇝ 58/7 | note:70 gain:0.029857864376268962 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 225/28 ⇜ (519/64 → 65/8) ⇝ 58/7 | note:75 gain:0.029857864376268962 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 225/28 ⇜ (519/64 → 65/8) ⇝ 58/7 | note:76 gain:0.029857864376268962 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 225/28 ⇜ (519/64 → 65/8) ⇝ 58/7 | note:80 gain:0.029857864376268962 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 8/1 ⇜ (65/8 → 521/64) ⇝ 33/4 | note:C2 gain:0.4399999999999926 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 225/28 ⇜ (65/8 → 521/64) ⇝ 58/7 | note:70 gain:0.04399999999999926 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 225/28 ⇜ (65/8 → 521/64) ⇝ 58/7 | note:75 gain:0.04399999999999926 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 225/28 ⇜ (65/8 → 521/64) ⇝ 58/7 | note:76 gain:0.04399999999999926 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 225/28 ⇜ (65/8 → 521/64) ⇝ 58/7 | note:80 gain:0.04399999999999926 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ (65/8 → 521/64) ⇝ 33/4 | note:C4 gain:0.4399999999999926 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ (65/8 → 521/64) ⇝ 33/4 | note:G4 gain:0.4399999999999926 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (65/8 → 521/64) ⇝ 33/4 | note:Bb4 gain:0.4399999999999926 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 8/1 ⇜ (521/64 → 261/32) ⇝ 33/4 | note:C2 gain:0.5814213562373078 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 225/28 ⇜ (521/64 → 261/32) ⇝ 58/7 | note:70 gain:0.05814213562373079 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 225/28 ⇜ (521/64 → 261/32) ⇝ 58/7 | note:75 gain:0.05814213562373079 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 225/28 ⇜ (521/64 → 261/32) ⇝ 58/7 | note:76 gain:0.05814213562373079 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 225/28 ⇜ (521/64 → 261/32) ⇝ 58/7 | note:80 gain:0.05814213562373079 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 65/8 ⇜ (521/64 → 261/32) ⇝ 33/4 | note:C4 gain:0.5814213562373078 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 65/8 ⇜ (521/64 → 261/32) ⇝ 33/4 | note:G4 gain:0.5814213562373078 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 65/8 ⇜ (521/64 → 261/32) ⇝ 33/4 | note:Bb4 gain:0.5814213562373078 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 8/1 ⇜ (261/32 → 523/64) ⇝ 33/4 | note:C2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 225/28 ⇜ (261/32 → 523/64) ⇝ 58/7 | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 225/28 ⇜ (261/32 → 523/64) ⇝ 58/7 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 225/28 ⇜ (261/32 → 523/64) ⇝ 58/7 | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 225/28 ⇜ (261/32 → 523/64) ⇝ 58/7 | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 65/8 ⇜ (261/32 → 523/64) ⇝ 33/4 | note:C4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 65/8 ⇜ (261/32 → 523/64) ⇝ 33/4 | note:G4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 65/8 ⇜ (261/32 → 523/64) ⇝ 33/4 | note:Bb4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 8/1 ⇜ (523/64 → 131/16) ⇝ 33/4 | note:C2 gain:0.581421356237312 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 225/28 ⇜ (523/64 → 131/16) ⇝ 58/7 | note:70 gain:0.058142135623731196 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 225/28 ⇜ (523/64 → 131/16) ⇝ 58/7 | note:75 gain:0.058142135623731196 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 225/28 ⇜ (523/64 → 131/16) ⇝ 58/7 | note:76 gain:0.058142135623731196 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 225/28 ⇜ (523/64 → 131/16) ⇝ 58/7 | note:80 gain:0.058142135623731196 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 65/8 ⇜ (523/64 → 131/16) ⇝ 33/4 | note:C4 gain:0.581421356237312 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 65/8 ⇜ (523/64 → 131/16) ⇝ 33/4 | note:G4 gain:0.581421356237312 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 65/8 ⇜ (523/64 → 131/16) ⇝ 33/4 | note:Bb4 gain:0.581421356237312 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 8/1 ⇜ (131/16 → 525/64) ⇝ 33/4 | note:C2 gain:0.4399999999999983 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 225/28 ⇜ (131/16 → 525/64) ⇝ 58/7 | note:70 gain:0.04399999999999983 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 225/28 ⇜ (131/16 → 525/64) ⇝ 58/7 | note:75 gain:0.04399999999999983 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 225/28 ⇜ (131/16 → 525/64) ⇝ 58/7 | note:76 gain:0.04399999999999983 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 225/28 ⇜ (131/16 → 525/64) ⇝ 58/7 | note:80 gain:0.04399999999999983 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 65/8 ⇜ (131/16 → 525/64) ⇝ 33/4 | note:C4 gain:0.4399999999999983 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 65/8 ⇜ (131/16 → 525/64) ⇝ 33/4 | note:G4 gain:0.4399999999999983 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 65/8 ⇜ (131/16 → 525/64) ⇝ 33/4 | note:Bb4 gain:0.4399999999999983 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 8/1 ⇜ (525/64 → 263/32) ⇝ 33/4 | note:C2 gain:0.29857864376269366 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 225/28 ⇜ (525/64 → 263/32) ⇝ 58/7 | note:70 gain:0.029857864376269368 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 225/28 ⇜ (525/64 → 263/32) ⇝ 58/7 | note:75 gain:0.029857864376269368 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 225/28 ⇜ (525/64 → 263/32) ⇝ 58/7 | note:76 gain:0.029857864376269368 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 225/28 ⇜ (525/64 → 263/32) ⇝ 58/7 | note:80 gain:0.029857864376269368 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 65/8 ⇜ (525/64 → 263/32) ⇝ 33/4 | note:C4 gain:0.29857864376269366 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 65/8 ⇜ (525/64 → 263/32) ⇝ 33/4 | note:G4 gain:0.29857864376269366 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 65/8 ⇜ (525/64 → 263/32) ⇝ 33/4 | note:Bb4 gain:0.29857864376269366 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 8/1 ⇜ (263/32 → 527/64) ⇝ 33/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 225/28 ⇜ (263/32 → 527/64) ⇝ 58/7 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 225/28 ⇜ (263/32 → 527/64) ⇝ 58/7 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 225/28 ⇜ (263/32 → 527/64) ⇝ 58/7 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 225/28 ⇜ (263/32 → 527/64) ⇝ 58/7 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 65/8 ⇜ (263/32 → 527/64) ⇝ 33/4 | note:C4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 65/8 ⇜ (263/32 → 527/64) ⇝ 33/4 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 65/8 ⇜ (263/32 → 527/64) ⇝ 33/4 | note:Bb4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 8/1 ⇜ (527/64 → 33/4) | note:C2 gain:0.29857864376268656 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 225/28 ⇜ (527/64 → 33/4) ⇝ 58/7 | note:70 gain:0.029857864376268656 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 225/28 ⇜ (527/64 → 33/4) ⇝ 58/7 | note:75 gain:0.029857864376268656 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 225/28 ⇜ (527/64 → 33/4) ⇝ 58/7 | note:76 gain:0.029857864376268656 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 225/28 ⇜ (527/64 → 33/4) ⇝ 58/7 | note:80 gain:0.029857864376268656 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 65/8 ⇜ (527/64 → 33/4) | note:C4 gain:0.29857864376268656 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 65/8 ⇜ (527/64 → 33/4) | note:G4 gain:0.29857864376268656 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 65/8 ⇜ (527/64 → 33/4) | note:Bb4 gain:0.29857864376268656 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 225/28 ⇜ (33/4 → 529/64) ⇝ 58/7 | note:70 gain:0.04399999999999996 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 225/28 ⇜ (33/4 → 529/64) ⇝ 58/7 | note:75 gain:0.04399999999999996 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 225/28 ⇜ (33/4 → 529/64) ⇝ 58/7 | note:76 gain:0.04399999999999996 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 225/28 ⇜ (33/4 → 529/64) ⇝ 58/7 | note:80 gain:0.04399999999999996 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 225/28 ⇜ (529/64 → 265/32) ⇝ 58/7 | note:70 gain:0.05814213562373049 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 225/28 ⇜ (529/64 → 265/32) ⇝ 58/7 | note:75 gain:0.05814213562373049 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 225/28 ⇜ (529/64 → 265/32) ⇝ 58/7 | note:76 gain:0.05814213562373049 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 225/28 ⇜ (529/64 → 265/32) ⇝ 58/7 | note:80 gain:0.05814213562373049 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 225/28 ⇜ (265/32 → 58/7) | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 225/28 ⇜ (265/32 → 58/7) | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 225/28 ⇜ (265/32 → 58/7) | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 225/28 ⇜ (265/32 → 58/7) | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ (17/2 → 545/64) ⇝ 69/8 | note:G4 gain:0.4400000000000024 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (17/2 → 545/64) ⇝ 69/8 | note:D5 gain:0.4400000000000024 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (17/2 → 545/64) ⇝ 69/8 | note:F5 gain:0.4400000000000024 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ (17/2 → 545/64) ⇝ 35/4 | note:Bb3 gain:0.2200000000000012 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ (17/2 → 545/64) ⇝ 35/4 | note:D4 gain:0.2200000000000012 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ (17/2 → 545/64) ⇝ 35/4 | note:Eb4 gain:0.2200000000000012 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ (17/2 → 545/64) ⇝ 35/4 | note:G4 gain:0.2200000000000012 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (17/2 → 545/64) ⇝ 35/4 | note:C2 gain:0.4400000000000024 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 17/2 ⇜ (545/64 → 273/32) ⇝ 69/8 | note:G4 gain:0.5814213562373068 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 17/2 ⇜ (545/64 → 273/32) ⇝ 69/8 | note:D5 gain:0.5814213562373068 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 17/2 ⇜ (545/64 → 273/32) ⇝ 69/8 | note:F5 gain:0.5814213562373068 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 17/2 ⇜ (545/64 → 273/32) ⇝ 35/4 | note:Bb3 gain:0.2907106781186534 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 17/2 ⇜ (545/64 → 273/32) ⇝ 35/4 | note:D4 gain:0.2907106781186534 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 17/2 ⇜ (545/64 → 273/32) ⇝ 35/4 | note:Eb4 gain:0.2907106781186534 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 17/2 ⇜ (545/64 → 273/32) ⇝ 35/4 | note:G4 gain:0.2907106781186534 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 17/2 ⇜ (545/64 → 273/32) ⇝ 35/4 | note:C2 gain:0.5814213562373068 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 17/2 ⇜ (273/32 → 547/64) ⇝ 69/8 | note:G4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 17/2 ⇜ (273/32 → 547/64) ⇝ 69/8 | note:D5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 17/2 ⇜ (273/32 → 547/64) ⇝ 69/8 | note:F5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 17/2 ⇜ (273/32 → 547/64) ⇝ 35/4 | note:Bb3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 17/2 ⇜ (273/32 → 547/64) ⇝ 35/4 | note:D4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 17/2 ⇜ (273/32 → 547/64) ⇝ 35/4 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 17/2 ⇜ (273/32 → 547/64) ⇝ 35/4 | note:G4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 17/2 ⇜ (273/32 → 547/64) ⇝ 35/4 | note:C2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 17/2 ⇜ (547/64 → 137/16) ⇝ 69/8 | note:G4 gain:0.5814213562373131 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 17/2 ⇜ (547/64 → 137/16) ⇝ 69/8 | note:D5 gain:0.5814213562373131 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 17/2 ⇜ (547/64 → 137/16) ⇝ 69/8 | note:F5 gain:0.5814213562373131 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 17/2 ⇜ (547/64 → 137/16) ⇝ 35/4 | note:Bb3 gain:0.29071067811865653 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 17/2 ⇜ (547/64 → 137/16) ⇝ 35/4 | note:D4 gain:0.29071067811865653 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 17/2 ⇜ (547/64 → 137/16) ⇝ 35/4 | note:Eb4 gain:0.29071067811865653 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 17/2 ⇜ (547/64 → 137/16) ⇝ 35/4 | note:G4 gain:0.29071067811865653 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 17/2 ⇜ (547/64 → 137/16) ⇝ 35/4 | note:C2 gain:0.5814213562373131 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 17/2 ⇜ (137/16 → 549/64) ⇝ 69/8 | note:G4 gain:0.4399999999999998 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 17/2 ⇜ (137/16 → 549/64) ⇝ 69/8 | note:D5 gain:0.4399999999999998 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 17/2 ⇜ (137/16 → 549/64) ⇝ 69/8 | note:F5 gain:0.4399999999999998 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 17/2 ⇜ (137/16 → 549/64) ⇝ 35/4 | note:Bb3 gain:0.2199999999999999 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 17/2 ⇜ (137/16 → 549/64) ⇝ 35/4 | note:D4 gain:0.2199999999999999 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 17/2 ⇜ (137/16 → 549/64) ⇝ 35/4 | note:Eb4 gain:0.2199999999999999 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 17/2 ⇜ (137/16 → 549/64) ⇝ 35/4 | note:G4 gain:0.2199999999999999 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 17/2 ⇜ (137/16 → 549/64) ⇝ 35/4 | note:C2 gain:0.4399999999999998 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 17/2 ⇜ (549/64 → 275/32) ⇝ 69/8 | note:G4 gain:0.2985786437626947 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 17/2 ⇜ (549/64 → 275/32) ⇝ 69/8 | note:D5 gain:0.2985786437626947 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 17/2 ⇜ (549/64 → 275/32) ⇝ 69/8 | note:F5 gain:0.2985786437626947 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 17/2 ⇜ (549/64 → 275/32) ⇝ 35/4 | note:Bb3 gain:0.14928932188134736 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 17/2 ⇜ (549/64 → 275/32) ⇝ 35/4 | note:D4 gain:0.14928932188134736 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 17/2 ⇜ (549/64 → 275/32) ⇝ 35/4 | note:Eb4 gain:0.14928932188134736 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 17/2 ⇜ (549/64 → 275/32) ⇝ 35/4 | note:G4 gain:0.14928932188134736 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 17/2 ⇜ (549/64 → 275/32) ⇝ 35/4 | note:C2 gain:0.2985786437626947 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 17/2 ⇜ (275/32 → 551/64) ⇝ 69/8 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 17/2 ⇜ (275/32 → 551/64) ⇝ 69/8 | note:D5 gain:0.24 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 17/2 ⇜ (275/32 → 551/64) ⇝ 69/8 | note:F5 gain:0.24 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 17/2 ⇜ (275/32 → 551/64) ⇝ 35/4 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 17/2 ⇜ (275/32 → 551/64) ⇝ 35/4 | note:D4 gain:0.12 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 17/2 ⇜ (275/32 → 551/64) ⇝ 35/4 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 17/2 ⇜ (275/32 → 551/64) ⇝ 35/4 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 17/2 ⇜ (275/32 → 551/64) ⇝ 35/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 17/2 ⇜ (551/64 → 69/8) | note:G4 gain:0.2985786437626855 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 17/2 ⇜ (551/64 → 69/8) | note:D5 gain:0.2985786437626855 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 17/2 ⇜ (551/64 → 69/8) | note:F5 gain:0.2985786437626855 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 17/2 ⇜ (551/64 → 69/8) ⇝ 35/4 | note:Bb3 gain:0.14928932188134275 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 17/2 ⇜ (551/64 → 69/8) ⇝ 35/4 | note:D4 gain:0.14928932188134275 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 17/2 ⇜ (551/64 → 69/8) ⇝ 35/4 | note:Eb4 gain:0.14928932188134275 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 17/2 ⇜ (551/64 → 69/8) ⇝ 35/4 | note:G4 gain:0.14928932188134275 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 17/2 ⇜ (551/64 → 69/8) ⇝ 35/4 | note:C2 gain:0.2985786437626855 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 17/2 ⇜ (69/8 → 553/64) ⇝ 35/4 | note:Bb3 gain:0.21999999999999906 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 17/2 ⇜ (69/8 → 553/64) ⇝ 35/4 | note:D4 gain:0.21999999999999906 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 17/2 ⇜ (69/8 → 553/64) ⇝ 35/4 | note:Eb4 gain:0.21999999999999906 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 17/2 ⇜ (69/8 → 553/64) ⇝ 35/4 | note:G4 gain:0.21999999999999906 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 17/2 ⇜ (69/8 → 553/64) ⇝ 35/4 | note:C2 gain:0.4399999999999981 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 17/2 ⇜ (553/64 → 277/32) ⇝ 35/4 | note:Bb3 gain:0.29071067811865187 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 17/2 ⇜ (553/64 → 277/32) ⇝ 35/4 | note:D4 gain:0.29071067811865187 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 17/2 ⇜ (553/64 → 277/32) ⇝ 35/4 | note:Eb4 gain:0.29071067811865187 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 17/2 ⇜ (553/64 → 277/32) ⇝ 35/4 | note:G4 gain:0.29071067811865187 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 17/2 ⇜ (553/64 → 277/32) ⇝ 35/4 | note:C2 gain:0.5814213562373037 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 17/2 ⇜ (277/32 → 555/64) ⇝ 35/4 | note:Bb3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 17/2 ⇜ (277/32 → 555/64) ⇝ 35/4 | note:D4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 17/2 ⇜ (277/32 → 555/64) ⇝ 35/4 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 17/2 ⇜ (277/32 → 555/64) ⇝ 35/4 | note:G4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 17/2 ⇜ (277/32 → 555/64) ⇝ 35/4 | note:C2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 17/2 ⇜ (555/64 → 139/16) ⇝ 35/4 | note:Bb3 gain:0.29071067811865403 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 17/2 ⇜ (555/64 → 139/16) ⇝ 35/4 | note:D4 gain:0.29071067811865403 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 17/2 ⇜ (555/64 → 139/16) ⇝ 35/4 | note:Eb4 gain:0.29071067811865403 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 17/2 ⇜ (555/64 → 139/16) ⇝ 35/4 | note:G4 gain:0.29071067811865403 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 17/2 ⇜ (555/64 → 139/16) ⇝ 35/4 | note:C2 gain:0.5814213562373081 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 17/2 ⇜ (139/16 → 557/64) ⇝ 35/4 | note:Bb3 gain:0.22000000000000208 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 17/2 ⇜ (139/16 → 557/64) ⇝ 35/4 | note:D4 gain:0.22000000000000208 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 17/2 ⇜ (139/16 → 557/64) ⇝ 35/4 | note:Eb4 gain:0.22000000000000208 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 17/2 ⇜ (139/16 → 557/64) ⇝ 35/4 | note:G4 gain:0.22000000000000208 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 17/2 ⇜ (139/16 → 557/64) ⇝ 35/4 | note:C2 gain:0.44000000000000417 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 17/2 ⇜ (557/64 → 279/32) ⇝ 35/4 | note:Bb3 gain:0.1492893218813449 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 17/2 ⇜ (557/64 → 279/32) ⇝ 35/4 | note:D4 gain:0.1492893218813449 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 17/2 ⇜ (557/64 → 279/32) ⇝ 35/4 | note:Eb4 gain:0.1492893218813449 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 17/2 ⇜ (557/64 → 279/32) ⇝ 35/4 | note:G4 gain:0.1492893218813449 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 17/2 ⇜ (557/64 → 279/32) ⇝ 35/4 | note:C2 gain:0.2985786437626898 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 17/2 ⇜ (279/32 → 559/64) ⇝ 35/4 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 17/2 ⇜ (279/32 → 559/64) ⇝ 35/4 | note:D4 gain:0.12 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 17/2 ⇜ (279/32 → 559/64) ⇝ 35/4 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 17/2 ⇜ (279/32 → 559/64) ⇝ 35/4 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 17/2 ⇜ (279/32 → 559/64) ⇝ 35/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 17/2 ⇜ (559/64 → 35/4) | note:Bb3 gain:0.14928932188134522 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 17/2 ⇜ (559/64 → 35/4) | note:D4 gain:0.14928932188134522 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 17/2 ⇜ (559/64 → 35/4) | note:Eb4 gain:0.14928932188134522 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 17/2 ⇜ (559/64 → 35/4) | note:G4 gain:0.14928932188134522 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 17/2 ⇜ (559/64 → 35/4) | note:C2 gain:0.29857864376269044 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ (35/4 → 561/64) ⇝ 71/8 | note:C4 gain:0.43999999999999373 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ (35/4 → 561/64) ⇝ 71/8 | note:G4 gain:0.43999999999999373 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (35/4 → 561/64) ⇝ 71/8 | note:Bb4 gain:0.43999999999999373 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 35/4 ⇜ (561/64 → 281/32) ⇝ 71/8 | note:C4 gain:0.5814213562373087 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 35/4 ⇜ (561/64 → 281/32) ⇝ 71/8 | note:G4 gain:0.5814213562373087 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 35/4 ⇜ (561/64 → 281/32) ⇝ 71/8 | note:Bb4 gain:0.5814213562373087 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 35/4 ⇜ (281/32 → 563/64) ⇝ 71/8 | note:C4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 35/4 ⇜ (281/32 → 563/64) ⇝ 71/8 | note:G4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 35/4 ⇜ (281/32 → 563/64) ⇝ 71/8 | note:Bb4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ (123/14 → 563/64) ⇝ 253/28 | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ (123/14 → 563/64) ⇝ 253/28 | note:74 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (123/14 → 563/64) ⇝ 253/28 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ (123/14 → 563/64) ⇝ 253/28 | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 35/4 ⇜ (563/64 → 141/16) ⇝ 71/8 | note:C4 gain:0.5814213562373111 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 35/4 ⇜ (563/64 → 141/16) ⇝ 71/8 | note:G4 gain:0.5814213562373111 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 35/4 ⇜ (563/64 → 141/16) ⇝ 71/8 | note:Bb4 gain:0.5814213562373111 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 123/14 ⇜ (563/64 → 141/16) ⇝ 253/28 | note:70 gain:0.058142135623731106 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 123/14 ⇜ (563/64 → 141/16) ⇝ 253/28 | note:74 gain:0.058142135623731106 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 123/14 ⇜ (563/64 → 141/16) ⇝ 253/28 | note:75 gain:0.058142135623731106 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 123/14 ⇜ (563/64 → 141/16) ⇝ 253/28 | note:79 gain:0.058142135623731106 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 35/4 ⇜ (141/16 → 565/64) ⇝ 71/8 | note:C4 gain:0.4400000000000084 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 35/4 ⇜ (141/16 → 565/64) ⇝ 71/8 | note:G4 gain:0.4400000000000084 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 35/4 ⇜ (141/16 → 565/64) ⇝ 71/8 | note:Bb4 gain:0.4400000000000084 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 123/14 ⇜ (141/16 → 565/64) ⇝ 253/28 | note:70 gain:0.044000000000000844 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 123/14 ⇜ (141/16 → 565/64) ⇝ 253/28 | note:74 gain:0.044000000000000844 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 123/14 ⇜ (141/16 → 565/64) ⇝ 253/28 | note:75 gain:0.044000000000000844 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 123/14 ⇜ (141/16 → 565/64) ⇝ 253/28 | note:79 gain:0.044000000000000844 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 35/4 ⇜ (565/64 → 283/32) ⇝ 71/8 | note:C4 gain:0.29857864376269283 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 35/4 ⇜ (565/64 → 283/32) ⇝ 71/8 | note:G4 gain:0.29857864376269283 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 35/4 ⇜ (565/64 → 283/32) ⇝ 71/8 | note:Bb4 gain:0.29857864376269283 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 123/14 ⇜ (565/64 → 283/32) ⇝ 253/28 | note:70 gain:0.029857864376269284 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 123/14 ⇜ (565/64 → 283/32) ⇝ 253/28 | note:74 gain:0.029857864376269284 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 123/14 ⇜ (565/64 → 283/32) ⇝ 253/28 | note:75 gain:0.029857864376269284 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 123/14 ⇜ (565/64 → 283/32) ⇝ 253/28 | note:79 gain:0.029857864376269284 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 35/4 ⇜ (283/32 → 567/64) ⇝ 71/8 | note:C4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 35/4 ⇜ (283/32 → 567/64) ⇝ 71/8 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 35/4 ⇜ (283/32 → 567/64) ⇝ 71/8 | note:Bb4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 123/14 ⇜ (283/32 → 567/64) ⇝ 253/28 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 123/14 ⇜ (283/32 → 567/64) ⇝ 253/28 | note:74 gain:0.024 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 123/14 ⇜ (283/32 → 567/64) ⇝ 253/28 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 123/14 ⇜ (283/32 → 567/64) ⇝ 253/28 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 35/4 ⇜ (567/64 → 71/8) | note:C4 gain:0.2985786437626874 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 35/4 ⇜ (567/64 → 71/8) | note:G4 gain:0.2985786437626874 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 35/4 ⇜ (567/64 → 71/8) | note:Bb4 gain:0.2985786437626874 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 123/14 ⇜ (567/64 → 71/8) ⇝ 253/28 | note:70 gain:0.02985786437626874 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 123/14 ⇜ (567/64 → 71/8) ⇝ 253/28 | note:74 gain:0.02985786437626874 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 123/14 ⇜ (567/64 → 71/8) ⇝ 253/28 | note:75 gain:0.02985786437626874 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 123/14 ⇜ (567/64 → 71/8) ⇝ 253/28 | note:79 gain:0.02985786437626874 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 123/14 ⇜ (71/8 → 569/64) ⇝ 253/28 | note:70 gain:0.04400000000000008 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 123/14 ⇜ (71/8 → 569/64) ⇝ 253/28 | note:74 gain:0.04400000000000008 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 123/14 ⇜ (71/8 → 569/64) ⇝ 253/28 | note:75 gain:0.04400000000000008 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 123/14 ⇜ (71/8 → 569/64) ⇝ 253/28 | note:79 gain:0.04400000000000008 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 123/14 ⇜ (569/64 → 285/32) ⇝ 253/28 | note:70 gain:0.05814213562373058 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 123/14 ⇜ (569/64 → 285/32) ⇝ 253/28 | note:74 gain:0.05814213562373058 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 123/14 ⇜ (569/64 → 285/32) ⇝ 253/28 | note:75 gain:0.05814213562373058 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 123/14 ⇜ (569/64 → 285/32) ⇝ 253/28 | note:79 gain:0.05814213562373058 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 123/14 ⇜ (285/32 → 571/64) ⇝ 253/28 | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 123/14 ⇜ (285/32 → 571/64) ⇝ 253/28 | note:74 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 123/14 ⇜ (285/32 → 571/64) ⇝ 253/28 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 123/14 ⇜ (285/32 → 571/64) ⇝ 253/28 | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 123/14 ⇜ (571/64 → 143/16) ⇝ 253/28 | note:70 gain:0.05814213562373141 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 123/14 ⇜ (571/64 → 143/16) ⇝ 253/28 | note:74 gain:0.05814213562373141 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 123/14 ⇜ (571/64 → 143/16) ⇝ 253/28 | note:75 gain:0.05814213562373141 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 123/14 ⇜ (571/64 → 143/16) ⇝ 253/28 | note:79 gain:0.05814213562373141 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 123/14 ⇜ (143/16 → 573/64) ⇝ 253/28 | note:70 gain:0.04400000000000014 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 123/14 ⇜ (143/16 → 573/64) ⇝ 253/28 | note:74 gain:0.04400000000000014 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 123/14 ⇜ (143/16 → 573/64) ⇝ 253/28 | note:75 gain:0.04400000000000014 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 123/14 ⇜ (143/16 → 573/64) ⇝ 253/28 | note:79 gain:0.04400000000000014 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 123/14 ⇜ (573/64 → 287/32) ⇝ 253/28 | note:70 gain:0.02985786437626959 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 123/14 ⇜ (573/64 → 287/32) ⇝ 253/28 | note:74 gain:0.02985786437626959 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 123/14 ⇜ (573/64 → 287/32) ⇝ 253/28 | note:75 gain:0.02985786437626959 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 123/14 ⇜ (573/64 → 287/32) ⇝ 253/28 | note:79 gain:0.02985786437626959 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 123/14 ⇜ (287/32 → 575/64) ⇝ 253/28 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 123/14 ⇜ (287/32 → 575/64) ⇝ 253/28 | note:74 gain:0.024 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 123/14 ⇜ (287/32 → 575/64) ⇝ 253/28 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 123/14 ⇜ (287/32 → 575/64) ⇝ 253/28 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 123/14 ⇜ (575/64 → 9/1) ⇝ 253/28 | note:70 gain:0.029857864376268434 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 123/14 ⇜ (575/64 → 9/1) ⇝ 253/28 | note:74 gain:0.029857864376268434 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 123/14 ⇜ (575/64 → 9/1) ⇝ 253/28 | note:75 gain:0.029857864376268434 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 123/14 ⇜ (575/64 → 9/1) ⇝ 253/28 | note:79 gain:0.029857864376268434 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 123/14 ⇜ (9/1 → 577/64) ⇝ 253/28 | note:70 gain:0.04399999999999965 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 123/14 ⇜ (9/1 → 577/64) ⇝ 253/28 | note:74 gain:0.04399999999999965 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 123/14 ⇜ (9/1 → 577/64) ⇝ 253/28 | note:75 gain:0.04399999999999965 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 123/14 ⇜ (9/1 → 577/64) ⇝ 253/28 | note:79 gain:0.04399999999999965 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ (9/1 → 577/64) ⇝ 37/4 | note:C2 gain:0.4399999999999965 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 123/14 ⇜ (577/64 → 289/32) ⇝ 253/28 | note:70 gain:0.05814213562373108 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 123/14 ⇜ (577/64 → 289/32) ⇝ 253/28 | note:74 gain:0.05814213562373108 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 123/14 ⇜ (577/64 → 289/32) ⇝ 253/28 | note:75 gain:0.05814213562373108 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 123/14 ⇜ (577/64 → 289/32) ⇝ 253/28 | note:79 gain:0.05814213562373108 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 9/1 ⇜ (577/64 → 289/32) ⇝ 37/4 | note:C2 gain:0.5814213562373107 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 123/14 ⇜ (289/32 → 253/28) | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 123/14 ⇜ (289/32 → 253/28) | note:74 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 123/14 ⇜ (289/32 → 253/28) | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 123/14 ⇜ (289/32 → 253/28) | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 9/1 ⇜ (289/32 → 579/64) ⇝ 37/4 | note:C2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 9/1 ⇜ (579/64 → 145/16) ⇝ 37/4 | note:C2 gain:0.5814213562373091 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 9/1 ⇜ (145/16 → 581/64) ⇝ 37/4 | note:C2 gain:0.4400000000000057 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 9/1 ⇜ (581/64 → 291/32) ⇝ 37/4 | note:C2 gain:0.2985786437626909 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 9/1 ⇜ (291/32 → 583/64) ⇝ 37/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 9/1 ⇜ (583/64 → 73/8) ⇝ 37/4 | note:C2 gain:0.29857864376268933 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 9/1 ⇜ (73/8 → 585/64) ⇝ 37/4 | note:C2 gain:0.4399999999999922 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ (73/8 → 585/64) ⇝ 37/4 | note:C4 gain:0.4399999999999922 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ (73/8 → 585/64) ⇝ 37/4 | note:G4 gain:0.4399999999999922 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (73/8 → 585/64) ⇝ 37/4 | note:Bb4 gain:0.4399999999999922 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 9/1 ⇜ (585/64 → 293/32) ⇝ 37/4 | note:C2 gain:0.5814213562373077 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 73/8 ⇜ (585/64 → 293/32) ⇝ 37/4 | note:C4 gain:0.5814213562373077 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 73/8 ⇜ (585/64 → 293/32) ⇝ 37/4 | note:G4 gain:0.5814213562373077 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 73/8 ⇜ (585/64 → 293/32) ⇝ 37/4 | note:Bb4 gain:0.5814213562373077 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 9/1 ⇜ (293/32 → 587/64) ⇝ 37/4 | note:C2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 73/8 ⇜ (293/32 → 587/64) ⇝ 37/4 | note:C4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 73/8 ⇜ (293/32 → 587/64) ⇝ 37/4 | note:G4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 73/8 ⇜ (293/32 → 587/64) ⇝ 37/4 | note:Bb4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 9/1 ⇜ (587/64 → 147/16) ⇝ 37/4 | note:C2 gain:0.5814213562373122 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 73/8 ⇜ (587/64 → 147/16) ⇝ 37/4 | note:C4 gain:0.5814213562373122 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 73/8 ⇜ (587/64 → 147/16) ⇝ 37/4 | note:G4 gain:0.5814213562373122 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 73/8 ⇜ (587/64 → 147/16) ⇝ 37/4 | note:Bb4 gain:0.5814213562373122 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 9/1 ⇜ (147/16 → 589/64) ⇝ 37/4 | note:C2 gain:0.4399999999999986 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 73/8 ⇜ (147/16 → 589/64) ⇝ 37/4 | note:C4 gain:0.4399999999999986 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 73/8 ⇜ (147/16 → 589/64) ⇝ 37/4 | note:G4 gain:0.4399999999999986 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 73/8 ⇜ (147/16 → 589/64) ⇝ 37/4 | note:Bb4 gain:0.4399999999999986 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 9/1 ⇜ (589/64 → 295/32) ⇝ 37/4 | note:C2 gain:0.29857864376269394 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 73/8 ⇜ (589/64 → 295/32) ⇝ 37/4 | note:C4 gain:0.29857864376269394 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 73/8 ⇜ (589/64 → 295/32) ⇝ 37/4 | note:G4 gain:0.29857864376269394 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 73/8 ⇜ (589/64 → 295/32) ⇝ 37/4 | note:Bb4 gain:0.29857864376269394 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 9/1 ⇜ (295/32 → 591/64) ⇝ 37/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 73/8 ⇜ (295/32 → 591/64) ⇝ 37/4 | note:C4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 73/8 ⇜ (295/32 → 591/64) ⇝ 37/4 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 73/8 ⇜ (295/32 → 591/64) ⇝ 37/4 | note:Bb4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 9/1 ⇜ (591/64 → 37/4) | note:C2 gain:0.2985786437626863 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 73/8 ⇜ (591/64 → 37/4) | note:C4 gain:0.2985786437626863 clip:1 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 73/8 ⇜ (591/64 → 37/4) | note:G4 gain:0.2985786437626863 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 73/8 ⇜ (591/64 → 37/4) | note:Bb4 gain:0.2985786437626863 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ (37/4 → 593/64) ⇝ 19/2 | note:Bb3 gain:0.21999999999999964 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ (37/4 → 593/64) ⇝ 19/2 | note:D4 gain:0.21999999999999964 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ (37/4 → 593/64) ⇝ 19/2 | note:Eb4 gain:0.21999999999999964 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ (37/4 → 593/64) ⇝ 19/2 | note:G4 gain:0.21999999999999964 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 37/4 ⇜ (593/64 → 297/32) ⇝ 19/2 | note:Bb3 gain:0.2907106781186523 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 37/4 ⇜ (593/64 → 297/32) ⇝ 19/2 | note:D4 gain:0.2907106781186523 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 37/4 ⇜ (593/64 → 297/32) ⇝ 19/2 | note:Eb4 gain:0.2907106781186523 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 37/4 ⇜ (593/64 → 297/32) ⇝ 19/2 | note:G4 gain:0.2907106781186523 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 37/4 ⇜ (297/32 → 595/64) ⇝ 19/2 | note:Bb3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 37/4 ⇜ (297/32 → 595/64) ⇝ 19/2 | note:D4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 37/4 ⇜ (297/32 → 595/64) ⇝ 19/2 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 37/4 ⇜ (297/32 → 595/64) ⇝ 19/2 | note:G4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 37/4 ⇜ (595/64 → 149/16) ⇝ 19/2 | note:Bb3 gain:0.29071067811865764 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 37/4 ⇜ (595/64 → 149/16) ⇝ 19/2 | note:D4 gain:0.29071067811865764 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 37/4 ⇜ (595/64 → 149/16) ⇝ 19/2 | note:Eb4 gain:0.29071067811865764 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 37/4 ⇜ (595/64 → 149/16) ⇝ 19/2 | note:G4 gain:0.29071067811865764 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 37/4 ⇜ (149/16 → 597/64) ⇝ 19/2 | note:Bb3 gain:0.22000000000000144 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 37/4 ⇜ (149/16 → 597/64) ⇝ 19/2 | note:D4 gain:0.22000000000000144 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 37/4 ⇜ (149/16 → 597/64) ⇝ 19/2 | note:Eb4 gain:0.22000000000000144 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 37/4 ⇜ (149/16 → 597/64) ⇝ 19/2 | note:G4 gain:0.22000000000000144 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 37/4 ⇜ (597/64 → 299/32) ⇝ 19/2 | note:Bb3 gain:0.14928932188134847 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 37/4 ⇜ (597/64 → 299/32) ⇝ 19/2 | note:D4 gain:0.14928932188134847 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 37/4 ⇜ (597/64 → 299/32) ⇝ 19/2 | note:Eb4 gain:0.14928932188134847 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 37/4 ⇜ (597/64 → 299/32) ⇝ 19/2 | note:G4 gain:0.14928932188134847 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 37/4 ⇜ (299/32 → 599/64) ⇝ 19/2 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 37/4 ⇜ (299/32 → 599/64) ⇝ 19/2 | note:D4 gain:0.12 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 37/4 ⇜ (299/32 → 599/64) ⇝ 19/2 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 37/4 ⇜ (299/32 → 599/64) ⇝ 19/2 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 37/4 ⇜ (599/64 → 75/8) ⇝ 19/2 | note:Bb3 gain:0.14928932188134564 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 37/4 ⇜ (599/64 → 75/8) ⇝ 19/2 | note:D4 gain:0.14928932188134564 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 37/4 ⇜ (599/64 → 75/8) ⇝ 19/2 | note:Eb4 gain:0.14928932188134564 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 37/4 ⇜ (599/64 → 75/8) ⇝ 19/2 | note:G4 gain:0.14928932188134564 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 37/4 ⇜ (75/8 → 601/64) ⇝ 19/2 | note:Bb3 gain:0.21999999999999745 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 37/4 ⇜ (75/8 → 601/64) ⇝ 19/2 | note:D4 gain:0.21999999999999745 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 37/4 ⇜ (75/8 → 601/64) ⇝ 19/2 | note:Eb4 gain:0.21999999999999745 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 37/4 ⇜ (75/8 → 601/64) ⇝ 19/2 | note:G4 gain:0.21999999999999745 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 37/4 ⇜ (601/64 → 301/32) ⇝ 19/2 | note:Bb3 gain:0.29071067811865475 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 37/4 ⇜ (601/64 → 301/32) ⇝ 19/2 | note:D4 gain:0.29071067811865475 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 37/4 ⇜ (601/64 → 301/32) ⇝ 19/2 | note:Eb4 gain:0.29071067811865475 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 37/4 ⇜ (601/64 → 301/32) ⇝ 19/2 | note:G4 gain:0.29071067811865475 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 37/4 ⇜ (301/32 → 603/64) ⇝ 19/2 | note:Bb3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 37/4 ⇜ (301/32 → 603/64) ⇝ 19/2 | note:D4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 37/4 ⇜ (301/32 → 603/64) ⇝ 19/2 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 37/4 ⇜ (301/32 → 603/64) ⇝ 19/2 | note:G4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 37/4 ⇜ (603/64 → 151/16) ⇝ 19/2 | note:Bb3 gain:0.2907106781186551 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 37/4 ⇜ (603/64 → 151/16) ⇝ 19/2 | note:D4 gain:0.2907106781186551 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 37/4 ⇜ (603/64 → 151/16) ⇝ 19/2 | note:Eb4 gain:0.2907106781186551 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 37/4 ⇜ (603/64 → 151/16) ⇝ 19/2 | note:G4 gain:0.2907106781186551 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 37/4 ⇜ (151/16 → 605/64) ⇝ 19/2 | note:Bb3 gain:0.22000000000000364 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 37/4 ⇜ (151/16 → 605/64) ⇝ 19/2 | note:D4 gain:0.22000000000000364 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 37/4 ⇜ (151/16 → 605/64) ⇝ 19/2 | note:Eb4 gain:0.22000000000000364 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 37/4 ⇜ (151/16 → 605/64) ⇝ 19/2 | note:G4 gain:0.22000000000000364 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 37/4 ⇜ (605/64 → 303/32) ⇝ 19/2 | note:Bb3 gain:0.149289321881346 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 37/4 ⇜ (605/64 → 303/32) ⇝ 19/2 | note:D4 gain:0.149289321881346 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 37/4 ⇜ (605/64 → 303/32) ⇝ 19/2 | note:Eb4 gain:0.149289321881346 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 37/4 ⇜ (605/64 → 303/32) ⇝ 19/2 | note:G4 gain:0.149289321881346 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 37/4 ⇜ (303/32 → 607/64) ⇝ 19/2 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 37/4 ⇜ (303/32 → 607/64) ⇝ 19/2 | note:D4 gain:0.12 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 37/4 ⇜ (303/32 → 607/64) ⇝ 19/2 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 37/4 ⇜ (303/32 → 607/64) ⇝ 19/2 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 37/4 ⇜ (607/64 → 19/2) | note:Bb3 gain:0.1492893218813441 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 37/4 ⇜ (607/64 → 19/2) | note:D4 gain:0.1492893218813441 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 37/4 ⇜ (607/64 → 19/2) | note:Eb4 gain:0.1492893218813441 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 37/4 ⇜ (607/64 → 19/2) | note:G4 gain:0.1492893218813441 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (19/2 → 609/64) ⇝ 77/8 | note:G4 gain:0.4399999999999906 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (19/2 → 609/64) ⇝ 77/8 | note:D5 gain:0.4399999999999906 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (19/2 → 609/64) ⇝ 77/8 | note:F5 gain:0.4399999999999906 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ (19/2 → 609/64) ⇝ 39/4 | note:C2 gain:0.4399999999999906 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 19/2 ⇜ (609/64 → 305/32) ⇝ 77/8 | note:G4 gain:0.5814213562373064 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 19/2 ⇜ (609/64 → 305/32) ⇝ 77/8 | note:D5 gain:0.5814213562373064 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 19/2 ⇜ (609/64 → 305/32) ⇝ 77/8 | note:F5 gain:0.5814213562373064 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 19/2 ⇜ (609/64 → 305/32) ⇝ 39/4 | note:C2 gain:0.5814213562373064 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 19/2 ⇜ (305/32 → 611/64) ⇝ 77/8 | note:G4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 19/2 ⇜ (305/32 → 611/64) ⇝ 77/8 | note:D5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 19/2 ⇜ (305/32 → 611/64) ⇝ 77/8 | note:F5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 19/2 ⇜ (305/32 → 611/64) ⇝ 39/4 | note:C2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ (267/28 → 611/64) ⇝ 137/14 | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ (267/28 → 611/64) ⇝ 137/14 | note:74 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (267/28 → 611/64) ⇝ 137/14 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ (267/28 → 611/64) ⇝ 137/14 | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 19/2 ⇜ (611/64 → 153/16) ⇝ 77/8 | note:G4 gain:0.5814213562373134 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 19/2 ⇜ (611/64 → 153/16) ⇝ 77/8 | note:D5 gain:0.5814213562373134 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 19/2 ⇜ (611/64 → 153/16) ⇝ 77/8 | note:F5 gain:0.5814213562373134 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 19/2 ⇜ (611/64 → 153/16) ⇝ 39/4 | note:C2 gain:0.5814213562373134 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 267/28 ⇜ (611/64 → 153/16) ⇝ 137/14 | note:70 gain:0.05814213562373134 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 267/28 ⇜ (611/64 → 153/16) ⇝ 137/14 | note:74 gain:0.05814213562373134 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 267/28 ⇜ (611/64 → 153/16) ⇝ 137/14 | note:75 gain:0.05814213562373134 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 267/28 ⇜ (611/64 → 153/16) ⇝ 137/14 | note:79 gain:0.05814213562373134 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 19/2 ⇜ (153/16 → 613/64) ⇝ 77/8 | note:G4 gain:0.4400000000000002 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 19/2 ⇜ (153/16 → 613/64) ⇝ 77/8 | note:D5 gain:0.4400000000000002 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 19/2 ⇜ (153/16 → 613/64) ⇝ 77/8 | note:F5 gain:0.4400000000000002 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 19/2 ⇜ (153/16 → 613/64) ⇝ 39/4 | note:C2 gain:0.4400000000000002 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 267/28 ⇜ (153/16 → 613/64) ⇝ 137/14 | note:70 gain:0.044000000000000025 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 267/28 ⇜ (153/16 → 613/64) ⇝ 137/14 | note:74 gain:0.044000000000000025 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 267/28 ⇜ (153/16 → 613/64) ⇝ 137/14 | note:75 gain:0.044000000000000025 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 267/28 ⇜ (153/16 → 613/64) ⇝ 137/14 | note:79 gain:0.044000000000000025 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 19/2 ⇜ (613/64 → 307/32) ⇝ 77/8 | note:G4 gain:0.29857864376269505 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 19/2 ⇜ (613/64 → 307/32) ⇝ 77/8 | note:D5 gain:0.29857864376269505 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 19/2 ⇜ (613/64 → 307/32) ⇝ 77/8 | note:F5 gain:0.29857864376269505 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 19/2 ⇜ (613/64 → 307/32) ⇝ 39/4 | note:C2 gain:0.29857864376269505 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 267/28 ⇜ (613/64 → 307/32) ⇝ 137/14 | note:70 gain:0.029857864376269506 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 267/28 ⇜ (613/64 → 307/32) ⇝ 137/14 | note:74 gain:0.029857864376269506 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 267/28 ⇜ (613/64 → 307/32) ⇝ 137/14 | note:75 gain:0.029857864376269506 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 267/28 ⇜ (613/64 → 307/32) ⇝ 137/14 | note:79 gain:0.029857864376269506 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 19/2 ⇜ (307/32 → 615/64) ⇝ 77/8 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 19/2 ⇜ (307/32 → 615/64) ⇝ 77/8 | note:D5 gain:0.24 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 19/2 ⇜ (307/32 → 615/64) ⇝ 77/8 | note:F5 gain:0.24 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 19/2 ⇜ (307/32 → 615/64) ⇝ 39/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 267/28 ⇜ (307/32 → 615/64) ⇝ 137/14 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 267/28 ⇜ (307/32 → 615/64) ⇝ 137/14 | note:74 gain:0.024 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 267/28 ⇜ (307/32 → 615/64) ⇝ 137/14 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 267/28 ⇜ (307/32 → 615/64) ⇝ 137/14 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 19/2 ⇜ (615/64 → 77/8) | note:G4 gain:0.2985786437626852 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 19/2 ⇜ (615/64 → 77/8) | note:D5 gain:0.2985786437626852 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 19/2 ⇜ (615/64 → 77/8) | note:F5 gain:0.2985786437626852 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 19/2 ⇜ (615/64 → 77/8) ⇝ 39/4 | note:C2 gain:0.2985786437626852 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 267/28 ⇜ (615/64 → 77/8) ⇝ 137/14 | note:70 gain:0.029857864376268525 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 267/28 ⇜ (615/64 → 77/8) ⇝ 137/14 | note:74 gain:0.029857864376268525 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 267/28 ⇜ (615/64 → 77/8) ⇝ 137/14 | note:75 gain:0.029857864376268525 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 267/28 ⇜ (615/64 → 77/8) ⇝ 137/14 | note:79 gain:0.029857864376268525 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 19/2 ⇜ (77/8 → 617/64) ⇝ 39/4 | note:C2 gain:0.43999999999999767 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 267/28 ⇜ (77/8 → 617/64) ⇝ 137/14 | note:70 gain:0.04399999999999977 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 267/28 ⇜ (77/8 → 617/64) ⇝ 137/14 | note:74 gain:0.04399999999999977 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 267/28 ⇜ (77/8 → 617/64) ⇝ 137/14 | note:75 gain:0.04399999999999977 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 267/28 ⇜ (77/8 → 617/64) ⇝ 137/14 | note:79 gain:0.04399999999999977 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 19/2 ⇜ (617/64 → 309/32) ⇝ 39/4 | note:C2 gain:0.5814213562373034 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 267/28 ⇜ (617/64 → 309/32) ⇝ 137/14 | note:70 gain:0.05814213562373034 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 267/28 ⇜ (617/64 → 309/32) ⇝ 137/14 | note:74 gain:0.05814213562373034 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 267/28 ⇜ (617/64 → 309/32) ⇝ 137/14 | note:75 gain:0.05814213562373034 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 267/28 ⇜ (617/64 → 309/32) ⇝ 137/14 | note:79 gain:0.05814213562373034 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 19/2 ⇜ (309/32 → 619/64) ⇝ 39/4 | note:C2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 267/28 ⇜ (309/32 → 619/64) ⇝ 137/14 | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 267/28 ⇜ (309/32 → 619/64) ⇝ 137/14 | note:74 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 267/28 ⇜ (309/32 → 619/64) ⇝ 137/14 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 267/28 ⇜ (309/32 → 619/64) ⇝ 137/14 | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 19/2 ⇜ (619/64 → 155/16) ⇝ 39/4 | note:C2 gain:0.5814213562373083 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 267/28 ⇜ (619/64 → 155/16) ⇝ 137/14 | note:70 gain:0.05814213562373083 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 267/28 ⇜ (619/64 → 155/16) ⇝ 137/14 | note:74 gain:0.05814213562373083 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 267/28 ⇜ (619/64 → 155/16) ⇝ 137/14 | note:75 gain:0.05814213562373083 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 267/28 ⇜ (619/64 → 155/16) ⇝ 137/14 | note:79 gain:0.05814213562373083 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 19/2 ⇜ (155/16 → 621/64) ⇝ 39/4 | note:C2 gain:0.4400000000000045 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 267/28 ⇜ (155/16 → 621/64) ⇝ 137/14 | note:70 gain:0.044000000000000455 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 267/28 ⇜ (155/16 → 621/64) ⇝ 137/14 | note:74 gain:0.044000000000000455 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 267/28 ⇜ (155/16 → 621/64) ⇝ 137/14 | note:75 gain:0.044000000000000455 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 267/28 ⇜ (155/16 → 621/64) ⇝ 137/14 | note:79 gain:0.044000000000000455 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 19/2 ⇜ (621/64 → 311/32) ⇝ 39/4 | note:C2 gain:0.29857864376269 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 267/28 ⇜ (621/64 → 311/32) ⇝ 137/14 | note:70 gain:0.029857864376269 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 267/28 ⇜ (621/64 → 311/32) ⇝ 137/14 | note:74 gain:0.029857864376269 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 267/28 ⇜ (621/64 → 311/32) ⇝ 137/14 | note:75 gain:0.029857864376269 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 267/28 ⇜ (621/64 → 311/32) ⇝ 137/14 | note:79 gain:0.029857864376269 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 19/2 ⇜ (311/32 → 623/64) ⇝ 39/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 267/28 ⇜ (311/32 → 623/64) ⇝ 137/14 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 267/28 ⇜ (311/32 → 623/64) ⇝ 137/14 | note:74 gain:0.024 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 267/28 ⇜ (311/32 → 623/64) ⇝ 137/14 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 267/28 ⇜ (311/32 → 623/64) ⇝ 137/14 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 19/2 ⇜ (623/64 → 39/4) | note:C2 gain:0.2985786437626902 clip:1 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 267/28 ⇜ (623/64 → 39/4) ⇝ 137/14 | note:70 gain:0.029857864376269024 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 267/28 ⇜ (623/64 → 39/4) ⇝ 137/14 | note:74 gain:0.029857864376269024 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 267/28 ⇜ (623/64 → 39/4) ⇝ 137/14 | note:75 gain:0.029857864376269024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 267/28 ⇜ (623/64 → 39/4) ⇝ 137/14 | note:79 gain:0.029857864376269024 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 267/28 ⇜ (39/4 → 625/64) ⇝ 137/14 | note:70 gain:0.04399999999999933 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 267/28 ⇜ (39/4 → 625/64) ⇝ 137/14 | note:74 gain:0.04399999999999933 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 267/28 ⇜ (39/4 → 625/64) ⇝ 137/14 | note:75 gain:0.04399999999999933 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 267/28 ⇜ (39/4 → 625/64) ⇝ 137/14 | note:79 gain:0.04399999999999933 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ (39/4 → 625/64) ⇝ 79/8 | note:G4 gain:0.4399999999999933 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (39/4 → 625/64) ⇝ 79/8 | note:D5 gain:0.4399999999999933 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (39/4 → 625/64) ⇝ 79/8 | note:F5 gain:0.4399999999999933 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ (39/4 → 625/64) ⇝ 10/1 | note:Bb3 gain:0.21999999999999664 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ (39/4 → 625/64) ⇝ 10/1 | note:D4 gain:0.21999999999999664 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ (39/4 → 625/64) ⇝ 10/1 | note:Eb4 gain:0.21999999999999664 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ (39/4 → 625/64) ⇝ 10/1 | note:G4 gain:0.21999999999999664 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 267/28 ⇜ (625/64 → 313/32) ⇝ 137/14 | note:70 gain:0.05814213562373084 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 267/28 ⇜ (625/64 → 313/32) ⇝ 137/14 | note:74 gain:0.05814213562373084 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 267/28 ⇜ (625/64 → 313/32) ⇝ 137/14 | note:75 gain:0.05814213562373084 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 267/28 ⇜ (625/64 → 313/32) ⇝ 137/14 | note:79 gain:0.05814213562373084 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 39/4 ⇜ (625/64 → 313/32) ⇝ 79/8 | note:G4 gain:0.5814213562373084 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 39/4 ⇜ (625/64 → 313/32) ⇝ 79/8 | note:D5 gain:0.5814213562373084 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 39/4 ⇜ (625/64 → 313/32) ⇝ 79/8 | note:F5 gain:0.5814213562373084 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 39/4 ⇜ (625/64 → 313/32) ⇝ 10/1 | note:Bb3 gain:0.2907106781186542 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 39/4 ⇜ (625/64 → 313/32) ⇝ 10/1 | note:D4 gain:0.2907106781186542 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 39/4 ⇜ (625/64 → 313/32) ⇝ 10/1 | note:Eb4 gain:0.2907106781186542 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 39/4 ⇜ (625/64 → 313/32) ⇝ 10/1 | note:G4 gain:0.2907106781186542 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 267/28 ⇜ (313/32 → 137/14) | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 267/28 ⇜ (313/32 → 137/14) | note:74 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 267/28 ⇜ (313/32 → 137/14) | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 267/28 ⇜ (313/32 → 137/14) | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 39/4 ⇜ (313/32 → 627/64) ⇝ 79/8 | note:G4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 39/4 ⇜ (313/32 → 627/64) ⇝ 79/8 | note:D5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 39/4 ⇜ (313/32 → 627/64) ⇝ 79/8 | note:F5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 39/4 ⇜ (313/32 → 627/64) ⇝ 10/1 | note:Bb3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 39/4 ⇜ (313/32 → 627/64) ⇝ 10/1 | note:D4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 39/4 ⇜ (313/32 → 627/64) ⇝ 10/1 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 39/4 ⇜ (313/32 → 627/64) ⇝ 10/1 | note:G4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 39/4 ⇜ (627/64 → 157/16) ⇝ 79/8 | note:G4 gain:0.5814213562373114 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 39/4 ⇜ (627/64 → 157/16) ⇝ 79/8 | note:D5 gain:0.5814213562373114 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 39/4 ⇜ (627/64 → 157/16) ⇝ 79/8 | note:F5 gain:0.5814213562373114 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 39/4 ⇜ (627/64 → 157/16) ⇝ 10/1 | note:Bb3 gain:0.2907106781186557 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 39/4 ⇜ (627/64 → 157/16) ⇝ 10/1 | note:D4 gain:0.2907106781186557 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 39/4 ⇜ (627/64 → 157/16) ⇝ 10/1 | note:Eb4 gain:0.2907106781186557 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 39/4 ⇜ (627/64 → 157/16) ⇝ 10/1 | note:G4 gain:0.2907106781186557 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 39/4 ⇜ (157/16 → 629/64) ⇝ 79/8 | note:G4 gain:0.44000000000000883 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 39/4 ⇜ (157/16 → 629/64) ⇝ 79/8 | note:D5 gain:0.44000000000000883 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 39/4 ⇜ (157/16 → 629/64) ⇝ 79/8 | note:F5 gain:0.44000000000000883 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 39/4 ⇜ (157/16 → 629/64) ⇝ 10/1 | note:Bb3 gain:0.22000000000000441 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 39/4 ⇜ (157/16 → 629/64) ⇝ 10/1 | note:D4 gain:0.22000000000000441 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 39/4 ⇜ (157/16 → 629/64) ⇝ 10/1 | note:Eb4 gain:0.22000000000000441 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 39/4 ⇜ (157/16 → 629/64) ⇝ 10/1 | note:G4 gain:0.22000000000000441 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 39/4 ⇜ (629/64 → 315/32) ⇝ 79/8 | note:G4 gain:0.2985786437626931 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 39/4 ⇜ (629/64 → 315/32) ⇝ 79/8 | note:D5 gain:0.2985786437626931 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 39/4 ⇜ (629/64 → 315/32) ⇝ 79/8 | note:F5 gain:0.2985786437626931 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 39/4 ⇜ (629/64 → 315/32) ⇝ 10/1 | note:Bb3 gain:0.14928932188134655 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 39/4 ⇜ (629/64 → 315/32) ⇝ 10/1 | note:D4 gain:0.14928932188134655 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 39/4 ⇜ (629/64 → 315/32) ⇝ 10/1 | note:Eb4 gain:0.14928932188134655 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 39/4 ⇜ (629/64 → 315/32) ⇝ 10/1 | note:G4 gain:0.14928932188134655 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 39/4 ⇜ (315/32 → 631/64) ⇝ 79/8 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 39/4 ⇜ (315/32 → 631/64) ⇝ 79/8 | note:D5 gain:0.24 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 39/4 ⇜ (315/32 → 631/64) ⇝ 79/8 | note:F5 gain:0.24 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 39/4 ⇜ (315/32 → 631/64) ⇝ 10/1 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 39/4 ⇜ (315/32 → 631/64) ⇝ 10/1 | note:D4 gain:0.12 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 39/4 ⇜ (315/32 → 631/64) ⇝ 10/1 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 39/4 ⇜ (315/32 → 631/64) ⇝ 10/1 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 39/4 ⇜ (631/64 → 79/8) | note:G4 gain:0.2985786437626871 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 39/4 ⇜ (631/64 → 79/8) | note:D5 gain:0.2985786437626871 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 39/4 ⇜ (631/64 → 79/8) | note:F5 gain:0.2985786437626871 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 39/4 ⇜ (631/64 → 79/8) ⇝ 10/1 | note:Bb3 gain:0.14928932188134356 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 39/4 ⇜ (631/64 → 79/8) ⇝ 10/1 | note:D4 gain:0.14928932188134356 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 39/4 ⇜ (631/64 → 79/8) ⇝ 10/1 | note:Eb4 gain:0.14928932188134356 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 39/4 ⇜ (631/64 → 79/8) ⇝ 10/1 | note:G4 gain:0.14928932188134356 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 39/4 ⇜ (79/8 → 633/64) ⇝ 10/1 | note:Bb3 gain:0.2200000000000002 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 39/4 ⇜ (79/8 → 633/64) ⇝ 10/1 | note:D4 gain:0.2200000000000002 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 39/4 ⇜ (79/8 → 633/64) ⇝ 10/1 | note:Eb4 gain:0.2200000000000002 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 39/4 ⇜ (79/8 → 633/64) ⇝ 10/1 | note:G4 gain:0.2200000000000002 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 39/4 ⇜ (633/64 → 317/32) ⇝ 10/1 | note:Bb3 gain:0.2907106781186527 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 39/4 ⇜ (633/64 → 317/32) ⇝ 10/1 | note:D4 gain:0.2907106781186527 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 39/4 ⇜ (633/64 → 317/32) ⇝ 10/1 | note:Eb4 gain:0.2907106781186527 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 39/4 ⇜ (633/64 → 317/32) ⇝ 10/1 | note:G4 gain:0.2907106781186527 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 39/4 ⇜ (317/32 → 635/64) ⇝ 10/1 | note:Bb3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 39/4 ⇜ (317/32 → 635/64) ⇝ 10/1 | note:D4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 39/4 ⇜ (317/32 → 635/64) ⇝ 10/1 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 39/4 ⇜ (317/32 → 635/64) ⇝ 10/1 | note:G4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 39/4 ⇜ (635/64 → 159/16) ⇝ 10/1 | note:Bb3 gain:0.2907106781186572 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 39/4 ⇜ (635/64 → 159/16) ⇝ 10/1 | note:D4 gain:0.2907106781186572 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 39/4 ⇜ (635/64 → 159/16) ⇝ 10/1 | note:Eb4 gain:0.2907106781186572 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 39/4 ⇜ (635/64 → 159/16) ⇝ 10/1 | note:G4 gain:0.2907106781186572 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 39/4 ⇜ (159/16 → 637/64) ⇝ 10/1 | note:Bb3 gain:0.22000000000000092 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 39/4 ⇜ (159/16 → 637/64) ⇝ 10/1 | note:D4 gain:0.22000000000000092 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 39/4 ⇜ (159/16 → 637/64) ⇝ 10/1 | note:Eb4 gain:0.22000000000000092 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 39/4 ⇜ (159/16 → 637/64) ⇝ 10/1 | note:G4 gain:0.22000000000000092 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 39/4 ⇜ (637/64 → 319/32) ⇝ 10/1 | note:Bb3 gain:0.14928932188134808 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 39/4 ⇜ (637/64 → 319/32) ⇝ 10/1 | note:D4 gain:0.14928932188134808 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 39/4 ⇜ (637/64 → 319/32) ⇝ 10/1 | note:Eb4 gain:0.14928932188134808 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 39/4 ⇜ (637/64 → 319/32) ⇝ 10/1 | note:G4 gain:0.14928932188134808 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 39/4 ⇜ (319/32 → 639/64) ⇝ 10/1 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 39/4 ⇜ (319/32 → 639/64) ⇝ 10/1 | note:D4 gain:0.12 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 39/4 ⇜ (319/32 → 639/64) ⇝ 10/1 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 39/4 ⇜ (319/32 → 639/64) ⇝ 10/1 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 39/4 ⇜ (639/64 → 10/1) | note:Bb3 gain:0.14928932188134203 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 39/4 ⇜ (639/64 → 10/1) | note:D4 gain:0.14928932188134203 clip:1 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 39/4 ⇜ (639/64 → 10/1) | note:Eb4 gain:0.14928932188134203 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 39/4 ⇜ (639/64 → 10/1) | note:G4 gain:0.14928932188134203 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (10/1 → 641/64) ⇝ 41/4 | note:F2 gain:0.43999999999999617 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 10/1 ⇜ (641/64 → 321/32) ⇝ 41/4 | note:F2 gain:0.5814213562373104 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 10/1 ⇜ (321/32 → 643/64) ⇝ 41/4 | note:F2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ (281/28 → 643/64) ⇝ 72/7 | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ (281/28 → 643/64) ⇝ 72/7 | note:74 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (281/28 → 643/64) ⇝ 72/7 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ (281/28 → 643/64) ⇝ 72/7 | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 10/1 ⇜ (643/64 → 161/16) ⇝ 41/4 | note:F2 gain:0.5814213562373095 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 281/28 ⇜ (643/64 → 161/16) ⇝ 72/7 | note:70 gain:0.05814213562373095 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 281/28 ⇜ (643/64 → 161/16) ⇝ 72/7 | note:74 gain:0.05814213562373095 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 281/28 ⇜ (643/64 → 161/16) ⇝ 72/7 | note:75 gain:0.05814213562373095 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 281/28 ⇜ (643/64 → 161/16) ⇝ 72/7 | note:79 gain:0.05814213562373095 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 10/1 ⇜ (161/16 → 645/64) ⇝ 41/4 | note:F2 gain:0.4400000000000061 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 281/28 ⇜ (161/16 → 645/64) ⇝ 72/7 | note:70 gain:0.044000000000000615 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 281/28 ⇜ (161/16 → 645/64) ⇝ 72/7 | note:74 gain:0.044000000000000615 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 281/28 ⇜ (161/16 → 645/64) ⇝ 72/7 | note:75 gain:0.044000000000000615 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 281/28 ⇜ (161/16 → 645/64) ⇝ 72/7 | note:79 gain:0.044000000000000615 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 10/1 ⇜ (645/64 → 323/32) ⇝ 41/4 | note:F2 gain:0.29857864376269116 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 281/28 ⇜ (645/64 → 323/32) ⇝ 72/7 | note:70 gain:0.029857864376269118 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 281/28 ⇜ (645/64 → 323/32) ⇝ 72/7 | note:74 gain:0.029857864376269118 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 281/28 ⇜ (645/64 → 323/32) ⇝ 72/7 | note:75 gain:0.029857864376269118 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 281/28 ⇜ (645/64 → 323/32) ⇝ 72/7 | note:79 gain:0.029857864376269118 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 10/1 ⇜ (323/32 → 647/64) ⇝ 41/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 281/28 ⇜ (323/32 → 647/64) ⇝ 72/7 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 281/28 ⇜ (323/32 → 647/64) ⇝ 72/7 | note:74 gain:0.024 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 281/28 ⇜ (323/32 → 647/64) ⇝ 72/7 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 281/28 ⇜ (323/32 → 647/64) ⇝ 72/7 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 10/1 ⇜ (647/64 → 81/8) ⇝ 41/4 | note:F2 gain:0.2985786437626891 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 281/28 ⇜ (647/64 → 81/8) ⇝ 72/7 | note:70 gain:0.029857864376268913 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 281/28 ⇜ (647/64 → 81/8) ⇝ 72/7 | note:74 gain:0.029857864376268913 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 281/28 ⇜ (647/64 → 81/8) ⇝ 72/7 | note:75 gain:0.029857864376268913 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 281/28 ⇜ (647/64 → 81/8) ⇝ 72/7 | note:79 gain:0.029857864376268913 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 10/1 ⇜ (81/8 → 649/64) ⇝ 41/4 | note:F2 gain:0.4399999999999918 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 281/28 ⇜ (81/8 → 649/64) ⇝ 72/7 | note:70 gain:0.04399999999999918 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 281/28 ⇜ (81/8 → 649/64) ⇝ 72/7 | note:74 gain:0.04399999999999918 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 281/28 ⇜ (81/8 → 649/64) ⇝ 72/7 | note:75 gain:0.04399999999999918 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 281/28 ⇜ (81/8 → 649/64) ⇝ 72/7 | note:79 gain:0.04399999999999918 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ (81/8 → 649/64) ⇝ 41/4 | note:F4 gain:0.4399999999999918 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (81/8 → 649/64) ⇝ 41/4 | note:C5 gain:0.4399999999999918 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ (81/8 → 649/64) ⇝ 41/4 | note:Eb5 gain:0.4399999999999918 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 10/1 ⇜ (649/64 → 325/32) ⇝ 41/4 | note:F2 gain:0.5814213562373073 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 281/28 ⇜ (649/64 → 325/32) ⇝ 72/7 | note:70 gain:0.05814213562373073 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 281/28 ⇜ (649/64 → 325/32) ⇝ 72/7 | note:74 gain:0.05814213562373073 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 281/28 ⇜ (649/64 → 325/32) ⇝ 72/7 | note:75 gain:0.05814213562373073 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 281/28 ⇜ (649/64 → 325/32) ⇝ 72/7 | note:79 gain:0.05814213562373073 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 81/8 ⇜ (649/64 → 325/32) ⇝ 41/4 | note:F4 gain:0.5814213562373073 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 81/8 ⇜ (649/64 → 325/32) ⇝ 41/4 | note:C5 gain:0.5814213562373073 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 81/8 ⇜ (649/64 → 325/32) ⇝ 41/4 | note:Eb5 gain:0.5814213562373073 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 10/1 ⇜ (325/32 → 651/64) ⇝ 41/4 | note:F2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 281/28 ⇜ (325/32 → 651/64) ⇝ 72/7 | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 281/28 ⇜ (325/32 → 651/64) ⇝ 72/7 | note:74 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 281/28 ⇜ (325/32 → 651/64) ⇝ 72/7 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 281/28 ⇜ (325/32 → 651/64) ⇝ 72/7 | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 81/8 ⇜ (325/32 → 651/64) ⇝ 41/4 | note:F4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 81/8 ⇜ (325/32 → 651/64) ⇝ 41/4 | note:C5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 81/8 ⇜ (325/32 → 651/64) ⇝ 41/4 | note:Eb5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 10/1 ⇜ (651/64 → 163/16) ⇝ 41/4 | note:F2 gain:0.5814213562373125 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 281/28 ⇜ (651/64 → 163/16) ⇝ 72/7 | note:70 gain:0.05814213562373125 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 281/28 ⇜ (651/64 → 163/16) ⇝ 72/7 | note:74 gain:0.05814213562373125 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 281/28 ⇜ (651/64 → 163/16) ⇝ 72/7 | note:75 gain:0.05814213562373125 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 281/28 ⇜ (651/64 → 163/16) ⇝ 72/7 | note:79 gain:0.05814213562373125 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 81/8 ⇜ (651/64 → 163/16) ⇝ 41/4 | note:F4 gain:0.5814213562373125 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 81/8 ⇜ (651/64 → 163/16) ⇝ 41/4 | note:C5 gain:0.5814213562373125 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 81/8 ⇜ (651/64 → 163/16) ⇝ 41/4 | note:Eb5 gain:0.5814213562373125 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 10/1 ⇜ (163/16 → 653/64) ⇝ 41/4 | note:F2 gain:0.4400000000000104 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 281/28 ⇜ (163/16 → 653/64) ⇝ 72/7 | note:70 gain:0.04400000000000104 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 281/28 ⇜ (163/16 → 653/64) ⇝ 72/7 | note:74 gain:0.04400000000000104 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 281/28 ⇜ (163/16 → 653/64) ⇝ 72/7 | note:75 gain:0.04400000000000104 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 281/28 ⇜ (163/16 → 653/64) ⇝ 72/7 | note:79 gain:0.04400000000000104 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 81/8 ⇜ (163/16 → 653/64) ⇝ 41/4 | note:F4 gain:0.4400000000000104 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 81/8 ⇜ (163/16 → 653/64) ⇝ 41/4 | note:C5 gain:0.4400000000000104 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 81/8 ⇜ (163/16 → 653/64) ⇝ 41/4 | note:Eb5 gain:0.4400000000000104 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 10/1 ⇜ (653/64 → 327/32) ⇝ 41/4 | note:F2 gain:0.29857864376268617 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 281/28 ⇜ (653/64 → 327/32) ⇝ 72/7 | note:70 gain:0.02985786437626862 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 281/28 ⇜ (653/64 → 327/32) ⇝ 72/7 | note:74 gain:0.02985786437626862 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 281/28 ⇜ (653/64 → 327/32) ⇝ 72/7 | note:75 gain:0.02985786437626862 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 281/28 ⇜ (653/64 → 327/32) ⇝ 72/7 | note:79 gain:0.02985786437626862 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 81/8 ⇜ (653/64 → 327/32) ⇝ 41/4 | note:F4 gain:0.29857864376268617 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 81/8 ⇜ (653/64 → 327/32) ⇝ 41/4 | note:C5 gain:0.29857864376268617 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 81/8 ⇜ (653/64 → 327/32) ⇝ 41/4 | note:Eb5 gain:0.29857864376268617 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 10/1 ⇜ (327/32 → 655/64) ⇝ 41/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 281/28 ⇜ (327/32 → 655/64) ⇝ 72/7 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 281/28 ⇜ (327/32 → 655/64) ⇝ 72/7 | note:74 gain:0.024 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 281/28 ⇜ (327/32 → 655/64) ⇝ 72/7 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 281/28 ⇜ (327/32 → 655/64) ⇝ 72/7 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 81/8 ⇜ (327/32 → 655/64) ⇝ 41/4 | note:F4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 81/8 ⇜ (327/32 → 655/64) ⇝ 41/4 | note:C5 gain:0.24 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 81/8 ⇜ (327/32 → 655/64) ⇝ 41/4 | note:Eb5 gain:0.24 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 10/1 ⇜ (655/64 → 41/4) | note:F2 gain:0.298578643762686 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 281/28 ⇜ (655/64 → 41/4) ⇝ 72/7 | note:70 gain:0.0298578643762686 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 281/28 ⇜ (655/64 → 41/4) ⇝ 72/7 | note:74 gain:0.0298578643762686 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 281/28 ⇜ (655/64 → 41/4) ⇝ 72/7 | note:75 gain:0.0298578643762686 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 281/28 ⇜ (655/64 → 41/4) ⇝ 72/7 | note:79 gain:0.0298578643762686 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 81/8 ⇜ (655/64 → 41/4) | note:F4 gain:0.298578643762686 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 81/8 ⇜ (655/64 → 41/4) | note:C5 gain:0.298578643762686 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 81/8 ⇜ (655/64 → 41/4) | note:Eb5 gain:0.298578643762686 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 281/28 ⇜ (41/4 → 657/64) ⇝ 72/7 | note:70 gain:0.04399999999999875 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 281/28 ⇜ (41/4 → 657/64) ⇝ 72/7 | note:74 gain:0.04399999999999875 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 281/28 ⇜ (41/4 → 657/64) ⇝ 72/7 | note:75 gain:0.04399999999999875 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 281/28 ⇜ (41/4 → 657/64) ⇝ 72/7 | note:79 gain:0.04399999999999875 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 281/28 ⇜ (657/64 → 329/32) ⇝ 72/7 | note:70 gain:0.05814213562373123 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 281/28 ⇜ (657/64 → 329/32) ⇝ 72/7 | note:74 gain:0.05814213562373123 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 281/28 ⇜ (657/64 → 329/32) ⇝ 72/7 | note:75 gain:0.05814213562373123 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 281/28 ⇜ (657/64 → 329/32) ⇝ 72/7 | note:79 gain:0.05814213562373123 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 281/28 ⇜ (329/32 → 72/7) | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 281/28 ⇜ (329/32 → 72/7) | note:74 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 281/28 ⇜ (329/32 → 72/7) | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 281/28 ⇜ (329/32 → 72/7) | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ (21/2 → 673/64) ⇝ 85/8 | note:C5 gain:0.44000000000000156 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ (21/2 → 673/64) ⇝ 85/8 | note:G5 gain:0.44000000000000156 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ (21/2 → 673/64) ⇝ 85/8 | note:Bb5 gain:0.44000000000000156 clip:1 s:piano release:0.1 pan:0.6296296296296297 ]", - "[ (21/2 → 673/64) ⇝ 43/4 | note:Eb4 gain:0.22000000000000078 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ (21/2 → 673/64) ⇝ 43/4 | note:G4 gain:0.22000000000000078 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (21/2 → 673/64) ⇝ 43/4 | note:Ab4 gain:0.22000000000000078 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ (21/2 → 673/64) ⇝ 43/4 | note:C5 gain:0.22000000000000078 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ (21/2 → 673/64) ⇝ 43/4 | note:F2 gain:0.44000000000000156 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 21/2 ⇜ (673/64 → 337/32) ⇝ 85/8 | note:C5 gain:0.5814213562373063 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 21/2 ⇜ (673/64 → 337/32) ⇝ 85/8 | note:G5 gain:0.5814213562373063 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 21/2 ⇜ (673/64 → 337/32) ⇝ 85/8 | note:Bb5 gain:0.5814213562373063 clip:1 s:piano release:0.1 pan:0.6296296296296297 ]", - "[ 21/2 ⇜ (673/64 → 337/32) ⇝ 43/4 | note:Eb4 gain:0.29071067811865314 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 21/2 ⇜ (673/64 → 337/32) ⇝ 43/4 | note:G4 gain:0.29071067811865314 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 21/2 ⇜ (673/64 → 337/32) ⇝ 43/4 | note:Ab4 gain:0.29071067811865314 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 21/2 ⇜ (673/64 → 337/32) ⇝ 43/4 | note:C5 gain:0.29071067811865314 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 21/2 ⇜ (673/64 → 337/32) ⇝ 43/4 | note:F2 gain:0.5814213562373063 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 21/2 ⇜ (337/32 → 675/64) ⇝ 85/8 | note:C5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 21/2 ⇜ (337/32 → 675/64) ⇝ 85/8 | note:G5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 21/2 ⇜ (337/32 → 675/64) ⇝ 85/8 | note:Bb5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6296296296296297 ]", - "[ 21/2 ⇜ (337/32 → 675/64) ⇝ 43/4 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 21/2 ⇜ (337/32 → 675/64) ⇝ 43/4 | note:G4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 21/2 ⇜ (337/32 → 675/64) ⇝ 43/4 | note:Ab4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 21/2 ⇜ (337/32 → 675/64) ⇝ 43/4 | note:C5 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 21/2 ⇜ (337/32 → 675/64) ⇝ 43/4 | note:F2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 21/2 ⇜ (675/64 → 169/16) ⇝ 85/8 | note:C5 gain:0.5814213562373055 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 21/2 ⇜ (675/64 → 169/16) ⇝ 85/8 | note:G5 gain:0.5814213562373055 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 21/2 ⇜ (675/64 → 169/16) ⇝ 85/8 | note:Bb5 gain:0.5814213562373055 clip:1 s:piano release:0.1 pan:0.6296296296296297 ]", - "[ 21/2 ⇜ (675/64 → 169/16) ⇝ 43/4 | note:Eb4 gain:0.29071067811865275 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 21/2 ⇜ (675/64 → 169/16) ⇝ 43/4 | note:G4 gain:0.29071067811865275 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 21/2 ⇜ (675/64 → 169/16) ⇝ 43/4 | note:Ab4 gain:0.29071067811865275 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 21/2 ⇜ (675/64 → 169/16) ⇝ 43/4 | note:C5 gain:0.29071067811865275 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 21/2 ⇜ (675/64 → 169/16) ⇝ 43/4 | note:F2 gain:0.5814213562373055 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 21/2 ⇜ (169/16 → 677/64) ⇝ 85/8 | note:C5 gain:0.4400000000000006 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 21/2 ⇜ (169/16 → 677/64) ⇝ 85/8 | note:G5 gain:0.4400000000000006 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 21/2 ⇜ (169/16 → 677/64) ⇝ 85/8 | note:Bb5 gain:0.4400000000000006 clip:1 s:piano release:0.1 pan:0.6296296296296297 ]", - "[ 21/2 ⇜ (169/16 → 677/64) ⇝ 43/4 | note:Eb4 gain:0.2200000000000003 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 21/2 ⇜ (169/16 → 677/64) ⇝ 43/4 | note:G4 gain:0.2200000000000003 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 21/2 ⇜ (169/16 → 677/64) ⇝ 43/4 | note:Ab4 gain:0.2200000000000003 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 21/2 ⇜ (169/16 → 677/64) ⇝ 43/4 | note:C5 gain:0.2200000000000003 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 21/2 ⇜ (169/16 → 677/64) ⇝ 43/4 | note:F2 gain:0.4400000000000006 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 21/2 ⇜ (677/64 → 339/32) ⇝ 85/8 | note:C5 gain:0.29857864376269533 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 21/2 ⇜ (677/64 → 339/32) ⇝ 85/8 | note:G5 gain:0.29857864376269533 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 21/2 ⇜ (677/64 → 339/32) ⇝ 85/8 | note:Bb5 gain:0.29857864376269533 clip:1 s:piano release:0.1 pan:0.6296296296296297 ]", - "[ 21/2 ⇜ (677/64 → 339/32) ⇝ 43/4 | note:Eb4 gain:0.14928932188134766 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 21/2 ⇜ (677/64 → 339/32) ⇝ 43/4 | note:G4 gain:0.14928932188134766 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 21/2 ⇜ (677/64 → 339/32) ⇝ 43/4 | note:Ab4 gain:0.14928932188134766 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 21/2 ⇜ (677/64 → 339/32) ⇝ 43/4 | note:C5 gain:0.14928932188134766 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 21/2 ⇜ (677/64 → 339/32) ⇝ 43/4 | note:F2 gain:0.29857864376269533 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 21/2 ⇜ (339/32 → 679/64) ⇝ 85/8 | note:C5 gain:0.24 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 21/2 ⇜ (339/32 → 679/64) ⇝ 85/8 | note:G5 gain:0.24 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 21/2 ⇜ (339/32 → 679/64) ⇝ 85/8 | note:Bb5 gain:0.24 clip:1 s:piano release:0.1 pan:0.6296296296296297 ]", - "[ 21/2 ⇜ (339/32 → 679/64) ⇝ 43/4 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 21/2 ⇜ (339/32 → 679/64) ⇝ 43/4 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 21/2 ⇜ (339/32 → 679/64) ⇝ 43/4 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 21/2 ⇜ (339/32 → 679/64) ⇝ 43/4 | note:C5 gain:0.12 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 21/2 ⇜ (339/32 → 679/64) ⇝ 43/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 21/2 ⇜ (679/64 → 85/8) | note:C5 gain:0.29857864376269294 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 21/2 ⇜ (679/64 → 85/8) | note:G5 gain:0.29857864376269294 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 21/2 ⇜ (679/64 → 85/8) | note:Bb5 gain:0.29857864376269294 clip:1 s:piano release:0.1 pan:0.6296296296296297 ]", - "[ 21/2 ⇜ (679/64 → 85/8) ⇝ 43/4 | note:Eb4 gain:0.14928932188134647 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 21/2 ⇜ (679/64 → 85/8) ⇝ 43/4 | note:G4 gain:0.14928932188134647 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 21/2 ⇜ (679/64 → 85/8) ⇝ 43/4 | note:Ab4 gain:0.14928932188134647 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 21/2 ⇜ (679/64 → 85/8) ⇝ 43/4 | note:C5 gain:0.14928932188134647 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 21/2 ⇜ (679/64 → 85/8) ⇝ 43/4 | note:F2 gain:0.29857864376269294 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 21/2 ⇜ (85/8 → 681/64) ⇝ 43/4 | note:Eb4 gain:0.2199999999999986 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 21/2 ⇜ (85/8 → 681/64) ⇝ 43/4 | note:G4 gain:0.2199999999999986 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 21/2 ⇜ (85/8 → 681/64) ⇝ 43/4 | note:Ab4 gain:0.2199999999999986 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 21/2 ⇜ (85/8 → 681/64) ⇝ 43/4 | note:C5 gain:0.2199999999999986 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 21/2 ⇜ (85/8 → 681/64) ⇝ 43/4 | note:F2 gain:0.4399999999999972 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 21/2 ⇜ (681/64 → 341/32) ⇝ 43/4 | note:Eb4 gain:0.29071067811865164 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 21/2 ⇜ (681/64 → 341/32) ⇝ 43/4 | note:G4 gain:0.29071067811865164 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 21/2 ⇜ (681/64 → 341/32) ⇝ 43/4 | note:Ab4 gain:0.29071067811865164 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 21/2 ⇜ (681/64 → 341/32) ⇝ 43/4 | note:C5 gain:0.29071067811865164 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 21/2 ⇜ (681/64 → 341/32) ⇝ 43/4 | note:F2 gain:0.5814213562373033 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 21/2 ⇜ (341/32 → 683/64) ⇝ 43/4 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 21/2 ⇜ (341/32 → 683/64) ⇝ 43/4 | note:G4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 21/2 ⇜ (341/32 → 683/64) ⇝ 43/4 | note:Ab4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 21/2 ⇜ (341/32 → 683/64) ⇝ 43/4 | note:C5 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 21/2 ⇜ (341/32 → 683/64) ⇝ 43/4 | note:F2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 21/2 ⇜ (683/64 → 171/16) ⇝ 43/4 | note:Eb4 gain:0.2907106781186543 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 21/2 ⇜ (683/64 → 171/16) ⇝ 43/4 | note:G4 gain:0.2907106781186543 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 21/2 ⇜ (683/64 → 171/16) ⇝ 43/4 | note:Ab4 gain:0.2907106781186543 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 21/2 ⇜ (683/64 → 171/16) ⇝ 43/4 | note:C5 gain:0.2907106781186543 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 21/2 ⇜ (683/64 → 171/16) ⇝ 43/4 | note:F2 gain:0.5814213562373086 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 21/2 ⇜ (171/16 → 685/64) ⇝ 43/4 | note:Eb4 gain:0.22000000000000242 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 21/2 ⇜ (171/16 → 685/64) ⇝ 43/4 | note:G4 gain:0.22000000000000242 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 21/2 ⇜ (171/16 → 685/64) ⇝ 43/4 | note:Ab4 gain:0.22000000000000242 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 21/2 ⇜ (171/16 → 685/64) ⇝ 43/4 | note:C5 gain:0.22000000000000242 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 21/2 ⇜ (171/16 → 685/64) ⇝ 43/4 | note:F2 gain:0.44000000000000483 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 21/2 ⇜ (685/64 → 343/32) ⇝ 43/4 | note:Eb4 gain:0.1492893218813492 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 21/2 ⇜ (685/64 → 343/32) ⇝ 43/4 | note:G4 gain:0.1492893218813492 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 21/2 ⇜ (685/64 → 343/32) ⇝ 43/4 | note:Ab4 gain:0.1492893218813492 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 21/2 ⇜ (685/64 → 343/32) ⇝ 43/4 | note:C5 gain:0.1492893218813492 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 21/2 ⇜ (685/64 → 343/32) ⇝ 43/4 | note:F2 gain:0.2985786437626984 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 21/2 ⇜ (343/32 → 687/64) ⇝ 43/4 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 21/2 ⇜ (343/32 → 687/64) ⇝ 43/4 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 21/2 ⇜ (343/32 → 687/64) ⇝ 43/4 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 21/2 ⇜ (343/32 → 687/64) ⇝ 43/4 | note:C5 gain:0.12 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 21/2 ⇜ (343/32 → 687/64) ⇝ 43/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 21/2 ⇜ (687/64 → 43/4) | note:Eb4 gain:0.14928932188134497 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 21/2 ⇜ (687/64 → 43/4) | note:G4 gain:0.14928932188134497 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 21/2 ⇜ (687/64 → 43/4) | note:Ab4 gain:0.14928932188134497 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 21/2 ⇜ (687/64 → 43/4) | note:C5 gain:0.14928932188134497 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 21/2 ⇜ (687/64 → 43/4) | note:F2 gain:0.29857864376268994 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ (43/4 → 689/64) ⇝ 87/8 | note:F4 gain:0.43999999999999295 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (43/4 → 689/64) ⇝ 87/8 | note:C5 gain:0.43999999999999295 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ (43/4 → 689/64) ⇝ 87/8 | note:Eb5 gain:0.43999999999999295 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 43/4 ⇜ (689/64 → 345/32) ⇝ 87/8 | note:F4 gain:0.5814213562373002 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 43/4 ⇜ (689/64 → 345/32) ⇝ 87/8 | note:C5 gain:0.5814213562373002 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 43/4 ⇜ (689/64 → 345/32) ⇝ 87/8 | note:Eb5 gain:0.5814213562373002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 43/4 ⇜ (345/32 → 691/64) ⇝ 87/8 | note:F4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 43/4 ⇜ (345/32 → 691/64) ⇝ 87/8 | note:C5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 43/4 ⇜ (345/32 → 691/64) ⇝ 87/8 | note:Eb5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ (151/14 → 691/64) ⇝ 309/28 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ (151/14 → 691/64) ⇝ 309/28 | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ (151/14 → 691/64) ⇝ 309/28 | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ (151/14 → 691/64) ⇝ 309/28 | note:84 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 43/4 ⇜ (691/64 → 173/16) ⇝ 87/8 | note:F4 gain:0.5814213562373116 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 43/4 ⇜ (691/64 → 173/16) ⇝ 87/8 | note:C5 gain:0.5814213562373116 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 43/4 ⇜ (691/64 → 173/16) ⇝ 87/8 | note:Eb5 gain:0.5814213562373116 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 151/14 ⇜ (691/64 → 173/16) ⇝ 309/28 | note:75 gain:0.05814213562373116 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 151/14 ⇜ (691/64 → 173/16) ⇝ 309/28 | note:79 gain:0.05814213562373116 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 151/14 ⇜ (691/64 → 173/16) ⇝ 309/28 | note:80 gain:0.05814213562373116 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 151/14 ⇜ (691/64 → 173/16) ⇝ 309/28 | note:84 gain:0.05814213562373116 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 43/4 ⇜ (173/16 → 693/64) ⇝ 87/8 | note:F4 gain:0.4400000000000092 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 43/4 ⇜ (173/16 → 693/64) ⇝ 87/8 | note:C5 gain:0.4400000000000092 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 43/4 ⇜ (173/16 → 693/64) ⇝ 87/8 | note:Eb5 gain:0.4400000000000092 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 151/14 ⇜ (173/16 → 693/64) ⇝ 309/28 | note:75 gain:0.04400000000000093 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 151/14 ⇜ (173/16 → 693/64) ⇝ 309/28 | note:79 gain:0.04400000000000093 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 151/14 ⇜ (173/16 → 693/64) ⇝ 309/28 | note:80 gain:0.04400000000000093 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 151/14 ⇜ (173/16 → 693/64) ⇝ 309/28 | note:84 gain:0.04400000000000093 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 43/4 ⇜ (693/64 → 347/32) ⇝ 87/8 | note:F4 gain:0.2985786437627014 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 43/4 ⇜ (693/64 → 347/32) ⇝ 87/8 | note:C5 gain:0.2985786437627014 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 43/4 ⇜ (693/64 → 347/32) ⇝ 87/8 | note:Eb5 gain:0.2985786437627014 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 151/14 ⇜ (693/64 → 347/32) ⇝ 309/28 | note:75 gain:0.029857864376270138 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 151/14 ⇜ (693/64 → 347/32) ⇝ 309/28 | note:79 gain:0.029857864376270138 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 151/14 ⇜ (693/64 → 347/32) ⇝ 309/28 | note:80 gain:0.029857864376270138 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 151/14 ⇜ (693/64 → 347/32) ⇝ 309/28 | note:84 gain:0.029857864376270138 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 43/4 ⇜ (347/32 → 695/64) ⇝ 87/8 | note:F4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 43/4 ⇜ (347/32 → 695/64) ⇝ 87/8 | note:C5 gain:0.24 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 43/4 ⇜ (347/32 → 695/64) ⇝ 87/8 | note:Eb5 gain:0.24 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 151/14 ⇜ (347/32 → 695/64) ⇝ 309/28 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 151/14 ⇜ (347/32 → 695/64) ⇝ 309/28 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 151/14 ⇜ (347/32 → 695/64) ⇝ 309/28 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 151/14 ⇜ (347/32 → 695/64) ⇝ 309/28 | note:84 gain:0.024 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 43/4 ⇜ (695/64 → 87/8) | note:F4 gain:0.2985786437626869 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 43/4 ⇜ (695/64 → 87/8) | note:C5 gain:0.2985786437626869 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 43/4 ⇜ (695/64 → 87/8) | note:Eb5 gain:0.2985786437626869 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 151/14 ⇜ (695/64 → 87/8) ⇝ 309/28 | note:75 gain:0.02985786437626869 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 151/14 ⇜ (695/64 → 87/8) ⇝ 309/28 | note:79 gain:0.02985786437626869 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 151/14 ⇜ (695/64 → 87/8) ⇝ 309/28 | note:80 gain:0.02985786437626869 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 151/14 ⇜ (695/64 → 87/8) ⇝ 309/28 | note:84 gain:0.02985786437626869 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 151/14 ⇜ (87/8 → 697/64) ⇝ 309/28 | note:75 gain:0.04399999999999887 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 151/14 ⇜ (87/8 → 697/64) ⇝ 309/28 | note:79 gain:0.04399999999999887 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 151/14 ⇜ (87/8 → 697/64) ⇝ 309/28 | note:80 gain:0.04399999999999887 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 151/14 ⇜ (87/8 → 697/64) ⇝ 309/28 | note:84 gain:0.04399999999999887 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 151/14 ⇜ (697/64 → 349/32) ⇝ 309/28 | note:75 gain:0.05814213562373132 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 151/14 ⇜ (697/64 → 349/32) ⇝ 309/28 | note:79 gain:0.05814213562373132 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 151/14 ⇜ (697/64 → 349/32) ⇝ 309/28 | note:80 gain:0.05814213562373132 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 151/14 ⇜ (697/64 → 349/32) ⇝ 309/28 | note:84 gain:0.05814213562373132 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 151/14 ⇜ (349/32 → 699/64) ⇝ 309/28 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 151/14 ⇜ (349/32 → 699/64) ⇝ 309/28 | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 151/14 ⇜ (349/32 → 699/64) ⇝ 309/28 | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 151/14 ⇜ (349/32 → 699/64) ⇝ 309/28 | note:84 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 151/14 ⇜ (699/64 → 175/16) ⇝ 309/28 | note:75 gain:0.05814213562373147 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 151/14 ⇜ (699/64 → 175/16) ⇝ 309/28 | note:79 gain:0.05814213562373147 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 151/14 ⇜ (699/64 → 175/16) ⇝ 309/28 | note:80 gain:0.05814213562373147 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 151/14 ⇜ (699/64 → 175/16) ⇝ 309/28 | note:84 gain:0.05814213562373147 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 151/14 ⇜ (175/16 → 701/64) ⇝ 309/28 | note:75 gain:0.04400000000000136 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 151/14 ⇜ (175/16 → 701/64) ⇝ 309/28 | note:79 gain:0.04400000000000136 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 151/14 ⇜ (175/16 → 701/64) ⇝ 309/28 | note:80 gain:0.04400000000000136 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 151/14 ⇜ (175/16 → 701/64) ⇝ 309/28 | note:84 gain:0.04400000000000136 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 151/14 ⇜ (701/64 → 351/32) ⇝ 309/28 | note:75 gain:0.02985786437626884 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 151/14 ⇜ (701/64 → 351/32) ⇝ 309/28 | note:79 gain:0.02985786437626884 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 151/14 ⇜ (701/64 → 351/32) ⇝ 309/28 | note:80 gain:0.02985786437626884 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 151/14 ⇜ (701/64 → 351/32) ⇝ 309/28 | note:84 gain:0.02985786437626884 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 151/14 ⇜ (351/32 → 703/64) ⇝ 309/28 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 151/14 ⇜ (351/32 → 703/64) ⇝ 309/28 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 151/14 ⇜ (351/32 → 703/64) ⇝ 309/28 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 151/14 ⇜ (351/32 → 703/64) ⇝ 309/28 | note:84 gain:0.024 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 151/14 ⇜ (703/64 → 11/1) ⇝ 309/28 | note:75 gain:0.02985786437626838 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 151/14 ⇜ (703/64 → 11/1) ⇝ 309/28 | note:79 gain:0.02985786437626838 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 151/14 ⇜ (703/64 → 11/1) ⇝ 309/28 | note:80 gain:0.02985786437626838 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 151/14 ⇜ (703/64 → 11/1) ⇝ 309/28 | note:84 gain:0.02985786437626838 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 151/14 ⇜ (11/1 → 705/64) ⇝ 309/28 | note:75 gain:0.043999999999998436 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 151/14 ⇜ (11/1 → 705/64) ⇝ 309/28 | note:79 gain:0.043999999999998436 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 151/14 ⇜ (11/1 → 705/64) ⇝ 309/28 | note:80 gain:0.043999999999998436 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 151/14 ⇜ (11/1 → 705/64) ⇝ 309/28 | note:84 gain:0.043999999999998436 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ (11/1 → 705/64) ⇝ 45/4 | note:F2 gain:0.43999999999998435 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 151/14 ⇜ (705/64 → 353/32) ⇝ 309/28 | note:75 gain:0.05814213562373102 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 151/14 ⇜ (705/64 → 353/32) ⇝ 309/28 | note:79 gain:0.05814213562373102 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 151/14 ⇜ (705/64 → 353/32) ⇝ 309/28 | note:80 gain:0.05814213562373102 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 151/14 ⇜ (705/64 → 353/32) ⇝ 309/28 | note:84 gain:0.05814213562373102 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 11/1 ⇜ (705/64 → 353/32) ⇝ 45/4 | note:F2 gain:0.5814213562373102 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 151/14 ⇜ (353/32 → 309/28) | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 151/14 ⇜ (353/32 → 309/28) | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 151/14 ⇜ (353/32 → 309/28) | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 151/14 ⇜ (353/32 → 309/28) | note:84 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 11/1 ⇜ (353/32 → 707/64) ⇝ 45/4 | note:F2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 11/1 ⇜ (707/64 → 177/16) ⇝ 45/4 | note:F2 gain:0.5814213562373177 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 11/1 ⇜ (177/16 → 709/64) ⇝ 45/4 | note:F2 gain:0.43999999999999506 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 11/1 ⇜ (709/64 → 355/32) ⇝ 45/4 | note:F2 gain:0.29857864376269144 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 11/1 ⇜ (355/32 → 711/64) ⇝ 45/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 11/1 ⇜ (711/64 → 89/8) ⇝ 45/4 | note:F2 gain:0.2985786437626808 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 11/1 ⇜ (89/8 → 713/64) ⇝ 45/4 | note:F2 gain:0.4400000000000027 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ (89/8 → 713/64) ⇝ 45/4 | note:F4 gain:0.4400000000000027 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (89/8 → 713/64) ⇝ 45/4 | note:C5 gain:0.4400000000000027 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ (89/8 → 713/64) ⇝ 45/4 | note:Eb5 gain:0.4400000000000027 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 11/1 ⇜ (713/64 → 357/32) ⇝ 45/4 | note:F2 gain:0.5814213562373071 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 89/8 ⇜ (713/64 → 357/32) ⇝ 45/4 | note:F4 gain:0.5814213562373071 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 89/8 ⇜ (713/64 → 357/32) ⇝ 45/4 | note:C5 gain:0.5814213562373071 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 89/8 ⇜ (713/64 → 357/32) ⇝ 45/4 | note:Eb5 gain:0.5814213562373071 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 11/1 ⇜ (357/32 → 715/64) ⇝ 45/4 | note:F2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 89/8 ⇜ (357/32 → 715/64) ⇝ 45/4 | note:F4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 89/8 ⇜ (357/32 → 715/64) ⇝ 45/4 | note:C5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 89/8 ⇜ (357/32 → 715/64) ⇝ 45/4 | note:Eb5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 11/1 ⇜ (715/64 → 179/16) ⇝ 45/4 | note:F2 gain:0.5814213562373046 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 89/8 ⇜ (715/64 → 179/16) ⇝ 45/4 | note:F4 gain:0.5814213562373046 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 89/8 ⇜ (715/64 → 179/16) ⇝ 45/4 | note:C5 gain:0.5814213562373046 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 89/8 ⇜ (715/64 → 179/16) ⇝ 45/4 | note:Eb5 gain:0.5814213562373046 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 11/1 ⇜ (179/16 → 717/64) ⇝ 45/4 | note:F2 gain:0.43999999999999945 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 89/8 ⇜ (179/16 → 717/64) ⇝ 45/4 | note:F4 gain:0.43999999999999945 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 89/8 ⇜ (179/16 → 717/64) ⇝ 45/4 | note:C5 gain:0.43999999999999945 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 89/8 ⇜ (179/16 → 717/64) ⇝ 45/4 | note:Eb5 gain:0.43999999999999945 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 11/1 ⇜ (717/64 → 359/32) ⇝ 45/4 | note:F2 gain:0.29857864376269444 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 89/8 ⇜ (717/64 → 359/32) ⇝ 45/4 | note:F4 gain:0.29857864376269444 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 89/8 ⇜ (717/64 → 359/32) ⇝ 45/4 | note:C5 gain:0.29857864376269444 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 89/8 ⇜ (717/64 → 359/32) ⇝ 45/4 | note:Eb5 gain:0.29857864376269444 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 11/1 ⇜ (359/32 → 719/64) ⇝ 45/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 89/8 ⇜ (359/32 → 719/64) ⇝ 45/4 | note:F4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 89/8 ⇜ (359/32 → 719/64) ⇝ 45/4 | note:C5 gain:0.24 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 89/8 ⇜ (359/32 → 719/64) ⇝ 45/4 | note:Eb5 gain:0.24 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 11/1 ⇜ (719/64 → 45/4) | note:F2 gain:0.2985786437626938 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 89/8 ⇜ (719/64 → 45/4) | note:F4 gain:0.2985786437626938 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 89/8 ⇜ (719/64 → 45/4) | note:C5 gain:0.2985786437626938 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 89/8 ⇜ (719/64 → 45/4) | note:Eb5 gain:0.2985786437626938 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ (45/4 → 721/64) ⇝ 23/2 | note:Eb4 gain:0.21999999999999922 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ (45/4 → 721/64) ⇝ 23/2 | note:G4 gain:0.21999999999999922 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (45/4 → 721/64) ⇝ 23/2 | note:Ab4 gain:0.21999999999999922 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ (45/4 → 721/64) ⇝ 23/2 | note:C5 gain:0.21999999999999922 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 45/4 ⇜ (721/64 → 361/32) ⇝ 23/2 | note:Eb4 gain:0.290710678118652 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 45/4 ⇜ (721/64 → 361/32) ⇝ 23/2 | note:G4 gain:0.290710678118652 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 45/4 ⇜ (721/64 → 361/32) ⇝ 23/2 | note:Ab4 gain:0.290710678118652 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 45/4 ⇜ (721/64 → 361/32) ⇝ 23/2 | note:C5 gain:0.290710678118652 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 45/4 ⇜ (361/32 → 723/64) ⇝ 23/2 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 45/4 ⇜ (361/32 → 723/64) ⇝ 23/2 | note:G4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 45/4 ⇜ (361/32 → 723/64) ⇝ 23/2 | note:Ab4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 45/4 ⇜ (361/32 → 723/64) ⇝ 23/2 | note:C5 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 45/4 ⇜ (723/64 → 181/16) ⇝ 23/2 | note:Eb4 gain:0.29071067811865386 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 45/4 ⇜ (723/64 → 181/16) ⇝ 23/2 | note:G4 gain:0.29071067811865386 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 45/4 ⇜ (723/64 → 181/16) ⇝ 23/2 | note:Ab4 gain:0.29071067811865386 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 45/4 ⇜ (723/64 → 181/16) ⇝ 23/2 | note:C5 gain:0.29071067811865386 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 45/4 ⇜ (181/16 → 725/64) ⇝ 23/2 | note:Eb4 gain:0.2200000000000019 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 45/4 ⇜ (181/16 → 725/64) ⇝ 23/2 | note:G4 gain:0.2200000000000019 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 45/4 ⇜ (181/16 → 725/64) ⇝ 23/2 | note:Ab4 gain:0.2200000000000019 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 45/4 ⇜ (181/16 → 725/64) ⇝ 23/2 | note:C5 gain:0.2200000000000019 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 45/4 ⇜ (725/64 → 363/32) ⇝ 23/2 | note:Eb4 gain:0.14928932188134877 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 45/4 ⇜ (725/64 → 363/32) ⇝ 23/2 | note:G4 gain:0.14928932188134877 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 45/4 ⇜ (725/64 → 363/32) ⇝ 23/2 | note:Ab4 gain:0.14928932188134877 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 45/4 ⇜ (725/64 → 363/32) ⇝ 23/2 | note:C5 gain:0.14928932188134877 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 45/4 ⇜ (363/32 → 727/64) ⇝ 23/2 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 45/4 ⇜ (363/32 → 727/64) ⇝ 23/2 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 45/4 ⇜ (363/32 → 727/64) ⇝ 23/2 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 45/4 ⇜ (363/32 → 727/64) ⇝ 23/2 | note:C5 gain:0.12 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 45/4 ⇜ (727/64 → 91/8) ⇝ 23/2 | note:Eb4 gain:0.14928932188134536 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 45/4 ⇜ (727/64 → 91/8) ⇝ 23/2 | note:G4 gain:0.14928932188134536 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 45/4 ⇜ (727/64 → 91/8) ⇝ 23/2 | note:Ab4 gain:0.14928932188134536 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 45/4 ⇜ (727/64 → 91/8) ⇝ 23/2 | note:C5 gain:0.14928932188134536 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 45/4 ⇜ (91/8 → 729/64) ⇝ 23/2 | note:Eb4 gain:0.21999999999999706 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 45/4 ⇜ (91/8 → 729/64) ⇝ 23/2 | note:G4 gain:0.21999999999999706 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 45/4 ⇜ (91/8 → 729/64) ⇝ 23/2 | note:Ab4 gain:0.21999999999999706 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 45/4 ⇜ (91/8 → 729/64) ⇝ 23/2 | note:C5 gain:0.21999999999999706 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 45/4 ⇜ (729/64 → 365/32) ⇝ 23/2 | note:Eb4 gain:0.2907106781186505 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 45/4 ⇜ (729/64 → 365/32) ⇝ 23/2 | note:G4 gain:0.2907106781186505 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 45/4 ⇜ (729/64 → 365/32) ⇝ 23/2 | note:Ab4 gain:0.2907106781186505 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 45/4 ⇜ (729/64 → 365/32) ⇝ 23/2 | note:C5 gain:0.2907106781186505 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 45/4 ⇜ (365/32 → 731/64) ⇝ 23/2 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 45/4 ⇜ (365/32 → 731/64) ⇝ 23/2 | note:G4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 45/4 ⇜ (365/32 → 731/64) ⇝ 23/2 | note:Ab4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 45/4 ⇜ (365/32 → 731/64) ⇝ 23/2 | note:C5 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 45/4 ⇜ (731/64 → 183/16) ⇝ 23/2 | note:Eb4 gain:0.2907106781186554 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 45/4 ⇜ (731/64 → 183/16) ⇝ 23/2 | note:G4 gain:0.2907106781186554 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 45/4 ⇜ (731/64 → 183/16) ⇝ 23/2 | note:Ab4 gain:0.2907106781186554 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 45/4 ⇜ (731/64 → 183/16) ⇝ 23/2 | note:C5 gain:0.2907106781186554 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 45/4 ⇜ (183/16 → 733/64) ⇝ 23/2 | note:Eb4 gain:0.22000000000000403 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 45/4 ⇜ (183/16 → 733/64) ⇝ 23/2 | note:G4 gain:0.22000000000000403 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 45/4 ⇜ (183/16 → 733/64) ⇝ 23/2 | note:Ab4 gain:0.22000000000000403 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 45/4 ⇜ (183/16 → 733/64) ⇝ 23/2 | note:C5 gain:0.22000000000000403 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 45/4 ⇜ (733/64 → 367/32) ⇝ 23/2 | note:Eb4 gain:0.1492893218813503 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 45/4 ⇜ (733/64 → 367/32) ⇝ 23/2 | note:G4 gain:0.1492893218813503 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 45/4 ⇜ (733/64 → 367/32) ⇝ 23/2 | note:Ab4 gain:0.1492893218813503 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 45/4 ⇜ (733/64 → 367/32) ⇝ 23/2 | note:C5 gain:0.1492893218813503 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 45/4 ⇜ (367/32 → 735/64) ⇝ 23/2 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 45/4 ⇜ (367/32 → 735/64) ⇝ 23/2 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 45/4 ⇜ (367/32 → 735/64) ⇝ 23/2 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 45/4 ⇜ (367/32 → 735/64) ⇝ 23/2 | note:C5 gain:0.12 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 45/4 ⇜ (735/64 → 23/2) | note:Eb4 gain:0.14928932188134386 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 45/4 ⇜ (735/64 → 23/2) | note:G4 gain:0.14928932188134386 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 45/4 ⇜ (735/64 → 23/2) | note:Ab4 gain:0.14928932188134386 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 45/4 ⇜ (735/64 → 23/2) | note:C5 gain:0.14928932188134386 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ (23/2 → 737/64) ⇝ 93/8 | note:C5 gain:0.43999999999998984 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ (23/2 → 737/64) ⇝ 93/8 | note:G5 gain:0.43999999999998984 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ (23/2 → 737/64) ⇝ 93/8 | note:Bb5 gain:0.43999999999998984 clip:1 s:piano release:0.1 pan:0.6296296296296297 ]", - "[ (23/2 → 737/64) ⇝ 47/4 | note:F2 gain:0.43999999999998984 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 23/2 ⇜ (737/64 → 369/32) ⇝ 93/8 | note:C5 gain:0.581421356237314 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 23/2 ⇜ (737/64 → 369/32) ⇝ 93/8 | note:G5 gain:0.581421356237314 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 23/2 ⇜ (737/64 → 369/32) ⇝ 93/8 | note:Bb5 gain:0.581421356237314 clip:1 s:piano release:0.1 pan:0.6296296296296297 ]", - "[ 23/2 ⇜ (737/64 → 369/32) ⇝ 47/4 | note:F2 gain:0.581421356237314 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 23/2 ⇜ (369/32 → 739/64) ⇝ 93/8 | note:C5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 23/2 ⇜ (369/32 → 739/64) ⇝ 93/8 | note:G5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 23/2 ⇜ (369/32 → 739/64) ⇝ 93/8 | note:Bb5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6296296296296297 ]", - "[ 23/2 ⇜ (369/32 → 739/64) ⇝ 47/4 | note:F2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ (323/28 → 739/64) ⇝ 165/14 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ (323/28 → 739/64) ⇝ 165/14 | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ (323/28 → 739/64) ⇝ 165/14 | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ (323/28 → 739/64) ⇝ 165/14 | note:84 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 23/2 ⇜ (739/64 → 185/16) ⇝ 93/8 | note:C5 gain:0.581421356237314 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 23/2 ⇜ (739/64 → 185/16) ⇝ 93/8 | note:G5 gain:0.581421356237314 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 23/2 ⇜ (739/64 → 185/16) ⇝ 93/8 | note:Bb5 gain:0.581421356237314 clip:1 s:piano release:0.1 pan:0.6296296296296297 ]", - "[ 23/2 ⇜ (739/64 → 185/16) ⇝ 47/4 | note:F2 gain:0.581421356237314 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 323/28 ⇜ (739/64 → 185/16) ⇝ 165/14 | note:75 gain:0.0581421356237314 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 323/28 ⇜ (739/64 → 185/16) ⇝ 165/14 | note:79 gain:0.0581421356237314 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 323/28 ⇜ (739/64 → 185/16) ⇝ 165/14 | note:80 gain:0.0581421356237314 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 323/28 ⇜ (739/64 → 185/16) ⇝ 165/14 | note:84 gain:0.0581421356237314 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 23/2 ⇜ (185/16 → 741/64) ⇝ 93/8 | note:C5 gain:0.4400000000000123 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 23/2 ⇜ (185/16 → 741/64) ⇝ 93/8 | note:G5 gain:0.4400000000000123 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 23/2 ⇜ (185/16 → 741/64) ⇝ 93/8 | note:Bb5 gain:0.4400000000000123 clip:1 s:piano release:0.1 pan:0.6296296296296297 ]", - "[ 23/2 ⇜ (185/16 → 741/64) ⇝ 47/4 | note:F2 gain:0.4400000000000123 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 323/28 ⇜ (185/16 → 741/64) ⇝ 165/14 | note:75 gain:0.04400000000000123 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 323/28 ⇜ (185/16 → 741/64) ⇝ 165/14 | note:79 gain:0.04400000000000123 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 323/28 ⇜ (185/16 → 741/64) ⇝ 165/14 | note:80 gain:0.04400000000000123 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 323/28 ⇜ (185/16 → 741/64) ⇝ 165/14 | note:84 gain:0.04400000000000123 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 23/2 ⇜ (741/64 → 371/32) ⇝ 93/8 | note:C5 gain:0.29857864376268756 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 23/2 ⇜ (741/64 → 371/32) ⇝ 93/8 | note:G5 gain:0.29857864376268756 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 23/2 ⇜ (741/64 → 371/32) ⇝ 93/8 | note:Bb5 gain:0.29857864376268756 clip:1 s:piano release:0.1 pan:0.6296296296296297 ]", - "[ 23/2 ⇜ (741/64 → 371/32) ⇝ 47/4 | note:F2 gain:0.29857864376268756 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 323/28 ⇜ (741/64 → 371/32) ⇝ 165/14 | note:75 gain:0.029857864376268757 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 323/28 ⇜ (741/64 → 371/32) ⇝ 165/14 | note:79 gain:0.029857864376268757 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 323/28 ⇜ (741/64 → 371/32) ⇝ 165/14 | note:80 gain:0.029857864376268757 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 323/28 ⇜ (741/64 → 371/32) ⇝ 165/14 | note:84 gain:0.029857864376268757 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 23/2 ⇜ (371/32 → 743/64) ⇝ 93/8 | note:C5 gain:0.24 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 23/2 ⇜ (371/32 → 743/64) ⇝ 93/8 | note:G5 gain:0.24 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 23/2 ⇜ (371/32 → 743/64) ⇝ 93/8 | note:Bb5 gain:0.24 clip:1 s:piano release:0.1 pan:0.6296296296296297 ]", - "[ 23/2 ⇜ (371/32 → 743/64) ⇝ 47/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 323/28 ⇜ (371/32 → 743/64) ⇝ 165/14 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 323/28 ⇜ (371/32 → 743/64) ⇝ 165/14 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 323/28 ⇜ (371/32 → 743/64) ⇝ 165/14 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 323/28 ⇜ (371/32 → 743/64) ⇝ 165/14 | note:84 gain:0.024 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 23/2 ⇜ (743/64 → 93/8) | note:C5 gain:0.29857864376268467 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 23/2 ⇜ (743/64 → 93/8) | note:G5 gain:0.29857864376268467 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 23/2 ⇜ (743/64 → 93/8) | note:Bb5 gain:0.29857864376268467 clip:1 s:piano release:0.1 pan:0.6296296296296297 ]", - "[ 23/2 ⇜ (743/64 → 93/8) ⇝ 47/4 | note:F2 gain:0.29857864376268467 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 323/28 ⇜ (743/64 → 93/8) ⇝ 165/14 | note:75 gain:0.02985786437626847 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 323/28 ⇜ (743/64 → 93/8) ⇝ 165/14 | note:79 gain:0.02985786437626847 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 323/28 ⇜ (743/64 → 93/8) ⇝ 165/14 | note:80 gain:0.02985786437626847 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 323/28 ⇜ (743/64 → 93/8) ⇝ 165/14 | note:84 gain:0.02985786437626847 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 23/2 ⇜ (93/8 → 745/64) ⇝ 47/4 | note:F2 gain:0.4399999999999855 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 323/28 ⇜ (93/8 → 745/64) ⇝ 165/14 | note:75 gain:0.043999999999998554 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 323/28 ⇜ (93/8 → 745/64) ⇝ 165/14 | note:79 gain:0.043999999999998554 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 323/28 ⇜ (93/8 → 745/64) ⇝ 165/14 | note:80 gain:0.043999999999998554 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 323/28 ⇜ (93/8 → 745/64) ⇝ 165/14 | note:84 gain:0.043999999999998554 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 23/2 ⇜ (745/64 → 373/32) ⇝ 47/4 | note:F2 gain:0.5814213562373108 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 323/28 ⇜ (745/64 → 373/32) ⇝ 165/14 | note:75 gain:0.058142135623731085 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 323/28 ⇜ (745/64 → 373/32) ⇝ 165/14 | note:79 gain:0.058142135623731085 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 323/28 ⇜ (745/64 → 373/32) ⇝ 165/14 | note:80 gain:0.058142135623731085 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 323/28 ⇜ (745/64 → 373/32) ⇝ 165/14 | note:84 gain:0.058142135623731085 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 23/2 ⇜ (373/32 → 747/64) ⇝ 47/4 | note:F2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 323/28 ⇜ (373/32 → 747/64) ⇝ 165/14 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 323/28 ⇜ (373/32 → 747/64) ⇝ 165/14 | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 323/28 ⇜ (373/32 → 747/64) ⇝ 165/14 | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 323/28 ⇜ (373/32 → 747/64) ⇝ 165/14 | note:84 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 23/2 ⇜ (747/64 → 187/16) ⇝ 47/4 | note:F2 gain:0.5814213562373169 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 323/28 ⇜ (747/64 → 187/16) ⇝ 165/14 | note:75 gain:0.058142135623731696 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 323/28 ⇜ (747/64 → 187/16) ⇝ 165/14 | note:79 gain:0.058142135623731696 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 323/28 ⇜ (747/64 → 187/16) ⇝ 165/14 | note:80 gain:0.058142135623731696 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 323/28 ⇜ (747/64 → 187/16) ⇝ 165/14 | note:84 gain:0.058142135623731696 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 23/2 ⇜ (187/16 → 749/64) ⇝ 47/4 | note:F2 gain:0.43999999999999395 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 323/28 ⇜ (187/16 → 749/64) ⇝ 165/14 | note:75 gain:0.0439999999999994 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 323/28 ⇜ (187/16 → 749/64) ⇝ 165/14 | note:79 gain:0.0439999999999994 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 323/28 ⇜ (187/16 → 749/64) ⇝ 165/14 | note:80 gain:0.0439999999999994 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 323/28 ⇜ (187/16 → 749/64) ⇝ 165/14 | note:84 gain:0.0439999999999994 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 23/2 ⇜ (749/64 → 375/32) ⇝ 47/4 | note:F2 gain:0.2985786437626906 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 323/28 ⇜ (749/64 → 375/32) ⇝ 165/14 | note:75 gain:0.029857864376269062 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 323/28 ⇜ (749/64 → 375/32) ⇝ 165/14 | note:79 gain:0.029857864376269062 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 323/28 ⇜ (749/64 → 375/32) ⇝ 165/14 | note:80 gain:0.029857864376269062 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 323/28 ⇜ (749/64 → 375/32) ⇝ 165/14 | note:84 gain:0.029857864376269062 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 23/2 ⇜ (375/32 → 751/64) ⇝ 47/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 323/28 ⇜ (375/32 → 751/64) ⇝ 165/14 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 323/28 ⇜ (375/32 → 751/64) ⇝ 165/14 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 323/28 ⇜ (375/32 → 751/64) ⇝ 165/14 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 323/28 ⇜ (375/32 → 751/64) ⇝ 165/14 | note:84 gain:0.024 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 23/2 ⇜ (751/64 → 47/4) | note:F2 gain:0.29857864376268156 clip:1 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 323/28 ⇜ (751/64 → 47/4) ⇝ 165/14 | note:75 gain:0.029857864376268157 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 323/28 ⇜ (751/64 → 47/4) ⇝ 165/14 | note:79 gain:0.029857864376268157 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 323/28 ⇜ (751/64 → 47/4) ⇝ 165/14 | note:80 gain:0.029857864376268157 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 323/28 ⇜ (751/64 → 47/4) ⇝ 165/14 | note:84 gain:0.029857864376268157 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 323/28 ⇜ (47/4 → 753/64) ⇝ 165/14 | note:75 gain:0.0440000000000004 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 323/28 ⇜ (47/4 → 753/64) ⇝ 165/14 | note:79 gain:0.0440000000000004 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 323/28 ⇜ (47/4 → 753/64) ⇝ 165/14 | note:80 gain:0.0440000000000004 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 323/28 ⇜ (47/4 → 753/64) ⇝ 165/14 | note:84 gain:0.0440000000000004 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ (47/4 → 753/64) ⇝ 95/8 | note:C5 gain:0.44000000000000394 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ (47/4 → 753/64) ⇝ 95/8 | note:G5 gain:0.44000000000000394 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ (47/4 → 753/64) ⇝ 95/8 | note:Bb5 gain:0.44000000000000394 clip:1 s:piano release:0.1 pan:0.6296296296296297 ]", - "[ (47/4 → 753/64) ⇝ 12/1 | note:Eb4 gain:0.22000000000000197 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ (47/4 → 753/64) ⇝ 12/1 | note:G4 gain:0.22000000000000197 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (47/4 → 753/64) ⇝ 12/1 | note:Ab4 gain:0.22000000000000197 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ (47/4 → 753/64) ⇝ 12/1 | note:C5 gain:0.22000000000000197 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 323/28 ⇜ (753/64 → 377/32) ⇝ 165/14 | note:75 gain:0.05814213562373079 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 323/28 ⇜ (753/64 → 377/32) ⇝ 165/14 | note:79 gain:0.05814213562373079 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 323/28 ⇜ (753/64 → 377/32) ⇝ 165/14 | note:80 gain:0.05814213562373079 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 323/28 ⇜ (753/64 → 377/32) ⇝ 165/14 | note:84 gain:0.05814213562373079 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 47/4 ⇜ (753/64 → 377/32) ⇝ 95/8 | note:C5 gain:0.5814213562373078 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 47/4 ⇜ (753/64 → 377/32) ⇝ 95/8 | note:G5 gain:0.5814213562373078 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 47/4 ⇜ (753/64 → 377/32) ⇝ 95/8 | note:Bb5 gain:0.5814213562373078 clip:1 s:piano release:0.1 pan:0.6296296296296297 ]", - "[ 47/4 ⇜ (753/64 → 377/32) ⇝ 12/1 | note:Eb4 gain:0.2907106781186539 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 47/4 ⇜ (753/64 → 377/32) ⇝ 12/1 | note:G4 gain:0.2907106781186539 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 47/4 ⇜ (753/64 → 377/32) ⇝ 12/1 | note:Ab4 gain:0.2907106781186539 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 47/4 ⇜ (753/64 → 377/32) ⇝ 12/1 | note:C5 gain:0.2907106781186539 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 323/28 ⇜ (377/32 → 165/14) | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 323/28 ⇜ (377/32 → 165/14) | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 323/28 ⇜ (377/32 → 165/14) | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 323/28 ⇜ (377/32 → 165/14) | note:84 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 47/4 ⇜ (377/32 → 755/64) ⇝ 95/8 | note:C5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 47/4 ⇜ (377/32 → 755/64) ⇝ 95/8 | note:G5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 47/4 ⇜ (377/32 → 755/64) ⇝ 95/8 | note:Bb5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6296296296296297 ]", - "[ 47/4 ⇜ (377/32 → 755/64) ⇝ 12/1 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 47/4 ⇜ (377/32 → 755/64) ⇝ 12/1 | note:G4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 47/4 ⇜ (377/32 → 755/64) ⇝ 12/1 | note:Ab4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 47/4 ⇜ (377/32 → 755/64) ⇝ 12/1 | note:C5 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 47/4 ⇜ (755/64 → 189/16) ⇝ 95/8 | note:C5 gain:0.5814213562373199 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 47/4 ⇜ (755/64 → 189/16) ⇝ 95/8 | note:G5 gain:0.5814213562373199 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 47/4 ⇜ (755/64 → 189/16) ⇝ 95/8 | note:Bb5 gain:0.5814213562373199 clip:1 s:piano release:0.1 pan:0.6296296296296297 ]", - "[ 47/4 ⇜ (755/64 → 189/16) ⇝ 12/1 | note:Eb4 gain:0.29071067811865997 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 47/4 ⇜ (755/64 → 189/16) ⇝ 12/1 | note:G4 gain:0.29071067811865997 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 47/4 ⇜ (755/64 → 189/16) ⇝ 12/1 | note:Ab4 gain:0.29071067811865997 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 47/4 ⇜ (755/64 → 189/16) ⇝ 12/1 | note:C5 gain:0.29071067811865997 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 47/4 ⇜ (189/16 → 757/64) ⇝ 95/8 | note:C5 gain:0.4399999999999983 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 47/4 ⇜ (189/16 → 757/64) ⇝ 95/8 | note:G5 gain:0.4399999999999983 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 47/4 ⇜ (189/16 → 757/64) ⇝ 95/8 | note:Bb5 gain:0.4399999999999983 clip:1 s:piano release:0.1 pan:0.6296296296296297 ]", - "[ 47/4 ⇜ (189/16 → 757/64) ⇝ 12/1 | note:Eb4 gain:0.21999999999999914 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 47/4 ⇜ (189/16 → 757/64) ⇝ 12/1 | note:G4 gain:0.21999999999999914 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 47/4 ⇜ (189/16 → 757/64) ⇝ 12/1 | note:Ab4 gain:0.21999999999999914 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 47/4 ⇜ (189/16 → 757/64) ⇝ 12/1 | note:C5 gain:0.21999999999999914 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 47/4 ⇜ (757/64 → 379/32) ⇝ 95/8 | note:C5 gain:0.29857864376269366 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 47/4 ⇜ (757/64 → 379/32) ⇝ 95/8 | note:G5 gain:0.29857864376269366 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 47/4 ⇜ (757/64 → 379/32) ⇝ 95/8 | note:Bb5 gain:0.29857864376269366 clip:1 s:piano release:0.1 pan:0.6296296296296297 ]", - "[ 47/4 ⇜ (757/64 → 379/32) ⇝ 12/1 | note:Eb4 gain:0.14928932188134683 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 47/4 ⇜ (757/64 → 379/32) ⇝ 12/1 | note:G4 gain:0.14928932188134683 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 47/4 ⇜ (757/64 → 379/32) ⇝ 12/1 | note:Ab4 gain:0.14928932188134683 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 47/4 ⇜ (757/64 → 379/32) ⇝ 12/1 | note:C5 gain:0.14928932188134683 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 47/4 ⇜ (379/32 → 759/64) ⇝ 95/8 | note:C5 gain:0.24 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 47/4 ⇜ (379/32 → 759/64) ⇝ 95/8 | note:G5 gain:0.24 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 47/4 ⇜ (379/32 → 759/64) ⇝ 95/8 | note:Bb5 gain:0.24 clip:1 s:piano release:0.1 pan:0.6296296296296297 ]", - "[ 47/4 ⇜ (379/32 → 759/64) ⇝ 12/1 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 47/4 ⇜ (379/32 → 759/64) ⇝ 12/1 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 47/4 ⇜ (379/32 → 759/64) ⇝ 12/1 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 47/4 ⇜ (379/32 → 759/64) ⇝ 12/1 | note:C5 gain:0.12 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 47/4 ⇜ (759/64 → 95/8) | note:C5 gain:0.29857864376269466 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 47/4 ⇜ (759/64 → 95/8) | note:G5 gain:0.29857864376269466 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 47/4 ⇜ (759/64 → 95/8) | note:Bb5 gain:0.29857864376269466 clip:1 s:piano release:0.1 pan:0.6296296296296297 ]", - "[ 47/4 ⇜ (759/64 → 95/8) ⇝ 12/1 | note:Eb4 gain:0.14928932188134733 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 47/4 ⇜ (759/64 → 95/8) ⇝ 12/1 | note:G4 gain:0.14928932188134733 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 47/4 ⇜ (759/64 → 95/8) ⇝ 12/1 | note:Ab4 gain:0.14928932188134733 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 47/4 ⇜ (759/64 → 95/8) ⇝ 12/1 | note:C5 gain:0.14928932188134733 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 47/4 ⇜ (95/8 → 761/64) ⇝ 12/1 | note:Eb4 gain:0.2199999999999998 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 47/4 ⇜ (95/8 → 761/64) ⇝ 12/1 | note:G4 gain:0.2199999999999998 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 47/4 ⇜ (95/8 → 761/64) ⇝ 12/1 | note:Ab4 gain:0.2199999999999998 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 47/4 ⇜ (95/8 → 761/64) ⇝ 12/1 | note:C5 gain:0.2199999999999998 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 47/4 ⇜ (761/64 → 381/32) ⇝ 12/1 | note:Eb4 gain:0.2907106781186524 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 47/4 ⇜ (761/64 → 381/32) ⇝ 12/1 | note:G4 gain:0.2907106781186524 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 47/4 ⇜ (761/64 → 381/32) ⇝ 12/1 | note:Ab4 gain:0.2907106781186524 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 47/4 ⇜ (761/64 → 381/32) ⇝ 12/1 | note:C5 gain:0.2907106781186524 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 47/4 ⇜ (381/32 → 763/64) ⇝ 12/1 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 47/4 ⇜ (381/32 → 763/64) ⇝ 12/1 | note:G4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 47/4 ⇜ (381/32 → 763/64) ⇝ 12/1 | note:Ab4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 47/4 ⇜ (381/32 → 763/64) ⇝ 12/1 | note:C5 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 47/4 ⇜ (763/64 → 191/16) ⇝ 12/1 | note:Eb4 gain:0.2907106781186535 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 47/4 ⇜ (763/64 → 191/16) ⇝ 12/1 | note:G4 gain:0.2907106781186535 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 47/4 ⇜ (763/64 → 191/16) ⇝ 12/1 | note:Ab4 gain:0.2907106781186535 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 47/4 ⇜ (763/64 → 191/16) ⇝ 12/1 | note:C5 gain:0.2907106781186535 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 47/4 ⇜ (191/16 → 765/64) ⇝ 12/1 | note:Eb4 gain:0.22000000000000128 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 47/4 ⇜ (191/16 → 765/64) ⇝ 12/1 | note:G4 gain:0.22000000000000128 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 47/4 ⇜ (191/16 → 765/64) ⇝ 12/1 | note:Ab4 gain:0.22000000000000128 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 47/4 ⇜ (191/16 → 765/64) ⇝ 12/1 | note:C5 gain:0.22000000000000128 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 47/4 ⇜ (765/64 → 383/32) ⇝ 12/1 | note:Eb4 gain:0.14928932188134833 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 47/4 ⇜ (765/64 → 383/32) ⇝ 12/1 | note:G4 gain:0.14928932188134833 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 47/4 ⇜ (765/64 → 383/32) ⇝ 12/1 | note:Ab4 gain:0.14928932188134833 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 47/4 ⇜ (765/64 → 383/32) ⇝ 12/1 | note:C5 gain:0.14928932188134833 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 47/4 ⇜ (383/32 → 767/64) ⇝ 12/1 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 47/4 ⇜ (383/32 → 767/64) ⇝ 12/1 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 47/4 ⇜ (383/32 → 767/64) ⇝ 12/1 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 47/4 ⇜ (383/32 → 767/64) ⇝ 12/1 | note:C5 gain:0.12 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 47/4 ⇜ (767/64 → 12/1) | note:Eb4 gain:0.14928932188134578 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 47/4 ⇜ (767/64 → 12/1) | note:G4 gain:0.14928932188134578 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 47/4 ⇜ (767/64 → 12/1) | note:Ab4 gain:0.14928932188134578 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 47/4 ⇜ (767/64 → 12/1) | note:C5 gain:0.14928932188134578 clip:1 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ (12/1 → 769/64) ⇝ 49/4 | note:G2 gain:0.4399999999999953 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 12/1 ⇜ (769/64 → 385/32) ⇝ 49/4 | note:G2 gain:0.5814213562373018 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 12/1 ⇜ (385/32 → 771/64) ⇝ 49/4 | note:G2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ (337/28 → 771/64) ⇝ 86/7 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ (337/28 → 771/64) ⇝ 86/7 | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ (337/28 → 771/64) ⇝ 86/7 | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ (337/28 → 771/64) ⇝ 86/7 | note:84 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 12/1 ⇜ (771/64 → 193/16) ⇝ 49/4 | note:G2 gain:0.58142135623731 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 337/28 ⇜ (771/64 → 193/16) ⇝ 86/7 | note:75 gain:0.058142135623730995 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 337/28 ⇜ (771/64 → 193/16) ⇝ 86/7 | note:79 gain:0.058142135623730995 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 337/28 ⇜ (771/64 → 193/16) ⇝ 86/7 | note:80 gain:0.058142135623730995 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 337/28 ⇜ (771/64 → 193/16) ⇝ 86/7 | note:84 gain:0.058142135623730995 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 12/1 ⇜ (193/16 → 773/64) ⇝ 49/4 | note:G2 gain:0.44000000000000683 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 337/28 ⇜ (193/16 → 773/64) ⇝ 86/7 | note:75 gain:0.044000000000000684 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 337/28 ⇜ (193/16 → 773/64) ⇝ 86/7 | note:79 gain:0.044000000000000684 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 337/28 ⇜ (193/16 → 773/64) ⇝ 86/7 | note:80 gain:0.044000000000000684 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 337/28 ⇜ (193/16 → 773/64) ⇝ 86/7 | note:84 gain:0.044000000000000684 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 12/1 ⇜ (773/64 → 387/32) ⇝ 49/4 | note:G2 gain:0.29857864376269977 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 337/28 ⇜ (773/64 → 387/32) ⇝ 86/7 | note:75 gain:0.02985786437626998 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 337/28 ⇜ (773/64 → 387/32) ⇝ 86/7 | note:79 gain:0.02985786437626998 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 337/28 ⇜ (773/64 → 387/32) ⇝ 86/7 | note:80 gain:0.02985786437626998 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 337/28 ⇜ (773/64 → 387/32) ⇝ 86/7 | note:84 gain:0.02985786437626998 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 12/1 ⇜ (387/32 → 775/64) ⇝ 49/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 337/28 ⇜ (387/32 → 775/64) ⇝ 86/7 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 337/28 ⇜ (387/32 → 775/64) ⇝ 86/7 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 337/28 ⇜ (387/32 → 775/64) ⇝ 86/7 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 337/28 ⇜ (387/32 → 775/64) ⇝ 86/7 | note:84 gain:0.024 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 12/1 ⇜ (775/64 → 97/8) ⇝ 49/4 | note:G2 gain:0.2985786437626885 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 337/28 ⇜ (775/64 → 97/8) ⇝ 86/7 | note:75 gain:0.02985786437626885 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 337/28 ⇜ (775/64 → 97/8) ⇝ 86/7 | note:79 gain:0.02985786437626885 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 337/28 ⇜ (775/64 → 97/8) ⇝ 86/7 | note:80 gain:0.02985786437626885 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 337/28 ⇜ (775/64 → 97/8) ⇝ 86/7 | note:84 gain:0.02985786437626885 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 12/1 ⇜ (97/8 → 777/64) ⇝ 49/4 | note:G2 gain:0.439999999999991 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 337/28 ⇜ (97/8 → 777/64) ⇝ 86/7 | note:75 gain:0.0439999999999991 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 337/28 ⇜ (97/8 → 777/64) ⇝ 86/7 | note:79 gain:0.0439999999999991 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 337/28 ⇜ (97/8 → 777/64) ⇝ 86/7 | note:80 gain:0.0439999999999991 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 337/28 ⇜ (97/8 → 777/64) ⇝ 86/7 | note:84 gain:0.0439999999999991 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ (97/8 → 777/64) ⇝ 49/4 | note:G4 gain:0.439999999999991 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (97/8 → 777/64) ⇝ 49/4 | note:D5 gain:0.439999999999991 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (97/8 → 777/64) ⇝ 49/4 | note:F5 gain:0.439999999999991 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 12/1 ⇜ (777/64 → 389/32) ⇝ 49/4 | note:G2 gain:0.5814213562372988 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 337/28 ⇜ (777/64 → 389/32) ⇝ 86/7 | note:75 gain:0.058142135623729885 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 337/28 ⇜ (777/64 → 389/32) ⇝ 86/7 | note:79 gain:0.058142135623729885 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 337/28 ⇜ (777/64 → 389/32) ⇝ 86/7 | note:80 gain:0.058142135623729885 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 337/28 ⇜ (777/64 → 389/32) ⇝ 86/7 | note:84 gain:0.058142135623729885 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 97/8 ⇜ (777/64 → 389/32) ⇝ 49/4 | note:G4 gain:0.5814213562372988 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 97/8 ⇜ (777/64 → 389/32) ⇝ 49/4 | note:D5 gain:0.5814213562372988 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 97/8 ⇜ (777/64 → 389/32) ⇝ 49/4 | note:F5 gain:0.5814213562372988 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 12/1 ⇜ (389/32 → 779/64) ⇝ 49/4 | note:G2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 337/28 ⇜ (389/32 → 779/64) ⇝ 86/7 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 337/28 ⇜ (389/32 → 779/64) ⇝ 86/7 | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 337/28 ⇜ (389/32 → 779/64) ⇝ 86/7 | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 337/28 ⇜ (389/32 → 779/64) ⇝ 86/7 | note:84 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 97/8 ⇜ (389/32 → 779/64) ⇝ 49/4 | note:G4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 97/8 ⇜ (389/32 → 779/64) ⇝ 49/4 | note:D5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 97/8 ⇜ (389/32 → 779/64) ⇝ 49/4 | note:F5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 12/1 ⇜ (779/64 → 195/16) ⇝ 49/4 | note:G2 gain:0.5814213562373131 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 337/28 ⇜ (779/64 → 195/16) ⇝ 86/7 | note:75 gain:0.05814213562373131 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 337/28 ⇜ (779/64 → 195/16) ⇝ 86/7 | note:79 gain:0.05814213562373131 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 337/28 ⇜ (779/64 → 195/16) ⇝ 86/7 | note:80 gain:0.05814213562373131 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 337/28 ⇜ (779/64 → 195/16) ⇝ 86/7 | note:84 gain:0.05814213562373131 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 97/8 ⇜ (779/64 → 195/16) ⇝ 49/4 | note:G4 gain:0.5814213562373131 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 97/8 ⇜ (779/64 → 195/16) ⇝ 49/4 | note:D5 gain:0.5814213562373131 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 97/8 ⇜ (779/64 → 195/16) ⇝ 49/4 | note:F5 gain:0.5814213562373131 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 12/1 ⇜ (195/16 → 781/64) ⇝ 49/4 | note:G2 gain:0.44000000000001127 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 337/28 ⇜ (195/16 → 781/64) ⇝ 86/7 | note:75 gain:0.04400000000000113 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 337/28 ⇜ (195/16 → 781/64) ⇝ 86/7 | note:79 gain:0.04400000000000113 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 337/28 ⇜ (195/16 → 781/64) ⇝ 86/7 | note:80 gain:0.04400000000000113 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 337/28 ⇜ (195/16 → 781/64) ⇝ 86/7 | note:84 gain:0.04400000000000113 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 97/8 ⇜ (195/16 → 781/64) ⇝ 49/4 | note:G4 gain:0.44000000000001127 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 97/8 ⇜ (195/16 → 781/64) ⇝ 49/4 | note:D5 gain:0.44000000000001127 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 97/8 ⇜ (195/16 → 781/64) ⇝ 49/4 | note:F5 gain:0.44000000000001127 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 12/1 ⇜ (781/64 → 391/32) ⇝ 49/4 | note:G2 gain:0.2985786437626867 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 337/28 ⇜ (781/64 → 391/32) ⇝ 86/7 | note:75 gain:0.029857864376268674 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 337/28 ⇜ (781/64 → 391/32) ⇝ 86/7 | note:79 gain:0.029857864376268674 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 337/28 ⇜ (781/64 → 391/32) ⇝ 86/7 | note:80 gain:0.029857864376268674 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 337/28 ⇜ (781/64 → 391/32) ⇝ 86/7 | note:84 gain:0.029857864376268674 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 97/8 ⇜ (781/64 → 391/32) ⇝ 49/4 | note:G4 gain:0.2985786437626867 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 97/8 ⇜ (781/64 → 391/32) ⇝ 49/4 | note:D5 gain:0.2985786437626867 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 97/8 ⇜ (781/64 → 391/32) ⇝ 49/4 | note:F5 gain:0.2985786437626867 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 12/1 ⇜ (391/32 → 783/64) ⇝ 49/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 337/28 ⇜ (391/32 → 783/64) ⇝ 86/7 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 337/28 ⇜ (391/32 → 783/64) ⇝ 86/7 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 337/28 ⇜ (391/32 → 783/64) ⇝ 86/7 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 337/28 ⇜ (391/32 → 783/64) ⇝ 86/7 | note:84 gain:0.024 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 97/8 ⇜ (391/32 → 783/64) ⇝ 49/4 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 97/8 ⇜ (391/32 → 783/64) ⇝ 49/4 | note:D5 gain:0.24 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 97/8 ⇜ (391/32 → 783/64) ⇝ 49/4 | note:F5 gain:0.24 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 12/1 ⇜ (783/64 → 49/4) | note:G2 gain:0.2985786437626855 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 337/28 ⇜ (783/64 → 49/4) ⇝ 86/7 | note:75 gain:0.029857864376268552 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 337/28 ⇜ (783/64 → 49/4) ⇝ 86/7 | note:79 gain:0.029857864376268552 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 337/28 ⇜ (783/64 → 49/4) ⇝ 86/7 | note:80 gain:0.029857864376268552 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 337/28 ⇜ (783/64 → 49/4) ⇝ 86/7 | note:84 gain:0.029857864376268552 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 97/8 ⇜ (783/64 → 49/4) | note:G4 gain:0.2985786437626855 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 97/8 ⇜ (783/64 → 49/4) | note:D5 gain:0.2985786437626855 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 97/8 ⇜ (783/64 → 49/4) | note:F5 gain:0.2985786437626855 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 337/28 ⇜ (49/4 → 785/64) ⇝ 86/7 | note:75 gain:0.04399999999999868 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 337/28 ⇜ (49/4 → 785/64) ⇝ 86/7 | note:79 gain:0.04399999999999868 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 337/28 ⇜ (49/4 → 785/64) ⇝ 86/7 | note:80 gain:0.04399999999999868 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 337/28 ⇜ (49/4 → 785/64) ⇝ 86/7 | note:84 gain:0.04399999999999868 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 337/28 ⇜ (785/64 → 393/32) ⇝ 86/7 | note:75 gain:0.058142135623731175 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 337/28 ⇜ (785/64 → 393/32) ⇝ 86/7 | note:79 gain:0.058142135623731175 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 337/28 ⇜ (785/64 → 393/32) ⇝ 86/7 | note:80 gain:0.058142135623731175 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 337/28 ⇜ (785/64 → 393/32) ⇝ 86/7 | note:84 gain:0.058142135623731175 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 337/28 ⇜ (393/32 → 86/7) | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 337/28 ⇜ (393/32 → 86/7) | note:79 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 337/28 ⇜ (393/32 → 86/7) | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 337/28 ⇜ (393/32 → 86/7) | note:84 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ (25/2 → 801/64) ⇝ 101/8 | note:D5 gain:0.4400000000000008 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (25/2 → 801/64) ⇝ 101/8 | note:A5 gain:0.4400000000000008 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ (25/2 → 801/64) ⇝ 101/8 | note:C6 gain:0.4400000000000008 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ (25/2 → 801/64) ⇝ 51/4 | note:B3 gain:0.2200000000000004 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ (25/2 → 801/64) ⇝ 51/4 | note:E4 gain:0.2200000000000004 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (25/2 → 801/64) ⇝ 51/4 | note:F4 gain:0.2200000000000004 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (25/2 → 801/64) ⇝ 51/4 | note:A4 gain:0.2200000000000004 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (25/2 → 801/64) ⇝ 51/4 | note:G2 gain:0.4400000000000008 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 25/2 ⇜ (801/64 → 401/32) ⇝ 101/8 | note:D5 gain:0.5814213562373057 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 25/2 ⇜ (801/64 → 401/32) ⇝ 101/8 | note:A5 gain:0.5814213562373057 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 25/2 ⇜ (801/64 → 401/32) ⇝ 101/8 | note:C6 gain:0.5814213562373057 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 25/2 ⇜ (801/64 → 401/32) ⇝ 51/4 | note:B3 gain:0.29071067811865287 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 25/2 ⇜ (801/64 → 401/32) ⇝ 51/4 | note:E4 gain:0.29071067811865287 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 25/2 ⇜ (801/64 → 401/32) ⇝ 51/4 | note:F4 gain:0.29071067811865287 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 25/2 ⇜ (801/64 → 401/32) ⇝ 51/4 | note:A4 gain:0.29071067811865287 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 25/2 ⇜ (801/64 → 401/32) ⇝ 51/4 | note:G2 gain:0.5814213562373057 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 25/2 ⇜ (401/32 → 803/64) ⇝ 101/8 | note:D5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 25/2 ⇜ (401/32 → 803/64) ⇝ 101/8 | note:A5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 25/2 ⇜ (401/32 → 803/64) ⇝ 101/8 | note:C6 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 25/2 ⇜ (401/32 → 803/64) ⇝ 51/4 | note:B3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 25/2 ⇜ (401/32 → 803/64) ⇝ 51/4 | note:E4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 25/2 ⇜ (401/32 → 803/64) ⇝ 51/4 | note:F4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 25/2 ⇜ (401/32 → 803/64) ⇝ 51/4 | note:A4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 25/2 ⇜ (401/32 → 803/64) ⇝ 51/4 | note:G2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 25/2 ⇜ (803/64 → 201/16) ⇝ 101/8 | note:D5 gain:0.5814213562373061 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 25/2 ⇜ (803/64 → 201/16) ⇝ 101/8 | note:A5 gain:0.5814213562373061 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 25/2 ⇜ (803/64 → 201/16) ⇝ 101/8 | note:C6 gain:0.5814213562373061 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 25/2 ⇜ (803/64 → 201/16) ⇝ 51/4 | note:B3 gain:0.29071067811865303 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 25/2 ⇜ (803/64 → 201/16) ⇝ 51/4 | note:E4 gain:0.29071067811865303 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 25/2 ⇜ (803/64 → 201/16) ⇝ 51/4 | note:F4 gain:0.29071067811865303 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 25/2 ⇜ (803/64 → 201/16) ⇝ 51/4 | note:A4 gain:0.29071067811865303 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 25/2 ⇜ (803/64 → 201/16) ⇝ 51/4 | note:G2 gain:0.5814213562373061 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 25/2 ⇜ (201/16 → 805/64) ⇝ 101/8 | note:D5 gain:0.4400000000000014 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 25/2 ⇜ (201/16 → 805/64) ⇝ 101/8 | note:A5 gain:0.4400000000000014 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 25/2 ⇜ (201/16 → 805/64) ⇝ 101/8 | note:C6 gain:0.4400000000000014 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 25/2 ⇜ (201/16 → 805/64) ⇝ 51/4 | note:B3 gain:0.2200000000000007 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 25/2 ⇜ (201/16 → 805/64) ⇝ 51/4 | note:E4 gain:0.2200000000000007 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 25/2 ⇜ (201/16 → 805/64) ⇝ 51/4 | note:F4 gain:0.2200000000000007 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 25/2 ⇜ (201/16 → 805/64) ⇝ 51/4 | note:A4 gain:0.2200000000000007 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 25/2 ⇜ (201/16 → 805/64) ⇝ 51/4 | note:G2 gain:0.4400000000000014 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 25/2 ⇜ (805/64 → 403/32) ⇝ 101/8 | note:D5 gain:0.2985786437626959 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 25/2 ⇜ (805/64 → 403/32) ⇝ 101/8 | note:A5 gain:0.2985786437626959 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 25/2 ⇜ (805/64 → 403/32) ⇝ 101/8 | note:C6 gain:0.2985786437626959 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 25/2 ⇜ (805/64 → 403/32) ⇝ 51/4 | note:B3 gain:0.14928932188134794 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 25/2 ⇜ (805/64 → 403/32) ⇝ 51/4 | note:E4 gain:0.14928932188134794 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 25/2 ⇜ (805/64 → 403/32) ⇝ 51/4 | note:F4 gain:0.14928932188134794 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 25/2 ⇜ (805/64 → 403/32) ⇝ 51/4 | note:A4 gain:0.14928932188134794 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 25/2 ⇜ (805/64 → 403/32) ⇝ 51/4 | note:G2 gain:0.2985786437626959 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 25/2 ⇜ (403/32 → 807/64) ⇝ 101/8 | note:D5 gain:0.24 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", + "[ 49/8 ⇜ (199/32 → 399/64) ⇝ 25/4 | note:F#4 gain:0.24 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 49/8 ⇜ (199/32 → 399/64) ⇝ 25/4 | note:A#4 gain:0.24 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 6/1 ⇜ (399/64 → 25/4) | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 169/28 ⇜ (399/64 → 25/4) ⇝ 44/7 | note:71 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 169/28 ⇜ (399/64 → 25/4) ⇝ 44/7 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 169/28 ⇜ (399/64 → 25/4) ⇝ 44/7 | note:77 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 169/28 ⇜ (399/64 → 25/4) ⇝ 44/7 | note:81 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 49/8 ⇜ (399/64 → 25/4) | note:F#4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 49/8 ⇜ (399/64 → 25/4) | note:A#4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 169/28 ⇜ (25/4 → 401/64) ⇝ 44/7 | note:71 gain:0.044 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 169/28 ⇜ (25/4 → 401/64) ⇝ 44/7 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 169/28 ⇜ (25/4 → 401/64) ⇝ 44/7 | note:77 gain:0.044 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 169/28 ⇜ (25/4 → 401/64) ⇝ 44/7 | note:81 gain:0.044 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 169/28 ⇜ (401/64 → 201/32) ⇝ 44/7 | note:71 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 169/28 ⇜ (401/64 → 201/32) ⇝ 44/7 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 169/28 ⇜ (401/64 → 201/32) ⇝ 44/7 | note:77 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 169/28 ⇜ (401/64 → 201/32) ⇝ 44/7 | note:81 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 169/28 ⇜ (201/32 → 44/7) | note:71 gain:0.064 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 169/28 ⇜ (201/32 → 44/7) | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 169/28 ⇜ (201/32 → 44/7) | note:77 gain:0.064 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 169/28 ⇜ (201/32 → 44/7) | note:81 gain:0.064 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ (13/2 → 417/64) ⇝ 53/8 | note:C#5 gain:0.44 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ (13/2 → 417/64) ⇝ 53/8 | note:E5 gain:0.44 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ (13/2 → 417/64) ⇝ 27/4 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ (13/2 → 417/64) ⇝ 27/4 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ (13/2 → 417/64) ⇝ 27/4 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (13/2 → 417/64) ⇝ 27/4 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ (13/2 → 417/64) ⇝ 27/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 13/2 ⇜ (417/64 → 209/32) ⇝ 53/8 | note:C#5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 13/2 ⇜ (417/64 → 209/32) ⇝ 53/8 | note:E5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 13/2 ⇜ (417/64 → 209/32) ⇝ 27/4 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 13/2 ⇜ (417/64 → 209/32) ⇝ 27/4 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/2 ⇜ (417/64 → 209/32) ⇝ 27/4 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 13/2 ⇜ (417/64 → 209/32) ⇝ 27/4 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/2 ⇜ (417/64 → 209/32) ⇝ 27/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 13/2 ⇜ (209/32 → 419/64) ⇝ 53/8 | note:C#5 gain:0.64 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 13/2 ⇜ (209/32 → 419/64) ⇝ 53/8 | note:E5 gain:0.64 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 13/2 ⇜ (209/32 → 419/64) ⇝ 27/4 | note:Bb3 gain:0.32 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 13/2 ⇜ (209/32 → 419/64) ⇝ 27/4 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/2 ⇜ (209/32 → 419/64) ⇝ 27/4 | note:E4 gain:0.32 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 13/2 ⇜ (209/32 → 419/64) ⇝ 27/4 | note:Ab4 gain:0.32 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/2 ⇜ (209/32 → 419/64) ⇝ 27/4 | note:F#2 gain:0.64 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 13/2 ⇜ (419/64 → 105/16) ⇝ 53/8 | note:C#5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 13/2 ⇜ (419/64 → 105/16) ⇝ 53/8 | note:E5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 13/2 ⇜ (419/64 → 105/16) ⇝ 27/4 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 13/2 ⇜ (419/64 → 105/16) ⇝ 27/4 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/2 ⇜ (419/64 → 105/16) ⇝ 27/4 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 13/2 ⇜ (419/64 → 105/16) ⇝ 27/4 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/2 ⇜ (419/64 → 105/16) ⇝ 27/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 13/2 ⇜ (105/16 → 421/64) ⇝ 53/8 | note:C#5 gain:0.44 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 13/2 ⇜ (105/16 → 421/64) ⇝ 53/8 | note:E5 gain:0.44 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 13/2 ⇜ (105/16 → 421/64) ⇝ 27/4 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 13/2 ⇜ (105/16 → 421/64) ⇝ 27/4 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/2 ⇜ (105/16 → 421/64) ⇝ 27/4 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 13/2 ⇜ (105/16 → 421/64) ⇝ 27/4 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/2 ⇜ (105/16 → 421/64) ⇝ 27/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 13/2 ⇜ (421/64 → 211/32) ⇝ 53/8 | note:C#5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 13/2 ⇜ (421/64 → 211/32) ⇝ 53/8 | note:E5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 13/2 ⇜ (421/64 → 211/32) ⇝ 27/4 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 13/2 ⇜ (421/64 → 211/32) ⇝ 27/4 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/2 ⇜ (421/64 → 211/32) ⇝ 27/4 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 13/2 ⇜ (421/64 → 211/32) ⇝ 27/4 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/2 ⇜ (421/64 → 211/32) ⇝ 27/4 | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 13/2 ⇜ (211/32 → 423/64) ⇝ 53/8 | note:C#5 gain:0.24 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 13/2 ⇜ (211/32 → 423/64) ⇝ 53/8 | note:E5 gain:0.24 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 13/2 ⇜ (211/32 → 423/64) ⇝ 27/4 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 13/2 ⇜ (211/32 → 423/64) ⇝ 27/4 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/2 ⇜ (211/32 → 423/64) ⇝ 27/4 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 13/2 ⇜ (211/32 → 423/64) ⇝ 27/4 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/2 ⇜ (211/32 → 423/64) ⇝ 27/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 13/2 ⇜ (423/64 → 53/8) | note:C#5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 13/2 ⇜ (423/64 → 53/8) | note:E5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 13/2 ⇜ (423/64 → 53/8) ⇝ 27/4 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 13/2 ⇜ (423/64 → 53/8) ⇝ 27/4 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/2 ⇜ (423/64 → 53/8) ⇝ 27/4 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 13/2 ⇜ (423/64 → 53/8) ⇝ 27/4 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/2 ⇜ (423/64 → 53/8) ⇝ 27/4 | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 13/2 ⇜ (53/8 → 425/64) ⇝ 27/4 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 13/2 ⇜ (53/8 → 425/64) ⇝ 27/4 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/2 ⇜ (53/8 → 425/64) ⇝ 27/4 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 13/2 ⇜ (53/8 → 425/64) ⇝ 27/4 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/2 ⇜ (53/8 → 425/64) ⇝ 27/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 13/2 ⇜ (425/64 → 213/32) ⇝ 27/4 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 13/2 ⇜ (425/64 → 213/32) ⇝ 27/4 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/2 ⇜ (425/64 → 213/32) ⇝ 27/4 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 13/2 ⇜ (425/64 → 213/32) ⇝ 27/4 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/2 ⇜ (425/64 → 213/32) ⇝ 27/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 13/2 ⇜ (213/32 → 427/64) ⇝ 27/4 | note:Bb3 gain:0.32 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 13/2 ⇜ (213/32 → 427/64) ⇝ 27/4 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/2 ⇜ (213/32 → 427/64) ⇝ 27/4 | note:E4 gain:0.32 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 13/2 ⇜ (213/32 → 427/64) ⇝ 27/4 | note:Ab4 gain:0.32 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/2 ⇜ (213/32 → 427/64) ⇝ 27/4 | note:F#2 gain:0.64 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 13/2 ⇜ (427/64 → 107/16) ⇝ 27/4 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 13/2 ⇜ (427/64 → 107/16) ⇝ 27/4 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/2 ⇜ (427/64 → 107/16) ⇝ 27/4 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 13/2 ⇜ (427/64 → 107/16) ⇝ 27/4 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/2 ⇜ (427/64 → 107/16) ⇝ 27/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 13/2 ⇜ (107/16 → 429/64) ⇝ 27/4 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 13/2 ⇜ (107/16 → 429/64) ⇝ 27/4 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/2 ⇜ (107/16 → 429/64) ⇝ 27/4 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 13/2 ⇜ (107/16 → 429/64) ⇝ 27/4 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/2 ⇜ (107/16 → 429/64) ⇝ 27/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 13/2 ⇜ (429/64 → 215/32) ⇝ 27/4 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 13/2 ⇜ (429/64 → 215/32) ⇝ 27/4 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/2 ⇜ (429/64 → 215/32) ⇝ 27/4 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 13/2 ⇜ (429/64 → 215/32) ⇝ 27/4 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/2 ⇜ (429/64 → 215/32) ⇝ 27/4 | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 13/2 ⇜ (215/32 → 431/64) ⇝ 27/4 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 13/2 ⇜ (215/32 → 431/64) ⇝ 27/4 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/2 ⇜ (215/32 → 431/64) ⇝ 27/4 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 13/2 ⇜ (215/32 → 431/64) ⇝ 27/4 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/2 ⇜ (215/32 → 431/64) ⇝ 27/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 13/2 ⇜ (431/64 → 27/4) | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 13/2 ⇜ (431/64 → 27/4) | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/2 ⇜ (431/64 → 27/4) | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 13/2 ⇜ (431/64 → 27/4) | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 13/2 ⇜ (431/64 → 27/4) | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ (27/4 → 433/64) ⇝ 55/8 | note:F#4 gain:0.44 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ (27/4 → 433/64) ⇝ 55/8 | note:A#4 gain:0.44 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 27/4 ⇜ (433/64 → 217/32) ⇝ 55/8 | note:F#4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 27/4 ⇜ (433/64 → 217/32) ⇝ 55/8 | note:A#4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 27/4 ⇜ (217/32 → 435/64) ⇝ 55/8 | note:F#4 gain:0.64 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 27/4 ⇜ (217/32 → 435/64) ⇝ 55/8 | note:A#4 gain:0.64 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ (95/14 → 435/64) ⇝ 197/28 | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ (95/14 → 435/64) ⇝ 197/28 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ (95/14 → 435/64) ⇝ 197/28 | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ (95/14 → 435/64) ⇝ 197/28 | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 27/4 ⇜ (435/64 → 109/16) ⇝ 55/8 | note:F#4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 27/4 ⇜ (435/64 → 109/16) ⇝ 55/8 | note:A#4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 95/14 ⇜ (435/64 → 109/16) ⇝ 197/28 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 95/14 ⇜ (435/64 → 109/16) ⇝ 197/28 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 95/14 ⇜ (435/64 → 109/16) ⇝ 197/28 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 95/14 ⇜ (435/64 → 109/16) ⇝ 197/28 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 27/4 ⇜ (109/16 → 437/64) ⇝ 55/8 | note:F#4 gain:0.44 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 27/4 ⇜ (109/16 → 437/64) ⇝ 55/8 | note:A#4 gain:0.44 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 95/14 ⇜ (109/16 → 437/64) ⇝ 197/28 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 95/14 ⇜ (109/16 → 437/64) ⇝ 197/28 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 95/14 ⇜ (109/16 → 437/64) ⇝ 197/28 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 95/14 ⇜ (109/16 → 437/64) ⇝ 197/28 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 27/4 ⇜ (437/64 → 219/32) ⇝ 55/8 | note:F#4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 27/4 ⇜ (437/64 → 219/32) ⇝ 55/8 | note:A#4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 95/14 ⇜ (437/64 → 219/32) ⇝ 197/28 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 95/14 ⇜ (437/64 → 219/32) ⇝ 197/28 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 95/14 ⇜ (437/64 → 219/32) ⇝ 197/28 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 95/14 ⇜ (437/64 → 219/32) ⇝ 197/28 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 27/4 ⇜ (219/32 → 439/64) ⇝ 55/8 | note:F#4 gain:0.24 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 27/4 ⇜ (219/32 → 439/64) ⇝ 55/8 | note:A#4 gain:0.24 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 95/14 ⇜ (219/32 → 439/64) ⇝ 197/28 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 95/14 ⇜ (219/32 → 439/64) ⇝ 197/28 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 95/14 ⇜ (219/32 → 439/64) ⇝ 197/28 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 95/14 ⇜ (219/32 → 439/64) ⇝ 197/28 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 27/4 ⇜ (439/64 → 55/8) | note:F#4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 27/4 ⇜ (439/64 → 55/8) | note:A#4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 95/14 ⇜ (439/64 → 55/8) ⇝ 197/28 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 95/14 ⇜ (439/64 → 55/8) ⇝ 197/28 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 95/14 ⇜ (439/64 → 55/8) ⇝ 197/28 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 95/14 ⇜ (439/64 → 55/8) ⇝ 197/28 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 95/14 ⇜ (55/8 → 441/64) ⇝ 197/28 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 95/14 ⇜ (55/8 → 441/64) ⇝ 197/28 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 95/14 ⇜ (55/8 → 441/64) ⇝ 197/28 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 95/14 ⇜ (55/8 → 441/64) ⇝ 197/28 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 95/14 ⇜ (441/64 → 221/32) ⇝ 197/28 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 95/14 ⇜ (441/64 → 221/32) ⇝ 197/28 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 95/14 ⇜ (441/64 → 221/32) ⇝ 197/28 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 95/14 ⇜ (441/64 → 221/32) ⇝ 197/28 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 95/14 ⇜ (221/32 → 443/64) ⇝ 197/28 | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 95/14 ⇜ (221/32 → 443/64) ⇝ 197/28 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 95/14 ⇜ (221/32 → 443/64) ⇝ 197/28 | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 95/14 ⇜ (221/32 → 443/64) ⇝ 197/28 | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 95/14 ⇜ (443/64 → 111/16) ⇝ 197/28 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 95/14 ⇜ (443/64 → 111/16) ⇝ 197/28 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 95/14 ⇜ (443/64 → 111/16) ⇝ 197/28 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 95/14 ⇜ (443/64 → 111/16) ⇝ 197/28 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 95/14 ⇜ (111/16 → 445/64) ⇝ 197/28 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 95/14 ⇜ (111/16 → 445/64) ⇝ 197/28 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 95/14 ⇜ (111/16 → 445/64) ⇝ 197/28 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 95/14 ⇜ (111/16 → 445/64) ⇝ 197/28 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 95/14 ⇜ (445/64 → 223/32) ⇝ 197/28 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 95/14 ⇜ (445/64 → 223/32) ⇝ 197/28 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 95/14 ⇜ (445/64 → 223/32) ⇝ 197/28 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 95/14 ⇜ (445/64 → 223/32) ⇝ 197/28 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 95/14 ⇜ (223/32 → 447/64) ⇝ 197/28 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 95/14 ⇜ (223/32 → 447/64) ⇝ 197/28 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 95/14 ⇜ (223/32 → 447/64) ⇝ 197/28 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 95/14 ⇜ (223/32 → 447/64) ⇝ 197/28 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 95/14 ⇜ (447/64 → 7/1) ⇝ 197/28 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 95/14 ⇜ (447/64 → 7/1) ⇝ 197/28 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 95/14 ⇜ (447/64 → 7/1) ⇝ 197/28 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 95/14 ⇜ (447/64 → 7/1) ⇝ 197/28 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 95/14 ⇜ (7/1 → 449/64) ⇝ 197/28 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 95/14 ⇜ (7/1 → 449/64) ⇝ 197/28 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 95/14 ⇜ (7/1 → 449/64) ⇝ 197/28 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 95/14 ⇜ (7/1 → 449/64) ⇝ 197/28 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ (7/1 → 449/64) ⇝ 29/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 95/14 ⇜ (449/64 → 225/32) ⇝ 197/28 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 95/14 ⇜ (449/64 → 225/32) ⇝ 197/28 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 95/14 ⇜ (449/64 → 225/32) ⇝ 197/28 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 95/14 ⇜ (449/64 → 225/32) ⇝ 197/28 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 7/1 ⇜ (449/64 → 225/32) ⇝ 29/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 95/14 ⇜ (225/32 → 197/28) | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 95/14 ⇜ (225/32 → 197/28) | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 95/14 ⇜ (225/32 → 197/28) | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 95/14 ⇜ (225/32 → 197/28) | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 7/1 ⇜ (225/32 → 451/64) ⇝ 29/4 | note:F#2 gain:0.64 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 7/1 ⇜ (451/64 → 113/16) ⇝ 29/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 7/1 ⇜ (113/16 → 453/64) ⇝ 29/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 7/1 ⇜ (453/64 → 227/32) ⇝ 29/4 | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 7/1 ⇜ (227/32 → 455/64) ⇝ 29/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 7/1 ⇜ (455/64 → 57/8) ⇝ 29/4 | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 7/1 ⇜ (57/8 → 457/64) ⇝ 29/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ (57/8 → 457/64) ⇝ 29/4 | note:F#4 gain:0.44 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ (57/8 → 457/64) ⇝ 29/4 | note:A#4 gain:0.44 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 7/1 ⇜ (457/64 → 229/32) ⇝ 29/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 57/8 ⇜ (457/64 → 229/32) ⇝ 29/4 | note:F#4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 57/8 ⇜ (457/64 → 229/32) ⇝ 29/4 | note:A#4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 7/1 ⇜ (229/32 → 459/64) ⇝ 29/4 | note:F#2 gain:0.64 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 57/8 ⇜ (229/32 → 459/64) ⇝ 29/4 | note:F#4 gain:0.64 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 57/8 ⇜ (229/32 → 459/64) ⇝ 29/4 | note:A#4 gain:0.64 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 7/1 ⇜ (459/64 → 115/16) ⇝ 29/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 57/8 ⇜ (459/64 → 115/16) ⇝ 29/4 | note:F#4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 57/8 ⇜ (459/64 → 115/16) ⇝ 29/4 | note:A#4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 7/1 ⇜ (115/16 → 461/64) ⇝ 29/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 57/8 ⇜ (115/16 → 461/64) ⇝ 29/4 | note:F#4 gain:0.44 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 57/8 ⇜ (115/16 → 461/64) ⇝ 29/4 | note:A#4 gain:0.44 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 7/1 ⇜ (461/64 → 231/32) ⇝ 29/4 | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 57/8 ⇜ (461/64 → 231/32) ⇝ 29/4 | note:F#4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 57/8 ⇜ (461/64 → 231/32) ⇝ 29/4 | note:A#4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 7/1 ⇜ (231/32 → 463/64) ⇝ 29/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 57/8 ⇜ (231/32 → 463/64) ⇝ 29/4 | note:F#4 gain:0.24 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 57/8 ⇜ (231/32 → 463/64) ⇝ 29/4 | note:A#4 gain:0.24 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 7/1 ⇜ (463/64 → 29/4) | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 57/8 ⇜ (463/64 → 29/4) | note:F#4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 57/8 ⇜ (463/64 → 29/4) | note:A#4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ (29/4 → 465/64) ⇝ 15/2 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ (29/4 → 465/64) ⇝ 15/2 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ (29/4 → 465/64) ⇝ 15/2 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (29/4 → 465/64) ⇝ 15/2 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/4 ⇜ (465/64 → 233/32) ⇝ 15/2 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/4 ⇜ (465/64 → 233/32) ⇝ 15/2 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/4 ⇜ (465/64 → 233/32) ⇝ 15/2 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/4 ⇜ (465/64 → 233/32) ⇝ 15/2 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/4 ⇜ (233/32 → 467/64) ⇝ 15/2 | note:Bb3 gain:0.32 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/4 ⇜ (233/32 → 467/64) ⇝ 15/2 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/4 ⇜ (233/32 → 467/64) ⇝ 15/2 | note:E4 gain:0.32 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/4 ⇜ (233/32 → 467/64) ⇝ 15/2 | note:Ab4 gain:0.32 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/4 ⇜ (467/64 → 117/16) ⇝ 15/2 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/4 ⇜ (467/64 → 117/16) ⇝ 15/2 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/4 ⇜ (467/64 → 117/16) ⇝ 15/2 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/4 ⇜ (467/64 → 117/16) ⇝ 15/2 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/4 ⇜ (117/16 → 469/64) ⇝ 15/2 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/4 ⇜ (117/16 → 469/64) ⇝ 15/2 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/4 ⇜ (117/16 → 469/64) ⇝ 15/2 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/4 ⇜ (117/16 → 469/64) ⇝ 15/2 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/4 ⇜ (469/64 → 235/32) ⇝ 15/2 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/4 ⇜ (469/64 → 235/32) ⇝ 15/2 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/4 ⇜ (469/64 → 235/32) ⇝ 15/2 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/4 ⇜ (469/64 → 235/32) ⇝ 15/2 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/4 ⇜ (235/32 → 471/64) ⇝ 15/2 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/4 ⇜ (235/32 → 471/64) ⇝ 15/2 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/4 ⇜ (235/32 → 471/64) ⇝ 15/2 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/4 ⇜ (235/32 → 471/64) ⇝ 15/2 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/4 ⇜ (471/64 → 59/8) ⇝ 15/2 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/4 ⇜ (471/64 → 59/8) ⇝ 15/2 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/4 ⇜ (471/64 → 59/8) ⇝ 15/2 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/4 ⇜ (471/64 → 59/8) ⇝ 15/2 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/4 ⇜ (59/8 → 473/64) ⇝ 15/2 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/4 ⇜ (59/8 → 473/64) ⇝ 15/2 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/4 ⇜ (59/8 → 473/64) ⇝ 15/2 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/4 ⇜ (59/8 → 473/64) ⇝ 15/2 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/4 ⇜ (473/64 → 237/32) ⇝ 15/2 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/4 ⇜ (473/64 → 237/32) ⇝ 15/2 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/4 ⇜ (473/64 → 237/32) ⇝ 15/2 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/4 ⇜ (473/64 → 237/32) ⇝ 15/2 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/4 ⇜ (237/32 → 475/64) ⇝ 15/2 | note:Bb3 gain:0.32 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/4 ⇜ (237/32 → 475/64) ⇝ 15/2 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/4 ⇜ (237/32 → 475/64) ⇝ 15/2 | note:E4 gain:0.32 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/4 ⇜ (237/32 → 475/64) ⇝ 15/2 | note:Ab4 gain:0.32 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/4 ⇜ (475/64 → 119/16) ⇝ 15/2 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/4 ⇜ (475/64 → 119/16) ⇝ 15/2 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/4 ⇜ (475/64 → 119/16) ⇝ 15/2 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/4 ⇜ (475/64 → 119/16) ⇝ 15/2 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/4 ⇜ (119/16 → 477/64) ⇝ 15/2 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/4 ⇜ (119/16 → 477/64) ⇝ 15/2 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/4 ⇜ (119/16 → 477/64) ⇝ 15/2 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/4 ⇜ (119/16 → 477/64) ⇝ 15/2 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/4 ⇜ (477/64 → 239/32) ⇝ 15/2 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/4 ⇜ (477/64 → 239/32) ⇝ 15/2 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/4 ⇜ (477/64 → 239/32) ⇝ 15/2 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/4 ⇜ (477/64 → 239/32) ⇝ 15/2 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/4 ⇜ (239/32 → 479/64) ⇝ 15/2 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/4 ⇜ (239/32 → 479/64) ⇝ 15/2 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/4 ⇜ (239/32 → 479/64) ⇝ 15/2 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/4 ⇜ (239/32 → 479/64) ⇝ 15/2 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/4 ⇜ (479/64 → 15/2) | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/4 ⇜ (479/64 → 15/2) | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/4 ⇜ (479/64 → 15/2) | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/4 ⇜ (479/64 → 15/2) | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ (15/2 → 481/64) ⇝ 61/8 | note:C#5 gain:0.44 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ (15/2 → 481/64) ⇝ 61/8 | note:E5 gain:0.44 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ (15/2 → 481/64) ⇝ 31/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 15/2 ⇜ (481/64 → 241/32) ⇝ 61/8 | note:C#5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 15/2 ⇜ (481/64 → 241/32) ⇝ 61/8 | note:E5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 15/2 ⇜ (481/64 → 241/32) ⇝ 31/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 15/2 ⇜ (241/32 → 483/64) ⇝ 61/8 | note:C#5 gain:0.64 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 15/2 ⇜ (241/32 → 483/64) ⇝ 61/8 | note:E5 gain:0.64 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 15/2 ⇜ (241/32 → 483/64) ⇝ 31/4 | note:F#2 gain:0.64 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ (211/28 → 483/64) ⇝ 109/14 | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ (211/28 → 483/64) ⇝ 109/14 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ (211/28 → 483/64) ⇝ 109/14 | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ (211/28 → 483/64) ⇝ 109/14 | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 15/2 ⇜ (483/64 → 121/16) ⇝ 61/8 | note:C#5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 15/2 ⇜ (483/64 → 121/16) ⇝ 61/8 | note:E5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 15/2 ⇜ (483/64 → 121/16) ⇝ 31/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 211/28 ⇜ (483/64 → 121/16) ⇝ 109/14 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 211/28 ⇜ (483/64 → 121/16) ⇝ 109/14 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 211/28 ⇜ (483/64 → 121/16) ⇝ 109/14 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 211/28 ⇜ (483/64 → 121/16) ⇝ 109/14 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 15/2 ⇜ (121/16 → 485/64) ⇝ 61/8 | note:C#5 gain:0.44 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 15/2 ⇜ (121/16 → 485/64) ⇝ 61/8 | note:E5 gain:0.44 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 15/2 ⇜ (121/16 → 485/64) ⇝ 31/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 211/28 ⇜ (121/16 → 485/64) ⇝ 109/14 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 211/28 ⇜ (121/16 → 485/64) ⇝ 109/14 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 211/28 ⇜ (121/16 → 485/64) ⇝ 109/14 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 211/28 ⇜ (121/16 → 485/64) ⇝ 109/14 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 15/2 ⇜ (485/64 → 243/32) ⇝ 61/8 | note:C#5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 15/2 ⇜ (485/64 → 243/32) ⇝ 61/8 | note:E5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 15/2 ⇜ (485/64 → 243/32) ⇝ 31/4 | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 211/28 ⇜ (485/64 → 243/32) ⇝ 109/14 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 211/28 ⇜ (485/64 → 243/32) ⇝ 109/14 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 211/28 ⇜ (485/64 → 243/32) ⇝ 109/14 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 211/28 ⇜ (485/64 → 243/32) ⇝ 109/14 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 15/2 ⇜ (243/32 → 487/64) ⇝ 61/8 | note:C#5 gain:0.24 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 15/2 ⇜ (243/32 → 487/64) ⇝ 61/8 | note:E5 gain:0.24 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 15/2 ⇜ (243/32 → 487/64) ⇝ 31/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 211/28 ⇜ (243/32 → 487/64) ⇝ 109/14 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 211/28 ⇜ (243/32 → 487/64) ⇝ 109/14 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 211/28 ⇜ (243/32 → 487/64) ⇝ 109/14 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 211/28 ⇜ (243/32 → 487/64) ⇝ 109/14 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 15/2 ⇜ (487/64 → 61/8) | note:C#5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 15/2 ⇜ (487/64 → 61/8) | note:E5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 15/2 ⇜ (487/64 → 61/8) ⇝ 31/4 | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 211/28 ⇜ (487/64 → 61/8) ⇝ 109/14 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 211/28 ⇜ (487/64 → 61/8) ⇝ 109/14 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 211/28 ⇜ (487/64 → 61/8) ⇝ 109/14 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 211/28 ⇜ (487/64 → 61/8) ⇝ 109/14 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 15/2 ⇜ (61/8 → 489/64) ⇝ 31/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 211/28 ⇜ (61/8 → 489/64) ⇝ 109/14 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 211/28 ⇜ (61/8 → 489/64) ⇝ 109/14 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 211/28 ⇜ (61/8 → 489/64) ⇝ 109/14 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 211/28 ⇜ (61/8 → 489/64) ⇝ 109/14 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 15/2 ⇜ (489/64 → 245/32) ⇝ 31/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 211/28 ⇜ (489/64 → 245/32) ⇝ 109/14 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 211/28 ⇜ (489/64 → 245/32) ⇝ 109/14 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 211/28 ⇜ (489/64 → 245/32) ⇝ 109/14 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 211/28 ⇜ (489/64 → 245/32) ⇝ 109/14 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 15/2 ⇜ (245/32 → 491/64) ⇝ 31/4 | note:F#2 gain:0.64 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 211/28 ⇜ (245/32 → 491/64) ⇝ 109/14 | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 211/28 ⇜ (245/32 → 491/64) ⇝ 109/14 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 211/28 ⇜ (245/32 → 491/64) ⇝ 109/14 | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 211/28 ⇜ (245/32 → 491/64) ⇝ 109/14 | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 15/2 ⇜ (491/64 → 123/16) ⇝ 31/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 211/28 ⇜ (491/64 → 123/16) ⇝ 109/14 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 211/28 ⇜ (491/64 → 123/16) ⇝ 109/14 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 211/28 ⇜ (491/64 → 123/16) ⇝ 109/14 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 211/28 ⇜ (491/64 → 123/16) ⇝ 109/14 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 15/2 ⇜ (123/16 → 493/64) ⇝ 31/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 211/28 ⇜ (123/16 → 493/64) ⇝ 109/14 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 211/28 ⇜ (123/16 → 493/64) ⇝ 109/14 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 211/28 ⇜ (123/16 → 493/64) ⇝ 109/14 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 211/28 ⇜ (123/16 → 493/64) ⇝ 109/14 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 15/2 ⇜ (493/64 → 247/32) ⇝ 31/4 | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 211/28 ⇜ (493/64 → 247/32) ⇝ 109/14 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 211/28 ⇜ (493/64 → 247/32) ⇝ 109/14 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 211/28 ⇜ (493/64 → 247/32) ⇝ 109/14 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 211/28 ⇜ (493/64 → 247/32) ⇝ 109/14 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 15/2 ⇜ (247/32 → 495/64) ⇝ 31/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 211/28 ⇜ (247/32 → 495/64) ⇝ 109/14 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 211/28 ⇜ (247/32 → 495/64) ⇝ 109/14 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 211/28 ⇜ (247/32 → 495/64) ⇝ 109/14 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 211/28 ⇜ (247/32 → 495/64) ⇝ 109/14 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 15/2 ⇜ (495/64 → 31/4) | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 211/28 ⇜ (495/64 → 31/4) ⇝ 109/14 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 211/28 ⇜ (495/64 → 31/4) ⇝ 109/14 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 211/28 ⇜ (495/64 → 31/4) ⇝ 109/14 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 211/28 ⇜ (495/64 → 31/4) ⇝ 109/14 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 211/28 ⇜ (31/4 → 497/64) ⇝ 109/14 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 211/28 ⇜ (31/4 → 497/64) ⇝ 109/14 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 211/28 ⇜ (31/4 → 497/64) ⇝ 109/14 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 211/28 ⇜ (31/4 → 497/64) ⇝ 109/14 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ (31/4 → 497/64) ⇝ 63/8 | note:C#5 gain:0.44 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ (31/4 → 497/64) ⇝ 63/8 | note:E5 gain:0.44 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ (31/4 → 497/64) ⇝ 8/1 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ (31/4 → 497/64) ⇝ 8/1 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ (31/4 → 497/64) ⇝ 8/1 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (31/4 → 497/64) ⇝ 8/1 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 211/28 ⇜ (497/64 → 249/32) ⇝ 109/14 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 211/28 ⇜ (497/64 → 249/32) ⇝ 109/14 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 211/28 ⇜ (497/64 → 249/32) ⇝ 109/14 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 211/28 ⇜ (497/64 → 249/32) ⇝ 109/14 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 31/4 ⇜ (497/64 → 249/32) ⇝ 63/8 | note:C#5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 31/4 ⇜ (497/64 → 249/32) ⇝ 63/8 | note:E5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 31/4 ⇜ (497/64 → 249/32) ⇝ 8/1 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 31/4 ⇜ (497/64 → 249/32) ⇝ 8/1 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 31/4 ⇜ (497/64 → 249/32) ⇝ 8/1 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 31/4 ⇜ (497/64 → 249/32) ⇝ 8/1 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 211/28 ⇜ (249/32 → 109/14) | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 211/28 ⇜ (249/32 → 109/14) | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 211/28 ⇜ (249/32 → 109/14) | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 211/28 ⇜ (249/32 → 109/14) | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 31/4 ⇜ (249/32 → 499/64) ⇝ 63/8 | note:C#5 gain:0.64 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 31/4 ⇜ (249/32 → 499/64) ⇝ 63/8 | note:E5 gain:0.64 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 31/4 ⇜ (249/32 → 499/64) ⇝ 8/1 | note:Bb3 gain:0.32 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 31/4 ⇜ (249/32 → 499/64) ⇝ 8/1 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 31/4 ⇜ (249/32 → 499/64) ⇝ 8/1 | note:E4 gain:0.32 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 31/4 ⇜ (249/32 → 499/64) ⇝ 8/1 | note:Ab4 gain:0.32 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 31/4 ⇜ (499/64 → 125/16) ⇝ 63/8 | note:C#5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 31/4 ⇜ (499/64 → 125/16) ⇝ 63/8 | note:E5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 31/4 ⇜ (499/64 → 125/16) ⇝ 8/1 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 31/4 ⇜ (499/64 → 125/16) ⇝ 8/1 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 31/4 ⇜ (499/64 → 125/16) ⇝ 8/1 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 31/4 ⇜ (499/64 → 125/16) ⇝ 8/1 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 31/4 ⇜ (125/16 → 501/64) ⇝ 63/8 | note:C#5 gain:0.44 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 31/4 ⇜ (125/16 → 501/64) ⇝ 63/8 | note:E5 gain:0.44 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 31/4 ⇜ (125/16 → 501/64) ⇝ 8/1 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 31/4 ⇜ (125/16 → 501/64) ⇝ 8/1 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 31/4 ⇜ (125/16 → 501/64) ⇝ 8/1 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 31/4 ⇜ (125/16 → 501/64) ⇝ 8/1 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 31/4 ⇜ (501/64 → 251/32) ⇝ 63/8 | note:C#5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 31/4 ⇜ (501/64 → 251/32) ⇝ 63/8 | note:E5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 31/4 ⇜ (501/64 → 251/32) ⇝ 8/1 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 31/4 ⇜ (501/64 → 251/32) ⇝ 8/1 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 31/4 ⇜ (501/64 → 251/32) ⇝ 8/1 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 31/4 ⇜ (501/64 → 251/32) ⇝ 8/1 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 31/4 ⇜ (251/32 → 503/64) ⇝ 63/8 | note:C#5 gain:0.24 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 31/4 ⇜ (251/32 → 503/64) ⇝ 63/8 | note:E5 gain:0.24 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 31/4 ⇜ (251/32 → 503/64) ⇝ 8/1 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 31/4 ⇜ (251/32 → 503/64) ⇝ 8/1 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 31/4 ⇜ (251/32 → 503/64) ⇝ 8/1 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 31/4 ⇜ (251/32 → 503/64) ⇝ 8/1 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 31/4 ⇜ (503/64 → 63/8) | note:C#5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 31/4 ⇜ (503/64 → 63/8) | note:E5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 31/4 ⇜ (503/64 → 63/8) ⇝ 8/1 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 31/4 ⇜ (503/64 → 63/8) ⇝ 8/1 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 31/4 ⇜ (503/64 → 63/8) ⇝ 8/1 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 31/4 ⇜ (503/64 → 63/8) ⇝ 8/1 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 31/4 ⇜ (63/8 → 505/64) ⇝ 8/1 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 31/4 ⇜ (63/8 → 505/64) ⇝ 8/1 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 31/4 ⇜ (63/8 → 505/64) ⇝ 8/1 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 31/4 ⇜ (63/8 → 505/64) ⇝ 8/1 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 31/4 ⇜ (505/64 → 253/32) ⇝ 8/1 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 31/4 ⇜ (505/64 → 253/32) ⇝ 8/1 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 31/4 ⇜ (505/64 → 253/32) ⇝ 8/1 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 31/4 ⇜ (505/64 → 253/32) ⇝ 8/1 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 31/4 ⇜ (253/32 → 507/64) ⇝ 8/1 | note:Bb3 gain:0.32 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 31/4 ⇜ (253/32 → 507/64) ⇝ 8/1 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 31/4 ⇜ (253/32 → 507/64) ⇝ 8/1 | note:E4 gain:0.32 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 31/4 ⇜ (253/32 → 507/64) ⇝ 8/1 | note:Ab4 gain:0.32 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 31/4 ⇜ (507/64 → 127/16) ⇝ 8/1 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 31/4 ⇜ (507/64 → 127/16) ⇝ 8/1 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 31/4 ⇜ (507/64 → 127/16) ⇝ 8/1 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 31/4 ⇜ (507/64 → 127/16) ⇝ 8/1 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 31/4 ⇜ (127/16 → 509/64) ⇝ 8/1 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 31/4 ⇜ (127/16 → 509/64) ⇝ 8/1 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 31/4 ⇜ (127/16 → 509/64) ⇝ 8/1 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 31/4 ⇜ (127/16 → 509/64) ⇝ 8/1 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 31/4 ⇜ (509/64 → 255/32) ⇝ 8/1 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 31/4 ⇜ (509/64 → 255/32) ⇝ 8/1 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 31/4 ⇜ (509/64 → 255/32) ⇝ 8/1 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 31/4 ⇜ (509/64 → 255/32) ⇝ 8/1 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 31/4 ⇜ (255/32 → 511/64) ⇝ 8/1 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 31/4 ⇜ (255/32 → 511/64) ⇝ 8/1 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 31/4 ⇜ (255/32 → 511/64) ⇝ 8/1 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 31/4 ⇜ (255/32 → 511/64) ⇝ 8/1 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 31/4 ⇜ (511/64 → 8/1) | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 31/4 ⇜ (511/64 → 8/1) | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 31/4 ⇜ (511/64 → 8/1) | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 31/4 ⇜ (511/64 → 8/1) | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ (8/1 → 513/64) ⇝ 33/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 8/1 ⇜ (513/64 → 257/32) ⇝ 33/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 8/1 ⇜ (257/32 → 515/64) ⇝ 33/4 | note:C2 gain:0.64 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ (225/28 → 515/64) ⇝ 58/7 | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ (225/28 → 515/64) ⇝ 58/7 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ (225/28 → 515/64) ⇝ 58/7 | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ (225/28 → 515/64) ⇝ 58/7 | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 8/1 ⇜ (515/64 → 129/16) ⇝ 33/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 225/28 ⇜ (515/64 → 129/16) ⇝ 58/7 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 225/28 ⇜ (515/64 → 129/16) ⇝ 58/7 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 225/28 ⇜ (515/64 → 129/16) ⇝ 58/7 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 225/28 ⇜ (515/64 → 129/16) ⇝ 58/7 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 8/1 ⇜ (129/16 → 517/64) ⇝ 33/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 225/28 ⇜ (129/16 → 517/64) ⇝ 58/7 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 225/28 ⇜ (129/16 → 517/64) ⇝ 58/7 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 225/28 ⇜ (129/16 → 517/64) ⇝ 58/7 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 225/28 ⇜ (129/16 → 517/64) ⇝ 58/7 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 8/1 ⇜ (517/64 → 259/32) ⇝ 33/4 | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 225/28 ⇜ (517/64 → 259/32) ⇝ 58/7 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 225/28 ⇜ (517/64 → 259/32) ⇝ 58/7 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 225/28 ⇜ (517/64 → 259/32) ⇝ 58/7 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 225/28 ⇜ (517/64 → 259/32) ⇝ 58/7 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 8/1 ⇜ (259/32 → 519/64) ⇝ 33/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 225/28 ⇜ (259/32 → 519/64) ⇝ 58/7 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 225/28 ⇜ (259/32 → 519/64) ⇝ 58/7 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 225/28 ⇜ (259/32 → 519/64) ⇝ 58/7 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 225/28 ⇜ (259/32 → 519/64) ⇝ 58/7 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 8/1 ⇜ (519/64 → 65/8) ⇝ 33/4 | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 225/28 ⇜ (519/64 → 65/8) ⇝ 58/7 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 225/28 ⇜ (519/64 → 65/8) ⇝ 58/7 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 225/28 ⇜ (519/64 → 65/8) ⇝ 58/7 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 225/28 ⇜ (519/64 → 65/8) ⇝ 58/7 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 8/1 ⇜ (65/8 → 521/64) ⇝ 33/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 225/28 ⇜ (65/8 → 521/64) ⇝ 58/7 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 225/28 ⇜ (65/8 → 521/64) ⇝ 58/7 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 225/28 ⇜ (65/8 → 521/64) ⇝ 58/7 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 225/28 ⇜ (65/8 → 521/64) ⇝ 58/7 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ (65/8 → 521/64) ⇝ 33/4 | note:C4 gain:0.44 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ (65/8 → 521/64) ⇝ 33/4 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (65/8 → 521/64) ⇝ 33/4 | note:Bb4 gain:0.44 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 8/1 ⇜ (521/64 → 261/32) ⇝ 33/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 225/28 ⇜ (521/64 → 261/32) ⇝ 58/7 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 225/28 ⇜ (521/64 → 261/32) ⇝ 58/7 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 225/28 ⇜ (521/64 → 261/32) ⇝ 58/7 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 225/28 ⇜ (521/64 → 261/32) ⇝ 58/7 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 65/8 ⇜ (521/64 → 261/32) ⇝ 33/4 | note:C4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 65/8 ⇜ (521/64 → 261/32) ⇝ 33/4 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 65/8 ⇜ (521/64 → 261/32) ⇝ 33/4 | note:Bb4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 8/1 ⇜ (261/32 → 523/64) ⇝ 33/4 | note:C2 gain:0.64 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 225/28 ⇜ (261/32 → 523/64) ⇝ 58/7 | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 225/28 ⇜ (261/32 → 523/64) ⇝ 58/7 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 225/28 ⇜ (261/32 → 523/64) ⇝ 58/7 | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 225/28 ⇜ (261/32 → 523/64) ⇝ 58/7 | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 65/8 ⇜ (261/32 → 523/64) ⇝ 33/4 | note:C4 gain:0.64 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 65/8 ⇜ (261/32 → 523/64) ⇝ 33/4 | note:G4 gain:0.64 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 65/8 ⇜ (261/32 → 523/64) ⇝ 33/4 | note:Bb4 gain:0.64 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 8/1 ⇜ (523/64 → 131/16) ⇝ 33/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 225/28 ⇜ (523/64 → 131/16) ⇝ 58/7 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 225/28 ⇜ (523/64 → 131/16) ⇝ 58/7 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 225/28 ⇜ (523/64 → 131/16) ⇝ 58/7 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 225/28 ⇜ (523/64 → 131/16) ⇝ 58/7 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 65/8 ⇜ (523/64 → 131/16) ⇝ 33/4 | note:C4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 65/8 ⇜ (523/64 → 131/16) ⇝ 33/4 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 65/8 ⇜ (523/64 → 131/16) ⇝ 33/4 | note:Bb4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 8/1 ⇜ (131/16 → 525/64) ⇝ 33/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 225/28 ⇜ (131/16 → 525/64) ⇝ 58/7 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 225/28 ⇜ (131/16 → 525/64) ⇝ 58/7 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 225/28 ⇜ (131/16 → 525/64) ⇝ 58/7 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 225/28 ⇜ (131/16 → 525/64) ⇝ 58/7 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 65/8 ⇜ (131/16 → 525/64) ⇝ 33/4 | note:C4 gain:0.44 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 65/8 ⇜ (131/16 → 525/64) ⇝ 33/4 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 65/8 ⇜ (131/16 → 525/64) ⇝ 33/4 | note:Bb4 gain:0.44 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 8/1 ⇜ (525/64 → 263/32) ⇝ 33/4 | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 225/28 ⇜ (525/64 → 263/32) ⇝ 58/7 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 225/28 ⇜ (525/64 → 263/32) ⇝ 58/7 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 225/28 ⇜ (525/64 → 263/32) ⇝ 58/7 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 225/28 ⇜ (525/64 → 263/32) ⇝ 58/7 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 65/8 ⇜ (525/64 → 263/32) ⇝ 33/4 | note:C4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 65/8 ⇜ (525/64 → 263/32) ⇝ 33/4 | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 65/8 ⇜ (525/64 → 263/32) ⇝ 33/4 | note:Bb4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 8/1 ⇜ (263/32 → 527/64) ⇝ 33/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 225/28 ⇜ (263/32 → 527/64) ⇝ 58/7 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 225/28 ⇜ (263/32 → 527/64) ⇝ 58/7 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 225/28 ⇜ (263/32 → 527/64) ⇝ 58/7 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 225/28 ⇜ (263/32 → 527/64) ⇝ 58/7 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 65/8 ⇜ (263/32 → 527/64) ⇝ 33/4 | note:C4 gain:0.24 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 65/8 ⇜ (263/32 → 527/64) ⇝ 33/4 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 65/8 ⇜ (263/32 → 527/64) ⇝ 33/4 | note:Bb4 gain:0.24 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 8/1 ⇜ (527/64 → 33/4) | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 225/28 ⇜ (527/64 → 33/4) ⇝ 58/7 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 225/28 ⇜ (527/64 → 33/4) ⇝ 58/7 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 225/28 ⇜ (527/64 → 33/4) ⇝ 58/7 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 225/28 ⇜ (527/64 → 33/4) ⇝ 58/7 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 65/8 ⇜ (527/64 → 33/4) | note:C4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 65/8 ⇜ (527/64 → 33/4) | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 65/8 ⇜ (527/64 → 33/4) | note:Bb4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 225/28 ⇜ (33/4 → 529/64) ⇝ 58/7 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 225/28 ⇜ (33/4 → 529/64) ⇝ 58/7 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 225/28 ⇜ (33/4 → 529/64) ⇝ 58/7 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 225/28 ⇜ (33/4 → 529/64) ⇝ 58/7 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 225/28 ⇜ (529/64 → 265/32) ⇝ 58/7 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 225/28 ⇜ (529/64 → 265/32) ⇝ 58/7 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 225/28 ⇜ (529/64 → 265/32) ⇝ 58/7 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 225/28 ⇜ (529/64 → 265/32) ⇝ 58/7 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 225/28 ⇜ (265/32 → 58/7) | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 225/28 ⇜ (265/32 → 58/7) | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 225/28 ⇜ (265/32 → 58/7) | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 225/28 ⇜ (265/32 → 58/7) | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ (17/2 → 545/64) ⇝ 69/8 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (17/2 → 545/64) ⇝ 69/8 | note:D5 gain:0.44 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ (17/2 → 545/64) ⇝ 69/8 | note:F5 gain:0.44 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ (17/2 → 545/64) ⇝ 35/4 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ (17/2 → 545/64) ⇝ 35/4 | note:D4 gain:0.22 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ (17/2 → 545/64) ⇝ 35/4 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ (17/2 → 545/64) ⇝ 35/4 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (17/2 → 545/64) ⇝ 35/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 17/2 ⇜ (545/64 → 273/32) ⇝ 69/8 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 17/2 ⇜ (545/64 → 273/32) ⇝ 69/8 | note:D5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 17/2 ⇜ (545/64 → 273/32) ⇝ 69/8 | note:F5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 17/2 ⇜ (545/64 → 273/32) ⇝ 35/4 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 17/2 ⇜ (545/64 → 273/32) ⇝ 35/4 | note:D4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 17/2 ⇜ (545/64 → 273/32) ⇝ 35/4 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 17/2 ⇜ (545/64 → 273/32) ⇝ 35/4 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 17/2 ⇜ (545/64 → 273/32) ⇝ 35/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 17/2 ⇜ (273/32 → 547/64) ⇝ 69/8 | note:G4 gain:0.64 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 17/2 ⇜ (273/32 → 547/64) ⇝ 69/8 | note:D5 gain:0.64 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 17/2 ⇜ (273/32 → 547/64) ⇝ 69/8 | note:F5 gain:0.64 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 17/2 ⇜ (273/32 → 547/64) ⇝ 35/4 | note:Bb3 gain:0.32 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 17/2 ⇜ (273/32 → 547/64) ⇝ 35/4 | note:D4 gain:0.32 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 17/2 ⇜ (273/32 → 547/64) ⇝ 35/4 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 17/2 ⇜ (273/32 → 547/64) ⇝ 35/4 | note:G4 gain:0.32 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 17/2 ⇜ (273/32 → 547/64) ⇝ 35/4 | note:C2 gain:0.64 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 17/2 ⇜ (547/64 → 137/16) ⇝ 69/8 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 17/2 ⇜ (547/64 → 137/16) ⇝ 69/8 | note:D5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 17/2 ⇜ (547/64 → 137/16) ⇝ 69/8 | note:F5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 17/2 ⇜ (547/64 → 137/16) ⇝ 35/4 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 17/2 ⇜ (547/64 → 137/16) ⇝ 35/4 | note:D4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 17/2 ⇜ (547/64 → 137/16) ⇝ 35/4 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 17/2 ⇜ (547/64 → 137/16) ⇝ 35/4 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 17/2 ⇜ (547/64 → 137/16) ⇝ 35/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 17/2 ⇜ (137/16 → 549/64) ⇝ 69/8 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 17/2 ⇜ (137/16 → 549/64) ⇝ 69/8 | note:D5 gain:0.44 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 17/2 ⇜ (137/16 → 549/64) ⇝ 69/8 | note:F5 gain:0.44 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 17/2 ⇜ (137/16 → 549/64) ⇝ 35/4 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 17/2 ⇜ (137/16 → 549/64) ⇝ 35/4 | note:D4 gain:0.22 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 17/2 ⇜ (137/16 → 549/64) ⇝ 35/4 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 17/2 ⇜ (137/16 → 549/64) ⇝ 35/4 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 17/2 ⇜ (137/16 → 549/64) ⇝ 35/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 17/2 ⇜ (549/64 → 275/32) ⇝ 69/8 | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 17/2 ⇜ (549/64 → 275/32) ⇝ 69/8 | note:D5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 17/2 ⇜ (549/64 → 275/32) ⇝ 69/8 | note:F5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 17/2 ⇜ (549/64 → 275/32) ⇝ 35/4 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 17/2 ⇜ (549/64 → 275/32) ⇝ 35/4 | note:D4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 17/2 ⇜ (549/64 → 275/32) ⇝ 35/4 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 17/2 ⇜ (549/64 → 275/32) ⇝ 35/4 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 17/2 ⇜ (549/64 → 275/32) ⇝ 35/4 | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 17/2 ⇜ (275/32 → 551/64) ⇝ 69/8 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 17/2 ⇜ (275/32 → 551/64) ⇝ 69/8 | note:D5 gain:0.24 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 17/2 ⇜ (275/32 → 551/64) ⇝ 69/8 | note:F5 gain:0.24 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 17/2 ⇜ (275/32 → 551/64) ⇝ 35/4 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 17/2 ⇜ (275/32 → 551/64) ⇝ 35/4 | note:D4 gain:0.12 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 17/2 ⇜ (275/32 → 551/64) ⇝ 35/4 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 17/2 ⇜ (275/32 → 551/64) ⇝ 35/4 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 17/2 ⇜ (275/32 → 551/64) ⇝ 35/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 17/2 ⇜ (551/64 → 69/8) | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 17/2 ⇜ (551/64 → 69/8) | note:D5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 17/2 ⇜ (551/64 → 69/8) | note:F5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 17/2 ⇜ (551/64 → 69/8) ⇝ 35/4 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 17/2 ⇜ (551/64 → 69/8) ⇝ 35/4 | note:D4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 17/2 ⇜ (551/64 → 69/8) ⇝ 35/4 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 17/2 ⇜ (551/64 → 69/8) ⇝ 35/4 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 17/2 ⇜ (551/64 → 69/8) ⇝ 35/4 | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 17/2 ⇜ (69/8 → 553/64) ⇝ 35/4 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 17/2 ⇜ (69/8 → 553/64) ⇝ 35/4 | note:D4 gain:0.22 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 17/2 ⇜ (69/8 → 553/64) ⇝ 35/4 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 17/2 ⇜ (69/8 → 553/64) ⇝ 35/4 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 17/2 ⇜ (69/8 → 553/64) ⇝ 35/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 17/2 ⇜ (553/64 → 277/32) ⇝ 35/4 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 17/2 ⇜ (553/64 → 277/32) ⇝ 35/4 | note:D4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 17/2 ⇜ (553/64 → 277/32) ⇝ 35/4 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 17/2 ⇜ (553/64 → 277/32) ⇝ 35/4 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 17/2 ⇜ (553/64 → 277/32) ⇝ 35/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 17/2 ⇜ (277/32 → 555/64) ⇝ 35/4 | note:Bb3 gain:0.32 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 17/2 ⇜ (277/32 → 555/64) ⇝ 35/4 | note:D4 gain:0.32 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 17/2 ⇜ (277/32 → 555/64) ⇝ 35/4 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 17/2 ⇜ (277/32 → 555/64) ⇝ 35/4 | note:G4 gain:0.32 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 17/2 ⇜ (277/32 → 555/64) ⇝ 35/4 | note:C2 gain:0.64 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 17/2 ⇜ (555/64 → 139/16) ⇝ 35/4 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 17/2 ⇜ (555/64 → 139/16) ⇝ 35/4 | note:D4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 17/2 ⇜ (555/64 → 139/16) ⇝ 35/4 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 17/2 ⇜ (555/64 → 139/16) ⇝ 35/4 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 17/2 ⇜ (555/64 → 139/16) ⇝ 35/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 17/2 ⇜ (139/16 → 557/64) ⇝ 35/4 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 17/2 ⇜ (139/16 → 557/64) ⇝ 35/4 | note:D4 gain:0.22 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 17/2 ⇜ (139/16 → 557/64) ⇝ 35/4 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 17/2 ⇜ (139/16 → 557/64) ⇝ 35/4 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 17/2 ⇜ (139/16 → 557/64) ⇝ 35/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 17/2 ⇜ (557/64 → 279/32) ⇝ 35/4 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 17/2 ⇜ (557/64 → 279/32) ⇝ 35/4 | note:D4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 17/2 ⇜ (557/64 → 279/32) ⇝ 35/4 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 17/2 ⇜ (557/64 → 279/32) ⇝ 35/4 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 17/2 ⇜ (557/64 → 279/32) ⇝ 35/4 | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 17/2 ⇜ (279/32 → 559/64) ⇝ 35/4 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 17/2 ⇜ (279/32 → 559/64) ⇝ 35/4 | note:D4 gain:0.12 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 17/2 ⇜ (279/32 → 559/64) ⇝ 35/4 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 17/2 ⇜ (279/32 → 559/64) ⇝ 35/4 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 17/2 ⇜ (279/32 → 559/64) ⇝ 35/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 17/2 ⇜ (559/64 → 35/4) | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 17/2 ⇜ (559/64 → 35/4) | note:D4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 17/2 ⇜ (559/64 → 35/4) | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 17/2 ⇜ (559/64 → 35/4) | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 17/2 ⇜ (559/64 → 35/4) | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ (35/4 → 561/64) ⇝ 71/8 | note:C4 gain:0.44 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ (35/4 → 561/64) ⇝ 71/8 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (35/4 → 561/64) ⇝ 71/8 | note:Bb4 gain:0.44 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 35/4 ⇜ (561/64 → 281/32) ⇝ 71/8 | note:C4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 35/4 ⇜ (561/64 → 281/32) ⇝ 71/8 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 35/4 ⇜ (561/64 → 281/32) ⇝ 71/8 | note:Bb4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 35/4 ⇜ (281/32 → 563/64) ⇝ 71/8 | note:C4 gain:0.64 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 35/4 ⇜ (281/32 → 563/64) ⇝ 71/8 | note:G4 gain:0.64 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 35/4 ⇜ (281/32 → 563/64) ⇝ 71/8 | note:Bb4 gain:0.64 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ (123/14 → 563/64) ⇝ 253/28 | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ (123/14 → 563/64) ⇝ 253/28 | note:74 gain:0.064 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ (123/14 → 563/64) ⇝ 253/28 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ (123/14 → 563/64) ⇝ 253/28 | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 35/4 ⇜ (563/64 → 141/16) ⇝ 71/8 | note:C4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 35/4 ⇜ (563/64 → 141/16) ⇝ 71/8 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 35/4 ⇜ (563/64 → 141/16) ⇝ 71/8 | note:Bb4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 123/14 ⇜ (563/64 → 141/16) ⇝ 253/28 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 123/14 ⇜ (563/64 → 141/16) ⇝ 253/28 | note:74 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 123/14 ⇜ (563/64 → 141/16) ⇝ 253/28 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 123/14 ⇜ (563/64 → 141/16) ⇝ 253/28 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 35/4 ⇜ (141/16 → 565/64) ⇝ 71/8 | note:C4 gain:0.44 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 35/4 ⇜ (141/16 → 565/64) ⇝ 71/8 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 35/4 ⇜ (141/16 → 565/64) ⇝ 71/8 | note:Bb4 gain:0.44 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 123/14 ⇜ (141/16 → 565/64) ⇝ 253/28 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 123/14 ⇜ (141/16 → 565/64) ⇝ 253/28 | note:74 gain:0.044 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 123/14 ⇜ (141/16 → 565/64) ⇝ 253/28 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 123/14 ⇜ (141/16 → 565/64) ⇝ 253/28 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 35/4 ⇜ (565/64 → 283/32) ⇝ 71/8 | note:C4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 35/4 ⇜ (565/64 → 283/32) ⇝ 71/8 | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 35/4 ⇜ (565/64 → 283/32) ⇝ 71/8 | note:Bb4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 123/14 ⇜ (565/64 → 283/32) ⇝ 253/28 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 123/14 ⇜ (565/64 → 283/32) ⇝ 253/28 | note:74 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 123/14 ⇜ (565/64 → 283/32) ⇝ 253/28 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 123/14 ⇜ (565/64 → 283/32) ⇝ 253/28 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 35/4 ⇜ (283/32 → 567/64) ⇝ 71/8 | note:C4 gain:0.24 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 35/4 ⇜ (283/32 → 567/64) ⇝ 71/8 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 35/4 ⇜ (283/32 → 567/64) ⇝ 71/8 | note:Bb4 gain:0.24 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 123/14 ⇜ (283/32 → 567/64) ⇝ 253/28 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 123/14 ⇜ (283/32 → 567/64) ⇝ 253/28 | note:74 gain:0.024 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 123/14 ⇜ (283/32 → 567/64) ⇝ 253/28 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 123/14 ⇜ (283/32 → 567/64) ⇝ 253/28 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 35/4 ⇜ (567/64 → 71/8) | note:C4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 35/4 ⇜ (567/64 → 71/8) | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 35/4 ⇜ (567/64 → 71/8) | note:Bb4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 123/14 ⇜ (567/64 → 71/8) ⇝ 253/28 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 123/14 ⇜ (567/64 → 71/8) ⇝ 253/28 | note:74 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 123/14 ⇜ (567/64 → 71/8) ⇝ 253/28 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 123/14 ⇜ (567/64 → 71/8) ⇝ 253/28 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 123/14 ⇜ (71/8 → 569/64) ⇝ 253/28 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 123/14 ⇜ (71/8 → 569/64) ⇝ 253/28 | note:74 gain:0.044 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 123/14 ⇜ (71/8 → 569/64) ⇝ 253/28 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 123/14 ⇜ (71/8 → 569/64) ⇝ 253/28 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 123/14 ⇜ (569/64 → 285/32) ⇝ 253/28 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 123/14 ⇜ (569/64 → 285/32) ⇝ 253/28 | note:74 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 123/14 ⇜ (569/64 → 285/32) ⇝ 253/28 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 123/14 ⇜ (569/64 → 285/32) ⇝ 253/28 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 123/14 ⇜ (285/32 → 571/64) ⇝ 253/28 | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 123/14 ⇜ (285/32 → 571/64) ⇝ 253/28 | note:74 gain:0.064 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 123/14 ⇜ (285/32 → 571/64) ⇝ 253/28 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 123/14 ⇜ (285/32 → 571/64) ⇝ 253/28 | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 123/14 ⇜ (571/64 → 143/16) ⇝ 253/28 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 123/14 ⇜ (571/64 → 143/16) ⇝ 253/28 | note:74 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 123/14 ⇜ (571/64 → 143/16) ⇝ 253/28 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 123/14 ⇜ (571/64 → 143/16) ⇝ 253/28 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 123/14 ⇜ (143/16 → 573/64) ⇝ 253/28 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 123/14 ⇜ (143/16 → 573/64) ⇝ 253/28 | note:74 gain:0.044 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 123/14 ⇜ (143/16 → 573/64) ⇝ 253/28 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 123/14 ⇜ (143/16 → 573/64) ⇝ 253/28 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 123/14 ⇜ (573/64 → 287/32) ⇝ 253/28 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 123/14 ⇜ (573/64 → 287/32) ⇝ 253/28 | note:74 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 123/14 ⇜ (573/64 → 287/32) ⇝ 253/28 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 123/14 ⇜ (573/64 → 287/32) ⇝ 253/28 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 123/14 ⇜ (287/32 → 575/64) ⇝ 253/28 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 123/14 ⇜ (287/32 → 575/64) ⇝ 253/28 | note:74 gain:0.024 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 123/14 ⇜ (287/32 → 575/64) ⇝ 253/28 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 123/14 ⇜ (287/32 → 575/64) ⇝ 253/28 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 123/14 ⇜ (575/64 → 9/1) ⇝ 253/28 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 123/14 ⇜ (575/64 → 9/1) ⇝ 253/28 | note:74 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 123/14 ⇜ (575/64 → 9/1) ⇝ 253/28 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 123/14 ⇜ (575/64 → 9/1) ⇝ 253/28 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 123/14 ⇜ (9/1 → 577/64) ⇝ 253/28 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 123/14 ⇜ (9/1 → 577/64) ⇝ 253/28 | note:74 gain:0.044 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 123/14 ⇜ (9/1 → 577/64) ⇝ 253/28 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 123/14 ⇜ (9/1 → 577/64) ⇝ 253/28 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ (9/1 → 577/64) ⇝ 37/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 123/14 ⇜ (577/64 → 289/32) ⇝ 253/28 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 123/14 ⇜ (577/64 → 289/32) ⇝ 253/28 | note:74 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 123/14 ⇜ (577/64 → 289/32) ⇝ 253/28 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 123/14 ⇜ (577/64 → 289/32) ⇝ 253/28 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 9/1 ⇜ (577/64 → 289/32) ⇝ 37/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 123/14 ⇜ (289/32 → 253/28) | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 123/14 ⇜ (289/32 → 253/28) | note:74 gain:0.064 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 123/14 ⇜ (289/32 → 253/28) | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 123/14 ⇜ (289/32 → 253/28) | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 9/1 ⇜ (289/32 → 579/64) ⇝ 37/4 | note:C2 gain:0.64 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 9/1 ⇜ (579/64 → 145/16) ⇝ 37/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 9/1 ⇜ (145/16 → 581/64) ⇝ 37/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 9/1 ⇜ (581/64 → 291/32) ⇝ 37/4 | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 9/1 ⇜ (291/32 → 583/64) ⇝ 37/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 9/1 ⇜ (583/64 → 73/8) ⇝ 37/4 | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 9/1 ⇜ (73/8 → 585/64) ⇝ 37/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ (73/8 → 585/64) ⇝ 37/4 | note:C4 gain:0.44 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ (73/8 → 585/64) ⇝ 37/4 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (73/8 → 585/64) ⇝ 37/4 | note:Bb4 gain:0.44 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 9/1 ⇜ (585/64 → 293/32) ⇝ 37/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 73/8 ⇜ (585/64 → 293/32) ⇝ 37/4 | note:C4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 73/8 ⇜ (585/64 → 293/32) ⇝ 37/4 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 73/8 ⇜ (585/64 → 293/32) ⇝ 37/4 | note:Bb4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 9/1 ⇜ (293/32 → 587/64) ⇝ 37/4 | note:C2 gain:0.64 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 73/8 ⇜ (293/32 → 587/64) ⇝ 37/4 | note:C4 gain:0.64 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 73/8 ⇜ (293/32 → 587/64) ⇝ 37/4 | note:G4 gain:0.64 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 73/8 ⇜ (293/32 → 587/64) ⇝ 37/4 | note:Bb4 gain:0.64 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 9/1 ⇜ (587/64 → 147/16) ⇝ 37/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 73/8 ⇜ (587/64 → 147/16) ⇝ 37/4 | note:C4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 73/8 ⇜ (587/64 → 147/16) ⇝ 37/4 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 73/8 ⇜ (587/64 → 147/16) ⇝ 37/4 | note:Bb4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 9/1 ⇜ (147/16 → 589/64) ⇝ 37/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 73/8 ⇜ (147/16 → 589/64) ⇝ 37/4 | note:C4 gain:0.44 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 73/8 ⇜ (147/16 → 589/64) ⇝ 37/4 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 73/8 ⇜ (147/16 → 589/64) ⇝ 37/4 | note:Bb4 gain:0.44 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 9/1 ⇜ (589/64 → 295/32) ⇝ 37/4 | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 73/8 ⇜ (589/64 → 295/32) ⇝ 37/4 | note:C4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 73/8 ⇜ (589/64 → 295/32) ⇝ 37/4 | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 73/8 ⇜ (589/64 → 295/32) ⇝ 37/4 | note:Bb4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 9/1 ⇜ (295/32 → 591/64) ⇝ 37/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 73/8 ⇜ (295/32 → 591/64) ⇝ 37/4 | note:C4 gain:0.24 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 73/8 ⇜ (295/32 → 591/64) ⇝ 37/4 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 73/8 ⇜ (295/32 → 591/64) ⇝ 37/4 | note:Bb4 gain:0.24 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 9/1 ⇜ (591/64 → 37/4) | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 73/8 ⇜ (591/64 → 37/4) | note:C4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.527777777778 ]", + "[ 73/8 ⇜ (591/64 → 37/4) | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 73/8 ⇜ (591/64 → 37/4) | note:Bb4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ (37/4 → 593/64) ⇝ 19/2 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ (37/4 → 593/64) ⇝ 19/2 | note:D4 gain:0.22 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ (37/4 → 593/64) ⇝ 19/2 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ (37/4 → 593/64) ⇝ 19/2 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 37/4 ⇜ (593/64 → 297/32) ⇝ 19/2 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 37/4 ⇜ (593/64 → 297/32) ⇝ 19/2 | note:D4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 37/4 ⇜ (593/64 → 297/32) ⇝ 19/2 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 37/4 ⇜ (593/64 → 297/32) ⇝ 19/2 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 37/4 ⇜ (297/32 → 595/64) ⇝ 19/2 | note:Bb3 gain:0.32 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 37/4 ⇜ (297/32 → 595/64) ⇝ 19/2 | note:D4 gain:0.32 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 37/4 ⇜ (297/32 → 595/64) ⇝ 19/2 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 37/4 ⇜ (297/32 → 595/64) ⇝ 19/2 | note:G4 gain:0.32 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 37/4 ⇜ (595/64 → 149/16) ⇝ 19/2 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 37/4 ⇜ (595/64 → 149/16) ⇝ 19/2 | note:D4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 37/4 ⇜ (595/64 → 149/16) ⇝ 19/2 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 37/4 ⇜ (595/64 → 149/16) ⇝ 19/2 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 37/4 ⇜ (149/16 → 597/64) ⇝ 19/2 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 37/4 ⇜ (149/16 → 597/64) ⇝ 19/2 | note:D4 gain:0.22 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 37/4 ⇜ (149/16 → 597/64) ⇝ 19/2 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 37/4 ⇜ (149/16 → 597/64) ⇝ 19/2 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 37/4 ⇜ (597/64 → 299/32) ⇝ 19/2 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 37/4 ⇜ (597/64 → 299/32) ⇝ 19/2 | note:D4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 37/4 ⇜ (597/64 → 299/32) ⇝ 19/2 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 37/4 ⇜ (597/64 → 299/32) ⇝ 19/2 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 37/4 ⇜ (299/32 → 599/64) ⇝ 19/2 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 37/4 ⇜ (299/32 → 599/64) ⇝ 19/2 | note:D4 gain:0.12 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 37/4 ⇜ (299/32 → 599/64) ⇝ 19/2 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 37/4 ⇜ (299/32 → 599/64) ⇝ 19/2 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 37/4 ⇜ (599/64 → 75/8) ⇝ 19/2 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 37/4 ⇜ (599/64 → 75/8) ⇝ 19/2 | note:D4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 37/4 ⇜ (599/64 → 75/8) ⇝ 19/2 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 37/4 ⇜ (599/64 → 75/8) ⇝ 19/2 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 37/4 ⇜ (75/8 → 601/64) ⇝ 19/2 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 37/4 ⇜ (75/8 → 601/64) ⇝ 19/2 | note:D4 gain:0.22 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 37/4 ⇜ (75/8 → 601/64) ⇝ 19/2 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 37/4 ⇜ (75/8 → 601/64) ⇝ 19/2 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 37/4 ⇜ (601/64 → 301/32) ⇝ 19/2 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 37/4 ⇜ (601/64 → 301/32) ⇝ 19/2 | note:D4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 37/4 ⇜ (601/64 → 301/32) ⇝ 19/2 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 37/4 ⇜ (601/64 → 301/32) ⇝ 19/2 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 37/4 ⇜ (301/32 → 603/64) ⇝ 19/2 | note:Bb3 gain:0.32 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 37/4 ⇜ (301/32 → 603/64) ⇝ 19/2 | note:D4 gain:0.32 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 37/4 ⇜ (301/32 → 603/64) ⇝ 19/2 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 37/4 ⇜ (301/32 → 603/64) ⇝ 19/2 | note:G4 gain:0.32 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 37/4 ⇜ (603/64 → 151/16) ⇝ 19/2 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 37/4 ⇜ (603/64 → 151/16) ⇝ 19/2 | note:D4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 37/4 ⇜ (603/64 → 151/16) ⇝ 19/2 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 37/4 ⇜ (603/64 → 151/16) ⇝ 19/2 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 37/4 ⇜ (151/16 → 605/64) ⇝ 19/2 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 37/4 ⇜ (151/16 → 605/64) ⇝ 19/2 | note:D4 gain:0.22 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 37/4 ⇜ (151/16 → 605/64) ⇝ 19/2 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 37/4 ⇜ (151/16 → 605/64) ⇝ 19/2 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 37/4 ⇜ (605/64 → 303/32) ⇝ 19/2 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 37/4 ⇜ (605/64 → 303/32) ⇝ 19/2 | note:D4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 37/4 ⇜ (605/64 → 303/32) ⇝ 19/2 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 37/4 ⇜ (605/64 → 303/32) ⇝ 19/2 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 37/4 ⇜ (303/32 → 607/64) ⇝ 19/2 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 37/4 ⇜ (303/32 → 607/64) ⇝ 19/2 | note:D4 gain:0.12 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 37/4 ⇜ (303/32 → 607/64) ⇝ 19/2 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 37/4 ⇜ (303/32 → 607/64) ⇝ 19/2 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 37/4 ⇜ (607/64 → 19/2) | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 37/4 ⇜ (607/64 → 19/2) | note:D4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 37/4 ⇜ (607/64 → 19/2) | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 37/4 ⇜ (607/64 → 19/2) | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (19/2 → 609/64) ⇝ 77/8 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (19/2 → 609/64) ⇝ 77/8 | note:D5 gain:0.44 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ (19/2 → 609/64) ⇝ 77/8 | note:F5 gain:0.44 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ (19/2 → 609/64) ⇝ 39/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 19/2 ⇜ (609/64 → 305/32) ⇝ 77/8 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 19/2 ⇜ (609/64 → 305/32) ⇝ 77/8 | note:D5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 19/2 ⇜ (609/64 → 305/32) ⇝ 77/8 | note:F5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 19/2 ⇜ (609/64 → 305/32) ⇝ 39/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 19/2 ⇜ (305/32 → 611/64) ⇝ 77/8 | note:G4 gain:0.64 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 19/2 ⇜ (305/32 → 611/64) ⇝ 77/8 | note:D5 gain:0.64 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 19/2 ⇜ (305/32 → 611/64) ⇝ 77/8 | note:F5 gain:0.64 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 19/2 ⇜ (305/32 → 611/64) ⇝ 39/4 | note:C2 gain:0.64 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ (267/28 → 611/64) ⇝ 137/14 | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ (267/28 → 611/64) ⇝ 137/14 | note:74 gain:0.064 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ (267/28 → 611/64) ⇝ 137/14 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ (267/28 → 611/64) ⇝ 137/14 | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 19/2 ⇜ (611/64 → 153/16) ⇝ 77/8 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 19/2 ⇜ (611/64 → 153/16) ⇝ 77/8 | note:D5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 19/2 ⇜ (611/64 → 153/16) ⇝ 77/8 | note:F5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 19/2 ⇜ (611/64 → 153/16) ⇝ 39/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 267/28 ⇜ (611/64 → 153/16) ⇝ 137/14 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 267/28 ⇜ (611/64 → 153/16) ⇝ 137/14 | note:74 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 267/28 ⇜ (611/64 → 153/16) ⇝ 137/14 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 267/28 ⇜ (611/64 → 153/16) ⇝ 137/14 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 19/2 ⇜ (153/16 → 613/64) ⇝ 77/8 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 19/2 ⇜ (153/16 → 613/64) ⇝ 77/8 | note:D5 gain:0.44 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 19/2 ⇜ (153/16 → 613/64) ⇝ 77/8 | note:F5 gain:0.44 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 19/2 ⇜ (153/16 → 613/64) ⇝ 39/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 267/28 ⇜ (153/16 → 613/64) ⇝ 137/14 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 267/28 ⇜ (153/16 → 613/64) ⇝ 137/14 | note:74 gain:0.044 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 267/28 ⇜ (153/16 → 613/64) ⇝ 137/14 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 267/28 ⇜ (153/16 → 613/64) ⇝ 137/14 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 19/2 ⇜ (613/64 → 307/32) ⇝ 77/8 | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 19/2 ⇜ (613/64 → 307/32) ⇝ 77/8 | note:D5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 19/2 ⇜ (613/64 → 307/32) ⇝ 77/8 | note:F5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 19/2 ⇜ (613/64 → 307/32) ⇝ 39/4 | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 267/28 ⇜ (613/64 → 307/32) ⇝ 137/14 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 267/28 ⇜ (613/64 → 307/32) ⇝ 137/14 | note:74 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 267/28 ⇜ (613/64 → 307/32) ⇝ 137/14 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 267/28 ⇜ (613/64 → 307/32) ⇝ 137/14 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 19/2 ⇜ (307/32 → 615/64) ⇝ 77/8 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 19/2 ⇜ (307/32 → 615/64) ⇝ 77/8 | note:D5 gain:0.24 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 19/2 ⇜ (307/32 → 615/64) ⇝ 77/8 | note:F5 gain:0.24 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 19/2 ⇜ (307/32 → 615/64) ⇝ 39/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 267/28 ⇜ (307/32 → 615/64) ⇝ 137/14 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 267/28 ⇜ (307/32 → 615/64) ⇝ 137/14 | note:74 gain:0.024 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 267/28 ⇜ (307/32 → 615/64) ⇝ 137/14 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 267/28 ⇜ (307/32 → 615/64) ⇝ 137/14 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 19/2 ⇜ (615/64 → 77/8) | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 19/2 ⇜ (615/64 → 77/8) | note:D5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 19/2 ⇜ (615/64 → 77/8) | note:F5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 19/2 ⇜ (615/64 → 77/8) ⇝ 39/4 | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 267/28 ⇜ (615/64 → 77/8) ⇝ 137/14 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 267/28 ⇜ (615/64 → 77/8) ⇝ 137/14 | note:74 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 267/28 ⇜ (615/64 → 77/8) ⇝ 137/14 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 267/28 ⇜ (615/64 → 77/8) ⇝ 137/14 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 19/2 ⇜ (77/8 → 617/64) ⇝ 39/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 267/28 ⇜ (77/8 → 617/64) ⇝ 137/14 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 267/28 ⇜ (77/8 → 617/64) ⇝ 137/14 | note:74 gain:0.044 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 267/28 ⇜ (77/8 → 617/64) ⇝ 137/14 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 267/28 ⇜ (77/8 → 617/64) ⇝ 137/14 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 19/2 ⇜ (617/64 → 309/32) ⇝ 39/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 267/28 ⇜ (617/64 → 309/32) ⇝ 137/14 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 267/28 ⇜ (617/64 → 309/32) ⇝ 137/14 | note:74 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 267/28 ⇜ (617/64 → 309/32) ⇝ 137/14 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 267/28 ⇜ (617/64 → 309/32) ⇝ 137/14 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 19/2 ⇜ (309/32 → 619/64) ⇝ 39/4 | note:C2 gain:0.64 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 267/28 ⇜ (309/32 → 619/64) ⇝ 137/14 | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 267/28 ⇜ (309/32 → 619/64) ⇝ 137/14 | note:74 gain:0.064 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 267/28 ⇜ (309/32 → 619/64) ⇝ 137/14 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 267/28 ⇜ (309/32 → 619/64) ⇝ 137/14 | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 19/2 ⇜ (619/64 → 155/16) ⇝ 39/4 | note:C2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 267/28 ⇜ (619/64 → 155/16) ⇝ 137/14 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 267/28 ⇜ (619/64 → 155/16) ⇝ 137/14 | note:74 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 267/28 ⇜ (619/64 → 155/16) ⇝ 137/14 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 267/28 ⇜ (619/64 → 155/16) ⇝ 137/14 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 19/2 ⇜ (155/16 → 621/64) ⇝ 39/4 | note:C2 gain:0.44 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 267/28 ⇜ (155/16 → 621/64) ⇝ 137/14 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 267/28 ⇜ (155/16 → 621/64) ⇝ 137/14 | note:74 gain:0.044 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 267/28 ⇜ (155/16 → 621/64) ⇝ 137/14 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 267/28 ⇜ (155/16 → 621/64) ⇝ 137/14 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 19/2 ⇜ (621/64 → 311/32) ⇝ 39/4 | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 267/28 ⇜ (621/64 → 311/32) ⇝ 137/14 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 267/28 ⇜ (621/64 → 311/32) ⇝ 137/14 | note:74 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 267/28 ⇜ (621/64 → 311/32) ⇝ 137/14 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 267/28 ⇜ (621/64 → 311/32) ⇝ 137/14 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 19/2 ⇜ (311/32 → 623/64) ⇝ 39/4 | note:C2 gain:0.24 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 267/28 ⇜ (311/32 → 623/64) ⇝ 137/14 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 267/28 ⇜ (311/32 → 623/64) ⇝ 137/14 | note:74 gain:0.024 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 267/28 ⇜ (311/32 → 623/64) ⇝ 137/14 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 267/28 ⇜ (311/32 → 623/64) ⇝ 137/14 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 19/2 ⇜ (623/64 → 39/4) | note:C2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.416666666667 ]", + "[ 267/28 ⇜ (623/64 → 39/4) ⇝ 137/14 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 267/28 ⇜ (623/64 → 39/4) ⇝ 137/14 | note:74 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 267/28 ⇜ (623/64 → 39/4) ⇝ 137/14 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 267/28 ⇜ (623/64 → 39/4) ⇝ 137/14 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 267/28 ⇜ (39/4 → 625/64) ⇝ 137/14 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 267/28 ⇜ (39/4 → 625/64) ⇝ 137/14 | note:74 gain:0.044 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 267/28 ⇜ (39/4 → 625/64) ⇝ 137/14 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 267/28 ⇜ (39/4 → 625/64) ⇝ 137/14 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ (39/4 → 625/64) ⇝ 79/8 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (39/4 → 625/64) ⇝ 79/8 | note:D5 gain:0.44 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ (39/4 → 625/64) ⇝ 79/8 | note:F5 gain:0.44 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ (39/4 → 625/64) ⇝ 10/1 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ (39/4 → 625/64) ⇝ 10/1 | note:D4 gain:0.22 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ (39/4 → 625/64) ⇝ 10/1 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ (39/4 → 625/64) ⇝ 10/1 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 267/28 ⇜ (625/64 → 313/32) ⇝ 137/14 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 267/28 ⇜ (625/64 → 313/32) ⇝ 137/14 | note:74 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 267/28 ⇜ (625/64 → 313/32) ⇝ 137/14 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 267/28 ⇜ (625/64 → 313/32) ⇝ 137/14 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 39/4 ⇜ (625/64 → 313/32) ⇝ 79/8 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 39/4 ⇜ (625/64 → 313/32) ⇝ 79/8 | note:D5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 39/4 ⇜ (625/64 → 313/32) ⇝ 79/8 | note:F5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 39/4 ⇜ (625/64 → 313/32) ⇝ 10/1 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 39/4 ⇜ (625/64 → 313/32) ⇝ 10/1 | note:D4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 39/4 ⇜ (625/64 → 313/32) ⇝ 10/1 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 39/4 ⇜ (625/64 → 313/32) ⇝ 10/1 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 267/28 ⇜ (313/32 → 137/14) | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 267/28 ⇜ (313/32 → 137/14) | note:74 gain:0.064 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 267/28 ⇜ (313/32 → 137/14) | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 267/28 ⇜ (313/32 → 137/14) | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 39/4 ⇜ (313/32 → 627/64) ⇝ 79/8 | note:G4 gain:0.64 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 39/4 ⇜ (313/32 → 627/64) ⇝ 79/8 | note:D5 gain:0.64 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 39/4 ⇜ (313/32 → 627/64) ⇝ 79/8 | note:F5 gain:0.64 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 39/4 ⇜ (313/32 → 627/64) ⇝ 10/1 | note:Bb3 gain:0.32 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 39/4 ⇜ (313/32 → 627/64) ⇝ 10/1 | note:D4 gain:0.32 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 39/4 ⇜ (313/32 → 627/64) ⇝ 10/1 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 39/4 ⇜ (313/32 → 627/64) ⇝ 10/1 | note:G4 gain:0.32 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 39/4 ⇜ (627/64 → 157/16) ⇝ 79/8 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 39/4 ⇜ (627/64 → 157/16) ⇝ 79/8 | note:D5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 39/4 ⇜ (627/64 → 157/16) ⇝ 79/8 | note:F5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 39/4 ⇜ (627/64 → 157/16) ⇝ 10/1 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 39/4 ⇜ (627/64 → 157/16) ⇝ 10/1 | note:D4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 39/4 ⇜ (627/64 → 157/16) ⇝ 10/1 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 39/4 ⇜ (627/64 → 157/16) ⇝ 10/1 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 39/4 ⇜ (157/16 → 629/64) ⇝ 79/8 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 39/4 ⇜ (157/16 → 629/64) ⇝ 79/8 | note:D5 gain:0.44 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 39/4 ⇜ (157/16 → 629/64) ⇝ 79/8 | note:F5 gain:0.44 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 39/4 ⇜ (157/16 → 629/64) ⇝ 10/1 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 39/4 ⇜ (157/16 → 629/64) ⇝ 10/1 | note:D4 gain:0.22 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 39/4 ⇜ (157/16 → 629/64) ⇝ 10/1 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 39/4 ⇜ (157/16 → 629/64) ⇝ 10/1 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 39/4 ⇜ (629/64 → 315/32) ⇝ 79/8 | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 39/4 ⇜ (629/64 → 315/32) ⇝ 79/8 | note:D5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 39/4 ⇜ (629/64 → 315/32) ⇝ 79/8 | note:F5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 39/4 ⇜ (629/64 → 315/32) ⇝ 10/1 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 39/4 ⇜ (629/64 → 315/32) ⇝ 10/1 | note:D4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 39/4 ⇜ (629/64 → 315/32) ⇝ 10/1 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 39/4 ⇜ (629/64 → 315/32) ⇝ 10/1 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 39/4 ⇜ (315/32 → 631/64) ⇝ 79/8 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 39/4 ⇜ (315/32 → 631/64) ⇝ 79/8 | note:D5 gain:0.24 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 39/4 ⇜ (315/32 → 631/64) ⇝ 79/8 | note:F5 gain:0.24 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 39/4 ⇜ (315/32 → 631/64) ⇝ 10/1 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 39/4 ⇜ (315/32 → 631/64) ⇝ 10/1 | note:D4 gain:0.12 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 39/4 ⇜ (315/32 → 631/64) ⇝ 10/1 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 39/4 ⇜ (315/32 → 631/64) ⇝ 10/1 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 39/4 ⇜ (631/64 → 79/8) | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 39/4 ⇜ (631/64 → 79/8) | note:D5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 39/4 ⇜ (631/64 → 79/8) | note:F5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 39/4 ⇜ (631/64 → 79/8) ⇝ 10/1 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 39/4 ⇜ (631/64 → 79/8) ⇝ 10/1 | note:D4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 39/4 ⇜ (631/64 → 79/8) ⇝ 10/1 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 39/4 ⇜ (631/64 → 79/8) ⇝ 10/1 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 39/4 ⇜ (79/8 → 633/64) ⇝ 10/1 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 39/4 ⇜ (79/8 → 633/64) ⇝ 10/1 | note:D4 gain:0.22 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 39/4 ⇜ (79/8 → 633/64) ⇝ 10/1 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 39/4 ⇜ (79/8 → 633/64) ⇝ 10/1 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 39/4 ⇜ (633/64 → 317/32) ⇝ 10/1 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 39/4 ⇜ (633/64 → 317/32) ⇝ 10/1 | note:D4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 39/4 ⇜ (633/64 → 317/32) ⇝ 10/1 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 39/4 ⇜ (633/64 → 317/32) ⇝ 10/1 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 39/4 ⇜ (317/32 → 635/64) ⇝ 10/1 | note:Bb3 gain:0.32 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 39/4 ⇜ (317/32 → 635/64) ⇝ 10/1 | note:D4 gain:0.32 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 39/4 ⇜ (317/32 → 635/64) ⇝ 10/1 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 39/4 ⇜ (317/32 → 635/64) ⇝ 10/1 | note:G4 gain:0.32 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 39/4 ⇜ (635/64 → 159/16) ⇝ 10/1 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 39/4 ⇜ (635/64 → 159/16) ⇝ 10/1 | note:D4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 39/4 ⇜ (635/64 → 159/16) ⇝ 10/1 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 39/4 ⇜ (635/64 → 159/16) ⇝ 10/1 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 39/4 ⇜ (159/16 → 637/64) ⇝ 10/1 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 39/4 ⇜ (159/16 → 637/64) ⇝ 10/1 | note:D4 gain:0.22 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 39/4 ⇜ (159/16 → 637/64) ⇝ 10/1 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 39/4 ⇜ (159/16 → 637/64) ⇝ 10/1 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 39/4 ⇜ (637/64 → 319/32) ⇝ 10/1 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 39/4 ⇜ (637/64 → 319/32) ⇝ 10/1 | note:D4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 39/4 ⇜ (637/64 → 319/32) ⇝ 10/1 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 39/4 ⇜ (637/64 → 319/32) ⇝ 10/1 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 39/4 ⇜ (319/32 → 639/64) ⇝ 10/1 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 39/4 ⇜ (319/32 → 639/64) ⇝ 10/1 | note:D4 gain:0.12 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 39/4 ⇜ (319/32 → 639/64) ⇝ 10/1 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 39/4 ⇜ (319/32 → 639/64) ⇝ 10/1 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 39/4 ⇜ (639/64 → 10/1) | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 39/4 ⇜ (639/64 → 10/1) | note:D4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.537037037037 ]", + "[ 39/4 ⇜ (639/64 → 10/1) | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 39/4 ⇜ (639/64 → 10/1) | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (10/1 → 641/64) ⇝ 41/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 10/1 ⇜ (641/64 → 321/32) ⇝ 41/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 10/1 ⇜ (321/32 → 643/64) ⇝ 41/4 | note:F2 gain:0.64 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ (281/28 → 643/64) ⇝ 72/7 | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ (281/28 → 643/64) ⇝ 72/7 | note:74 gain:0.064 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ (281/28 → 643/64) ⇝ 72/7 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ (281/28 → 643/64) ⇝ 72/7 | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 10/1 ⇜ (643/64 → 161/16) ⇝ 41/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 281/28 ⇜ (643/64 → 161/16) ⇝ 72/7 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 281/28 ⇜ (643/64 → 161/16) ⇝ 72/7 | note:74 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 281/28 ⇜ (643/64 → 161/16) ⇝ 72/7 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 281/28 ⇜ (643/64 → 161/16) ⇝ 72/7 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 10/1 ⇜ (161/16 → 645/64) ⇝ 41/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 281/28 ⇜ (161/16 → 645/64) ⇝ 72/7 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 281/28 ⇜ (161/16 → 645/64) ⇝ 72/7 | note:74 gain:0.044 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 281/28 ⇜ (161/16 → 645/64) ⇝ 72/7 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 281/28 ⇜ (161/16 → 645/64) ⇝ 72/7 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 10/1 ⇜ (645/64 → 323/32) ⇝ 41/4 | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 281/28 ⇜ (645/64 → 323/32) ⇝ 72/7 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 281/28 ⇜ (645/64 → 323/32) ⇝ 72/7 | note:74 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 281/28 ⇜ (645/64 → 323/32) ⇝ 72/7 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 281/28 ⇜ (645/64 → 323/32) ⇝ 72/7 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 10/1 ⇜ (323/32 → 647/64) ⇝ 41/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 281/28 ⇜ (323/32 → 647/64) ⇝ 72/7 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 281/28 ⇜ (323/32 → 647/64) ⇝ 72/7 | note:74 gain:0.024 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 281/28 ⇜ (323/32 → 647/64) ⇝ 72/7 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 281/28 ⇜ (323/32 → 647/64) ⇝ 72/7 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 10/1 ⇜ (647/64 → 81/8) ⇝ 41/4 | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 281/28 ⇜ (647/64 → 81/8) ⇝ 72/7 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 281/28 ⇜ (647/64 → 81/8) ⇝ 72/7 | note:74 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 281/28 ⇜ (647/64 → 81/8) ⇝ 72/7 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 281/28 ⇜ (647/64 → 81/8) ⇝ 72/7 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 10/1 ⇜ (81/8 → 649/64) ⇝ 41/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 281/28 ⇜ (81/8 → 649/64) ⇝ 72/7 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 281/28 ⇜ (81/8 → 649/64) ⇝ 72/7 | note:74 gain:0.044 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 281/28 ⇜ (81/8 → 649/64) ⇝ 72/7 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 281/28 ⇜ (81/8 → 649/64) ⇝ 72/7 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ (81/8 → 649/64) ⇝ 41/4 | note:F4 gain:0.44 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ (81/8 → 649/64) ⇝ 41/4 | note:C5 gain:0.44 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ (81/8 → 649/64) ⇝ 41/4 | note:Eb5 gain:0.44 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 10/1 ⇜ (649/64 → 325/32) ⇝ 41/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 281/28 ⇜ (649/64 → 325/32) ⇝ 72/7 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 281/28 ⇜ (649/64 → 325/32) ⇝ 72/7 | note:74 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 281/28 ⇜ (649/64 → 325/32) ⇝ 72/7 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 281/28 ⇜ (649/64 → 325/32) ⇝ 72/7 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 81/8 ⇜ (649/64 → 325/32) ⇝ 41/4 | note:F4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 81/8 ⇜ (649/64 → 325/32) ⇝ 41/4 | note:C5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 81/8 ⇜ (649/64 → 325/32) ⇝ 41/4 | note:Eb5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 10/1 ⇜ (325/32 → 651/64) ⇝ 41/4 | note:F2 gain:0.64 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 281/28 ⇜ (325/32 → 651/64) ⇝ 72/7 | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 281/28 ⇜ (325/32 → 651/64) ⇝ 72/7 | note:74 gain:0.064 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 281/28 ⇜ (325/32 → 651/64) ⇝ 72/7 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 281/28 ⇜ (325/32 → 651/64) ⇝ 72/7 | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 81/8 ⇜ (325/32 → 651/64) ⇝ 41/4 | note:F4 gain:0.64 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 81/8 ⇜ (325/32 → 651/64) ⇝ 41/4 | note:C5 gain:0.64 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 81/8 ⇜ (325/32 → 651/64) ⇝ 41/4 | note:Eb5 gain:0.64 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 10/1 ⇜ (651/64 → 163/16) ⇝ 41/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 281/28 ⇜ (651/64 → 163/16) ⇝ 72/7 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 281/28 ⇜ (651/64 → 163/16) ⇝ 72/7 | note:74 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 281/28 ⇜ (651/64 → 163/16) ⇝ 72/7 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 281/28 ⇜ (651/64 → 163/16) ⇝ 72/7 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 81/8 ⇜ (651/64 → 163/16) ⇝ 41/4 | note:F4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 81/8 ⇜ (651/64 → 163/16) ⇝ 41/4 | note:C5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 81/8 ⇜ (651/64 → 163/16) ⇝ 41/4 | note:Eb5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 10/1 ⇜ (163/16 → 653/64) ⇝ 41/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 281/28 ⇜ (163/16 → 653/64) ⇝ 72/7 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 281/28 ⇜ (163/16 → 653/64) ⇝ 72/7 | note:74 gain:0.044 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 281/28 ⇜ (163/16 → 653/64) ⇝ 72/7 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 281/28 ⇜ (163/16 → 653/64) ⇝ 72/7 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 81/8 ⇜ (163/16 → 653/64) ⇝ 41/4 | note:F4 gain:0.44 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 81/8 ⇜ (163/16 → 653/64) ⇝ 41/4 | note:C5 gain:0.44 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 81/8 ⇜ (163/16 → 653/64) ⇝ 41/4 | note:Eb5 gain:0.44 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 10/1 ⇜ (653/64 → 327/32) ⇝ 41/4 | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 281/28 ⇜ (653/64 → 327/32) ⇝ 72/7 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 281/28 ⇜ (653/64 → 327/32) ⇝ 72/7 | note:74 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 281/28 ⇜ (653/64 → 327/32) ⇝ 72/7 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 281/28 ⇜ (653/64 → 327/32) ⇝ 72/7 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 81/8 ⇜ (653/64 → 327/32) ⇝ 41/4 | note:F4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 81/8 ⇜ (653/64 → 327/32) ⇝ 41/4 | note:C5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 81/8 ⇜ (653/64 → 327/32) ⇝ 41/4 | note:Eb5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 10/1 ⇜ (327/32 → 655/64) ⇝ 41/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 281/28 ⇜ (327/32 → 655/64) ⇝ 72/7 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 281/28 ⇜ (327/32 → 655/64) ⇝ 72/7 | note:74 gain:0.024 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 281/28 ⇜ (327/32 → 655/64) ⇝ 72/7 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 281/28 ⇜ (327/32 → 655/64) ⇝ 72/7 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 81/8 ⇜ (327/32 → 655/64) ⇝ 41/4 | note:F4 gain:0.24 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 81/8 ⇜ (327/32 → 655/64) ⇝ 41/4 | note:C5 gain:0.24 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 81/8 ⇜ (327/32 → 655/64) ⇝ 41/4 | note:Eb5 gain:0.24 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 10/1 ⇜ (655/64 → 41/4) | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 281/28 ⇜ (655/64 → 41/4) ⇝ 72/7 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 281/28 ⇜ (655/64 → 41/4) ⇝ 72/7 | note:74 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 281/28 ⇜ (655/64 → 41/4) ⇝ 72/7 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 281/28 ⇜ (655/64 → 41/4) ⇝ 72/7 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 81/8 ⇜ (655/64 → 41/4) | note:F4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 81/8 ⇜ (655/64 → 41/4) | note:C5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 81/8 ⇜ (655/64 → 41/4) | note:Eb5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 281/28 ⇜ (41/4 → 657/64) ⇝ 72/7 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 281/28 ⇜ (41/4 → 657/64) ⇝ 72/7 | note:74 gain:0.044 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 281/28 ⇜ (41/4 → 657/64) ⇝ 72/7 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 281/28 ⇜ (41/4 → 657/64) ⇝ 72/7 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 281/28 ⇜ (657/64 → 329/32) ⇝ 72/7 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 281/28 ⇜ (657/64 → 329/32) ⇝ 72/7 | note:74 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 281/28 ⇜ (657/64 → 329/32) ⇝ 72/7 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 281/28 ⇜ (657/64 → 329/32) ⇝ 72/7 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 281/28 ⇜ (329/32 → 72/7) | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 281/28 ⇜ (329/32 → 72/7) | note:74 gain:0.064 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 281/28 ⇜ (329/32 → 72/7) | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 281/28 ⇜ (329/32 → 72/7) | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ (21/2 → 673/64) ⇝ 85/8 | note:C5 gain:0.44 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ (21/2 → 673/64) ⇝ 85/8 | note:G5 gain:0.44 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ (21/2 → 673/64) ⇝ 85/8 | note:Bb5 gain:0.44 clip:1 s:piano release:0.1 pan:0.62962962963 ]", + "[ (21/2 → 673/64) ⇝ 43/4 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ (21/2 → 673/64) ⇝ 43/4 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (21/2 → 673/64) ⇝ 43/4 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ (21/2 → 673/64) ⇝ 43/4 | note:C5 gain:0.22 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ (21/2 → 673/64) ⇝ 43/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 21/2 ⇜ (673/64 → 337/32) ⇝ 85/8 | note:C5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 21/2 ⇜ (673/64 → 337/32) ⇝ 85/8 | note:G5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 21/2 ⇜ (673/64 → 337/32) ⇝ 85/8 | note:Bb5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.62962962963 ]", + "[ 21/2 ⇜ (673/64 → 337/32) ⇝ 43/4 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 21/2 ⇜ (673/64 → 337/32) ⇝ 43/4 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 21/2 ⇜ (673/64 → 337/32) ⇝ 43/4 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 21/2 ⇜ (673/64 → 337/32) ⇝ 43/4 | note:C5 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 21/2 ⇜ (673/64 → 337/32) ⇝ 43/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 21/2 ⇜ (337/32 → 675/64) ⇝ 85/8 | note:C5 gain:0.64 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 21/2 ⇜ (337/32 → 675/64) ⇝ 85/8 | note:G5 gain:0.64 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 21/2 ⇜ (337/32 → 675/64) ⇝ 85/8 | note:Bb5 gain:0.64 clip:1 s:piano release:0.1 pan:0.62962962963 ]", + "[ 21/2 ⇜ (337/32 → 675/64) ⇝ 43/4 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 21/2 ⇜ (337/32 → 675/64) ⇝ 43/4 | note:G4 gain:0.32 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 21/2 ⇜ (337/32 → 675/64) ⇝ 43/4 | note:Ab4 gain:0.32 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 21/2 ⇜ (337/32 → 675/64) ⇝ 43/4 | note:C5 gain:0.32 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 21/2 ⇜ (337/32 → 675/64) ⇝ 43/4 | note:F2 gain:0.64 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 21/2 ⇜ (675/64 → 169/16) ⇝ 85/8 | note:C5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 21/2 ⇜ (675/64 → 169/16) ⇝ 85/8 | note:G5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 21/2 ⇜ (675/64 → 169/16) ⇝ 85/8 | note:Bb5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.62962962963 ]", + "[ 21/2 ⇜ (675/64 → 169/16) ⇝ 43/4 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 21/2 ⇜ (675/64 → 169/16) ⇝ 43/4 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 21/2 ⇜ (675/64 → 169/16) ⇝ 43/4 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 21/2 ⇜ (675/64 → 169/16) ⇝ 43/4 | note:C5 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 21/2 ⇜ (675/64 → 169/16) ⇝ 43/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 21/2 ⇜ (169/16 → 677/64) ⇝ 85/8 | note:C5 gain:0.44 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 21/2 ⇜ (169/16 → 677/64) ⇝ 85/8 | note:G5 gain:0.44 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 21/2 ⇜ (169/16 → 677/64) ⇝ 85/8 | note:Bb5 gain:0.44 clip:1 s:piano release:0.1 pan:0.62962962963 ]", + "[ 21/2 ⇜ (169/16 → 677/64) ⇝ 43/4 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 21/2 ⇜ (169/16 → 677/64) ⇝ 43/4 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 21/2 ⇜ (169/16 → 677/64) ⇝ 43/4 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 21/2 ⇜ (169/16 → 677/64) ⇝ 43/4 | note:C5 gain:0.22 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 21/2 ⇜ (169/16 → 677/64) ⇝ 43/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 21/2 ⇜ (677/64 → 339/32) ⇝ 85/8 | note:C5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 21/2 ⇜ (677/64 → 339/32) ⇝ 85/8 | note:G5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 21/2 ⇜ (677/64 → 339/32) ⇝ 85/8 | note:Bb5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.62962962963 ]", + "[ 21/2 ⇜ (677/64 → 339/32) ⇝ 43/4 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 21/2 ⇜ (677/64 → 339/32) ⇝ 43/4 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 21/2 ⇜ (677/64 → 339/32) ⇝ 43/4 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 21/2 ⇜ (677/64 → 339/32) ⇝ 43/4 | note:C5 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 21/2 ⇜ (677/64 → 339/32) ⇝ 43/4 | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 21/2 ⇜ (339/32 → 679/64) ⇝ 85/8 | note:C5 gain:0.24 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 21/2 ⇜ (339/32 → 679/64) ⇝ 85/8 | note:G5 gain:0.24 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 21/2 ⇜ (339/32 → 679/64) ⇝ 85/8 | note:Bb5 gain:0.24 clip:1 s:piano release:0.1 pan:0.62962962963 ]", + "[ 21/2 ⇜ (339/32 → 679/64) ⇝ 43/4 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 21/2 ⇜ (339/32 → 679/64) ⇝ 43/4 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 21/2 ⇜ (339/32 → 679/64) ⇝ 43/4 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 21/2 ⇜ (339/32 → 679/64) ⇝ 43/4 | note:C5 gain:0.12 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 21/2 ⇜ (339/32 → 679/64) ⇝ 43/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 21/2 ⇜ (679/64 → 85/8) | note:C5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 21/2 ⇜ (679/64 → 85/8) | note:G5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 21/2 ⇜ (679/64 → 85/8) | note:Bb5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.62962962963 ]", + "[ 21/2 ⇜ (679/64 → 85/8) ⇝ 43/4 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 21/2 ⇜ (679/64 → 85/8) ⇝ 43/4 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 21/2 ⇜ (679/64 → 85/8) ⇝ 43/4 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 21/2 ⇜ (679/64 → 85/8) ⇝ 43/4 | note:C5 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 21/2 ⇜ (679/64 → 85/8) ⇝ 43/4 | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 21/2 ⇜ (85/8 → 681/64) ⇝ 43/4 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 21/2 ⇜ (85/8 → 681/64) ⇝ 43/4 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 21/2 ⇜ (85/8 → 681/64) ⇝ 43/4 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 21/2 ⇜ (85/8 → 681/64) ⇝ 43/4 | note:C5 gain:0.22 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 21/2 ⇜ (85/8 → 681/64) ⇝ 43/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 21/2 ⇜ (681/64 → 341/32) ⇝ 43/4 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 21/2 ⇜ (681/64 → 341/32) ⇝ 43/4 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 21/2 ⇜ (681/64 → 341/32) ⇝ 43/4 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 21/2 ⇜ (681/64 → 341/32) ⇝ 43/4 | note:C5 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 21/2 ⇜ (681/64 → 341/32) ⇝ 43/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 21/2 ⇜ (341/32 → 683/64) ⇝ 43/4 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 21/2 ⇜ (341/32 → 683/64) ⇝ 43/4 | note:G4 gain:0.32 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 21/2 ⇜ (341/32 → 683/64) ⇝ 43/4 | note:Ab4 gain:0.32 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 21/2 ⇜ (341/32 → 683/64) ⇝ 43/4 | note:C5 gain:0.32 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 21/2 ⇜ (341/32 → 683/64) ⇝ 43/4 | note:F2 gain:0.64 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 21/2 ⇜ (683/64 → 171/16) ⇝ 43/4 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 21/2 ⇜ (683/64 → 171/16) ⇝ 43/4 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 21/2 ⇜ (683/64 → 171/16) ⇝ 43/4 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 21/2 ⇜ (683/64 → 171/16) ⇝ 43/4 | note:C5 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 21/2 ⇜ (683/64 → 171/16) ⇝ 43/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 21/2 ⇜ (171/16 → 685/64) ⇝ 43/4 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 21/2 ⇜ (171/16 → 685/64) ⇝ 43/4 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 21/2 ⇜ (171/16 → 685/64) ⇝ 43/4 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 21/2 ⇜ (171/16 → 685/64) ⇝ 43/4 | note:C5 gain:0.22 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 21/2 ⇜ (171/16 → 685/64) ⇝ 43/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 21/2 ⇜ (685/64 → 343/32) ⇝ 43/4 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 21/2 ⇜ (685/64 → 343/32) ⇝ 43/4 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 21/2 ⇜ (685/64 → 343/32) ⇝ 43/4 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 21/2 ⇜ (685/64 → 343/32) ⇝ 43/4 | note:C5 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 21/2 ⇜ (685/64 → 343/32) ⇝ 43/4 | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 21/2 ⇜ (343/32 → 687/64) ⇝ 43/4 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 21/2 ⇜ (343/32 → 687/64) ⇝ 43/4 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 21/2 ⇜ (343/32 → 687/64) ⇝ 43/4 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 21/2 ⇜ (343/32 → 687/64) ⇝ 43/4 | note:C5 gain:0.12 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 21/2 ⇜ (343/32 → 687/64) ⇝ 43/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 21/2 ⇜ (687/64 → 43/4) | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 21/2 ⇜ (687/64 → 43/4) | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 21/2 ⇜ (687/64 → 43/4) | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 21/2 ⇜ (687/64 → 43/4) | note:C5 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 21/2 ⇜ (687/64 → 43/4) | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ (43/4 → 689/64) ⇝ 87/8 | note:F4 gain:0.44 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ (43/4 → 689/64) ⇝ 87/8 | note:C5 gain:0.44 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ (43/4 → 689/64) ⇝ 87/8 | note:Eb5 gain:0.44 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 43/4 ⇜ (689/64 → 345/32) ⇝ 87/8 | note:F4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 43/4 ⇜ (689/64 → 345/32) ⇝ 87/8 | note:C5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 43/4 ⇜ (689/64 → 345/32) ⇝ 87/8 | note:Eb5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 43/4 ⇜ (345/32 → 691/64) ⇝ 87/8 | note:F4 gain:0.64 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 43/4 ⇜ (345/32 → 691/64) ⇝ 87/8 | note:C5 gain:0.64 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 43/4 ⇜ (345/32 → 691/64) ⇝ 87/8 | note:Eb5 gain:0.64 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ (151/14 → 691/64) ⇝ 309/28 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ (151/14 → 691/64) ⇝ 309/28 | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ (151/14 → 691/64) ⇝ 309/28 | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ (151/14 → 691/64) ⇝ 309/28 | note:84 gain:0.064 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 43/4 ⇜ (691/64 → 173/16) ⇝ 87/8 | note:F4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 43/4 ⇜ (691/64 → 173/16) ⇝ 87/8 | note:C5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 43/4 ⇜ (691/64 → 173/16) ⇝ 87/8 | note:Eb5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 151/14 ⇜ (691/64 → 173/16) ⇝ 309/28 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 151/14 ⇜ (691/64 → 173/16) ⇝ 309/28 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 151/14 ⇜ (691/64 → 173/16) ⇝ 309/28 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 151/14 ⇜ (691/64 → 173/16) ⇝ 309/28 | note:84 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 43/4 ⇜ (173/16 → 693/64) ⇝ 87/8 | note:F4 gain:0.44 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 43/4 ⇜ (173/16 → 693/64) ⇝ 87/8 | note:C5 gain:0.44 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 43/4 ⇜ (173/16 → 693/64) ⇝ 87/8 | note:Eb5 gain:0.44 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 151/14 ⇜ (173/16 → 693/64) ⇝ 309/28 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 151/14 ⇜ (173/16 → 693/64) ⇝ 309/28 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 151/14 ⇜ (173/16 → 693/64) ⇝ 309/28 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 151/14 ⇜ (173/16 → 693/64) ⇝ 309/28 | note:84 gain:0.044 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 43/4 ⇜ (693/64 → 347/32) ⇝ 87/8 | note:F4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 43/4 ⇜ (693/64 → 347/32) ⇝ 87/8 | note:C5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 43/4 ⇜ (693/64 → 347/32) ⇝ 87/8 | note:Eb5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 151/14 ⇜ (693/64 → 347/32) ⇝ 309/28 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 151/14 ⇜ (693/64 → 347/32) ⇝ 309/28 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 151/14 ⇜ (693/64 → 347/32) ⇝ 309/28 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 151/14 ⇜ (693/64 → 347/32) ⇝ 309/28 | note:84 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 43/4 ⇜ (347/32 → 695/64) ⇝ 87/8 | note:F4 gain:0.24 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 43/4 ⇜ (347/32 → 695/64) ⇝ 87/8 | note:C5 gain:0.24 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 43/4 ⇜ (347/32 → 695/64) ⇝ 87/8 | note:Eb5 gain:0.24 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 151/14 ⇜ (347/32 → 695/64) ⇝ 309/28 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 151/14 ⇜ (347/32 → 695/64) ⇝ 309/28 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 151/14 ⇜ (347/32 → 695/64) ⇝ 309/28 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 151/14 ⇜ (347/32 → 695/64) ⇝ 309/28 | note:84 gain:0.024 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 43/4 ⇜ (695/64 → 87/8) | note:F4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 43/4 ⇜ (695/64 → 87/8) | note:C5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 43/4 ⇜ (695/64 → 87/8) | note:Eb5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 151/14 ⇜ (695/64 → 87/8) ⇝ 309/28 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 151/14 ⇜ (695/64 → 87/8) ⇝ 309/28 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 151/14 ⇜ (695/64 → 87/8) ⇝ 309/28 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 151/14 ⇜ (695/64 → 87/8) ⇝ 309/28 | note:84 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 151/14 ⇜ (87/8 → 697/64) ⇝ 309/28 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 151/14 ⇜ (87/8 → 697/64) ⇝ 309/28 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 151/14 ⇜ (87/8 → 697/64) ⇝ 309/28 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 151/14 ⇜ (87/8 → 697/64) ⇝ 309/28 | note:84 gain:0.044 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 151/14 ⇜ (697/64 → 349/32) ⇝ 309/28 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 151/14 ⇜ (697/64 → 349/32) ⇝ 309/28 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 151/14 ⇜ (697/64 → 349/32) ⇝ 309/28 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 151/14 ⇜ (697/64 → 349/32) ⇝ 309/28 | note:84 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 151/14 ⇜ (349/32 → 699/64) ⇝ 309/28 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 151/14 ⇜ (349/32 → 699/64) ⇝ 309/28 | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 151/14 ⇜ (349/32 → 699/64) ⇝ 309/28 | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 151/14 ⇜ (349/32 → 699/64) ⇝ 309/28 | note:84 gain:0.064 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 151/14 ⇜ (699/64 → 175/16) ⇝ 309/28 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 151/14 ⇜ (699/64 → 175/16) ⇝ 309/28 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 151/14 ⇜ (699/64 → 175/16) ⇝ 309/28 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 151/14 ⇜ (699/64 → 175/16) ⇝ 309/28 | note:84 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 151/14 ⇜ (175/16 → 701/64) ⇝ 309/28 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 151/14 ⇜ (175/16 → 701/64) ⇝ 309/28 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 151/14 ⇜ (175/16 → 701/64) ⇝ 309/28 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 151/14 ⇜ (175/16 → 701/64) ⇝ 309/28 | note:84 gain:0.044 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 151/14 ⇜ (701/64 → 351/32) ⇝ 309/28 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 151/14 ⇜ (701/64 → 351/32) ⇝ 309/28 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 151/14 ⇜ (701/64 → 351/32) ⇝ 309/28 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 151/14 ⇜ (701/64 → 351/32) ⇝ 309/28 | note:84 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 151/14 ⇜ (351/32 → 703/64) ⇝ 309/28 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 151/14 ⇜ (351/32 → 703/64) ⇝ 309/28 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 151/14 ⇜ (351/32 → 703/64) ⇝ 309/28 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 151/14 ⇜ (351/32 → 703/64) ⇝ 309/28 | note:84 gain:0.024 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 151/14 ⇜ (703/64 → 11/1) ⇝ 309/28 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 151/14 ⇜ (703/64 → 11/1) ⇝ 309/28 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 151/14 ⇜ (703/64 → 11/1) ⇝ 309/28 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 151/14 ⇜ (703/64 → 11/1) ⇝ 309/28 | note:84 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 151/14 ⇜ (11/1 → 705/64) ⇝ 309/28 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 151/14 ⇜ (11/1 → 705/64) ⇝ 309/28 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 151/14 ⇜ (11/1 → 705/64) ⇝ 309/28 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 151/14 ⇜ (11/1 → 705/64) ⇝ 309/28 | note:84 gain:0.044 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ (11/1 → 705/64) ⇝ 45/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 151/14 ⇜ (705/64 → 353/32) ⇝ 309/28 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 151/14 ⇜ (705/64 → 353/32) ⇝ 309/28 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 151/14 ⇜ (705/64 → 353/32) ⇝ 309/28 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 151/14 ⇜ (705/64 → 353/32) ⇝ 309/28 | note:84 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 11/1 ⇜ (705/64 → 353/32) ⇝ 45/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 151/14 ⇜ (353/32 → 309/28) | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 151/14 ⇜ (353/32 → 309/28) | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 151/14 ⇜ (353/32 → 309/28) | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 151/14 ⇜ (353/32 → 309/28) | note:84 gain:0.064 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 11/1 ⇜ (353/32 → 707/64) ⇝ 45/4 | note:F2 gain:0.64 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 11/1 ⇜ (707/64 → 177/16) ⇝ 45/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 11/1 ⇜ (177/16 → 709/64) ⇝ 45/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 11/1 ⇜ (709/64 → 355/32) ⇝ 45/4 | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 11/1 ⇜ (355/32 → 711/64) ⇝ 45/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 11/1 ⇜ (711/64 → 89/8) ⇝ 45/4 | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 11/1 ⇜ (89/8 → 713/64) ⇝ 45/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ (89/8 → 713/64) ⇝ 45/4 | note:F4 gain:0.44 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ (89/8 → 713/64) ⇝ 45/4 | note:C5 gain:0.44 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ (89/8 → 713/64) ⇝ 45/4 | note:Eb5 gain:0.44 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 11/1 ⇜ (713/64 → 357/32) ⇝ 45/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 89/8 ⇜ (713/64 → 357/32) ⇝ 45/4 | note:F4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 89/8 ⇜ (713/64 → 357/32) ⇝ 45/4 | note:C5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 89/8 ⇜ (713/64 → 357/32) ⇝ 45/4 | note:Eb5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 11/1 ⇜ (357/32 → 715/64) ⇝ 45/4 | note:F2 gain:0.64 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 89/8 ⇜ (357/32 → 715/64) ⇝ 45/4 | note:F4 gain:0.64 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 89/8 ⇜ (357/32 → 715/64) ⇝ 45/4 | note:C5 gain:0.64 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 89/8 ⇜ (357/32 → 715/64) ⇝ 45/4 | note:Eb5 gain:0.64 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 11/1 ⇜ (715/64 → 179/16) ⇝ 45/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 89/8 ⇜ (715/64 → 179/16) ⇝ 45/4 | note:F4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 89/8 ⇜ (715/64 → 179/16) ⇝ 45/4 | note:C5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 89/8 ⇜ (715/64 → 179/16) ⇝ 45/4 | note:Eb5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 11/1 ⇜ (179/16 → 717/64) ⇝ 45/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 89/8 ⇜ (179/16 → 717/64) ⇝ 45/4 | note:F4 gain:0.44 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 89/8 ⇜ (179/16 → 717/64) ⇝ 45/4 | note:C5 gain:0.44 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 89/8 ⇜ (179/16 → 717/64) ⇝ 45/4 | note:Eb5 gain:0.44 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 11/1 ⇜ (717/64 → 359/32) ⇝ 45/4 | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 89/8 ⇜ (717/64 → 359/32) ⇝ 45/4 | note:F4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 89/8 ⇜ (717/64 → 359/32) ⇝ 45/4 | note:C5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 89/8 ⇜ (717/64 → 359/32) ⇝ 45/4 | note:Eb5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 11/1 ⇜ (359/32 → 719/64) ⇝ 45/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 89/8 ⇜ (359/32 → 719/64) ⇝ 45/4 | note:F4 gain:0.24 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 89/8 ⇜ (359/32 → 719/64) ⇝ 45/4 | note:C5 gain:0.24 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 89/8 ⇜ (359/32 → 719/64) ⇝ 45/4 | note:Eb5 gain:0.24 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 11/1 ⇜ (719/64 → 45/4) | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 89/8 ⇜ (719/64 → 45/4) | note:F4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 89/8 ⇜ (719/64 → 45/4) | note:C5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 89/8 ⇜ (719/64 → 45/4) | note:Eb5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ (45/4 → 721/64) ⇝ 23/2 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ (45/4 → 721/64) ⇝ 23/2 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (45/4 → 721/64) ⇝ 23/2 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ (45/4 → 721/64) ⇝ 23/2 | note:C5 gain:0.22 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 45/4 ⇜ (721/64 → 361/32) ⇝ 23/2 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 45/4 ⇜ (721/64 → 361/32) ⇝ 23/2 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 45/4 ⇜ (721/64 → 361/32) ⇝ 23/2 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 45/4 ⇜ (721/64 → 361/32) ⇝ 23/2 | note:C5 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 45/4 ⇜ (361/32 → 723/64) ⇝ 23/2 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 45/4 ⇜ (361/32 → 723/64) ⇝ 23/2 | note:G4 gain:0.32 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 45/4 ⇜ (361/32 → 723/64) ⇝ 23/2 | note:Ab4 gain:0.32 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 45/4 ⇜ (361/32 → 723/64) ⇝ 23/2 | note:C5 gain:0.32 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 45/4 ⇜ (723/64 → 181/16) ⇝ 23/2 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 45/4 ⇜ (723/64 → 181/16) ⇝ 23/2 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 45/4 ⇜ (723/64 → 181/16) ⇝ 23/2 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 45/4 ⇜ (723/64 → 181/16) ⇝ 23/2 | note:C5 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 45/4 ⇜ (181/16 → 725/64) ⇝ 23/2 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 45/4 ⇜ (181/16 → 725/64) ⇝ 23/2 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 45/4 ⇜ (181/16 → 725/64) ⇝ 23/2 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 45/4 ⇜ (181/16 → 725/64) ⇝ 23/2 | note:C5 gain:0.22 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 45/4 ⇜ (725/64 → 363/32) ⇝ 23/2 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 45/4 ⇜ (725/64 → 363/32) ⇝ 23/2 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 45/4 ⇜ (725/64 → 363/32) ⇝ 23/2 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 45/4 ⇜ (725/64 → 363/32) ⇝ 23/2 | note:C5 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 45/4 ⇜ (363/32 → 727/64) ⇝ 23/2 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 45/4 ⇜ (363/32 → 727/64) ⇝ 23/2 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 45/4 ⇜ (363/32 → 727/64) ⇝ 23/2 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 45/4 ⇜ (363/32 → 727/64) ⇝ 23/2 | note:C5 gain:0.12 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 45/4 ⇜ (727/64 → 91/8) ⇝ 23/2 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 45/4 ⇜ (727/64 → 91/8) ⇝ 23/2 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 45/4 ⇜ (727/64 → 91/8) ⇝ 23/2 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 45/4 ⇜ (727/64 → 91/8) ⇝ 23/2 | note:C5 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 45/4 ⇜ (91/8 → 729/64) ⇝ 23/2 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 45/4 ⇜ (91/8 → 729/64) ⇝ 23/2 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 45/4 ⇜ (91/8 → 729/64) ⇝ 23/2 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 45/4 ⇜ (91/8 → 729/64) ⇝ 23/2 | note:C5 gain:0.22 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 45/4 ⇜ (729/64 → 365/32) ⇝ 23/2 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 45/4 ⇜ (729/64 → 365/32) ⇝ 23/2 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 45/4 ⇜ (729/64 → 365/32) ⇝ 23/2 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 45/4 ⇜ (729/64 → 365/32) ⇝ 23/2 | note:C5 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 45/4 ⇜ (365/32 → 731/64) ⇝ 23/2 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 45/4 ⇜ (365/32 → 731/64) ⇝ 23/2 | note:G4 gain:0.32 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 45/4 ⇜ (365/32 → 731/64) ⇝ 23/2 | note:Ab4 gain:0.32 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 45/4 ⇜ (365/32 → 731/64) ⇝ 23/2 | note:C5 gain:0.32 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 45/4 ⇜ (731/64 → 183/16) ⇝ 23/2 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 45/4 ⇜ (731/64 → 183/16) ⇝ 23/2 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 45/4 ⇜ (731/64 → 183/16) ⇝ 23/2 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 45/4 ⇜ (731/64 → 183/16) ⇝ 23/2 | note:C5 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 45/4 ⇜ (183/16 → 733/64) ⇝ 23/2 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 45/4 ⇜ (183/16 → 733/64) ⇝ 23/2 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 45/4 ⇜ (183/16 → 733/64) ⇝ 23/2 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 45/4 ⇜ (183/16 → 733/64) ⇝ 23/2 | note:C5 gain:0.22 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 45/4 ⇜ (733/64 → 367/32) ⇝ 23/2 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 45/4 ⇜ (733/64 → 367/32) ⇝ 23/2 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 45/4 ⇜ (733/64 → 367/32) ⇝ 23/2 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 45/4 ⇜ (733/64 → 367/32) ⇝ 23/2 | note:C5 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 45/4 ⇜ (367/32 → 735/64) ⇝ 23/2 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 45/4 ⇜ (367/32 → 735/64) ⇝ 23/2 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 45/4 ⇜ (367/32 → 735/64) ⇝ 23/2 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 45/4 ⇜ (367/32 → 735/64) ⇝ 23/2 | note:C5 gain:0.12 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 45/4 ⇜ (735/64 → 23/2) | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 45/4 ⇜ (735/64 → 23/2) | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 45/4 ⇜ (735/64 → 23/2) | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 45/4 ⇜ (735/64 → 23/2) | note:C5 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ (23/2 → 737/64) ⇝ 93/8 | note:C5 gain:0.44 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ (23/2 → 737/64) ⇝ 93/8 | note:G5 gain:0.44 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ (23/2 → 737/64) ⇝ 93/8 | note:Bb5 gain:0.44 clip:1 s:piano release:0.1 pan:0.62962962963 ]", + "[ (23/2 → 737/64) ⇝ 47/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 23/2 ⇜ (737/64 → 369/32) ⇝ 93/8 | note:C5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 23/2 ⇜ (737/64 → 369/32) ⇝ 93/8 | note:G5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 23/2 ⇜ (737/64 → 369/32) ⇝ 93/8 | note:Bb5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.62962962963 ]", + "[ 23/2 ⇜ (737/64 → 369/32) ⇝ 47/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 23/2 ⇜ (369/32 → 739/64) ⇝ 93/8 | note:C5 gain:0.64 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 23/2 ⇜ (369/32 → 739/64) ⇝ 93/8 | note:G5 gain:0.64 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 23/2 ⇜ (369/32 → 739/64) ⇝ 93/8 | note:Bb5 gain:0.64 clip:1 s:piano release:0.1 pan:0.62962962963 ]", + "[ 23/2 ⇜ (369/32 → 739/64) ⇝ 47/4 | note:F2 gain:0.64 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ (323/28 → 739/64) ⇝ 165/14 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ (323/28 → 739/64) ⇝ 165/14 | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ (323/28 → 739/64) ⇝ 165/14 | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ (323/28 → 739/64) ⇝ 165/14 | note:84 gain:0.064 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 23/2 ⇜ (739/64 → 185/16) ⇝ 93/8 | note:C5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 23/2 ⇜ (739/64 → 185/16) ⇝ 93/8 | note:G5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 23/2 ⇜ (739/64 → 185/16) ⇝ 93/8 | note:Bb5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.62962962963 ]", + "[ 23/2 ⇜ (739/64 → 185/16) ⇝ 47/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 323/28 ⇜ (739/64 → 185/16) ⇝ 165/14 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 323/28 ⇜ (739/64 → 185/16) ⇝ 165/14 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 323/28 ⇜ (739/64 → 185/16) ⇝ 165/14 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 323/28 ⇜ (739/64 → 185/16) ⇝ 165/14 | note:84 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 23/2 ⇜ (185/16 → 741/64) ⇝ 93/8 | note:C5 gain:0.44 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 23/2 ⇜ (185/16 → 741/64) ⇝ 93/8 | note:G5 gain:0.44 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 23/2 ⇜ (185/16 → 741/64) ⇝ 93/8 | note:Bb5 gain:0.44 clip:1 s:piano release:0.1 pan:0.62962962963 ]", + "[ 23/2 ⇜ (185/16 → 741/64) ⇝ 47/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 323/28 ⇜ (185/16 → 741/64) ⇝ 165/14 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 323/28 ⇜ (185/16 → 741/64) ⇝ 165/14 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 323/28 ⇜ (185/16 → 741/64) ⇝ 165/14 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 323/28 ⇜ (185/16 → 741/64) ⇝ 165/14 | note:84 gain:0.044 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 23/2 ⇜ (741/64 → 371/32) ⇝ 93/8 | note:C5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 23/2 ⇜ (741/64 → 371/32) ⇝ 93/8 | note:G5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 23/2 ⇜ (741/64 → 371/32) ⇝ 93/8 | note:Bb5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.62962962963 ]", + "[ 23/2 ⇜ (741/64 → 371/32) ⇝ 47/4 | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 323/28 ⇜ (741/64 → 371/32) ⇝ 165/14 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 323/28 ⇜ (741/64 → 371/32) ⇝ 165/14 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 323/28 ⇜ (741/64 → 371/32) ⇝ 165/14 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 323/28 ⇜ (741/64 → 371/32) ⇝ 165/14 | note:84 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 23/2 ⇜ (371/32 → 743/64) ⇝ 93/8 | note:C5 gain:0.24 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 23/2 ⇜ (371/32 → 743/64) ⇝ 93/8 | note:G5 gain:0.24 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 23/2 ⇜ (371/32 → 743/64) ⇝ 93/8 | note:Bb5 gain:0.24 clip:1 s:piano release:0.1 pan:0.62962962963 ]", + "[ 23/2 ⇜ (371/32 → 743/64) ⇝ 47/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 323/28 ⇜ (371/32 → 743/64) ⇝ 165/14 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 323/28 ⇜ (371/32 → 743/64) ⇝ 165/14 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 323/28 ⇜ (371/32 → 743/64) ⇝ 165/14 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 323/28 ⇜ (371/32 → 743/64) ⇝ 165/14 | note:84 gain:0.024 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 23/2 ⇜ (743/64 → 93/8) | note:C5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 23/2 ⇜ (743/64 → 93/8) | note:G5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 23/2 ⇜ (743/64 → 93/8) | note:Bb5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.62962962963 ]", + "[ 23/2 ⇜ (743/64 → 93/8) ⇝ 47/4 | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 323/28 ⇜ (743/64 → 93/8) ⇝ 165/14 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 323/28 ⇜ (743/64 → 93/8) ⇝ 165/14 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 323/28 ⇜ (743/64 → 93/8) ⇝ 165/14 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 323/28 ⇜ (743/64 → 93/8) ⇝ 165/14 | note:84 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 23/2 ⇜ (93/8 → 745/64) ⇝ 47/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 323/28 ⇜ (93/8 → 745/64) ⇝ 165/14 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 323/28 ⇜ (93/8 → 745/64) ⇝ 165/14 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 323/28 ⇜ (93/8 → 745/64) ⇝ 165/14 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 323/28 ⇜ (93/8 → 745/64) ⇝ 165/14 | note:84 gain:0.044 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 23/2 ⇜ (745/64 → 373/32) ⇝ 47/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 323/28 ⇜ (745/64 → 373/32) ⇝ 165/14 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 323/28 ⇜ (745/64 → 373/32) ⇝ 165/14 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 323/28 ⇜ (745/64 → 373/32) ⇝ 165/14 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 323/28 ⇜ (745/64 → 373/32) ⇝ 165/14 | note:84 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 23/2 ⇜ (373/32 → 747/64) ⇝ 47/4 | note:F2 gain:0.64 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 323/28 ⇜ (373/32 → 747/64) ⇝ 165/14 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 323/28 ⇜ (373/32 → 747/64) ⇝ 165/14 | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 323/28 ⇜ (373/32 → 747/64) ⇝ 165/14 | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 323/28 ⇜ (373/32 → 747/64) ⇝ 165/14 | note:84 gain:0.064 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 23/2 ⇜ (747/64 → 187/16) ⇝ 47/4 | note:F2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 323/28 ⇜ (747/64 → 187/16) ⇝ 165/14 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 323/28 ⇜ (747/64 → 187/16) ⇝ 165/14 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 323/28 ⇜ (747/64 → 187/16) ⇝ 165/14 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 323/28 ⇜ (747/64 → 187/16) ⇝ 165/14 | note:84 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 23/2 ⇜ (187/16 → 749/64) ⇝ 47/4 | note:F2 gain:0.44 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 323/28 ⇜ (187/16 → 749/64) ⇝ 165/14 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 323/28 ⇜ (187/16 → 749/64) ⇝ 165/14 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 323/28 ⇜ (187/16 → 749/64) ⇝ 165/14 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 323/28 ⇜ (187/16 → 749/64) ⇝ 165/14 | note:84 gain:0.044 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 23/2 ⇜ (749/64 → 375/32) ⇝ 47/4 | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 323/28 ⇜ (749/64 → 375/32) ⇝ 165/14 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 323/28 ⇜ (749/64 → 375/32) ⇝ 165/14 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 323/28 ⇜ (749/64 → 375/32) ⇝ 165/14 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 323/28 ⇜ (749/64 → 375/32) ⇝ 165/14 | note:84 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 23/2 ⇜ (375/32 → 751/64) ⇝ 47/4 | note:F2 gain:0.24 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 323/28 ⇜ (375/32 → 751/64) ⇝ 165/14 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 323/28 ⇜ (375/32 → 751/64) ⇝ 165/14 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 323/28 ⇜ (375/32 → 751/64) ⇝ 165/14 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 323/28 ⇜ (375/32 → 751/64) ⇝ 165/14 | note:84 gain:0.024 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 23/2 ⇜ (751/64 → 47/4) | note:F2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.439814814815 ]", + "[ 323/28 ⇜ (751/64 → 47/4) ⇝ 165/14 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 323/28 ⇜ (751/64 → 47/4) ⇝ 165/14 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 323/28 ⇜ (751/64 → 47/4) ⇝ 165/14 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 323/28 ⇜ (751/64 → 47/4) ⇝ 165/14 | note:84 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 323/28 ⇜ (47/4 → 753/64) ⇝ 165/14 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 323/28 ⇜ (47/4 → 753/64) ⇝ 165/14 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 323/28 ⇜ (47/4 → 753/64) ⇝ 165/14 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 323/28 ⇜ (47/4 → 753/64) ⇝ 165/14 | note:84 gain:0.044 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ (47/4 → 753/64) ⇝ 95/8 | note:C5 gain:0.44 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ (47/4 → 753/64) ⇝ 95/8 | note:G5 gain:0.44 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ (47/4 → 753/64) ⇝ 95/8 | note:Bb5 gain:0.44 clip:1 s:piano release:0.1 pan:0.62962962963 ]", + "[ (47/4 → 753/64) ⇝ 12/1 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ (47/4 → 753/64) ⇝ 12/1 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (47/4 → 753/64) ⇝ 12/1 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ (47/4 → 753/64) ⇝ 12/1 | note:C5 gain:0.22 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 323/28 ⇜ (753/64 → 377/32) ⇝ 165/14 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 323/28 ⇜ (753/64 → 377/32) ⇝ 165/14 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 323/28 ⇜ (753/64 → 377/32) ⇝ 165/14 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 323/28 ⇜ (753/64 → 377/32) ⇝ 165/14 | note:84 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 47/4 ⇜ (753/64 → 377/32) ⇝ 95/8 | note:C5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 47/4 ⇜ (753/64 → 377/32) ⇝ 95/8 | note:G5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 47/4 ⇜ (753/64 → 377/32) ⇝ 95/8 | note:Bb5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.62962962963 ]", + "[ 47/4 ⇜ (753/64 → 377/32) ⇝ 12/1 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 47/4 ⇜ (753/64 → 377/32) ⇝ 12/1 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 47/4 ⇜ (753/64 → 377/32) ⇝ 12/1 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 47/4 ⇜ (753/64 → 377/32) ⇝ 12/1 | note:C5 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 323/28 ⇜ (377/32 → 165/14) | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 323/28 ⇜ (377/32 → 165/14) | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 323/28 ⇜ (377/32 → 165/14) | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 323/28 ⇜ (377/32 → 165/14) | note:84 gain:0.064 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 47/4 ⇜ (377/32 → 755/64) ⇝ 95/8 | note:C5 gain:0.64 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 47/4 ⇜ (377/32 → 755/64) ⇝ 95/8 | note:G5 gain:0.64 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 47/4 ⇜ (377/32 → 755/64) ⇝ 95/8 | note:Bb5 gain:0.64 clip:1 s:piano release:0.1 pan:0.62962962963 ]", + "[ 47/4 ⇜ (377/32 → 755/64) ⇝ 12/1 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 47/4 ⇜ (377/32 → 755/64) ⇝ 12/1 | note:G4 gain:0.32 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 47/4 ⇜ (377/32 → 755/64) ⇝ 12/1 | note:Ab4 gain:0.32 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 47/4 ⇜ (377/32 → 755/64) ⇝ 12/1 | note:C5 gain:0.32 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 47/4 ⇜ (755/64 → 189/16) ⇝ 95/8 | note:C5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 47/4 ⇜ (755/64 → 189/16) ⇝ 95/8 | note:G5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 47/4 ⇜ (755/64 → 189/16) ⇝ 95/8 | note:Bb5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.62962962963 ]", + "[ 47/4 ⇜ (755/64 → 189/16) ⇝ 12/1 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 47/4 ⇜ (755/64 → 189/16) ⇝ 12/1 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 47/4 ⇜ (755/64 → 189/16) ⇝ 12/1 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 47/4 ⇜ (755/64 → 189/16) ⇝ 12/1 | note:C5 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 47/4 ⇜ (189/16 → 757/64) ⇝ 95/8 | note:C5 gain:0.44 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 47/4 ⇜ (189/16 → 757/64) ⇝ 95/8 | note:G5 gain:0.44 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 47/4 ⇜ (189/16 → 757/64) ⇝ 95/8 | note:Bb5 gain:0.44 clip:1 s:piano release:0.1 pan:0.62962962963 ]", + "[ 47/4 ⇜ (189/16 → 757/64) ⇝ 12/1 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 47/4 ⇜ (189/16 → 757/64) ⇝ 12/1 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 47/4 ⇜ (189/16 → 757/64) ⇝ 12/1 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 47/4 ⇜ (189/16 → 757/64) ⇝ 12/1 | note:C5 gain:0.22 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 47/4 ⇜ (757/64 → 379/32) ⇝ 95/8 | note:C5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 47/4 ⇜ (757/64 → 379/32) ⇝ 95/8 | note:G5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 47/4 ⇜ (757/64 → 379/32) ⇝ 95/8 | note:Bb5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.62962962963 ]", + "[ 47/4 ⇜ (757/64 → 379/32) ⇝ 12/1 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 47/4 ⇜ (757/64 → 379/32) ⇝ 12/1 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 47/4 ⇜ (757/64 → 379/32) ⇝ 12/1 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 47/4 ⇜ (757/64 → 379/32) ⇝ 12/1 | note:C5 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 47/4 ⇜ (379/32 → 759/64) ⇝ 95/8 | note:C5 gain:0.24 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 47/4 ⇜ (379/32 → 759/64) ⇝ 95/8 | note:G5 gain:0.24 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 47/4 ⇜ (379/32 → 759/64) ⇝ 95/8 | note:Bb5 gain:0.24 clip:1 s:piano release:0.1 pan:0.62962962963 ]", + "[ 47/4 ⇜ (379/32 → 759/64) ⇝ 12/1 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 47/4 ⇜ (379/32 → 759/64) ⇝ 12/1 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 47/4 ⇜ (379/32 → 759/64) ⇝ 12/1 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 47/4 ⇜ (379/32 → 759/64) ⇝ 12/1 | note:C5 gain:0.12 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 47/4 ⇜ (759/64 → 95/8) | note:C5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 47/4 ⇜ (759/64 → 95/8) | note:G5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 47/4 ⇜ (759/64 → 95/8) | note:Bb5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.62962962963 ]", + "[ 47/4 ⇜ (759/64 → 95/8) ⇝ 12/1 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 47/4 ⇜ (759/64 → 95/8) ⇝ 12/1 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 47/4 ⇜ (759/64 → 95/8) ⇝ 12/1 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 47/4 ⇜ (759/64 → 95/8) ⇝ 12/1 | note:C5 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 47/4 ⇜ (95/8 → 761/64) ⇝ 12/1 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 47/4 ⇜ (95/8 → 761/64) ⇝ 12/1 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 47/4 ⇜ (95/8 → 761/64) ⇝ 12/1 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 47/4 ⇜ (95/8 → 761/64) ⇝ 12/1 | note:C5 gain:0.22 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 47/4 ⇜ (761/64 → 381/32) ⇝ 12/1 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 47/4 ⇜ (761/64 → 381/32) ⇝ 12/1 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 47/4 ⇜ (761/64 → 381/32) ⇝ 12/1 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 47/4 ⇜ (761/64 → 381/32) ⇝ 12/1 | note:C5 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 47/4 ⇜ (381/32 → 763/64) ⇝ 12/1 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 47/4 ⇜ (381/32 → 763/64) ⇝ 12/1 | note:G4 gain:0.32 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 47/4 ⇜ (381/32 → 763/64) ⇝ 12/1 | note:Ab4 gain:0.32 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 47/4 ⇜ (381/32 → 763/64) ⇝ 12/1 | note:C5 gain:0.32 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 47/4 ⇜ (763/64 → 191/16) ⇝ 12/1 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 47/4 ⇜ (763/64 → 191/16) ⇝ 12/1 | note:G4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 47/4 ⇜ (763/64 → 191/16) ⇝ 12/1 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 47/4 ⇜ (763/64 → 191/16) ⇝ 12/1 | note:C5 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 47/4 ⇜ (191/16 → 765/64) ⇝ 12/1 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 47/4 ⇜ (191/16 → 765/64) ⇝ 12/1 | note:G4 gain:0.22 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 47/4 ⇜ (191/16 → 765/64) ⇝ 12/1 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 47/4 ⇜ (191/16 → 765/64) ⇝ 12/1 | note:C5 gain:0.22 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 47/4 ⇜ (765/64 → 383/32) ⇝ 12/1 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 47/4 ⇜ (765/64 → 383/32) ⇝ 12/1 | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 47/4 ⇜ (765/64 → 383/32) ⇝ 12/1 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 47/4 ⇜ (765/64 → 383/32) ⇝ 12/1 | note:C5 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 47/4 ⇜ (383/32 → 767/64) ⇝ 12/1 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 47/4 ⇜ (383/32 → 767/64) ⇝ 12/1 | note:G4 gain:0.12 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 47/4 ⇜ (383/32 → 767/64) ⇝ 12/1 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 47/4 ⇜ (383/32 → 767/64) ⇝ 12/1 | note:C5 gain:0.12 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ 47/4 ⇜ (767/64 → 12/1) | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 47/4 ⇜ (767/64 → 12/1) | note:G4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 47/4 ⇜ (767/64 → 12/1) | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 47/4 ⇜ (767/64 → 12/1) | note:C5 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.583333333333 ]", + "[ (12/1 → 769/64) ⇝ 49/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 12/1 ⇜ (769/64 → 385/32) ⇝ 49/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 12/1 ⇜ (385/32 → 771/64) ⇝ 49/4 | note:G2 gain:0.64 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ (337/28 → 771/64) ⇝ 86/7 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ (337/28 → 771/64) ⇝ 86/7 | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ (337/28 → 771/64) ⇝ 86/7 | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ (337/28 → 771/64) ⇝ 86/7 | note:84 gain:0.064 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 12/1 ⇜ (771/64 → 193/16) ⇝ 49/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 337/28 ⇜ (771/64 → 193/16) ⇝ 86/7 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 337/28 ⇜ (771/64 → 193/16) ⇝ 86/7 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 337/28 ⇜ (771/64 → 193/16) ⇝ 86/7 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 337/28 ⇜ (771/64 → 193/16) ⇝ 86/7 | note:84 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 12/1 ⇜ (193/16 → 773/64) ⇝ 49/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 337/28 ⇜ (193/16 → 773/64) ⇝ 86/7 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 337/28 ⇜ (193/16 → 773/64) ⇝ 86/7 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 337/28 ⇜ (193/16 → 773/64) ⇝ 86/7 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 337/28 ⇜ (193/16 → 773/64) ⇝ 86/7 | note:84 gain:0.044 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 12/1 ⇜ (773/64 → 387/32) ⇝ 49/4 | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 337/28 ⇜ (773/64 → 387/32) ⇝ 86/7 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 337/28 ⇜ (773/64 → 387/32) ⇝ 86/7 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 337/28 ⇜ (773/64 → 387/32) ⇝ 86/7 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 337/28 ⇜ (773/64 → 387/32) ⇝ 86/7 | note:84 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 12/1 ⇜ (387/32 → 775/64) ⇝ 49/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 337/28 ⇜ (387/32 → 775/64) ⇝ 86/7 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 337/28 ⇜ (387/32 → 775/64) ⇝ 86/7 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 337/28 ⇜ (387/32 → 775/64) ⇝ 86/7 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 337/28 ⇜ (387/32 → 775/64) ⇝ 86/7 | note:84 gain:0.024 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 12/1 ⇜ (775/64 → 97/8) ⇝ 49/4 | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 337/28 ⇜ (775/64 → 97/8) ⇝ 86/7 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 337/28 ⇜ (775/64 → 97/8) ⇝ 86/7 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 337/28 ⇜ (775/64 → 97/8) ⇝ 86/7 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 337/28 ⇜ (775/64 → 97/8) ⇝ 86/7 | note:84 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 12/1 ⇜ (97/8 → 777/64) ⇝ 49/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 337/28 ⇜ (97/8 → 777/64) ⇝ 86/7 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 337/28 ⇜ (97/8 → 777/64) ⇝ 86/7 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 337/28 ⇜ (97/8 → 777/64) ⇝ 86/7 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 337/28 ⇜ (97/8 → 777/64) ⇝ 86/7 | note:84 gain:0.044 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ (97/8 → 777/64) ⇝ 49/4 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (97/8 → 777/64) ⇝ 49/4 | note:D5 gain:0.44 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ (97/8 → 777/64) ⇝ 49/4 | note:F5 gain:0.44 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 12/1 ⇜ (777/64 → 389/32) ⇝ 49/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 337/28 ⇜ (777/64 → 389/32) ⇝ 86/7 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 337/28 ⇜ (777/64 → 389/32) ⇝ 86/7 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 337/28 ⇜ (777/64 → 389/32) ⇝ 86/7 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 337/28 ⇜ (777/64 → 389/32) ⇝ 86/7 | note:84 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 97/8 ⇜ (777/64 → 389/32) ⇝ 49/4 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 97/8 ⇜ (777/64 → 389/32) ⇝ 49/4 | note:D5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 97/8 ⇜ (777/64 → 389/32) ⇝ 49/4 | note:F5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 12/1 ⇜ (389/32 → 779/64) ⇝ 49/4 | note:G2 gain:0.64 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 337/28 ⇜ (389/32 → 779/64) ⇝ 86/7 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 337/28 ⇜ (389/32 → 779/64) ⇝ 86/7 | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 337/28 ⇜ (389/32 → 779/64) ⇝ 86/7 | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 337/28 ⇜ (389/32 → 779/64) ⇝ 86/7 | note:84 gain:0.064 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 97/8 ⇜ (389/32 → 779/64) ⇝ 49/4 | note:G4 gain:0.64 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 97/8 ⇜ (389/32 → 779/64) ⇝ 49/4 | note:D5 gain:0.64 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 97/8 ⇜ (389/32 → 779/64) ⇝ 49/4 | note:F5 gain:0.64 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 12/1 ⇜ (779/64 → 195/16) ⇝ 49/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 337/28 ⇜ (779/64 → 195/16) ⇝ 86/7 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 337/28 ⇜ (779/64 → 195/16) ⇝ 86/7 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 337/28 ⇜ (779/64 → 195/16) ⇝ 86/7 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 337/28 ⇜ (779/64 → 195/16) ⇝ 86/7 | note:84 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 97/8 ⇜ (779/64 → 195/16) ⇝ 49/4 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 97/8 ⇜ (779/64 → 195/16) ⇝ 49/4 | note:D5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 97/8 ⇜ (779/64 → 195/16) ⇝ 49/4 | note:F5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 12/1 ⇜ (195/16 → 781/64) ⇝ 49/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 337/28 ⇜ (195/16 → 781/64) ⇝ 86/7 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 337/28 ⇜ (195/16 → 781/64) ⇝ 86/7 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 337/28 ⇜ (195/16 → 781/64) ⇝ 86/7 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 337/28 ⇜ (195/16 → 781/64) ⇝ 86/7 | note:84 gain:0.044 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 97/8 ⇜ (195/16 → 781/64) ⇝ 49/4 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 97/8 ⇜ (195/16 → 781/64) ⇝ 49/4 | note:D5 gain:0.44 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 97/8 ⇜ (195/16 → 781/64) ⇝ 49/4 | note:F5 gain:0.44 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 12/1 ⇜ (781/64 → 391/32) ⇝ 49/4 | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 337/28 ⇜ (781/64 → 391/32) ⇝ 86/7 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 337/28 ⇜ (781/64 → 391/32) ⇝ 86/7 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 337/28 ⇜ (781/64 → 391/32) ⇝ 86/7 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 337/28 ⇜ (781/64 → 391/32) ⇝ 86/7 | note:84 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 97/8 ⇜ (781/64 → 391/32) ⇝ 49/4 | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 97/8 ⇜ (781/64 → 391/32) ⇝ 49/4 | note:D5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 97/8 ⇜ (781/64 → 391/32) ⇝ 49/4 | note:F5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 12/1 ⇜ (391/32 → 783/64) ⇝ 49/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 337/28 ⇜ (391/32 → 783/64) ⇝ 86/7 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 337/28 ⇜ (391/32 → 783/64) ⇝ 86/7 | note:79 gain:0.024 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 337/28 ⇜ (391/32 → 783/64) ⇝ 86/7 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 337/28 ⇜ (391/32 → 783/64) ⇝ 86/7 | note:84 gain:0.024 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 97/8 ⇜ (391/32 → 783/64) ⇝ 49/4 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 97/8 ⇜ (391/32 → 783/64) ⇝ 49/4 | note:D5 gain:0.24 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 97/8 ⇜ (391/32 → 783/64) ⇝ 49/4 | note:F5 gain:0.24 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 12/1 ⇜ (783/64 → 49/4) | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 337/28 ⇜ (783/64 → 49/4) ⇝ 86/7 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 337/28 ⇜ (783/64 → 49/4) ⇝ 86/7 | note:79 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 337/28 ⇜ (783/64 → 49/4) ⇝ 86/7 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 337/28 ⇜ (783/64 → 49/4) ⇝ 86/7 | note:84 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 97/8 ⇜ (783/64 → 49/4) | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 97/8 ⇜ (783/64 → 49/4) | note:D5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 97/8 ⇜ (783/64 → 49/4) | note:F5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 337/28 ⇜ (49/4 → 785/64) ⇝ 86/7 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 337/28 ⇜ (49/4 → 785/64) ⇝ 86/7 | note:79 gain:0.044 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 337/28 ⇜ (49/4 → 785/64) ⇝ 86/7 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 337/28 ⇜ (49/4 → 785/64) ⇝ 86/7 | note:84 gain:0.044 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 337/28 ⇜ (785/64 → 393/32) ⇝ 86/7 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 337/28 ⇜ (785/64 → 393/32) ⇝ 86/7 | note:79 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 337/28 ⇜ (785/64 → 393/32) ⇝ 86/7 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 337/28 ⇜ (785/64 → 393/32) ⇝ 86/7 | note:84 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 337/28 ⇜ (393/32 → 86/7) | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 337/28 ⇜ (393/32 → 86/7) | note:79 gain:0.064 clip:1 s:piano release:0.1 pan:0.615740740741 ]", + "[ 337/28 ⇜ (393/32 → 86/7) | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 337/28 ⇜ (393/32 → 86/7) | note:84 gain:0.064 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ (25/2 → 801/64) ⇝ 101/8 | note:D5 gain:0.44 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ (25/2 → 801/64) ⇝ 101/8 | note:A5 gain:0.44 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ (25/2 → 801/64) ⇝ 101/8 | note:C6 gain:0.44 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ (25/2 → 801/64) ⇝ 51/4 | note:B3 gain:0.22 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ (25/2 → 801/64) ⇝ 51/4 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (25/2 → 801/64) ⇝ 51/4 | note:F4 gain:0.22 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ (25/2 → 801/64) ⇝ 51/4 | note:A4 gain:0.22 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ (25/2 → 801/64) ⇝ 51/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 25/2 ⇜ (801/64 → 401/32) ⇝ 101/8 | note:D5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 25/2 ⇜ (801/64 → 401/32) ⇝ 101/8 | note:A5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 25/2 ⇜ (801/64 → 401/32) ⇝ 101/8 | note:C6 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 25/2 ⇜ (801/64 → 401/32) ⇝ 51/4 | note:B3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 25/2 ⇜ (801/64 → 401/32) ⇝ 51/4 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 25/2 ⇜ (801/64 → 401/32) ⇝ 51/4 | note:F4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 25/2 ⇜ (801/64 → 401/32) ⇝ 51/4 | note:A4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 25/2 ⇜ (801/64 → 401/32) ⇝ 51/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 25/2 ⇜ (401/32 → 803/64) ⇝ 101/8 | note:D5 gain:0.64 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 25/2 ⇜ (401/32 → 803/64) ⇝ 101/8 | note:A5 gain:0.64 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 25/2 ⇜ (401/32 → 803/64) ⇝ 101/8 | note:C6 gain:0.64 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 25/2 ⇜ (401/32 → 803/64) ⇝ 51/4 | note:B3 gain:0.32 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 25/2 ⇜ (401/32 → 803/64) ⇝ 51/4 | note:E4 gain:0.32 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 25/2 ⇜ (401/32 → 803/64) ⇝ 51/4 | note:F4 gain:0.32 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 25/2 ⇜ (401/32 → 803/64) ⇝ 51/4 | note:A4 gain:0.32 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 25/2 ⇜ (401/32 → 803/64) ⇝ 51/4 | note:G2 gain:0.64 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 25/2 ⇜ (803/64 → 201/16) ⇝ 101/8 | note:D5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 25/2 ⇜ (803/64 → 201/16) ⇝ 101/8 | note:A5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 25/2 ⇜ (803/64 → 201/16) ⇝ 101/8 | note:C6 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 25/2 ⇜ (803/64 → 201/16) ⇝ 51/4 | note:B3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 25/2 ⇜ (803/64 → 201/16) ⇝ 51/4 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 25/2 ⇜ (803/64 → 201/16) ⇝ 51/4 | note:F4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 25/2 ⇜ (803/64 → 201/16) ⇝ 51/4 | note:A4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 25/2 ⇜ (803/64 → 201/16) ⇝ 51/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 25/2 ⇜ (201/16 → 805/64) ⇝ 101/8 | note:D5 gain:0.44 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 25/2 ⇜ (201/16 → 805/64) ⇝ 101/8 | note:A5 gain:0.44 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 25/2 ⇜ (201/16 → 805/64) ⇝ 101/8 | note:C6 gain:0.44 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 25/2 ⇜ (201/16 → 805/64) ⇝ 51/4 | note:B3 gain:0.22 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 25/2 ⇜ (201/16 → 805/64) ⇝ 51/4 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 25/2 ⇜ (201/16 → 805/64) ⇝ 51/4 | note:F4 gain:0.22 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 25/2 ⇜ (201/16 → 805/64) ⇝ 51/4 | note:A4 gain:0.22 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 25/2 ⇜ (201/16 → 805/64) ⇝ 51/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 25/2 ⇜ (805/64 → 403/32) ⇝ 101/8 | note:D5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 25/2 ⇜ (805/64 → 403/32) ⇝ 101/8 | note:A5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 25/2 ⇜ (805/64 → 403/32) ⇝ 101/8 | note:C6 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 25/2 ⇜ (805/64 → 403/32) ⇝ 51/4 | note:B3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 25/2 ⇜ (805/64 → 403/32) ⇝ 51/4 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 25/2 ⇜ (805/64 → 403/32) ⇝ 51/4 | note:F4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 25/2 ⇜ (805/64 → 403/32) ⇝ 51/4 | note:A4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 25/2 ⇜ (805/64 → 403/32) ⇝ 51/4 | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 25/2 ⇜ (403/32 → 807/64) ⇝ 101/8 | note:D5 gain:0.24 clip:1 s:piano release:0.1 pan:0.592592592593 ]", "[ 25/2 ⇜ (403/32 → 807/64) ⇝ 101/8 | note:A5 gain:0.24 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 25/2 ⇜ (403/32 → 807/64) ⇝ 101/8 | note:C6 gain:0.24 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 25/2 ⇜ (403/32 → 807/64) ⇝ 51/4 | note:B3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 25/2 ⇜ (403/32 → 807/64) ⇝ 51/4 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 25/2 ⇜ (403/32 → 807/64) ⇝ 51/4 | note:F4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 25/2 ⇜ (403/32 → 807/64) ⇝ 51/4 | note:A4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 25/2 ⇜ (403/32 → 807/64) ⇝ 51/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 25/2 ⇜ (807/64 → 101/8) | note:D5 gain:0.29857864376269244 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 25/2 ⇜ (807/64 → 101/8) | note:A5 gain:0.29857864376269244 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 25/2 ⇜ (807/64 → 101/8) | note:C6 gain:0.29857864376269244 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 25/2 ⇜ (807/64 → 101/8) ⇝ 51/4 | note:B3 gain:0.14928932188134622 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 25/2 ⇜ (807/64 → 101/8) ⇝ 51/4 | note:E4 gain:0.14928932188134622 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 25/2 ⇜ (807/64 → 101/8) ⇝ 51/4 | note:F4 gain:0.14928932188134622 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 25/2 ⇜ (807/64 → 101/8) ⇝ 51/4 | note:A4 gain:0.14928932188134622 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 25/2 ⇜ (807/64 → 101/8) ⇝ 51/4 | note:G2 gain:0.29857864376269244 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 25/2 ⇜ (101/8 → 809/64) ⇝ 51/4 | note:B3 gain:0.21999999999999825 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 25/2 ⇜ (101/8 → 809/64) ⇝ 51/4 | note:E4 gain:0.21999999999999825 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 25/2 ⇜ (101/8 → 809/64) ⇝ 51/4 | note:F4 gain:0.21999999999999825 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 25/2 ⇜ (101/8 → 809/64) ⇝ 51/4 | note:A4 gain:0.21999999999999825 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 25/2 ⇜ (101/8 → 809/64) ⇝ 51/4 | note:G2 gain:0.4399999999999965 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 25/2 ⇜ (809/64 → 405/32) ⇝ 51/4 | note:B3 gain:0.2907106781186513 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 25/2 ⇜ (809/64 → 405/32) ⇝ 51/4 | note:E4 gain:0.2907106781186513 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 25/2 ⇜ (809/64 → 405/32) ⇝ 51/4 | note:F4 gain:0.2907106781186513 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 25/2 ⇜ (809/64 → 405/32) ⇝ 51/4 | note:A4 gain:0.2907106781186513 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 25/2 ⇜ (809/64 → 405/32) ⇝ 51/4 | note:G2 gain:0.5814213562373026 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 25/2 ⇜ (405/32 → 811/64) ⇝ 51/4 | note:B3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 25/2 ⇜ (405/32 → 811/64) ⇝ 51/4 | note:E4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 25/2 ⇜ (405/32 → 811/64) ⇝ 51/4 | note:F4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 25/2 ⇜ (405/32 → 811/64) ⇝ 51/4 | note:A4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 25/2 ⇜ (405/32 → 811/64) ⇝ 51/4 | note:G2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 25/2 ⇜ (811/64 → 203/16) ⇝ 51/4 | note:B3 gain:0.29071067811865453 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 25/2 ⇜ (811/64 → 203/16) ⇝ 51/4 | note:E4 gain:0.29071067811865453 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 25/2 ⇜ (811/64 → 203/16) ⇝ 51/4 | note:F4 gain:0.29071067811865453 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 25/2 ⇜ (811/64 → 203/16) ⇝ 51/4 | note:A4 gain:0.29071067811865453 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 25/2 ⇜ (811/64 → 203/16) ⇝ 51/4 | note:G2 gain:0.5814213562373091 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 25/2 ⇜ (203/16 → 813/64) ⇝ 51/4 | note:B3 gain:0.22000000000000286 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 25/2 ⇜ (203/16 → 813/64) ⇝ 51/4 | note:E4 gain:0.22000000000000286 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 25/2 ⇜ (203/16 → 813/64) ⇝ 51/4 | note:F4 gain:0.22000000000000286 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 25/2 ⇜ (203/16 → 813/64) ⇝ 51/4 | note:A4 gain:0.22000000000000286 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 25/2 ⇜ (203/16 → 813/64) ⇝ 51/4 | note:G2 gain:0.4400000000000057 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 25/2 ⇜ (813/64 → 407/32) ⇝ 51/4 | note:B3 gain:0.14928932188134944 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 25/2 ⇜ (813/64 → 407/32) ⇝ 51/4 | note:E4 gain:0.14928932188134944 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 25/2 ⇜ (813/64 → 407/32) ⇝ 51/4 | note:F4 gain:0.14928932188134944 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 25/2 ⇜ (813/64 → 407/32) ⇝ 51/4 | note:A4 gain:0.14928932188134944 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 25/2 ⇜ (813/64 → 407/32) ⇝ 51/4 | note:G2 gain:0.2985786437626989 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 25/2 ⇜ (407/32 → 815/64) ⇝ 51/4 | note:B3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 25/2 ⇜ (407/32 → 815/64) ⇝ 51/4 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 25/2 ⇜ (407/32 → 815/64) ⇝ 51/4 | note:F4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 25/2 ⇜ (407/32 → 815/64) ⇝ 51/4 | note:A4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 25/2 ⇜ (407/32 → 815/64) ⇝ 51/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 25/2 ⇜ (815/64 → 51/4) | note:B3 gain:0.14928932188134467 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 25/2 ⇜ (815/64 → 51/4) | note:E4 gain:0.14928932188134467 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 25/2 ⇜ (815/64 → 51/4) | note:F4 gain:0.14928932188134467 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 25/2 ⇜ (815/64 → 51/4) | note:A4 gain:0.14928932188134467 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 25/2 ⇜ (815/64 → 51/4) | note:G2 gain:0.29857864376268933 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ (51/4 → 817/64) ⇝ 103/8 | note:G4 gain:0.4399999999999922 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (51/4 → 817/64) ⇝ 103/8 | note:D5 gain:0.4399999999999922 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (51/4 → 817/64) ⇝ 103/8 | note:F5 gain:0.4399999999999922 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 51/4 ⇜ (817/64 → 409/32) ⇝ 103/8 | note:G4 gain:0.5814213562372995 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 51/4 ⇜ (817/64 → 409/32) ⇝ 103/8 | note:D5 gain:0.5814213562372995 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 51/4 ⇜ (817/64 → 409/32) ⇝ 103/8 | note:F5 gain:0.5814213562372995 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 51/4 ⇜ (409/32 → 819/64) ⇝ 103/8 | note:G4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 51/4 ⇜ (409/32 → 819/64) ⇝ 103/8 | note:D5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 51/4 ⇜ (409/32 → 819/64) ⇝ 103/8 | note:F5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ (179/14 → 819/64) ⇝ 365/28 | note:71 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ (179/14 → 819/64) ⇝ 365/28 | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ (179/14 → 819/64) ⇝ 365/28 | note:77 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ (179/14 → 819/64) ⇝ 365/28 | note:81 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 51/4 ⇜ (819/64 → 205/16) ⇝ 103/8 | note:G4 gain:0.5814213562373122 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 51/4 ⇜ (819/64 → 205/16) ⇝ 103/8 | note:D5 gain:0.5814213562373122 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 51/4 ⇜ (819/64 → 205/16) ⇝ 103/8 | note:F5 gain:0.5814213562373122 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 179/14 ⇜ (819/64 → 205/16) ⇝ 365/28 | note:71 gain:0.05814213562373122 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 179/14 ⇜ (819/64 → 205/16) ⇝ 365/28 | note:76 gain:0.05814213562373122 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 179/14 ⇜ (819/64 → 205/16) ⇝ 365/28 | note:77 gain:0.05814213562373122 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 179/14 ⇜ (819/64 → 205/16) ⇝ 365/28 | note:81 gain:0.05814213562373122 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 51/4 ⇜ (205/16 → 821/64) ⇝ 103/8 | note:G4 gain:0.44000000000001 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 51/4 ⇜ (205/16 → 821/64) ⇝ 103/8 | note:D5 gain:0.44000000000001 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 51/4 ⇜ (205/16 → 821/64) ⇝ 103/8 | note:F5 gain:0.44000000000001 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 179/14 ⇜ (205/16 → 821/64) ⇝ 365/28 | note:71 gain:0.044000000000001004 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 179/14 ⇜ (205/16 → 821/64) ⇝ 365/28 | note:76 gain:0.044000000000001004 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 179/14 ⇜ (205/16 → 821/64) ⇝ 365/28 | note:77 gain:0.044000000000001004 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 179/14 ⇜ (205/16 → 821/64) ⇝ 365/28 | note:81 gain:0.044000000000001004 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 51/4 ⇜ (821/64 → 411/32) ⇝ 103/8 | note:G4 gain:0.298578643762702 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 51/4 ⇜ (821/64 → 411/32) ⇝ 103/8 | note:D5 gain:0.298578643762702 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 51/4 ⇜ (821/64 → 411/32) ⇝ 103/8 | note:F5 gain:0.298578643762702 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 179/14 ⇜ (821/64 → 411/32) ⇝ 365/28 | note:71 gain:0.0298578643762702 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 179/14 ⇜ (821/64 → 411/32) ⇝ 365/28 | note:76 gain:0.0298578643762702 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 179/14 ⇜ (821/64 → 411/32) ⇝ 365/28 | note:77 gain:0.0298578643762702 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 179/14 ⇜ (821/64 → 411/32) ⇝ 365/28 | note:81 gain:0.0298578643762702 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 51/4 ⇜ (411/32 → 823/64) ⇝ 103/8 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 51/4 ⇜ (411/32 → 823/64) ⇝ 103/8 | note:D5 gain:0.24 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 51/4 ⇜ (411/32 → 823/64) ⇝ 103/8 | note:F5 gain:0.24 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 179/14 ⇜ (411/32 → 823/64) ⇝ 365/28 | note:71 gain:0.024 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 179/14 ⇜ (411/32 → 823/64) ⇝ 365/28 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 179/14 ⇜ (411/32 → 823/64) ⇝ 365/28 | note:77 gain:0.024 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", + "[ 25/2 ⇜ (403/32 → 807/64) ⇝ 101/8 | note:C6 gain:0.24 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 25/2 ⇜ (403/32 → 807/64) ⇝ 51/4 | note:B3 gain:0.12 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 25/2 ⇜ (403/32 → 807/64) ⇝ 51/4 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 25/2 ⇜ (403/32 → 807/64) ⇝ 51/4 | note:F4 gain:0.12 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 25/2 ⇜ (403/32 → 807/64) ⇝ 51/4 | note:A4 gain:0.12 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 25/2 ⇜ (403/32 → 807/64) ⇝ 51/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 25/2 ⇜ (807/64 → 101/8) | note:D5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 25/2 ⇜ (807/64 → 101/8) | note:A5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 25/2 ⇜ (807/64 → 101/8) | note:C6 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 25/2 ⇜ (807/64 → 101/8) ⇝ 51/4 | note:B3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 25/2 ⇜ (807/64 → 101/8) ⇝ 51/4 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 25/2 ⇜ (807/64 → 101/8) ⇝ 51/4 | note:F4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 25/2 ⇜ (807/64 → 101/8) ⇝ 51/4 | note:A4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 25/2 ⇜ (807/64 → 101/8) ⇝ 51/4 | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 25/2 ⇜ (101/8 → 809/64) ⇝ 51/4 | note:B3 gain:0.22 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 25/2 ⇜ (101/8 → 809/64) ⇝ 51/4 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 25/2 ⇜ (101/8 → 809/64) ⇝ 51/4 | note:F4 gain:0.22 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 25/2 ⇜ (101/8 → 809/64) ⇝ 51/4 | note:A4 gain:0.22 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 25/2 ⇜ (101/8 → 809/64) ⇝ 51/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 25/2 ⇜ (809/64 → 405/32) ⇝ 51/4 | note:B3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 25/2 ⇜ (809/64 → 405/32) ⇝ 51/4 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 25/2 ⇜ (809/64 → 405/32) ⇝ 51/4 | note:F4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 25/2 ⇜ (809/64 → 405/32) ⇝ 51/4 | note:A4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 25/2 ⇜ (809/64 → 405/32) ⇝ 51/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 25/2 ⇜ (405/32 → 811/64) ⇝ 51/4 | note:B3 gain:0.32 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 25/2 ⇜ (405/32 → 811/64) ⇝ 51/4 | note:E4 gain:0.32 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 25/2 ⇜ (405/32 → 811/64) ⇝ 51/4 | note:F4 gain:0.32 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 25/2 ⇜ (405/32 → 811/64) ⇝ 51/4 | note:A4 gain:0.32 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 25/2 ⇜ (405/32 → 811/64) ⇝ 51/4 | note:G2 gain:0.64 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 25/2 ⇜ (811/64 → 203/16) ⇝ 51/4 | note:B3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 25/2 ⇜ (811/64 → 203/16) ⇝ 51/4 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 25/2 ⇜ (811/64 → 203/16) ⇝ 51/4 | note:F4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 25/2 ⇜ (811/64 → 203/16) ⇝ 51/4 | note:A4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 25/2 ⇜ (811/64 → 203/16) ⇝ 51/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 25/2 ⇜ (203/16 → 813/64) ⇝ 51/4 | note:B3 gain:0.22 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 25/2 ⇜ (203/16 → 813/64) ⇝ 51/4 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 25/2 ⇜ (203/16 → 813/64) ⇝ 51/4 | note:F4 gain:0.22 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 25/2 ⇜ (203/16 → 813/64) ⇝ 51/4 | note:A4 gain:0.22 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 25/2 ⇜ (203/16 → 813/64) ⇝ 51/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 25/2 ⇜ (813/64 → 407/32) ⇝ 51/4 | note:B3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 25/2 ⇜ (813/64 → 407/32) ⇝ 51/4 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 25/2 ⇜ (813/64 → 407/32) ⇝ 51/4 | note:F4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 25/2 ⇜ (813/64 → 407/32) ⇝ 51/4 | note:A4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 25/2 ⇜ (813/64 → 407/32) ⇝ 51/4 | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 25/2 ⇜ (407/32 → 815/64) ⇝ 51/4 | note:B3 gain:0.12 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 25/2 ⇜ (407/32 → 815/64) ⇝ 51/4 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 25/2 ⇜ (407/32 → 815/64) ⇝ 51/4 | note:F4 gain:0.12 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 25/2 ⇜ (407/32 → 815/64) ⇝ 51/4 | note:A4 gain:0.12 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 25/2 ⇜ (407/32 → 815/64) ⇝ 51/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 25/2 ⇜ (815/64 → 51/4) | note:B3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 25/2 ⇜ (815/64 → 51/4) | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 25/2 ⇜ (815/64 → 51/4) | note:F4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 25/2 ⇜ (815/64 → 51/4) | note:A4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 25/2 ⇜ (815/64 → 51/4) | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ (51/4 → 817/64) ⇝ 103/8 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (51/4 → 817/64) ⇝ 103/8 | note:D5 gain:0.44 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ (51/4 → 817/64) ⇝ 103/8 | note:F5 gain:0.44 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 51/4 ⇜ (817/64 → 409/32) ⇝ 103/8 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 51/4 ⇜ (817/64 → 409/32) ⇝ 103/8 | note:D5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 51/4 ⇜ (817/64 → 409/32) ⇝ 103/8 | note:F5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 51/4 ⇜ (409/32 → 819/64) ⇝ 103/8 | note:G4 gain:0.64 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 51/4 ⇜ (409/32 → 819/64) ⇝ 103/8 | note:D5 gain:0.64 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 51/4 ⇜ (409/32 → 819/64) ⇝ 103/8 | note:F5 gain:0.64 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ (179/14 → 819/64) ⇝ 365/28 | note:71 gain:0.064 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ (179/14 → 819/64) ⇝ 365/28 | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ (179/14 → 819/64) ⇝ 365/28 | note:77 gain:0.064 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ (179/14 → 819/64) ⇝ 365/28 | note:81 gain:0.064 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 51/4 ⇜ (819/64 → 205/16) ⇝ 103/8 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 51/4 ⇜ (819/64 → 205/16) ⇝ 103/8 | note:D5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 51/4 ⇜ (819/64 → 205/16) ⇝ 103/8 | note:F5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 179/14 ⇜ (819/64 → 205/16) ⇝ 365/28 | note:71 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 179/14 ⇜ (819/64 → 205/16) ⇝ 365/28 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 179/14 ⇜ (819/64 → 205/16) ⇝ 365/28 | note:77 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 179/14 ⇜ (819/64 → 205/16) ⇝ 365/28 | note:81 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 51/4 ⇜ (205/16 → 821/64) ⇝ 103/8 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 51/4 ⇜ (205/16 → 821/64) ⇝ 103/8 | note:D5 gain:0.44 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 51/4 ⇜ (205/16 → 821/64) ⇝ 103/8 | note:F5 gain:0.44 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 179/14 ⇜ (205/16 → 821/64) ⇝ 365/28 | note:71 gain:0.044 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 179/14 ⇜ (205/16 → 821/64) ⇝ 365/28 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 179/14 ⇜ (205/16 → 821/64) ⇝ 365/28 | note:77 gain:0.044 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 179/14 ⇜ (205/16 → 821/64) ⇝ 365/28 | note:81 gain:0.044 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 51/4 ⇜ (821/64 → 411/32) ⇝ 103/8 | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 51/4 ⇜ (821/64 → 411/32) ⇝ 103/8 | note:D5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 51/4 ⇜ (821/64 → 411/32) ⇝ 103/8 | note:F5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 179/14 ⇜ (821/64 → 411/32) ⇝ 365/28 | note:71 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 179/14 ⇜ (821/64 → 411/32) ⇝ 365/28 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 179/14 ⇜ (821/64 → 411/32) ⇝ 365/28 | note:77 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 179/14 ⇜ (821/64 → 411/32) ⇝ 365/28 | note:81 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 51/4 ⇜ (411/32 → 823/64) ⇝ 103/8 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 51/4 ⇜ (411/32 → 823/64) ⇝ 103/8 | note:D5 gain:0.24 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 51/4 ⇜ (411/32 → 823/64) ⇝ 103/8 | note:F5 gain:0.24 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 179/14 ⇜ (411/32 → 823/64) ⇝ 365/28 | note:71 gain:0.024 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 179/14 ⇜ (411/32 → 823/64) ⇝ 365/28 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 179/14 ⇜ (411/32 → 823/64) ⇝ 365/28 | note:77 gain:0.024 clip:1 s:piano release:0.1 pan:0.606481481481 ]", "[ 179/14 ⇜ (411/32 → 823/64) ⇝ 365/28 | note:81 gain:0.024 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 51/4 ⇜ (823/64 → 103/8) | note:G4 gain:0.2985786437626863 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 51/4 ⇜ (823/64 → 103/8) | note:D5 gain:0.2985786437626863 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 51/4 ⇜ (823/64 → 103/8) | note:F5 gain:0.2985786437626863 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 179/14 ⇜ (823/64 → 103/8) ⇝ 365/28 | note:71 gain:0.02985786437626863 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 179/14 ⇜ (823/64 → 103/8) ⇝ 365/28 | note:76 gain:0.02985786437626863 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 179/14 ⇜ (823/64 → 103/8) ⇝ 365/28 | note:77 gain:0.02985786437626863 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 179/14 ⇜ (823/64 → 103/8) ⇝ 365/28 | note:81 gain:0.02985786437626863 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 179/14 ⇜ (103/8 → 825/64) ⇝ 365/28 | note:71 gain:0.04399999999999879 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 179/14 ⇜ (103/8 → 825/64) ⇝ 365/28 | note:76 gain:0.04399999999999879 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 179/14 ⇜ (103/8 → 825/64) ⇝ 365/28 | note:77 gain:0.04399999999999879 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 179/14 ⇜ (103/8 → 825/64) ⇝ 365/28 | note:81 gain:0.04399999999999879 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 179/14 ⇜ (825/64 → 413/32) ⇝ 365/28 | note:71 gain:0.058142135623731266 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 179/14 ⇜ (825/64 → 413/32) ⇝ 365/28 | note:76 gain:0.058142135623731266 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 179/14 ⇜ (825/64 → 413/32) ⇝ 365/28 | note:77 gain:0.058142135623731266 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 179/14 ⇜ (825/64 → 413/32) ⇝ 365/28 | note:81 gain:0.058142135623731266 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 179/14 ⇜ (413/32 → 827/64) ⇝ 365/28 | note:71 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 179/14 ⇜ (413/32 → 827/64) ⇝ 365/28 | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 179/14 ⇜ (413/32 → 827/64) ⇝ 365/28 | note:77 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 179/14 ⇜ (413/32 → 827/64) ⇝ 365/28 | note:81 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 179/14 ⇜ (827/64 → 207/16) ⇝ 365/28 | note:71 gain:0.05814213562373153 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 179/14 ⇜ (827/64 → 207/16) ⇝ 365/28 | note:76 gain:0.05814213562373153 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 179/14 ⇜ (827/64 → 207/16) ⇝ 365/28 | note:77 gain:0.05814213562373153 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 179/14 ⇜ (827/64 → 207/16) ⇝ 365/28 | note:81 gain:0.05814213562373153 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 179/14 ⇜ (207/16 → 829/64) ⇝ 365/28 | note:71 gain:0.04400000000000143 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 179/14 ⇜ (207/16 → 829/64) ⇝ 365/28 | note:76 gain:0.04400000000000143 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 179/14 ⇜ (207/16 → 829/64) ⇝ 365/28 | note:77 gain:0.04400000000000143 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 179/14 ⇜ (207/16 → 829/64) ⇝ 365/28 | note:81 gain:0.04400000000000143 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 179/14 ⇜ (829/64 → 415/32) ⇝ 365/28 | note:71 gain:0.029857864376268896 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 179/14 ⇜ (829/64 → 415/32) ⇝ 365/28 | note:76 gain:0.029857864376268896 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 179/14 ⇜ (829/64 → 415/32) ⇝ 365/28 | note:77 gain:0.029857864376268896 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 179/14 ⇜ (829/64 → 415/32) ⇝ 365/28 | note:81 gain:0.029857864376268896 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 179/14 ⇜ (415/32 → 831/64) ⇝ 365/28 | note:71 gain:0.024 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 179/14 ⇜ (415/32 → 831/64) ⇝ 365/28 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 179/14 ⇜ (415/32 → 831/64) ⇝ 365/28 | note:77 gain:0.024 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", + "[ 51/4 ⇜ (823/64 → 103/8) | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 51/4 ⇜ (823/64 → 103/8) | note:D5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 51/4 ⇜ (823/64 → 103/8) | note:F5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 179/14 ⇜ (823/64 → 103/8) ⇝ 365/28 | note:71 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 179/14 ⇜ (823/64 → 103/8) ⇝ 365/28 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 179/14 ⇜ (823/64 → 103/8) ⇝ 365/28 | note:77 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 179/14 ⇜ (823/64 → 103/8) ⇝ 365/28 | note:81 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 179/14 ⇜ (103/8 → 825/64) ⇝ 365/28 | note:71 gain:0.044 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 179/14 ⇜ (103/8 → 825/64) ⇝ 365/28 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 179/14 ⇜ (103/8 → 825/64) ⇝ 365/28 | note:77 gain:0.044 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 179/14 ⇜ (103/8 → 825/64) ⇝ 365/28 | note:81 gain:0.044 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 179/14 ⇜ (825/64 → 413/32) ⇝ 365/28 | note:71 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 179/14 ⇜ (825/64 → 413/32) ⇝ 365/28 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 179/14 ⇜ (825/64 → 413/32) ⇝ 365/28 | note:77 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 179/14 ⇜ (825/64 → 413/32) ⇝ 365/28 | note:81 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 179/14 ⇜ (413/32 → 827/64) ⇝ 365/28 | note:71 gain:0.064 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 179/14 ⇜ (413/32 → 827/64) ⇝ 365/28 | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 179/14 ⇜ (413/32 → 827/64) ⇝ 365/28 | note:77 gain:0.064 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 179/14 ⇜ (413/32 → 827/64) ⇝ 365/28 | note:81 gain:0.064 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 179/14 ⇜ (827/64 → 207/16) ⇝ 365/28 | note:71 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 179/14 ⇜ (827/64 → 207/16) ⇝ 365/28 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 179/14 ⇜ (827/64 → 207/16) ⇝ 365/28 | note:77 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 179/14 ⇜ (827/64 → 207/16) ⇝ 365/28 | note:81 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 179/14 ⇜ (207/16 → 829/64) ⇝ 365/28 | note:71 gain:0.044 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 179/14 ⇜ (207/16 → 829/64) ⇝ 365/28 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 179/14 ⇜ (207/16 → 829/64) ⇝ 365/28 | note:77 gain:0.044 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 179/14 ⇜ (207/16 → 829/64) ⇝ 365/28 | note:81 gain:0.044 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 179/14 ⇜ (829/64 → 415/32) ⇝ 365/28 | note:71 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 179/14 ⇜ (829/64 → 415/32) ⇝ 365/28 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 179/14 ⇜ (829/64 → 415/32) ⇝ 365/28 | note:77 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 179/14 ⇜ (829/64 → 415/32) ⇝ 365/28 | note:81 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 179/14 ⇜ (415/32 → 831/64) ⇝ 365/28 | note:71 gain:0.024 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 179/14 ⇜ (415/32 → 831/64) ⇝ 365/28 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 179/14 ⇜ (415/32 → 831/64) ⇝ 365/28 | note:77 gain:0.024 clip:1 s:piano release:0.1 pan:0.606481481481 ]", "[ 179/14 ⇜ (415/32 → 831/64) ⇝ 365/28 | note:81 gain:0.024 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 179/14 ⇜ (831/64 → 13/1) ⇝ 365/28 | note:71 gain:0.02985786437626833 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 179/14 ⇜ (831/64 → 13/1) ⇝ 365/28 | note:76 gain:0.02985786437626833 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 179/14 ⇜ (831/64 → 13/1) ⇝ 365/28 | note:77 gain:0.02985786437626833 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 179/14 ⇜ (831/64 → 13/1) ⇝ 365/28 | note:81 gain:0.02985786437626833 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 179/14 ⇜ (13/1 → 833/64) ⇝ 365/28 | note:71 gain:0.04400000000000063 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 179/14 ⇜ (13/1 → 833/64) ⇝ 365/28 | note:76 gain:0.04400000000000063 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 179/14 ⇜ (13/1 → 833/64) ⇝ 365/28 | note:77 gain:0.04400000000000063 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 179/14 ⇜ (13/1 → 833/64) ⇝ 365/28 | note:81 gain:0.04400000000000063 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ (13/1 → 833/64) ⇝ 53/4 | note:G2 gain:0.4400000000000063 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 179/14 ⇜ (833/64 → 417/32) ⇝ 365/28 | note:71 gain:0.05814213562373095 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 179/14 ⇜ (833/64 → 417/32) ⇝ 365/28 | note:76 gain:0.05814213562373095 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 179/14 ⇜ (833/64 → 417/32) ⇝ 365/28 | note:77 gain:0.05814213562373095 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 179/14 ⇜ (833/64 → 417/32) ⇝ 365/28 | note:81 gain:0.05814213562373095 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 13/1 ⇜ (833/64 → 417/32) ⇝ 53/4 | note:G2 gain:0.5814213562373095 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 179/14 ⇜ (417/32 → 365/28) | note:71 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 179/14 ⇜ (417/32 → 365/28) | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 179/14 ⇜ (417/32 → 365/28) | note:77 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 179/14 ⇜ (417/32 → 365/28) | note:81 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 13/1 ⇜ (417/32 → 835/64) ⇝ 53/4 | note:G2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 13/1 ⇜ (835/64 → 209/16) ⇝ 53/4 | note:G2 gain:0.5814213562373184 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 13/1 ⇜ (209/16 → 837/64) ⇝ 53/4 | note:G2 gain:0.4399999999999959 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 13/1 ⇜ (837/64 → 419/32) ⇝ 53/4 | note:G2 gain:0.298578643762692 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 13/1 ⇜ (419/32 → 839/64) ⇝ 53/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 13/1 ⇜ (839/64 → 105/8) ⇝ 53/4 | note:G2 gain:0.29857864376268023 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 13/1 ⇜ (105/8 → 841/64) ⇝ 53/4 | note:G2 gain:0.440000000000002 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ (105/8 → 841/64) ⇝ 53/4 | note:G4 gain:0.440000000000002 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (105/8 → 841/64) ⇝ 53/4 | note:D5 gain:0.440000000000002 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (105/8 → 841/64) ⇝ 53/4 | note:F5 gain:0.440000000000002 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 13/1 ⇜ (841/64 → 421/32) ⇝ 53/4 | note:G2 gain:0.5814213562373064 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 105/8 ⇜ (841/64 → 421/32) ⇝ 53/4 | note:G4 gain:0.5814213562373064 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 105/8 ⇜ (841/64 → 421/32) ⇝ 53/4 | note:D5 gain:0.5814213562373064 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 105/8 ⇜ (841/64 → 421/32) ⇝ 53/4 | note:F5 gain:0.5814213562373064 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 13/1 ⇜ (421/32 → 843/64) ⇝ 53/4 | note:G2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 105/8 ⇜ (421/32 → 843/64) ⇝ 53/4 | note:G4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 105/8 ⇜ (421/32 → 843/64) ⇝ 53/4 | note:D5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 105/8 ⇜ (421/32 → 843/64) ⇝ 53/4 | note:F5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 13/1 ⇜ (843/64 → 211/16) ⇝ 53/4 | note:G2 gain:0.5814213562373052 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 105/8 ⇜ (843/64 → 211/16) ⇝ 53/4 | note:G4 gain:0.5814213562373052 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 105/8 ⇜ (843/64 → 211/16) ⇝ 53/4 | note:D5 gain:0.5814213562373052 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 105/8 ⇜ (843/64 → 211/16) ⇝ 53/4 | note:F5 gain:0.5814213562373052 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 13/1 ⇜ (211/16 → 845/64) ⇝ 53/4 | note:G2 gain:0.4400000000000002 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 105/8 ⇜ (211/16 → 845/64) ⇝ 53/4 | note:G4 gain:0.4400000000000002 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 105/8 ⇜ (211/16 → 845/64) ⇝ 53/4 | note:D5 gain:0.4400000000000002 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 105/8 ⇜ (211/16 → 845/64) ⇝ 53/4 | note:F5 gain:0.4400000000000002 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 13/1 ⇜ (845/64 → 423/32) ⇝ 53/4 | note:G2 gain:0.29857864376269505 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 105/8 ⇜ (845/64 → 423/32) ⇝ 53/4 | note:G4 gain:0.29857864376269505 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 105/8 ⇜ (845/64 → 423/32) ⇝ 53/4 | note:D5 gain:0.29857864376269505 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 105/8 ⇜ (845/64 → 423/32) ⇝ 53/4 | note:F5 gain:0.29857864376269505 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 13/1 ⇜ (423/32 → 847/64) ⇝ 53/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 105/8 ⇜ (423/32 → 847/64) ⇝ 53/4 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 105/8 ⇜ (423/32 → 847/64) ⇝ 53/4 | note:D5 gain:0.24 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 105/8 ⇜ (423/32 → 847/64) ⇝ 53/4 | note:F5 gain:0.24 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 13/1 ⇜ (847/64 → 53/4) | note:G2 gain:0.2985786437626932 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 105/8 ⇜ (847/64 → 53/4) | note:G4 gain:0.2985786437626932 clip:1 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 105/8 ⇜ (847/64 → 53/4) | note:D5 gain:0.2985786437626932 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 105/8 ⇜ (847/64 → 53/4) | note:F5 gain:0.2985786437626932 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ (53/4 → 849/64) ⇝ 27/2 | note:B3 gain:0.21999999999999884 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ (53/4 → 849/64) ⇝ 27/2 | note:E4 gain:0.21999999999999884 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (53/4 → 849/64) ⇝ 27/2 | note:F4 gain:0.21999999999999884 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (53/4 → 849/64) ⇝ 27/2 | note:A4 gain:0.21999999999999884 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 53/4 ⇜ (849/64 → 425/32) ⇝ 27/2 | note:B3 gain:0.2907106781186517 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 53/4 ⇜ (849/64 → 425/32) ⇝ 27/2 | note:E4 gain:0.2907106781186517 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 53/4 ⇜ (849/64 → 425/32) ⇝ 27/2 | note:F4 gain:0.2907106781186517 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 53/4 ⇜ (849/64 → 425/32) ⇝ 27/2 | note:A4 gain:0.2907106781186517 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 53/4 ⇜ (425/32 → 851/64) ⇝ 27/2 | note:B3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 53/4 ⇜ (425/32 → 851/64) ⇝ 27/2 | note:E4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 53/4 ⇜ (425/32 → 851/64) ⇝ 27/2 | note:F4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 53/4 ⇜ (425/32 → 851/64) ⇝ 27/2 | note:A4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 53/4 ⇜ (851/64 → 213/16) ⇝ 27/2 | note:B3 gain:0.29071067811865414 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 53/4 ⇜ (851/64 → 213/16) ⇝ 27/2 | note:E4 gain:0.29071067811865414 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 53/4 ⇜ (851/64 → 213/16) ⇝ 27/2 | note:F4 gain:0.29071067811865414 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 53/4 ⇜ (851/64 → 213/16) ⇝ 27/2 | note:A4 gain:0.29071067811865414 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 53/4 ⇜ (213/16 → 853/64) ⇝ 27/2 | note:B3 gain:0.22000000000000225 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 53/4 ⇜ (213/16 → 853/64) ⇝ 27/2 | note:E4 gain:0.22000000000000225 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 53/4 ⇜ (213/16 → 853/64) ⇝ 27/2 | note:F4 gain:0.22000000000000225 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 53/4 ⇜ (213/16 → 853/64) ⇝ 27/2 | note:A4 gain:0.22000000000000225 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 53/4 ⇜ (853/64 → 427/32) ⇝ 27/2 | note:B3 gain:0.14928932188134905 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 53/4 ⇜ (853/64 → 427/32) ⇝ 27/2 | note:E4 gain:0.14928932188134905 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 53/4 ⇜ (853/64 → 427/32) ⇝ 27/2 | note:F4 gain:0.14928932188134905 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 53/4 ⇜ (853/64 → 427/32) ⇝ 27/2 | note:A4 gain:0.14928932188134905 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 53/4 ⇜ (427/32 → 855/64) ⇝ 27/2 | note:B3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 53/4 ⇜ (427/32 → 855/64) ⇝ 27/2 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 53/4 ⇜ (427/32 → 855/64) ⇝ 27/2 | note:F4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 53/4 ⇜ (427/32 → 855/64) ⇝ 27/2 | note:A4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 53/4 ⇜ (855/64 → 107/8) ⇝ 27/2 | note:B3 gain:0.1492893218813451 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 53/4 ⇜ (855/64 → 107/8) ⇝ 27/2 | note:E4 gain:0.1492893218813451 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 53/4 ⇜ (855/64 → 107/8) ⇝ 27/2 | note:F4 gain:0.1492893218813451 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 53/4 ⇜ (855/64 → 107/8) ⇝ 27/2 | note:A4 gain:0.1492893218813451 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 53/4 ⇜ (107/8 → 857/64) ⇝ 27/2 | note:B3 gain:0.21999999999999664 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 53/4 ⇜ (107/8 → 857/64) ⇝ 27/2 | note:E4 gain:0.21999999999999664 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 53/4 ⇜ (107/8 → 857/64) ⇝ 27/2 | note:F4 gain:0.21999999999999664 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 53/4 ⇜ (107/8 → 857/64) ⇝ 27/2 | note:A4 gain:0.21999999999999664 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 53/4 ⇜ (857/64 → 429/32) ⇝ 27/2 | note:B3 gain:0.2907106781186502 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 53/4 ⇜ (857/64 → 429/32) ⇝ 27/2 | note:E4 gain:0.2907106781186502 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 53/4 ⇜ (857/64 → 429/32) ⇝ 27/2 | note:F4 gain:0.2907106781186502 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 53/4 ⇜ (857/64 → 429/32) ⇝ 27/2 | note:A4 gain:0.2907106781186502 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 53/4 ⇜ (429/32 → 859/64) ⇝ 27/2 | note:B3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 53/4 ⇜ (429/32 → 859/64) ⇝ 27/2 | note:E4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 53/4 ⇜ (429/32 → 859/64) ⇝ 27/2 | note:F4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 53/4 ⇜ (429/32 → 859/64) ⇝ 27/2 | note:A4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 53/4 ⇜ (859/64 → 215/16) ⇝ 27/2 | note:B3 gain:0.2907106781186557 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 53/4 ⇜ (859/64 → 215/16) ⇝ 27/2 | note:E4 gain:0.2907106781186557 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 53/4 ⇜ (859/64 → 215/16) ⇝ 27/2 | note:F4 gain:0.2907106781186557 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 53/4 ⇜ (859/64 → 215/16) ⇝ 27/2 | note:A4 gain:0.2907106781186557 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 53/4 ⇜ (215/16 → 861/64) ⇝ 27/2 | note:B3 gain:0.22000000000000441 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 53/4 ⇜ (215/16 → 861/64) ⇝ 27/2 | note:E4 gain:0.22000000000000441 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 53/4 ⇜ (215/16 → 861/64) ⇝ 27/2 | note:F4 gain:0.22000000000000441 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 53/4 ⇜ (215/16 → 861/64) ⇝ 27/2 | note:A4 gain:0.22000000000000441 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 53/4 ⇜ (861/64 → 431/32) ⇝ 27/2 | note:B3 gain:0.14928932188135055 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 53/4 ⇜ (861/64 → 431/32) ⇝ 27/2 | note:E4 gain:0.14928932188135055 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 53/4 ⇜ (861/64 → 431/32) ⇝ 27/2 | note:F4 gain:0.14928932188135055 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 53/4 ⇜ (861/64 → 431/32) ⇝ 27/2 | note:A4 gain:0.14928932188135055 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 53/4 ⇜ (431/32 → 863/64) ⇝ 27/2 | note:B3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 53/4 ⇜ (431/32 → 863/64) ⇝ 27/2 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 53/4 ⇜ (431/32 → 863/64) ⇝ 27/2 | note:F4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 53/4 ⇜ (431/32 → 863/64) ⇝ 27/2 | note:A4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 53/4 ⇜ (863/64 → 27/2) | note:B3 gain:0.14928932188134356 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 53/4 ⇜ (863/64 → 27/2) | note:E4 gain:0.14928932188134356 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 53/4 ⇜ (863/64 → 27/2) | note:F4 gain:0.14928932188134356 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 53/4 ⇜ (863/64 → 27/2) | note:A4 gain:0.14928932188134356 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (27/2 → 865/64) ⇝ 109/8 | note:D5 gain:0.43999999999998907 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (27/2 → 865/64) ⇝ 109/8 | note:A5 gain:0.43999999999998907 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ (27/2 → 865/64) ⇝ 109/8 | note:C6 gain:0.43999999999998907 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ (27/2 → 865/64) ⇝ 55/4 | note:G2 gain:0.43999999999998907 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 27/2 ⇜ (865/64 → 433/32) ⇝ 109/8 | note:D5 gain:0.5814213562373134 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 27/2 ⇜ (865/64 → 433/32) ⇝ 109/8 | note:A5 gain:0.5814213562373134 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 27/2 ⇜ (865/64 → 433/32) ⇝ 109/8 | note:C6 gain:0.5814213562373134 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 27/2 ⇜ (865/64 → 433/32) ⇝ 55/4 | note:G2 gain:0.5814213562373134 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 27/2 ⇜ (433/32 → 867/64) ⇝ 109/8 | note:D5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 27/2 ⇜ (433/32 → 867/64) ⇝ 109/8 | note:A5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 27/2 ⇜ (433/32 → 867/64) ⇝ 109/8 | note:C6 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 27/2 ⇜ (433/32 → 867/64) ⇝ 55/4 | note:G2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ (379/28 → 867/64) ⇝ 193/14 | note:71 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ (379/28 → 867/64) ⇝ 193/14 | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ (379/28 → 867/64) ⇝ 193/14 | note:77 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ (379/28 → 867/64) ⇝ 193/14 | note:81 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 27/2 ⇜ (867/64 → 217/16) ⇝ 109/8 | note:D5 gain:0.5814213562373144 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 27/2 ⇜ (867/64 → 217/16) ⇝ 109/8 | note:A5 gain:0.5814213562373144 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 27/2 ⇜ (867/64 → 217/16) ⇝ 109/8 | note:C6 gain:0.5814213562373144 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 27/2 ⇜ (867/64 → 217/16) ⇝ 55/4 | note:G2 gain:0.5814213562373144 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 379/28 ⇜ (867/64 → 217/16) ⇝ 193/14 | note:71 gain:0.05814213562373144 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 379/28 ⇜ (867/64 → 217/16) ⇝ 193/14 | note:76 gain:0.05814213562373144 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 379/28 ⇜ (867/64 → 217/16) ⇝ 193/14 | note:77 gain:0.05814213562373144 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 379/28 ⇜ (867/64 → 217/16) ⇝ 193/14 | note:81 gain:0.05814213562373144 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 27/2 ⇜ (217/16 → 869/64) ⇝ 109/8 | note:D5 gain:0.4400000000000132 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 27/2 ⇜ (217/16 → 869/64) ⇝ 109/8 | note:A5 gain:0.4400000000000132 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 27/2 ⇜ (217/16 → 869/64) ⇝ 109/8 | note:C6 gain:0.4400000000000132 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 27/2 ⇜ (217/16 → 869/64) ⇝ 55/4 | note:G2 gain:0.4400000000000132 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 379/28 ⇜ (217/16 → 869/64) ⇝ 193/14 | note:71 gain:0.04400000000000132 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 379/28 ⇜ (217/16 → 869/64) ⇝ 193/14 | note:76 gain:0.04400000000000132 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 379/28 ⇜ (217/16 → 869/64) ⇝ 193/14 | note:77 gain:0.04400000000000132 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 379/28 ⇜ (217/16 → 869/64) ⇝ 193/14 | note:81 gain:0.04400000000000132 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 27/2 ⇜ (869/64 → 435/32) ⇝ 109/8 | note:D5 gain:0.2985786437626881 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 27/2 ⇜ (869/64 → 435/32) ⇝ 109/8 | note:A5 gain:0.2985786437626881 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 27/2 ⇜ (869/64 → 435/32) ⇝ 109/8 | note:C6 gain:0.2985786437626881 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 27/2 ⇜ (869/64 → 435/32) ⇝ 55/4 | note:G2 gain:0.2985786437626881 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 379/28 ⇜ (869/64 → 435/32) ⇝ 193/14 | note:71 gain:0.029857864376268813 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 379/28 ⇜ (869/64 → 435/32) ⇝ 193/14 | note:76 gain:0.029857864376268813 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 379/28 ⇜ (869/64 → 435/32) ⇝ 193/14 | note:77 gain:0.029857864376268813 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 379/28 ⇜ (869/64 → 435/32) ⇝ 193/14 | note:81 gain:0.029857864376268813 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 27/2 ⇜ (435/32 → 871/64) ⇝ 109/8 | note:D5 gain:0.24 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", + "[ 179/14 ⇜ (831/64 → 13/1) ⇝ 365/28 | note:71 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 179/14 ⇜ (831/64 → 13/1) ⇝ 365/28 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 179/14 ⇜ (831/64 → 13/1) ⇝ 365/28 | note:77 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 179/14 ⇜ (831/64 → 13/1) ⇝ 365/28 | note:81 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 179/14 ⇜ (13/1 → 833/64) ⇝ 365/28 | note:71 gain:0.044 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 179/14 ⇜ (13/1 → 833/64) ⇝ 365/28 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 179/14 ⇜ (13/1 → 833/64) ⇝ 365/28 | note:77 gain:0.044 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 179/14 ⇜ (13/1 → 833/64) ⇝ 365/28 | note:81 gain:0.044 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ (13/1 → 833/64) ⇝ 53/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 179/14 ⇜ (833/64 → 417/32) ⇝ 365/28 | note:71 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 179/14 ⇜ (833/64 → 417/32) ⇝ 365/28 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 179/14 ⇜ (833/64 → 417/32) ⇝ 365/28 | note:77 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 179/14 ⇜ (833/64 → 417/32) ⇝ 365/28 | note:81 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 13/1 ⇜ (833/64 → 417/32) ⇝ 53/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 179/14 ⇜ (417/32 → 365/28) | note:71 gain:0.064 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 179/14 ⇜ (417/32 → 365/28) | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 179/14 ⇜ (417/32 → 365/28) | note:77 gain:0.064 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 179/14 ⇜ (417/32 → 365/28) | note:81 gain:0.064 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 13/1 ⇜ (417/32 → 835/64) ⇝ 53/4 | note:G2 gain:0.64 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 13/1 ⇜ (835/64 → 209/16) ⇝ 53/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 13/1 ⇜ (209/16 → 837/64) ⇝ 53/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 13/1 ⇜ (837/64 → 419/32) ⇝ 53/4 | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 13/1 ⇜ (419/32 → 839/64) ⇝ 53/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 13/1 ⇜ (839/64 → 105/8) ⇝ 53/4 | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 13/1 ⇜ (105/8 → 841/64) ⇝ 53/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ (105/8 → 841/64) ⇝ 53/4 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ (105/8 → 841/64) ⇝ 53/4 | note:D5 gain:0.44 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ (105/8 → 841/64) ⇝ 53/4 | note:F5 gain:0.44 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 13/1 ⇜ (841/64 → 421/32) ⇝ 53/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 105/8 ⇜ (841/64 → 421/32) ⇝ 53/4 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 105/8 ⇜ (841/64 → 421/32) ⇝ 53/4 | note:D5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 105/8 ⇜ (841/64 → 421/32) ⇝ 53/4 | note:F5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 13/1 ⇜ (421/32 → 843/64) ⇝ 53/4 | note:G2 gain:0.64 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 105/8 ⇜ (421/32 → 843/64) ⇝ 53/4 | note:G4 gain:0.64 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 105/8 ⇜ (421/32 → 843/64) ⇝ 53/4 | note:D5 gain:0.64 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 105/8 ⇜ (421/32 → 843/64) ⇝ 53/4 | note:F5 gain:0.64 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 13/1 ⇜ (843/64 → 211/16) ⇝ 53/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 105/8 ⇜ (843/64 → 211/16) ⇝ 53/4 | note:G4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 105/8 ⇜ (843/64 → 211/16) ⇝ 53/4 | note:D5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 105/8 ⇜ (843/64 → 211/16) ⇝ 53/4 | note:F5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 13/1 ⇜ (211/16 → 845/64) ⇝ 53/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 105/8 ⇜ (211/16 → 845/64) ⇝ 53/4 | note:G4 gain:0.44 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 105/8 ⇜ (211/16 → 845/64) ⇝ 53/4 | note:D5 gain:0.44 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 105/8 ⇜ (211/16 → 845/64) ⇝ 53/4 | note:F5 gain:0.44 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 13/1 ⇜ (845/64 → 423/32) ⇝ 53/4 | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 105/8 ⇜ (845/64 → 423/32) ⇝ 53/4 | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 105/8 ⇜ (845/64 → 423/32) ⇝ 53/4 | note:D5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 105/8 ⇜ (845/64 → 423/32) ⇝ 53/4 | note:F5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 13/1 ⇜ (423/32 → 847/64) ⇝ 53/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 105/8 ⇜ (423/32 → 847/64) ⇝ 53/4 | note:G4 gain:0.24 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 105/8 ⇜ (423/32 → 847/64) ⇝ 53/4 | note:D5 gain:0.24 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 105/8 ⇜ (423/32 → 847/64) ⇝ 53/4 | note:F5 gain:0.24 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 13/1 ⇜ (847/64 → 53/4) | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 105/8 ⇜ (847/64 → 53/4) | note:G4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.560185185185 ]", + "[ 105/8 ⇜ (847/64 → 53/4) | note:D5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 105/8 ⇜ (847/64 → 53/4) | note:F5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ (53/4 → 849/64) ⇝ 27/2 | note:B3 gain:0.22 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ (53/4 → 849/64) ⇝ 27/2 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (53/4 → 849/64) ⇝ 27/2 | note:F4 gain:0.22 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ (53/4 → 849/64) ⇝ 27/2 | note:A4 gain:0.22 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 53/4 ⇜ (849/64 → 425/32) ⇝ 27/2 | note:B3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 53/4 ⇜ (849/64 → 425/32) ⇝ 27/2 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 53/4 ⇜ (849/64 → 425/32) ⇝ 27/2 | note:F4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 53/4 ⇜ (849/64 → 425/32) ⇝ 27/2 | note:A4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 53/4 ⇜ (425/32 → 851/64) ⇝ 27/2 | note:B3 gain:0.32 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 53/4 ⇜ (425/32 → 851/64) ⇝ 27/2 | note:E4 gain:0.32 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 53/4 ⇜ (425/32 → 851/64) ⇝ 27/2 | note:F4 gain:0.32 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 53/4 ⇜ (425/32 → 851/64) ⇝ 27/2 | note:A4 gain:0.32 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 53/4 ⇜ (851/64 → 213/16) ⇝ 27/2 | note:B3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 53/4 ⇜ (851/64 → 213/16) ⇝ 27/2 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 53/4 ⇜ (851/64 → 213/16) ⇝ 27/2 | note:F4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 53/4 ⇜ (851/64 → 213/16) ⇝ 27/2 | note:A4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 53/4 ⇜ (213/16 → 853/64) ⇝ 27/2 | note:B3 gain:0.22 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 53/4 ⇜ (213/16 → 853/64) ⇝ 27/2 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 53/4 ⇜ (213/16 → 853/64) ⇝ 27/2 | note:F4 gain:0.22 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 53/4 ⇜ (213/16 → 853/64) ⇝ 27/2 | note:A4 gain:0.22 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 53/4 ⇜ (853/64 → 427/32) ⇝ 27/2 | note:B3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 53/4 ⇜ (853/64 → 427/32) ⇝ 27/2 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 53/4 ⇜ (853/64 → 427/32) ⇝ 27/2 | note:F4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 53/4 ⇜ (853/64 → 427/32) ⇝ 27/2 | note:A4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 53/4 ⇜ (427/32 → 855/64) ⇝ 27/2 | note:B3 gain:0.12 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 53/4 ⇜ (427/32 → 855/64) ⇝ 27/2 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 53/4 ⇜ (427/32 → 855/64) ⇝ 27/2 | note:F4 gain:0.12 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 53/4 ⇜ (427/32 → 855/64) ⇝ 27/2 | note:A4 gain:0.12 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 53/4 ⇜ (855/64 → 107/8) ⇝ 27/2 | note:B3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 53/4 ⇜ (855/64 → 107/8) ⇝ 27/2 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 53/4 ⇜ (855/64 → 107/8) ⇝ 27/2 | note:F4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 53/4 ⇜ (855/64 → 107/8) ⇝ 27/2 | note:A4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 53/4 ⇜ (107/8 → 857/64) ⇝ 27/2 | note:B3 gain:0.22 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 53/4 ⇜ (107/8 → 857/64) ⇝ 27/2 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 53/4 ⇜ (107/8 → 857/64) ⇝ 27/2 | note:F4 gain:0.22 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 53/4 ⇜ (107/8 → 857/64) ⇝ 27/2 | note:A4 gain:0.22 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 53/4 ⇜ (857/64 → 429/32) ⇝ 27/2 | note:B3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 53/4 ⇜ (857/64 → 429/32) ⇝ 27/2 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 53/4 ⇜ (857/64 → 429/32) ⇝ 27/2 | note:F4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 53/4 ⇜ (857/64 → 429/32) ⇝ 27/2 | note:A4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 53/4 ⇜ (429/32 → 859/64) ⇝ 27/2 | note:B3 gain:0.32 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 53/4 ⇜ (429/32 → 859/64) ⇝ 27/2 | note:E4 gain:0.32 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 53/4 ⇜ (429/32 → 859/64) ⇝ 27/2 | note:F4 gain:0.32 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 53/4 ⇜ (429/32 → 859/64) ⇝ 27/2 | note:A4 gain:0.32 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 53/4 ⇜ (859/64 → 215/16) ⇝ 27/2 | note:B3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 53/4 ⇜ (859/64 → 215/16) ⇝ 27/2 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 53/4 ⇜ (859/64 → 215/16) ⇝ 27/2 | note:F4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 53/4 ⇜ (859/64 → 215/16) ⇝ 27/2 | note:A4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 53/4 ⇜ (215/16 → 861/64) ⇝ 27/2 | note:B3 gain:0.22 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 53/4 ⇜ (215/16 → 861/64) ⇝ 27/2 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 53/4 ⇜ (215/16 → 861/64) ⇝ 27/2 | note:F4 gain:0.22 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 53/4 ⇜ (215/16 → 861/64) ⇝ 27/2 | note:A4 gain:0.22 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 53/4 ⇜ (861/64 → 431/32) ⇝ 27/2 | note:B3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 53/4 ⇜ (861/64 → 431/32) ⇝ 27/2 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 53/4 ⇜ (861/64 → 431/32) ⇝ 27/2 | note:F4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 53/4 ⇜ (861/64 → 431/32) ⇝ 27/2 | note:A4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 53/4 ⇜ (431/32 → 863/64) ⇝ 27/2 | note:B3 gain:0.12 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 53/4 ⇜ (431/32 → 863/64) ⇝ 27/2 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 53/4 ⇜ (431/32 → 863/64) ⇝ 27/2 | note:F4 gain:0.12 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 53/4 ⇜ (431/32 → 863/64) ⇝ 27/2 | note:A4 gain:0.12 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 53/4 ⇜ (863/64 → 27/2) | note:B3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 53/4 ⇜ (863/64 → 27/2) | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 53/4 ⇜ (863/64 → 27/2) | note:F4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 53/4 ⇜ (863/64 → 27/2) | note:A4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ (27/2 → 865/64) ⇝ 109/8 | note:D5 gain:0.44 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ (27/2 → 865/64) ⇝ 109/8 | note:A5 gain:0.44 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ (27/2 → 865/64) ⇝ 109/8 | note:C6 gain:0.44 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ (27/2 → 865/64) ⇝ 55/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 27/2 ⇜ (865/64 → 433/32) ⇝ 109/8 | note:D5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 27/2 ⇜ (865/64 → 433/32) ⇝ 109/8 | note:A5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 27/2 ⇜ (865/64 → 433/32) ⇝ 109/8 | note:C6 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 27/2 ⇜ (865/64 → 433/32) ⇝ 55/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 27/2 ⇜ (433/32 → 867/64) ⇝ 109/8 | note:D5 gain:0.64 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 27/2 ⇜ (433/32 → 867/64) ⇝ 109/8 | note:A5 gain:0.64 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 27/2 ⇜ (433/32 → 867/64) ⇝ 109/8 | note:C6 gain:0.64 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 27/2 ⇜ (433/32 → 867/64) ⇝ 55/4 | note:G2 gain:0.64 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ (379/28 → 867/64) ⇝ 193/14 | note:71 gain:0.064 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ (379/28 → 867/64) ⇝ 193/14 | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ (379/28 → 867/64) ⇝ 193/14 | note:77 gain:0.064 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ (379/28 → 867/64) ⇝ 193/14 | note:81 gain:0.064 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 27/2 ⇜ (867/64 → 217/16) ⇝ 109/8 | note:D5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 27/2 ⇜ (867/64 → 217/16) ⇝ 109/8 | note:A5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 27/2 ⇜ (867/64 → 217/16) ⇝ 109/8 | note:C6 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 27/2 ⇜ (867/64 → 217/16) ⇝ 55/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 379/28 ⇜ (867/64 → 217/16) ⇝ 193/14 | note:71 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 379/28 ⇜ (867/64 → 217/16) ⇝ 193/14 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 379/28 ⇜ (867/64 → 217/16) ⇝ 193/14 | note:77 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 379/28 ⇜ (867/64 → 217/16) ⇝ 193/14 | note:81 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 27/2 ⇜ (217/16 → 869/64) ⇝ 109/8 | note:D5 gain:0.44 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 27/2 ⇜ (217/16 → 869/64) ⇝ 109/8 | note:A5 gain:0.44 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 27/2 ⇜ (217/16 → 869/64) ⇝ 109/8 | note:C6 gain:0.44 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 27/2 ⇜ (217/16 → 869/64) ⇝ 55/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 379/28 ⇜ (217/16 → 869/64) ⇝ 193/14 | note:71 gain:0.044 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 379/28 ⇜ (217/16 → 869/64) ⇝ 193/14 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 379/28 ⇜ (217/16 → 869/64) ⇝ 193/14 | note:77 gain:0.044 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 379/28 ⇜ (217/16 → 869/64) ⇝ 193/14 | note:81 gain:0.044 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 27/2 ⇜ (869/64 → 435/32) ⇝ 109/8 | note:D5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 27/2 ⇜ (869/64 → 435/32) ⇝ 109/8 | note:A5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 27/2 ⇜ (869/64 → 435/32) ⇝ 109/8 | note:C6 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 27/2 ⇜ (869/64 → 435/32) ⇝ 55/4 | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 379/28 ⇜ (869/64 → 435/32) ⇝ 193/14 | note:71 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 379/28 ⇜ (869/64 → 435/32) ⇝ 193/14 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 379/28 ⇜ (869/64 → 435/32) ⇝ 193/14 | note:77 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 379/28 ⇜ (869/64 → 435/32) ⇝ 193/14 | note:81 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 27/2 ⇜ (435/32 → 871/64) ⇝ 109/8 | note:D5 gain:0.24 clip:1 s:piano release:0.1 pan:0.592592592593 ]", "[ 27/2 ⇜ (435/32 → 871/64) ⇝ 109/8 | note:A5 gain:0.24 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 27/2 ⇜ (435/32 → 871/64) ⇝ 109/8 | note:C6 gain:0.24 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 27/2 ⇜ (435/32 → 871/64) ⇝ 55/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 379/28 ⇜ (435/32 → 871/64) ⇝ 193/14 | note:71 gain:0.024 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 379/28 ⇜ (435/32 → 871/64) ⇝ 193/14 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 379/28 ⇜ (435/32 → 871/64) ⇝ 193/14 | note:77 gain:0.024 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", + "[ 27/2 ⇜ (435/32 → 871/64) ⇝ 109/8 | note:C6 gain:0.24 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 27/2 ⇜ (435/32 → 871/64) ⇝ 55/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 379/28 ⇜ (435/32 → 871/64) ⇝ 193/14 | note:71 gain:0.024 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 379/28 ⇜ (435/32 → 871/64) ⇝ 193/14 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 379/28 ⇜ (435/32 → 871/64) ⇝ 193/14 | note:77 gain:0.024 clip:1 s:piano release:0.1 pan:0.606481481481 ]", "[ 379/28 ⇜ (435/32 → 871/64) ⇝ 193/14 | note:81 gain:0.024 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 27/2 ⇜ (871/64 → 109/8) | note:D5 gain:0.29857864376268406 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 27/2 ⇜ (871/64 → 109/8) | note:A5 gain:0.29857864376268406 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 27/2 ⇜ (871/64 → 109/8) | note:C6 gain:0.29857864376268406 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 27/2 ⇜ (871/64 → 109/8) ⇝ 55/4 | note:G2 gain:0.29857864376268406 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 379/28 ⇜ (871/64 → 109/8) ⇝ 193/14 | note:71 gain:0.029857864376268407 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 379/28 ⇜ (871/64 → 109/8) ⇝ 193/14 | note:76 gain:0.029857864376268407 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 379/28 ⇜ (871/64 → 109/8) ⇝ 193/14 | note:77 gain:0.029857864376268407 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 379/28 ⇜ (871/64 → 109/8) ⇝ 193/14 | note:81 gain:0.029857864376268407 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 27/2 ⇜ (109/8 → 873/64) ⇝ 55/4 | note:G2 gain:0.4399999999999848 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 379/28 ⇜ (109/8 → 873/64) ⇝ 193/14 | note:71 gain:0.043999999999998485 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 379/28 ⇜ (109/8 → 873/64) ⇝ 193/14 | note:76 gain:0.043999999999998485 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 379/28 ⇜ (109/8 → 873/64) ⇝ 193/14 | note:77 gain:0.043999999999998485 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 379/28 ⇜ (109/8 → 873/64) ⇝ 193/14 | note:81 gain:0.043999999999998485 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 27/2 ⇜ (873/64 → 437/32) ⇝ 55/4 | note:G2 gain:0.5814213562373104 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 379/28 ⇜ (873/64 → 437/32) ⇝ 193/14 | note:71 gain:0.058142135623731044 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 379/28 ⇜ (873/64 → 437/32) ⇝ 193/14 | note:76 gain:0.058142135623731044 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 379/28 ⇜ (873/64 → 437/32) ⇝ 193/14 | note:77 gain:0.058142135623731044 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 379/28 ⇜ (873/64 → 437/32) ⇝ 193/14 | note:81 gain:0.058142135623731044 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 27/2 ⇜ (437/32 → 875/64) ⇝ 55/4 | note:G2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 379/28 ⇜ (437/32 → 875/64) ⇝ 193/14 | note:71 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 379/28 ⇜ (437/32 → 875/64) ⇝ 193/14 | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 379/28 ⇜ (437/32 → 875/64) ⇝ 193/14 | note:77 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 379/28 ⇜ (437/32 → 875/64) ⇝ 193/14 | note:81 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 27/2 ⇜ (875/64 → 219/16) ⇝ 55/4 | note:G2 gain:0.5814213562373175 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 379/28 ⇜ (875/64 → 219/16) ⇝ 193/14 | note:71 gain:0.05814213562373175 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 379/28 ⇜ (875/64 → 219/16) ⇝ 193/14 | note:76 gain:0.05814213562373175 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 379/28 ⇜ (875/64 → 219/16) ⇝ 193/14 | note:77 gain:0.05814213562373175 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 379/28 ⇜ (875/64 → 219/16) ⇝ 193/14 | note:81 gain:0.05814213562373175 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 27/2 ⇜ (219/16 → 877/64) ⇝ 55/4 | note:G2 gain:0.43999999999999473 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 379/28 ⇜ (219/16 → 877/64) ⇝ 193/14 | note:71 gain:0.04399999999999948 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 379/28 ⇜ (219/16 → 877/64) ⇝ 193/14 | note:76 gain:0.04399999999999948 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 379/28 ⇜ (219/16 → 877/64) ⇝ 193/14 | note:77 gain:0.04399999999999948 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 379/28 ⇜ (219/16 → 877/64) ⇝ 193/14 | note:81 gain:0.04399999999999948 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 27/2 ⇜ (877/64 → 439/32) ⇝ 55/4 | note:G2 gain:0.29857864376269116 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 379/28 ⇜ (877/64 → 439/32) ⇝ 193/14 | note:71 gain:0.029857864376269118 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 379/28 ⇜ (877/64 → 439/32) ⇝ 193/14 | note:76 gain:0.029857864376269118 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 379/28 ⇜ (877/64 → 439/32) ⇝ 193/14 | note:77 gain:0.029857864376269118 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 379/28 ⇜ (877/64 → 439/32) ⇝ 193/14 | note:81 gain:0.029857864376269118 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 27/2 ⇜ (439/32 → 879/64) ⇝ 55/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 379/28 ⇜ (439/32 → 879/64) ⇝ 193/14 | note:71 gain:0.024 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 379/28 ⇜ (439/32 → 879/64) ⇝ 193/14 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 379/28 ⇜ (439/32 → 879/64) ⇝ 193/14 | note:77 gain:0.024 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", + "[ 27/2 ⇜ (871/64 → 109/8) | note:D5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 27/2 ⇜ (871/64 → 109/8) | note:A5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 27/2 ⇜ (871/64 → 109/8) | note:C6 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 27/2 ⇜ (871/64 → 109/8) ⇝ 55/4 | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 379/28 ⇜ (871/64 → 109/8) ⇝ 193/14 | note:71 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 379/28 ⇜ (871/64 → 109/8) ⇝ 193/14 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 379/28 ⇜ (871/64 → 109/8) ⇝ 193/14 | note:77 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 379/28 ⇜ (871/64 → 109/8) ⇝ 193/14 | note:81 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 27/2 ⇜ (109/8 → 873/64) ⇝ 55/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 379/28 ⇜ (109/8 → 873/64) ⇝ 193/14 | note:71 gain:0.044 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 379/28 ⇜ (109/8 → 873/64) ⇝ 193/14 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 379/28 ⇜ (109/8 → 873/64) ⇝ 193/14 | note:77 gain:0.044 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 379/28 ⇜ (109/8 → 873/64) ⇝ 193/14 | note:81 gain:0.044 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 27/2 ⇜ (873/64 → 437/32) ⇝ 55/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 379/28 ⇜ (873/64 → 437/32) ⇝ 193/14 | note:71 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 379/28 ⇜ (873/64 → 437/32) ⇝ 193/14 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 379/28 ⇜ (873/64 → 437/32) ⇝ 193/14 | note:77 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 379/28 ⇜ (873/64 → 437/32) ⇝ 193/14 | note:81 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 27/2 ⇜ (437/32 → 875/64) ⇝ 55/4 | note:G2 gain:0.64 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 379/28 ⇜ (437/32 → 875/64) ⇝ 193/14 | note:71 gain:0.064 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 379/28 ⇜ (437/32 → 875/64) ⇝ 193/14 | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 379/28 ⇜ (437/32 → 875/64) ⇝ 193/14 | note:77 gain:0.064 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 379/28 ⇜ (437/32 → 875/64) ⇝ 193/14 | note:81 gain:0.064 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 27/2 ⇜ (875/64 → 219/16) ⇝ 55/4 | note:G2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 379/28 ⇜ (875/64 → 219/16) ⇝ 193/14 | note:71 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 379/28 ⇜ (875/64 → 219/16) ⇝ 193/14 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 379/28 ⇜ (875/64 → 219/16) ⇝ 193/14 | note:77 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 379/28 ⇜ (875/64 → 219/16) ⇝ 193/14 | note:81 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 27/2 ⇜ (219/16 → 877/64) ⇝ 55/4 | note:G2 gain:0.44 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 379/28 ⇜ (219/16 → 877/64) ⇝ 193/14 | note:71 gain:0.044 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 379/28 ⇜ (219/16 → 877/64) ⇝ 193/14 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 379/28 ⇜ (219/16 → 877/64) ⇝ 193/14 | note:77 gain:0.044 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 379/28 ⇜ (219/16 → 877/64) ⇝ 193/14 | note:81 gain:0.044 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 27/2 ⇜ (877/64 → 439/32) ⇝ 55/4 | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 379/28 ⇜ (877/64 → 439/32) ⇝ 193/14 | note:71 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 379/28 ⇜ (877/64 → 439/32) ⇝ 193/14 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 379/28 ⇜ (877/64 → 439/32) ⇝ 193/14 | note:77 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 379/28 ⇜ (877/64 → 439/32) ⇝ 193/14 | note:81 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 27/2 ⇜ (439/32 → 879/64) ⇝ 55/4 | note:G2 gain:0.24 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 379/28 ⇜ (439/32 → 879/64) ⇝ 193/14 | note:71 gain:0.024 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 379/28 ⇜ (439/32 → 879/64) ⇝ 193/14 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 379/28 ⇜ (439/32 → 879/64) ⇝ 193/14 | note:77 gain:0.024 clip:1 s:piano release:0.1 pan:0.606481481481 ]", "[ 379/28 ⇜ (439/32 → 879/64) ⇝ 193/14 | note:81 gain:0.024 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 27/2 ⇜ (879/64 → 55/4) | note:G2 gain:0.29857864376268106 clip:1 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 379/28 ⇜ (879/64 → 55/4) ⇝ 193/14 | note:71 gain:0.02985786437626811 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 379/28 ⇜ (879/64 → 55/4) ⇝ 193/14 | note:76 gain:0.02985786437626811 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 379/28 ⇜ (879/64 → 55/4) ⇝ 193/14 | note:77 gain:0.02985786437626811 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 379/28 ⇜ (879/64 → 55/4) ⇝ 193/14 | note:81 gain:0.02985786437626811 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 379/28 ⇜ (55/4 → 881/64) ⇝ 193/14 | note:71 gain:0.04400000000000032 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 379/28 ⇜ (55/4 → 881/64) ⇝ 193/14 | note:76 gain:0.04400000000000032 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 379/28 ⇜ (55/4 → 881/64) ⇝ 193/14 | note:77 gain:0.04400000000000032 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 379/28 ⇜ (55/4 → 881/64) ⇝ 193/14 | note:81 gain:0.04400000000000032 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ (55/4 → 881/64) ⇝ 111/8 | note:D5 gain:0.44000000000000317 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (55/4 → 881/64) ⇝ 111/8 | note:A5 gain:0.44000000000000317 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ (55/4 → 881/64) ⇝ 111/8 | note:C6 gain:0.44000000000000317 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ (55/4 → 881/64) ⇝ 14/1 | note:B3 gain:0.22000000000000158 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ (55/4 → 881/64) ⇝ 14/1 | note:E4 gain:0.22000000000000158 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (55/4 → 881/64) ⇝ 14/1 | note:F4 gain:0.22000000000000158 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (55/4 → 881/64) ⇝ 14/1 | note:A4 gain:0.22000000000000158 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 379/28 ⇜ (881/64 → 441/32) ⇝ 193/14 | note:71 gain:0.05814213562373073 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 379/28 ⇜ (881/64 → 441/32) ⇝ 193/14 | note:76 gain:0.05814213562373073 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 379/28 ⇜ (881/64 → 441/32) ⇝ 193/14 | note:77 gain:0.05814213562373073 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 379/28 ⇜ (881/64 → 441/32) ⇝ 193/14 | note:81 gain:0.05814213562373073 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 55/4 ⇜ (881/64 → 441/32) ⇝ 111/8 | note:D5 gain:0.5814213562373073 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 55/4 ⇜ (881/64 → 441/32) ⇝ 111/8 | note:A5 gain:0.5814213562373073 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 55/4 ⇜ (881/64 → 441/32) ⇝ 111/8 | note:C6 gain:0.5814213562373073 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 55/4 ⇜ (881/64 → 441/32) ⇝ 14/1 | note:B3 gain:0.29071067811865364 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 55/4 ⇜ (881/64 → 441/32) ⇝ 14/1 | note:E4 gain:0.29071067811865364 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 55/4 ⇜ (881/64 → 441/32) ⇝ 14/1 | note:F4 gain:0.29071067811865364 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 55/4 ⇜ (881/64 → 441/32) ⇝ 14/1 | note:A4 gain:0.29071067811865364 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 379/28 ⇜ (441/32 → 193/14) | note:71 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 379/28 ⇜ (441/32 → 193/14) | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 379/28 ⇜ (441/32 → 193/14) | note:77 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 379/28 ⇜ (441/32 → 193/14) | note:81 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 55/4 ⇜ (441/32 → 883/64) ⇝ 111/8 | note:D5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 55/4 ⇜ (441/32 → 883/64) ⇝ 111/8 | note:A5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 55/4 ⇜ (441/32 → 883/64) ⇝ 111/8 | note:C6 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 55/4 ⇜ (441/32 → 883/64) ⇝ 14/1 | note:B3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 55/4 ⇜ (441/32 → 883/64) ⇝ 14/1 | note:E4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 55/4 ⇜ (441/32 → 883/64) ⇝ 14/1 | note:F4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 55/4 ⇜ (441/32 → 883/64) ⇝ 14/1 | note:A4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 55/4 ⇜ (883/64 → 221/16) ⇝ 111/8 | note:D5 gain:0.5814213562373205 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 55/4 ⇜ (883/64 → 221/16) ⇝ 111/8 | note:A5 gain:0.5814213562373205 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 55/4 ⇜ (883/64 → 221/16) ⇝ 111/8 | note:C6 gain:0.5814213562373205 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 55/4 ⇜ (883/64 → 221/16) ⇝ 14/1 | note:B3 gain:0.29071067811866025 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 55/4 ⇜ (883/64 → 221/16) ⇝ 14/1 | note:E4 gain:0.29071067811866025 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 55/4 ⇜ (883/64 → 221/16) ⇝ 14/1 | note:F4 gain:0.29071067811866025 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 55/4 ⇜ (883/64 → 221/16) ⇝ 14/1 | note:A4 gain:0.29071067811866025 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 55/4 ⇜ (221/16 → 885/64) ⇝ 111/8 | note:D5 gain:0.439999999999999 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 55/4 ⇜ (221/16 → 885/64) ⇝ 111/8 | note:A5 gain:0.439999999999999 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 55/4 ⇜ (221/16 → 885/64) ⇝ 111/8 | note:C6 gain:0.439999999999999 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 55/4 ⇜ (221/16 → 885/64) ⇝ 14/1 | note:B3 gain:0.2199999999999995 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 55/4 ⇜ (221/16 → 885/64) ⇝ 14/1 | note:E4 gain:0.2199999999999995 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 55/4 ⇜ (221/16 → 885/64) ⇝ 14/1 | note:F4 gain:0.2199999999999995 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 55/4 ⇜ (221/16 → 885/64) ⇝ 14/1 | note:A4 gain:0.2199999999999995 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 55/4 ⇜ (885/64 → 443/32) ⇝ 111/8 | note:D5 gain:0.2985786437626942 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 55/4 ⇜ (885/64 → 443/32) ⇝ 111/8 | note:A5 gain:0.2985786437626942 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 55/4 ⇜ (885/64 → 443/32) ⇝ 111/8 | note:C6 gain:0.2985786437626942 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 55/4 ⇜ (885/64 → 443/32) ⇝ 14/1 | note:B3 gain:0.1492893218813471 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 55/4 ⇜ (885/64 → 443/32) ⇝ 14/1 | note:E4 gain:0.1492893218813471 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 55/4 ⇜ (885/64 → 443/32) ⇝ 14/1 | note:F4 gain:0.1492893218813471 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 55/4 ⇜ (885/64 → 443/32) ⇝ 14/1 | note:A4 gain:0.1492893218813471 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 55/4 ⇜ (443/32 → 887/64) ⇝ 111/8 | note:D5 gain:0.24 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", + "[ 27/2 ⇜ (879/64 → 55/4) | note:G2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.449074074074 ]", + "[ 379/28 ⇜ (879/64 → 55/4) ⇝ 193/14 | note:71 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 379/28 ⇜ (879/64 → 55/4) ⇝ 193/14 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 379/28 ⇜ (879/64 → 55/4) ⇝ 193/14 | note:77 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 379/28 ⇜ (879/64 → 55/4) ⇝ 193/14 | note:81 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 379/28 ⇜ (55/4 → 881/64) ⇝ 193/14 | note:71 gain:0.044 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 379/28 ⇜ (55/4 → 881/64) ⇝ 193/14 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 379/28 ⇜ (55/4 → 881/64) ⇝ 193/14 | note:77 gain:0.044 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 379/28 ⇜ (55/4 → 881/64) ⇝ 193/14 | note:81 gain:0.044 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ (55/4 → 881/64) ⇝ 111/8 | note:D5 gain:0.44 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ (55/4 → 881/64) ⇝ 111/8 | note:A5 gain:0.44 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ (55/4 → 881/64) ⇝ 111/8 | note:C6 gain:0.44 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ (55/4 → 881/64) ⇝ 14/1 | note:B3 gain:0.22 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ (55/4 → 881/64) ⇝ 14/1 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (55/4 → 881/64) ⇝ 14/1 | note:F4 gain:0.22 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ (55/4 → 881/64) ⇝ 14/1 | note:A4 gain:0.22 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 379/28 ⇜ (881/64 → 441/32) ⇝ 193/14 | note:71 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 379/28 ⇜ (881/64 → 441/32) ⇝ 193/14 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 379/28 ⇜ (881/64 → 441/32) ⇝ 193/14 | note:77 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 379/28 ⇜ (881/64 → 441/32) ⇝ 193/14 | note:81 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 55/4 ⇜ (881/64 → 441/32) ⇝ 111/8 | note:D5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 55/4 ⇜ (881/64 → 441/32) ⇝ 111/8 | note:A5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 55/4 ⇜ (881/64 → 441/32) ⇝ 111/8 | note:C6 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 55/4 ⇜ (881/64 → 441/32) ⇝ 14/1 | note:B3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 55/4 ⇜ (881/64 → 441/32) ⇝ 14/1 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 55/4 ⇜ (881/64 → 441/32) ⇝ 14/1 | note:F4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 55/4 ⇜ (881/64 → 441/32) ⇝ 14/1 | note:A4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 379/28 ⇜ (441/32 → 193/14) | note:71 gain:0.064 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 379/28 ⇜ (441/32 → 193/14) | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 379/28 ⇜ (441/32 → 193/14) | note:77 gain:0.064 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 379/28 ⇜ (441/32 → 193/14) | note:81 gain:0.064 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 55/4 ⇜ (441/32 → 883/64) ⇝ 111/8 | note:D5 gain:0.64 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 55/4 ⇜ (441/32 → 883/64) ⇝ 111/8 | note:A5 gain:0.64 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 55/4 ⇜ (441/32 → 883/64) ⇝ 111/8 | note:C6 gain:0.64 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 55/4 ⇜ (441/32 → 883/64) ⇝ 14/1 | note:B3 gain:0.32 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 55/4 ⇜ (441/32 → 883/64) ⇝ 14/1 | note:E4 gain:0.32 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 55/4 ⇜ (441/32 → 883/64) ⇝ 14/1 | note:F4 gain:0.32 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 55/4 ⇜ (441/32 → 883/64) ⇝ 14/1 | note:A4 gain:0.32 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 55/4 ⇜ (883/64 → 221/16) ⇝ 111/8 | note:D5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 55/4 ⇜ (883/64 → 221/16) ⇝ 111/8 | note:A5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 55/4 ⇜ (883/64 → 221/16) ⇝ 111/8 | note:C6 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 55/4 ⇜ (883/64 → 221/16) ⇝ 14/1 | note:B3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 55/4 ⇜ (883/64 → 221/16) ⇝ 14/1 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 55/4 ⇜ (883/64 → 221/16) ⇝ 14/1 | note:F4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 55/4 ⇜ (883/64 → 221/16) ⇝ 14/1 | note:A4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 55/4 ⇜ (221/16 → 885/64) ⇝ 111/8 | note:D5 gain:0.44 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 55/4 ⇜ (221/16 → 885/64) ⇝ 111/8 | note:A5 gain:0.44 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 55/4 ⇜ (221/16 → 885/64) ⇝ 111/8 | note:C6 gain:0.44 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 55/4 ⇜ (221/16 → 885/64) ⇝ 14/1 | note:B3 gain:0.22 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 55/4 ⇜ (221/16 → 885/64) ⇝ 14/1 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 55/4 ⇜ (221/16 → 885/64) ⇝ 14/1 | note:F4 gain:0.22 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 55/4 ⇜ (221/16 → 885/64) ⇝ 14/1 | note:A4 gain:0.22 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 55/4 ⇜ (885/64 → 443/32) ⇝ 111/8 | note:D5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 55/4 ⇜ (885/64 → 443/32) ⇝ 111/8 | note:A5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 55/4 ⇜ (885/64 → 443/32) ⇝ 111/8 | note:C6 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 55/4 ⇜ (885/64 → 443/32) ⇝ 14/1 | note:B3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 55/4 ⇜ (885/64 → 443/32) ⇝ 14/1 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 55/4 ⇜ (885/64 → 443/32) ⇝ 14/1 | note:F4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 55/4 ⇜ (885/64 → 443/32) ⇝ 14/1 | note:A4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 55/4 ⇜ (443/32 → 887/64) ⇝ 111/8 | note:D5 gain:0.24 clip:1 s:piano release:0.1 pan:0.592592592593 ]", "[ 55/4 ⇜ (443/32 → 887/64) ⇝ 111/8 | note:A5 gain:0.24 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 55/4 ⇜ (443/32 → 887/64) ⇝ 111/8 | note:C6 gain:0.24 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 55/4 ⇜ (443/32 → 887/64) ⇝ 14/1 | note:B3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 55/4 ⇜ (443/32 → 887/64) ⇝ 14/1 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 55/4 ⇜ (443/32 → 887/64) ⇝ 14/1 | note:F4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 55/4 ⇜ (443/32 → 887/64) ⇝ 14/1 | note:A4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 55/4 ⇜ (887/64 → 111/8) | note:D5 gain:0.29857864376269405 clip:1 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 55/4 ⇜ (887/64 → 111/8) | note:A5 gain:0.29857864376269405 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 55/4 ⇜ (887/64 → 111/8) | note:C6 gain:0.29857864376269405 clip:1 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 55/4 ⇜ (887/64 → 111/8) ⇝ 14/1 | note:B3 gain:0.14928932188134703 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 55/4 ⇜ (887/64 → 111/8) ⇝ 14/1 | note:E4 gain:0.14928932188134703 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 55/4 ⇜ (887/64 → 111/8) ⇝ 14/1 | note:F4 gain:0.14928932188134703 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 55/4 ⇜ (887/64 → 111/8) ⇝ 14/1 | note:A4 gain:0.14928932188134703 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 55/4 ⇜ (111/8 → 889/64) ⇝ 14/1 | note:B3 gain:0.21999999999999942 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 55/4 ⇜ (111/8 → 889/64) ⇝ 14/1 | note:E4 gain:0.21999999999999942 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 55/4 ⇜ (111/8 → 889/64) ⇝ 14/1 | note:F4 gain:0.21999999999999942 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 55/4 ⇜ (111/8 → 889/64) ⇝ 14/1 | note:A4 gain:0.21999999999999942 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 55/4 ⇜ (889/64 → 445/32) ⇝ 14/1 | note:B3 gain:0.29071067811865214 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 55/4 ⇜ (889/64 → 445/32) ⇝ 14/1 | note:E4 gain:0.29071067811865214 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 55/4 ⇜ (889/64 → 445/32) ⇝ 14/1 | note:F4 gain:0.29071067811865214 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 55/4 ⇜ (889/64 → 445/32) ⇝ 14/1 | note:A4 gain:0.29071067811865214 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 55/4 ⇜ (445/32 → 891/64) ⇝ 14/1 | note:B3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 55/4 ⇜ (445/32 → 891/64) ⇝ 14/1 | note:E4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 55/4 ⇜ (445/32 → 891/64) ⇝ 14/1 | note:F4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 55/4 ⇜ (445/32 → 891/64) ⇝ 14/1 | note:A4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 55/4 ⇜ (891/64 → 223/16) ⇝ 14/1 | note:B3 gain:0.29071067811865375 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 55/4 ⇜ (891/64 → 223/16) ⇝ 14/1 | note:E4 gain:0.29071067811865375 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 55/4 ⇜ (891/64 → 223/16) ⇝ 14/1 | note:F4 gain:0.29071067811865375 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 55/4 ⇜ (891/64 → 223/16) ⇝ 14/1 | note:A4 gain:0.29071067811865375 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 55/4 ⇜ (223/16 → 893/64) ⇝ 14/1 | note:B3 gain:0.22000000000000167 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 55/4 ⇜ (223/16 → 893/64) ⇝ 14/1 | note:E4 gain:0.22000000000000167 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 55/4 ⇜ (223/16 → 893/64) ⇝ 14/1 | note:F4 gain:0.22000000000000167 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 55/4 ⇜ (223/16 → 893/64) ⇝ 14/1 | note:A4 gain:0.22000000000000167 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 55/4 ⇜ (893/64 → 447/32) ⇝ 14/1 | note:B3 gain:0.14928932188134864 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 55/4 ⇜ (893/64 → 447/32) ⇝ 14/1 | note:E4 gain:0.14928932188134864 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 55/4 ⇜ (893/64 → 447/32) ⇝ 14/1 | note:F4 gain:0.14928932188134864 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 55/4 ⇜ (893/64 → 447/32) ⇝ 14/1 | note:A4 gain:0.14928932188134864 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 55/4 ⇜ (447/32 → 895/64) ⇝ 14/1 | note:B3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 55/4 ⇜ (447/32 → 895/64) ⇝ 14/1 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 55/4 ⇜ (447/32 → 895/64) ⇝ 14/1 | note:F4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 55/4 ⇜ (447/32 → 895/64) ⇝ 14/1 | note:A4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 55/4 ⇜ (895/64 → 14/1) | note:B3 gain:0.1492893218813455 clip:1 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 55/4 ⇜ (895/64 → 14/1) | note:E4 gain:0.1492893218813455 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 55/4 ⇜ (895/64 → 14/1) | note:F4 gain:0.1492893218813455 clip:1 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 55/4 ⇜ (895/64 → 14/1) | note:A4 gain:0.1492893218813455 clip:1 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (14/1 → 897/64) ⇝ 57/4 | note:F#2 gain:0.43999999999999456 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 14/1 ⇜ (897/64 → 449/32) ⇝ 57/4 | note:F#2 gain:0.5814213562373013 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 14/1 ⇜ (449/32 → 899/64) ⇝ 57/4 | note:F#2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ (393/28 → 899/64) ⇝ 100/7 | note:71 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ (393/28 → 899/64) ⇝ 100/7 | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ (393/28 → 899/64) ⇝ 100/7 | note:77 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ (393/28 → 899/64) ⇝ 100/7 | note:81 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 14/1 ⇜ (899/64 → 225/16) ⇝ 57/4 | note:F#2 gain:0.5814213562373105 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 393/28 ⇜ (899/64 → 225/16) ⇝ 100/7 | note:71 gain:0.05814213562373105 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 393/28 ⇜ (899/64 → 225/16) ⇝ 100/7 | note:76 gain:0.05814213562373105 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 393/28 ⇜ (899/64 → 225/16) ⇝ 100/7 | note:77 gain:0.05814213562373105 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 393/28 ⇜ (899/64 → 225/16) ⇝ 100/7 | note:81 gain:0.05814213562373105 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 14/1 ⇜ (225/16 → 901/64) ⇝ 57/4 | note:F#2 gain:0.4400000000000077 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 393/28 ⇜ (225/16 → 901/64) ⇝ 100/7 | note:71 gain:0.044000000000000775 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 393/28 ⇜ (225/16 → 901/64) ⇝ 100/7 | note:76 gain:0.044000000000000775 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 393/28 ⇜ (225/16 → 901/64) ⇝ 100/7 | note:77 gain:0.044000000000000775 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 393/28 ⇜ (225/16 → 901/64) ⇝ 100/7 | note:81 gain:0.044000000000000775 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 14/1 ⇜ (901/64 → 451/32) ⇝ 57/4 | note:F#2 gain:0.2985786437627003 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 393/28 ⇜ (901/64 → 451/32) ⇝ 100/7 | note:71 gain:0.029857864376270034 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 393/28 ⇜ (901/64 → 451/32) ⇝ 100/7 | note:76 gain:0.029857864376270034 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 393/28 ⇜ (901/64 → 451/32) ⇝ 100/7 | note:77 gain:0.029857864376270034 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 393/28 ⇜ (901/64 → 451/32) ⇝ 100/7 | note:81 gain:0.029857864376270034 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 14/1 ⇜ (451/32 → 903/64) ⇝ 57/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 393/28 ⇜ (451/32 → 903/64) ⇝ 100/7 | note:71 gain:0.024 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 393/28 ⇜ (451/32 → 903/64) ⇝ 100/7 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 393/28 ⇜ (451/32 → 903/64) ⇝ 100/7 | note:77 gain:0.024 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", + "[ 55/4 ⇜ (443/32 → 887/64) ⇝ 111/8 | note:C6 gain:0.24 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 55/4 ⇜ (443/32 → 887/64) ⇝ 14/1 | note:B3 gain:0.12 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 55/4 ⇜ (443/32 → 887/64) ⇝ 14/1 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 55/4 ⇜ (443/32 → 887/64) ⇝ 14/1 | note:F4 gain:0.12 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 55/4 ⇜ (443/32 → 887/64) ⇝ 14/1 | note:A4 gain:0.12 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 55/4 ⇜ (887/64 → 111/8) | note:D5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.592592592593 ]", + "[ 55/4 ⇜ (887/64 → 111/8) | note:A5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 55/4 ⇜ (887/64 → 111/8) | note:C6 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.638888888889 ]", + "[ 55/4 ⇜ (887/64 → 111/8) ⇝ 14/1 | note:B3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 55/4 ⇜ (887/64 → 111/8) ⇝ 14/1 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 55/4 ⇜ (887/64 → 111/8) ⇝ 14/1 | note:F4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 55/4 ⇜ (887/64 → 111/8) ⇝ 14/1 | note:A4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 55/4 ⇜ (111/8 → 889/64) ⇝ 14/1 | note:B3 gain:0.22 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 55/4 ⇜ (111/8 → 889/64) ⇝ 14/1 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 55/4 ⇜ (111/8 → 889/64) ⇝ 14/1 | note:F4 gain:0.22 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 55/4 ⇜ (111/8 → 889/64) ⇝ 14/1 | note:A4 gain:0.22 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 55/4 ⇜ (889/64 → 445/32) ⇝ 14/1 | note:B3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 55/4 ⇜ (889/64 → 445/32) ⇝ 14/1 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 55/4 ⇜ (889/64 → 445/32) ⇝ 14/1 | note:F4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 55/4 ⇜ (889/64 → 445/32) ⇝ 14/1 | note:A4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 55/4 ⇜ (445/32 → 891/64) ⇝ 14/1 | note:B3 gain:0.32 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 55/4 ⇜ (445/32 → 891/64) ⇝ 14/1 | note:E4 gain:0.32 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 55/4 ⇜ (445/32 → 891/64) ⇝ 14/1 | note:F4 gain:0.32 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 55/4 ⇜ (445/32 → 891/64) ⇝ 14/1 | note:A4 gain:0.32 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 55/4 ⇜ (891/64 → 223/16) ⇝ 14/1 | note:B3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 55/4 ⇜ (891/64 → 223/16) ⇝ 14/1 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 55/4 ⇜ (891/64 → 223/16) ⇝ 14/1 | note:F4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 55/4 ⇜ (891/64 → 223/16) ⇝ 14/1 | note:A4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 55/4 ⇜ (223/16 → 893/64) ⇝ 14/1 | note:B3 gain:0.22 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 55/4 ⇜ (223/16 → 893/64) ⇝ 14/1 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 55/4 ⇜ (223/16 → 893/64) ⇝ 14/1 | note:F4 gain:0.22 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 55/4 ⇜ (223/16 → 893/64) ⇝ 14/1 | note:A4 gain:0.22 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 55/4 ⇜ (893/64 → 447/32) ⇝ 14/1 | note:B3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 55/4 ⇜ (893/64 → 447/32) ⇝ 14/1 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 55/4 ⇜ (893/64 → 447/32) ⇝ 14/1 | note:F4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 55/4 ⇜ (893/64 → 447/32) ⇝ 14/1 | note:A4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 55/4 ⇜ (447/32 → 895/64) ⇝ 14/1 | note:B3 gain:0.12 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 55/4 ⇜ (447/32 → 895/64) ⇝ 14/1 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 55/4 ⇜ (447/32 → 895/64) ⇝ 14/1 | note:F4 gain:0.12 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 55/4 ⇜ (447/32 → 895/64) ⇝ 14/1 | note:A4 gain:0.12 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ 55/4 ⇜ (895/64 → 14/1) | note:B3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.523148148148 ]", + "[ 55/4 ⇜ (895/64 → 14/1) | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 55/4 ⇜ (895/64 → 14/1) | note:F4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.550925925926 ]", + "[ 55/4 ⇜ (895/64 → 14/1) | note:A4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.569444444444 ]", + "[ (14/1 → 897/64) ⇝ 57/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 14/1 ⇜ (897/64 → 449/32) ⇝ 57/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 14/1 ⇜ (449/32 → 899/64) ⇝ 57/4 | note:F#2 gain:0.64 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ (393/28 → 899/64) ⇝ 100/7 | note:71 gain:0.064 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ (393/28 → 899/64) ⇝ 100/7 | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ (393/28 → 899/64) ⇝ 100/7 | note:77 gain:0.064 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ (393/28 → 899/64) ⇝ 100/7 | note:81 gain:0.064 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 14/1 ⇜ (899/64 → 225/16) ⇝ 57/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 393/28 ⇜ (899/64 → 225/16) ⇝ 100/7 | note:71 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 393/28 ⇜ (899/64 → 225/16) ⇝ 100/7 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 393/28 ⇜ (899/64 → 225/16) ⇝ 100/7 | note:77 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 393/28 ⇜ (899/64 → 225/16) ⇝ 100/7 | note:81 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 14/1 ⇜ (225/16 → 901/64) ⇝ 57/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 393/28 ⇜ (225/16 → 901/64) ⇝ 100/7 | note:71 gain:0.044 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 393/28 ⇜ (225/16 → 901/64) ⇝ 100/7 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 393/28 ⇜ (225/16 → 901/64) ⇝ 100/7 | note:77 gain:0.044 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 393/28 ⇜ (225/16 → 901/64) ⇝ 100/7 | note:81 gain:0.044 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 14/1 ⇜ (901/64 → 451/32) ⇝ 57/4 | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 393/28 ⇜ (901/64 → 451/32) ⇝ 100/7 | note:71 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 393/28 ⇜ (901/64 → 451/32) ⇝ 100/7 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 393/28 ⇜ (901/64 → 451/32) ⇝ 100/7 | note:77 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 393/28 ⇜ (901/64 → 451/32) ⇝ 100/7 | note:81 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 14/1 ⇜ (451/32 → 903/64) ⇝ 57/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 393/28 ⇜ (451/32 → 903/64) ⇝ 100/7 | note:71 gain:0.024 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 393/28 ⇜ (451/32 → 903/64) ⇝ 100/7 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 393/28 ⇜ (451/32 → 903/64) ⇝ 100/7 | note:77 gain:0.024 clip:1 s:piano release:0.1 pan:0.606481481481 ]", "[ 393/28 ⇜ (451/32 → 903/64) ⇝ 100/7 | note:81 gain:0.024 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 14/1 ⇜ (903/64 → 113/8) ⇝ 57/4 | note:F#2 gain:0.298578643762688 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 393/28 ⇜ (903/64 → 113/8) ⇝ 100/7 | note:71 gain:0.029857864376268802 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 393/28 ⇜ (903/64 → 113/8) ⇝ 100/7 | note:76 gain:0.029857864376268802 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 393/28 ⇜ (903/64 → 113/8) ⇝ 100/7 | note:77 gain:0.029857864376268802 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 393/28 ⇜ (903/64 → 113/8) ⇝ 100/7 | note:81 gain:0.029857864376268802 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 14/1 ⇜ (113/8 → 905/64) ⇝ 57/4 | note:F#2 gain:0.4399999999999902 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 393/28 ⇜ (113/8 → 905/64) ⇝ 100/7 | note:71 gain:0.04399999999999902 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 393/28 ⇜ (113/8 → 905/64) ⇝ 100/7 | note:76 gain:0.04399999999999902 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 393/28 ⇜ (113/8 → 905/64) ⇝ 100/7 | note:77 gain:0.04399999999999902 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 393/28 ⇜ (113/8 → 905/64) ⇝ 100/7 | note:81 gain:0.04399999999999902 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ (113/8 → 905/64) ⇝ 57/4 | note:F#4 gain:0.4399999999999902 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ (113/8 → 905/64) ⇝ 57/4 | note:C#5 gain:0.4399999999999902 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ (113/8 → 905/64) ⇝ 57/4 | note:E5 gain:0.4399999999999902 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 14/1 ⇜ (905/64 → 453/32) ⇝ 57/4 | note:F#2 gain:0.5814213562372982 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 393/28 ⇜ (905/64 → 453/32) ⇝ 100/7 | note:71 gain:0.05814213562372982 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 393/28 ⇜ (905/64 → 453/32) ⇝ 100/7 | note:76 gain:0.05814213562372982 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 393/28 ⇜ (905/64 → 453/32) ⇝ 100/7 | note:77 gain:0.05814213562372982 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 393/28 ⇜ (905/64 → 453/32) ⇝ 100/7 | note:81 gain:0.05814213562372982 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 113/8 ⇜ (905/64 → 453/32) ⇝ 57/4 | note:F#4 gain:0.5814213562372982 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 113/8 ⇜ (905/64 → 453/32) ⇝ 57/4 | note:C#5 gain:0.5814213562372982 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 113/8 ⇜ (905/64 → 453/32) ⇝ 57/4 | note:E5 gain:0.5814213562372982 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 14/1 ⇜ (453/32 → 907/64) ⇝ 57/4 | note:F#2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 393/28 ⇜ (453/32 → 907/64) ⇝ 100/7 | note:71 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 393/28 ⇜ (453/32 → 907/64) ⇝ 100/7 | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 393/28 ⇜ (453/32 → 907/64) ⇝ 100/7 | note:77 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 393/28 ⇜ (453/32 → 907/64) ⇝ 100/7 | note:81 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 113/8 ⇜ (453/32 → 907/64) ⇝ 57/4 | note:F#4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 113/8 ⇜ (453/32 → 907/64) ⇝ 57/4 | note:C#5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 113/8 ⇜ (453/32 → 907/64) ⇝ 57/4 | note:E5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 14/1 ⇜ (907/64 → 227/16) ⇝ 57/4 | note:F#2 gain:0.5814213562373135 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 393/28 ⇜ (907/64 → 227/16) ⇝ 100/7 | note:71 gain:0.058142135623731356 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 393/28 ⇜ (907/64 → 227/16) ⇝ 100/7 | note:76 gain:0.058142135623731356 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 393/28 ⇜ (907/64 → 227/16) ⇝ 100/7 | note:77 gain:0.058142135623731356 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 393/28 ⇜ (907/64 → 227/16) ⇝ 100/7 | note:81 gain:0.058142135623731356 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 113/8 ⇜ (907/64 → 227/16) ⇝ 57/4 | note:F#4 gain:0.5814213562373135 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 113/8 ⇜ (907/64 → 227/16) ⇝ 57/4 | note:C#5 gain:0.5814213562373135 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 113/8 ⇜ (907/64 → 227/16) ⇝ 57/4 | note:E5 gain:0.5814213562373135 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 14/1 ⇜ (227/16 → 909/64) ⇝ 57/4 | note:F#2 gain:0.44000000000001194 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 393/28 ⇜ (227/16 → 909/64) ⇝ 100/7 | note:71 gain:0.0440000000000012 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 393/28 ⇜ (227/16 → 909/64) ⇝ 100/7 | note:76 gain:0.0440000000000012 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 393/28 ⇜ (227/16 → 909/64) ⇝ 100/7 | note:77 gain:0.0440000000000012 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 393/28 ⇜ (227/16 → 909/64) ⇝ 100/7 | note:81 gain:0.0440000000000012 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 113/8 ⇜ (227/16 → 909/64) ⇝ 57/4 | note:F#4 gain:0.44000000000001194 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 113/8 ⇜ (227/16 → 909/64) ⇝ 57/4 | note:C#5 gain:0.44000000000001194 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 113/8 ⇜ (227/16 → 909/64) ⇝ 57/4 | note:E5 gain:0.44000000000001194 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 14/1 ⇜ (909/64 → 455/32) ⇝ 57/4 | note:F#2 gain:0.2985786437626873 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 393/28 ⇜ (909/64 → 455/32) ⇝ 100/7 | note:71 gain:0.02985786437626873 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 393/28 ⇜ (909/64 → 455/32) ⇝ 100/7 | note:76 gain:0.02985786437626873 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 393/28 ⇜ (909/64 → 455/32) ⇝ 100/7 | note:77 gain:0.02985786437626873 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 393/28 ⇜ (909/64 → 455/32) ⇝ 100/7 | note:81 gain:0.02985786437626873 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 113/8 ⇜ (909/64 → 455/32) ⇝ 57/4 | note:F#4 gain:0.2985786437626873 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 113/8 ⇜ (909/64 → 455/32) ⇝ 57/4 | note:C#5 gain:0.2985786437626873 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 113/8 ⇜ (909/64 → 455/32) ⇝ 57/4 | note:E5 gain:0.2985786437626873 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 14/1 ⇜ (455/32 → 911/64) ⇝ 57/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 393/28 ⇜ (455/32 → 911/64) ⇝ 100/7 | note:71 gain:0.024 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 393/28 ⇜ (455/32 → 911/64) ⇝ 100/7 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 393/28 ⇜ (455/32 → 911/64) ⇝ 100/7 | note:77 gain:0.024 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", + "[ 14/1 ⇜ (903/64 → 113/8) ⇝ 57/4 | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 393/28 ⇜ (903/64 → 113/8) ⇝ 100/7 | note:71 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 393/28 ⇜ (903/64 → 113/8) ⇝ 100/7 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 393/28 ⇜ (903/64 → 113/8) ⇝ 100/7 | note:77 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 393/28 ⇜ (903/64 → 113/8) ⇝ 100/7 | note:81 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 14/1 ⇜ (113/8 → 905/64) ⇝ 57/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 393/28 ⇜ (113/8 → 905/64) ⇝ 100/7 | note:71 gain:0.044 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 393/28 ⇜ (113/8 → 905/64) ⇝ 100/7 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 393/28 ⇜ (113/8 → 905/64) ⇝ 100/7 | note:77 gain:0.044 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 393/28 ⇜ (113/8 → 905/64) ⇝ 100/7 | note:81 gain:0.044 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ (113/8 → 905/64) ⇝ 57/4 | note:F#4 gain:0.44 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ (113/8 → 905/64) ⇝ 57/4 | note:C#5 gain:0.44 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ (113/8 → 905/64) ⇝ 57/4 | note:E5 gain:0.44 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 14/1 ⇜ (905/64 → 453/32) ⇝ 57/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 393/28 ⇜ (905/64 → 453/32) ⇝ 100/7 | note:71 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 393/28 ⇜ (905/64 → 453/32) ⇝ 100/7 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 393/28 ⇜ (905/64 → 453/32) ⇝ 100/7 | note:77 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 393/28 ⇜ (905/64 → 453/32) ⇝ 100/7 | note:81 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 113/8 ⇜ (905/64 → 453/32) ⇝ 57/4 | note:F#4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 113/8 ⇜ (905/64 → 453/32) ⇝ 57/4 | note:C#5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 113/8 ⇜ (905/64 → 453/32) ⇝ 57/4 | note:E5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 14/1 ⇜ (453/32 → 907/64) ⇝ 57/4 | note:F#2 gain:0.64 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 393/28 ⇜ (453/32 → 907/64) ⇝ 100/7 | note:71 gain:0.064 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 393/28 ⇜ (453/32 → 907/64) ⇝ 100/7 | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 393/28 ⇜ (453/32 → 907/64) ⇝ 100/7 | note:77 gain:0.064 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 393/28 ⇜ (453/32 → 907/64) ⇝ 100/7 | note:81 gain:0.064 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 113/8 ⇜ (453/32 → 907/64) ⇝ 57/4 | note:F#4 gain:0.64 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 113/8 ⇜ (453/32 → 907/64) ⇝ 57/4 | note:C#5 gain:0.64 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 113/8 ⇜ (453/32 → 907/64) ⇝ 57/4 | note:E5 gain:0.64 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 14/1 ⇜ (907/64 → 227/16) ⇝ 57/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 393/28 ⇜ (907/64 → 227/16) ⇝ 100/7 | note:71 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 393/28 ⇜ (907/64 → 227/16) ⇝ 100/7 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 393/28 ⇜ (907/64 → 227/16) ⇝ 100/7 | note:77 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 393/28 ⇜ (907/64 → 227/16) ⇝ 100/7 | note:81 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 113/8 ⇜ (907/64 → 227/16) ⇝ 57/4 | note:F#4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 113/8 ⇜ (907/64 → 227/16) ⇝ 57/4 | note:C#5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 113/8 ⇜ (907/64 → 227/16) ⇝ 57/4 | note:E5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 14/1 ⇜ (227/16 → 909/64) ⇝ 57/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 393/28 ⇜ (227/16 → 909/64) ⇝ 100/7 | note:71 gain:0.044 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 393/28 ⇜ (227/16 → 909/64) ⇝ 100/7 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 393/28 ⇜ (227/16 → 909/64) ⇝ 100/7 | note:77 gain:0.044 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 393/28 ⇜ (227/16 → 909/64) ⇝ 100/7 | note:81 gain:0.044 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 113/8 ⇜ (227/16 → 909/64) ⇝ 57/4 | note:F#4 gain:0.44 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 113/8 ⇜ (227/16 → 909/64) ⇝ 57/4 | note:C#5 gain:0.44 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 113/8 ⇜ (227/16 → 909/64) ⇝ 57/4 | note:E5 gain:0.44 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 14/1 ⇜ (909/64 → 455/32) ⇝ 57/4 | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 393/28 ⇜ (909/64 → 455/32) ⇝ 100/7 | note:71 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 393/28 ⇜ (909/64 → 455/32) ⇝ 100/7 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 393/28 ⇜ (909/64 → 455/32) ⇝ 100/7 | note:77 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 393/28 ⇜ (909/64 → 455/32) ⇝ 100/7 | note:81 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 113/8 ⇜ (909/64 → 455/32) ⇝ 57/4 | note:F#4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 113/8 ⇜ (909/64 → 455/32) ⇝ 57/4 | note:C#5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 113/8 ⇜ (909/64 → 455/32) ⇝ 57/4 | note:E5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 14/1 ⇜ (455/32 → 911/64) ⇝ 57/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 393/28 ⇜ (455/32 → 911/64) ⇝ 100/7 | note:71 gain:0.024 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 393/28 ⇜ (455/32 → 911/64) ⇝ 100/7 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 393/28 ⇜ (455/32 → 911/64) ⇝ 100/7 | note:77 gain:0.024 clip:1 s:piano release:0.1 pan:0.606481481481 ]", "[ 393/28 ⇜ (455/32 → 911/64) ⇝ 100/7 | note:81 gain:0.024 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 113/8 ⇜ (455/32 → 911/64) ⇝ 57/4 | note:F#4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 113/8 ⇜ (455/32 → 911/64) ⇝ 57/4 | note:C#5 gain:0.24 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 113/8 ⇜ (455/32 → 911/64) ⇝ 57/4 | note:E5 gain:0.24 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 14/1 ⇜ (911/64 → 57/4) | note:F#2 gain:0.2985786437626849 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 393/28 ⇜ (911/64 → 57/4) ⇝ 100/7 | note:71 gain:0.02985786437626849 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 393/28 ⇜ (911/64 → 57/4) ⇝ 100/7 | note:76 gain:0.02985786437626849 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 393/28 ⇜ (911/64 → 57/4) ⇝ 100/7 | note:77 gain:0.02985786437626849 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 393/28 ⇜ (911/64 → 57/4) ⇝ 100/7 | note:81 gain:0.02985786437626849 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 113/8 ⇜ (911/64 → 57/4) | note:F#4 gain:0.2985786437626849 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 113/8 ⇜ (911/64 → 57/4) | note:C#5 gain:0.2985786437626849 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 113/8 ⇜ (911/64 → 57/4) | note:E5 gain:0.2985786437626849 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 393/28 ⇜ (57/4 → 913/64) ⇝ 100/7 | note:71 gain:0.043999999999998596 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 393/28 ⇜ (57/4 → 913/64) ⇝ 100/7 | note:76 gain:0.043999999999998596 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 393/28 ⇜ (57/4 → 913/64) ⇝ 100/7 | note:77 gain:0.043999999999998596 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 393/28 ⇜ (57/4 → 913/64) ⇝ 100/7 | note:81 gain:0.043999999999998596 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 393/28 ⇜ (913/64 → 457/32) ⇝ 100/7 | note:71 gain:0.058142135623731134 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 393/28 ⇜ (913/64 → 457/32) ⇝ 100/7 | note:76 gain:0.058142135623731134 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 393/28 ⇜ (913/64 → 457/32) ⇝ 100/7 | note:77 gain:0.058142135623731134 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 393/28 ⇜ (913/64 → 457/32) ⇝ 100/7 | note:81 gain:0.058142135623731134 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ 393/28 ⇜ (457/32 → 100/7) | note:71 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 393/28 ⇜ (457/32 → 100/7) | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 393/28 ⇜ (457/32 → 100/7) | note:77 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 393/28 ⇜ (457/32 → 100/7) | note:81 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.625 ]", - "[ (29/2 → 929/64) ⇝ 117/8 | note:C#5 gain:0.44000000000000006 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ (29/2 → 929/64) ⇝ 117/8 | note:G#5 gain:0.44000000000000006 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ (29/2 → 929/64) ⇝ 117/8 | note:B5 gain:0.44000000000000006 clip:1 s:piano release:0.1 pan:0.6342592592592593 ]", - "[ (29/2 → 929/64) ⇝ 59/4 | note:Bb3 gain:0.22000000000000003 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ (29/2 → 929/64) ⇝ 59/4 | note:Eb4 gain:0.22000000000000003 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ (29/2 → 929/64) ⇝ 59/4 | note:E4 gain:0.22000000000000003 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (29/2 → 929/64) ⇝ 59/4 | note:Ab4 gain:0.22000000000000003 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ (29/2 → 929/64) ⇝ 59/4 | note:F#2 gain:0.44000000000000006 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 29/2 ⇜ (929/64 → 465/32) ⇝ 117/8 | note:C#5 gain:0.5814213562373051 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 29/2 ⇜ (929/64 → 465/32) ⇝ 117/8 | note:G#5 gain:0.5814213562373051 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 29/2 ⇜ (929/64 → 465/32) ⇝ 117/8 | note:B5 gain:0.5814213562373051 clip:1 s:piano release:0.1 pan:0.6342592592592593 ]", - "[ 29/2 ⇜ (929/64 → 465/32) ⇝ 59/4 | note:Bb3 gain:0.29071067811865253 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/2 ⇜ (929/64 → 465/32) ⇝ 59/4 | note:Eb4 gain:0.29071067811865253 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/2 ⇜ (929/64 → 465/32) ⇝ 59/4 | note:E4 gain:0.29071067811865253 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/2 ⇜ (929/64 → 465/32) ⇝ 59/4 | note:Ab4 gain:0.29071067811865253 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/2 ⇜ (929/64 → 465/32) ⇝ 59/4 | note:F#2 gain:0.5814213562373051 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 29/2 ⇜ (465/32 → 931/64) ⇝ 117/8 | note:C#5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 29/2 ⇜ (465/32 → 931/64) ⇝ 117/8 | note:G#5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 29/2 ⇜ (465/32 → 931/64) ⇝ 117/8 | note:B5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6342592592592593 ]", - "[ 29/2 ⇜ (465/32 → 931/64) ⇝ 59/4 | note:Bb3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/2 ⇜ (465/32 → 931/64) ⇝ 59/4 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/2 ⇜ (465/32 → 931/64) ⇝ 59/4 | note:E4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/2 ⇜ (465/32 → 931/64) ⇝ 59/4 | note:Ab4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/2 ⇜ (465/32 → 931/64) ⇝ 59/4 | note:F#2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 29/2 ⇜ (931/64 → 233/16) ⇝ 117/8 | note:C#5 gain:0.5814213562373066 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 29/2 ⇜ (931/64 → 233/16) ⇝ 117/8 | note:G#5 gain:0.5814213562373066 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 29/2 ⇜ (931/64 → 233/16) ⇝ 117/8 | note:B5 gain:0.5814213562373066 clip:1 s:piano release:0.1 pan:0.6342592592592593 ]", - "[ 29/2 ⇜ (931/64 → 233/16) ⇝ 59/4 | note:Bb3 gain:0.2907106781186533 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/2 ⇜ (931/64 → 233/16) ⇝ 59/4 | note:Eb4 gain:0.2907106781186533 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/2 ⇜ (931/64 → 233/16) ⇝ 59/4 | note:E4 gain:0.2907106781186533 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/2 ⇜ (931/64 → 233/16) ⇝ 59/4 | note:Ab4 gain:0.2907106781186533 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/2 ⇜ (931/64 → 233/16) ⇝ 59/4 | note:F#2 gain:0.5814213562373066 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 29/2 ⇜ (233/16 → 933/64) ⇝ 117/8 | note:C#5 gain:0.44000000000000217 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 29/2 ⇜ (233/16 → 933/64) ⇝ 117/8 | note:G#5 gain:0.44000000000000217 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 29/2 ⇜ (233/16 → 933/64) ⇝ 117/8 | note:B5 gain:0.44000000000000217 clip:1 s:piano release:0.1 pan:0.6342592592592593 ]", - "[ 29/2 ⇜ (233/16 → 933/64) ⇝ 59/4 | note:Bb3 gain:0.22000000000000108 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/2 ⇜ (233/16 → 933/64) ⇝ 59/4 | note:Eb4 gain:0.22000000000000108 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/2 ⇜ (233/16 → 933/64) ⇝ 59/4 | note:E4 gain:0.22000000000000108 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/2 ⇜ (233/16 → 933/64) ⇝ 59/4 | note:Ab4 gain:0.22000000000000108 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/2 ⇜ (233/16 → 933/64) ⇝ 59/4 | note:F#2 gain:0.44000000000000217 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 29/2 ⇜ (933/64 → 467/32) ⇝ 117/8 | note:C#5 gain:0.29857864376269644 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 29/2 ⇜ (933/64 → 467/32) ⇝ 117/8 | note:G#5 gain:0.29857864376269644 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 29/2 ⇜ (933/64 → 467/32) ⇝ 117/8 | note:B5 gain:0.29857864376269644 clip:1 s:piano release:0.1 pan:0.6342592592592593 ]", - "[ 29/2 ⇜ (933/64 → 467/32) ⇝ 59/4 | note:Bb3 gain:0.14928932188134822 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/2 ⇜ (933/64 → 467/32) ⇝ 59/4 | note:Eb4 gain:0.14928932188134822 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/2 ⇜ (933/64 → 467/32) ⇝ 59/4 | note:E4 gain:0.14928932188134822 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/2 ⇜ (933/64 → 467/32) ⇝ 59/4 | note:Ab4 gain:0.14928932188134822 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/2 ⇜ (933/64 → 467/32) ⇝ 59/4 | note:F#2 gain:0.29857864376269644 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 29/2 ⇜ (467/32 → 935/64) ⇝ 117/8 | note:C#5 gain:0.24 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 29/2 ⇜ (467/32 → 935/64) ⇝ 117/8 | note:G#5 gain:0.24 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 29/2 ⇜ (467/32 → 935/64) ⇝ 117/8 | note:B5 gain:0.24 clip:1 s:piano release:0.1 pan:0.6342592592592593 ]", - "[ 29/2 ⇜ (467/32 → 935/64) ⇝ 59/4 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/2 ⇜ (467/32 → 935/64) ⇝ 59/4 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/2 ⇜ (467/32 → 935/64) ⇝ 59/4 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/2 ⇜ (467/32 → 935/64) ⇝ 59/4 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/2 ⇜ (467/32 → 935/64) ⇝ 59/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 29/2 ⇜ (935/64 → 117/8) | note:C#5 gain:0.29857864376269183 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 29/2 ⇜ (935/64 → 117/8) | note:G#5 gain:0.29857864376269183 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 29/2 ⇜ (935/64 → 117/8) | note:B5 gain:0.29857864376269183 clip:1 s:piano release:0.1 pan:0.6342592592592593 ]", - "[ 29/2 ⇜ (935/64 → 117/8) ⇝ 59/4 | note:Bb3 gain:0.14928932188134592 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/2 ⇜ (935/64 → 117/8) ⇝ 59/4 | note:Eb4 gain:0.14928932188134592 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/2 ⇜ (935/64 → 117/8) ⇝ 59/4 | note:E4 gain:0.14928932188134592 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/2 ⇜ (935/64 → 117/8) ⇝ 59/4 | note:Ab4 gain:0.14928932188134592 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/2 ⇜ (935/64 → 117/8) ⇝ 59/4 | note:F#2 gain:0.29857864376269183 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 29/2 ⇜ (117/8 → 937/64) ⇝ 59/4 | note:Bb3 gain:0.21999999999999786 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/2 ⇜ (117/8 → 937/64) ⇝ 59/4 | note:Eb4 gain:0.21999999999999786 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/2 ⇜ (117/8 → 937/64) ⇝ 59/4 | note:E4 gain:0.21999999999999786 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/2 ⇜ (117/8 → 937/64) ⇝ 59/4 | note:Ab4 gain:0.21999999999999786 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/2 ⇜ (117/8 → 937/64) ⇝ 59/4 | note:F#2 gain:0.43999999999999573 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 29/2 ⇜ (937/64 → 469/32) ⇝ 59/4 | note:Bb3 gain:0.290710678118651 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/2 ⇜ (937/64 → 469/32) ⇝ 59/4 | note:Eb4 gain:0.290710678118651 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/2 ⇜ (937/64 → 469/32) ⇝ 59/4 | note:E4 gain:0.290710678118651 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/2 ⇜ (937/64 → 469/32) ⇝ 59/4 | note:Ab4 gain:0.290710678118651 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/2 ⇜ (937/64 → 469/32) ⇝ 59/4 | note:F#2 gain:0.581421356237302 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 29/2 ⇜ (469/32 → 939/64) ⇝ 59/4 | note:Bb3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/2 ⇜ (469/32 → 939/64) ⇝ 59/4 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/2 ⇜ (469/32 → 939/64) ⇝ 59/4 | note:E4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/2 ⇜ (469/32 → 939/64) ⇝ 59/4 | note:Ab4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/2 ⇜ (469/32 → 939/64) ⇝ 59/4 | note:F#2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 29/2 ⇜ (939/64 → 235/16) ⇝ 59/4 | note:Bb3 gain:0.2907106781186548 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/2 ⇜ (939/64 → 235/16) ⇝ 59/4 | note:Eb4 gain:0.2907106781186548 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/2 ⇜ (939/64 → 235/16) ⇝ 59/4 | note:E4 gain:0.2907106781186548 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/2 ⇜ (939/64 → 235/16) ⇝ 59/4 | note:Ab4 gain:0.2907106781186548 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/2 ⇜ (939/64 → 235/16) ⇝ 59/4 | note:F#2 gain:0.5814213562373096 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 29/2 ⇜ (235/16 → 941/64) ⇝ 59/4 | note:Bb3 gain:0.22000000000000322 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/2 ⇜ (235/16 → 941/64) ⇝ 59/4 | note:Eb4 gain:0.22000000000000322 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/2 ⇜ (235/16 → 941/64) ⇝ 59/4 | note:E4 gain:0.22000000000000322 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/2 ⇜ (235/16 → 941/64) ⇝ 59/4 | note:Ab4 gain:0.22000000000000322 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/2 ⇜ (235/16 → 941/64) ⇝ 59/4 | note:F#2 gain:0.44000000000000644 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 29/2 ⇜ (941/64 → 471/32) ⇝ 59/4 | note:Bb3 gain:0.14928932188134972 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/2 ⇜ (941/64 → 471/32) ⇝ 59/4 | note:Eb4 gain:0.14928932188134972 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/2 ⇜ (941/64 → 471/32) ⇝ 59/4 | note:E4 gain:0.14928932188134972 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/2 ⇜ (941/64 → 471/32) ⇝ 59/4 | note:Ab4 gain:0.14928932188134972 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/2 ⇜ (941/64 → 471/32) ⇝ 59/4 | note:F#2 gain:0.29857864376269944 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 29/2 ⇜ (471/32 → 943/64) ⇝ 59/4 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/2 ⇜ (471/32 → 943/64) ⇝ 59/4 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/2 ⇜ (471/32 → 943/64) ⇝ 59/4 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/2 ⇜ (471/32 → 943/64) ⇝ 59/4 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/2 ⇜ (471/32 → 943/64) ⇝ 59/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 29/2 ⇜ (943/64 → 59/4) | note:Bb3 gain:0.1492893218813444 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 29/2 ⇜ (943/64 → 59/4) | note:Eb4 gain:0.1492893218813444 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/2 ⇜ (943/64 → 59/4) | note:E4 gain:0.1492893218813444 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 29/2 ⇜ (943/64 → 59/4) | note:Ab4 gain:0.1492893218813444 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 29/2 ⇜ (943/64 → 59/4) | note:F#2 gain:0.2985786437626888 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ (59/4 → 945/64) ⇝ 119/8 | note:F#4 gain:0.43999999999999134 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ (59/4 → 945/64) ⇝ 119/8 | note:C#5 gain:0.43999999999999134 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ (59/4 → 945/64) ⇝ 119/8 | note:E5 gain:0.43999999999999134 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 59/4 ⇜ (945/64 → 473/32) ⇝ 119/8 | note:F#4 gain:0.581421356237299 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 59/4 ⇜ (945/64 → 473/32) ⇝ 119/8 | note:C#5 gain:0.581421356237299 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 59/4 ⇜ (945/64 → 473/32) ⇝ 119/8 | note:E5 gain:0.581421356237299 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 59/4 ⇜ (473/32 → 947/64) ⇝ 119/8 | note:F#4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 59/4 ⇜ (473/32 → 947/64) ⇝ 119/8 | note:C#5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 59/4 ⇜ (473/32 → 947/64) ⇝ 119/8 | note:E5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ (207/14 → 947/64) ⇝ 421/28 | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ (207/14 → 947/64) ⇝ 421/28 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ (207/14 → 947/64) ⇝ 421/28 | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ (207/14 → 947/64) ⇝ 421/28 | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 59/4 ⇜ (947/64 → 237/16) ⇝ 119/8 | note:F#4 gain:0.5814213562373127 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 59/4 ⇜ (947/64 → 237/16) ⇝ 119/8 | note:C#5 gain:0.5814213562373127 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 59/4 ⇜ (947/64 → 237/16) ⇝ 119/8 | note:E5 gain:0.5814213562373127 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 207/14 ⇜ (947/64 → 237/16) ⇝ 421/28 | note:70 gain:0.05814213562373127 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 207/14 ⇜ (947/64 → 237/16) ⇝ 421/28 | note:75 gain:0.05814213562373127 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 207/14 ⇜ (947/64 → 237/16) ⇝ 421/28 | note:76 gain:0.05814213562373127 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 207/14 ⇜ (947/64 → 237/16) ⇝ 421/28 | note:80 gain:0.05814213562373127 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 59/4 ⇜ (237/16 → 949/64) ⇝ 119/8 | note:F#4 gain:0.4400000000000108 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 59/4 ⇜ (237/16 → 949/64) ⇝ 119/8 | note:C#5 gain:0.4400000000000108 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 59/4 ⇜ (237/16 → 949/64) ⇝ 119/8 | note:E5 gain:0.4400000000000108 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 207/14 ⇜ (237/16 → 949/64) ⇝ 421/28 | note:70 gain:0.04400000000000109 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 207/14 ⇜ (237/16 → 949/64) ⇝ 421/28 | note:75 gain:0.04400000000000109 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 207/14 ⇜ (237/16 → 949/64) ⇝ 421/28 | note:76 gain:0.04400000000000109 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 207/14 ⇜ (237/16 → 949/64) ⇝ 421/28 | note:80 gain:0.04400000000000109 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 59/4 ⇜ (949/64 → 475/32) ⇝ 119/8 | note:F#4 gain:0.29857864376270254 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 59/4 ⇜ (949/64 → 475/32) ⇝ 119/8 | note:C#5 gain:0.29857864376270254 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 59/4 ⇜ (949/64 → 475/32) ⇝ 119/8 | note:E5 gain:0.29857864376270254 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 207/14 ⇜ (949/64 → 475/32) ⇝ 421/28 | note:70 gain:0.029857864376270256 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 207/14 ⇜ (949/64 → 475/32) ⇝ 421/28 | note:75 gain:0.029857864376270256 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 207/14 ⇜ (949/64 → 475/32) ⇝ 421/28 | note:76 gain:0.029857864376270256 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 207/14 ⇜ (949/64 → 475/32) ⇝ 421/28 | note:80 gain:0.029857864376270256 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 59/4 ⇜ (475/32 → 951/64) ⇝ 119/8 | note:F#4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 59/4 ⇜ (475/32 → 951/64) ⇝ 119/8 | note:C#5 gain:0.24 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 59/4 ⇜ (475/32 → 951/64) ⇝ 119/8 | note:E5 gain:0.24 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 207/14 ⇜ (475/32 → 951/64) ⇝ 421/28 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 207/14 ⇜ (475/32 → 951/64) ⇝ 421/28 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 207/14 ⇜ (475/32 → 951/64) ⇝ 421/28 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 207/14 ⇜ (475/32 → 951/64) ⇝ 421/28 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 59/4 ⇜ (951/64 → 119/8) | note:F#4 gain:0.2985786437626858 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 59/4 ⇜ (951/64 → 119/8) | note:C#5 gain:0.2985786437626858 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 59/4 ⇜ (951/64 → 119/8) | note:E5 gain:0.2985786437626858 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 207/14 ⇜ (951/64 → 119/8) ⇝ 421/28 | note:70 gain:0.02985786437626858 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 207/14 ⇜ (951/64 → 119/8) ⇝ 421/28 | note:75 gain:0.02985786437626858 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 207/14 ⇜ (951/64 → 119/8) ⇝ 421/28 | note:76 gain:0.02985786437626858 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 207/14 ⇜ (951/64 → 119/8) ⇝ 421/28 | note:80 gain:0.02985786437626858 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 207/14 ⇜ (119/8 → 953/64) ⇝ 421/28 | note:70 gain:0.04399999999999871 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 207/14 ⇜ (119/8 → 953/64) ⇝ 421/28 | note:75 gain:0.04399999999999871 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 207/14 ⇜ (119/8 → 953/64) ⇝ 421/28 | note:76 gain:0.04399999999999871 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 207/14 ⇜ (119/8 → 953/64) ⇝ 421/28 | note:80 gain:0.04399999999999871 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 207/14 ⇜ (953/64 → 477/32) ⇝ 421/28 | note:70 gain:0.05814213562373122 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 207/14 ⇜ (953/64 → 477/32) ⇝ 421/28 | note:75 gain:0.05814213562373122 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 207/14 ⇜ (953/64 → 477/32) ⇝ 421/28 | note:76 gain:0.05814213562373122 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 207/14 ⇜ (953/64 → 477/32) ⇝ 421/28 | note:80 gain:0.05814213562373122 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 207/14 ⇜ (477/32 → 955/64) ⇝ 421/28 | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 207/14 ⇜ (477/32 → 955/64) ⇝ 421/28 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 207/14 ⇜ (477/32 → 955/64) ⇝ 421/28 | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 207/14 ⇜ (477/32 → 955/64) ⇝ 421/28 | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 207/14 ⇜ (955/64 → 239/16) ⇝ 421/28 | note:70 gain:0.058142135623731585 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 207/14 ⇜ (955/64 → 239/16) ⇝ 421/28 | note:75 gain:0.058142135623731585 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 207/14 ⇜ (955/64 → 239/16) ⇝ 421/28 | note:76 gain:0.058142135623731585 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 207/14 ⇜ (955/64 → 239/16) ⇝ 421/28 | note:80 gain:0.058142135623731585 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 207/14 ⇜ (239/16 → 957/64) ⇝ 421/28 | note:70 gain:0.04400000000000152 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 207/14 ⇜ (239/16 → 957/64) ⇝ 421/28 | note:75 gain:0.04400000000000152 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 207/14 ⇜ (239/16 → 957/64) ⇝ 421/28 | note:76 gain:0.04400000000000152 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 207/14 ⇜ (239/16 → 957/64) ⇝ 421/28 | note:80 gain:0.04400000000000152 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 207/14 ⇜ (957/64 → 479/32) ⇝ 421/28 | note:70 gain:0.02985786437626895 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 207/14 ⇜ (957/64 → 479/32) ⇝ 421/28 | note:75 gain:0.02985786437626895 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 207/14 ⇜ (957/64 → 479/32) ⇝ 421/28 | note:76 gain:0.02985786437626895 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 207/14 ⇜ (957/64 → 479/32) ⇝ 421/28 | note:80 gain:0.02985786437626895 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 207/14 ⇜ (479/32 → 959/64) ⇝ 421/28 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 207/14 ⇜ (479/32 → 959/64) ⇝ 421/28 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 207/14 ⇜ (479/32 → 959/64) ⇝ 421/28 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 207/14 ⇜ (479/32 → 959/64) ⇝ 421/28 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 207/14 ⇜ (959/64 → 15/1) ⇝ 421/28 | note:70 gain:0.029857864376268268 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 207/14 ⇜ (959/64 → 15/1) ⇝ 421/28 | note:75 gain:0.029857864376268268 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 207/14 ⇜ (959/64 → 15/1) ⇝ 421/28 | note:76 gain:0.029857864376268268 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 207/14 ⇜ (959/64 → 15/1) ⇝ 421/28 | note:80 gain:0.029857864376268268 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 207/14 ⇜ (15/1 → 961/64) ⇝ 421/28 | note:70 gain:0.04399999999999828 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 207/14 ⇜ (15/1 → 961/64) ⇝ 421/28 | note:75 gain:0.04399999999999828 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 207/14 ⇜ (15/1 → 961/64) ⇝ 421/28 | note:76 gain:0.04399999999999828 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 207/14 ⇜ (15/1 → 961/64) ⇝ 421/28 | note:80 gain:0.04399999999999828 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ (15/1 → 961/64) ⇝ 61/4 | note:F#2 gain:0.43999999999998274 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 207/14 ⇜ (961/64 → 481/32) ⇝ 421/28 | note:70 gain:0.0581421356237309 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 207/14 ⇜ (961/64 → 481/32) ⇝ 421/28 | note:75 gain:0.0581421356237309 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 207/14 ⇜ (961/64 → 481/32) ⇝ 421/28 | note:76 gain:0.0581421356237309 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 207/14 ⇜ (961/64 → 481/32) ⇝ 421/28 | note:80 gain:0.0581421356237309 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 15/1 ⇜ (961/64 → 481/32) ⇝ 61/4 | note:F#2 gain:0.581421356237309 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 207/14 ⇜ (481/32 → 421/28) | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 207/14 ⇜ (481/32 → 421/28) | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 207/14 ⇜ (481/32 → 421/28) | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 207/14 ⇜ (481/32 → 421/28) | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 15/1 ⇜ (481/32 → 963/64) ⇝ 61/4 | note:F#2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 15/1 ⇜ (963/64 → 241/16) ⇝ 61/4 | note:F#2 gain:0.5814213562373188 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 15/1 ⇜ (241/16 → 965/64) ⇝ 61/4 | note:F#2 gain:0.43999999999999667 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 15/1 ⇜ (965/64 → 483/32) ⇝ 61/4 | note:F#2 gain:0.2985786437626925 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 15/1 ⇜ (483/32 → 967/64) ⇝ 61/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 15/1 ⇜ (967/64 → 121/8) ⇝ 61/4 | note:F#2 gain:0.2985786437626796 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 15/1 ⇜ (121/8 → 969/64) ⇝ 61/4 | note:F#2 gain:0.4400000000000012 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ (121/8 → 969/64) ⇝ 61/4 | note:F#4 gain:0.4400000000000012 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ (121/8 → 969/64) ⇝ 61/4 | note:C#5 gain:0.4400000000000012 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ (121/8 → 969/64) ⇝ 61/4 | note:E5 gain:0.4400000000000012 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 15/1 ⇜ (969/64 → 485/32) ⇝ 61/4 | note:F#2 gain:0.581421356237306 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 121/8 ⇜ (969/64 → 485/32) ⇝ 61/4 | note:F#4 gain:0.581421356237306 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 121/8 ⇜ (969/64 → 485/32) ⇝ 61/4 | note:C#5 gain:0.581421356237306 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 121/8 ⇜ (969/64 → 485/32) ⇝ 61/4 | note:E5 gain:0.581421356237306 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 15/1 ⇜ (485/32 → 971/64) ⇝ 61/4 | note:F#2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 121/8 ⇜ (485/32 → 971/64) ⇝ 61/4 | note:F#4 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 121/8 ⇜ (485/32 → 971/64) ⇝ 61/4 | note:C#5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 121/8 ⇜ (485/32 → 971/64) ⇝ 61/4 | note:E5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 15/1 ⇜ (971/64 → 243/16) ⇝ 61/4 | note:F#2 gain:0.5814213562373058 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 121/8 ⇜ (971/64 → 243/16) ⇝ 61/4 | note:F#4 gain:0.5814213562373058 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 121/8 ⇜ (971/64 → 243/16) ⇝ 61/4 | note:C#5 gain:0.5814213562373058 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 121/8 ⇜ (971/64 → 243/16) ⇝ 61/4 | note:E5 gain:0.5814213562373058 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 15/1 ⇜ (243/16 → 973/64) ⇝ 61/4 | note:F#2 gain:0.44000000000000095 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 121/8 ⇜ (243/16 → 973/64) ⇝ 61/4 | note:F#4 gain:0.44000000000000095 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 121/8 ⇜ (243/16 → 973/64) ⇝ 61/4 | note:C#5 gain:0.44000000000000095 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 121/8 ⇜ (243/16 → 973/64) ⇝ 61/4 | note:E5 gain:0.44000000000000095 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 15/1 ⇜ (973/64 → 487/32) ⇝ 61/4 | note:F#2 gain:0.2985786437626956 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 121/8 ⇜ (973/64 → 487/32) ⇝ 61/4 | note:F#4 gain:0.2985786437626956 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 121/8 ⇜ (973/64 → 487/32) ⇝ 61/4 | note:C#5 gain:0.2985786437626956 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 121/8 ⇜ (973/64 → 487/32) ⇝ 61/4 | note:E5 gain:0.2985786437626956 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 15/1 ⇜ (487/32 → 975/64) ⇝ 61/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 121/8 ⇜ (487/32 → 975/64) ⇝ 61/4 | note:F#4 gain:0.24 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 121/8 ⇜ (487/32 → 975/64) ⇝ 61/4 | note:C#5 gain:0.24 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 121/8 ⇜ (487/32 → 975/64) ⇝ 61/4 | note:E5 gain:0.24 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 15/1 ⇜ (975/64 → 61/4) | note:F#2 gain:0.29857864376269266 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 121/8 ⇜ (975/64 → 61/4) | note:F#4 gain:0.29857864376269266 clip:1 s:piano release:0.1 pan:0.5555555555555556 ]", - "[ 121/8 ⇜ (975/64 → 61/4) | note:C#5 gain:0.29857864376269266 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 121/8 ⇜ (975/64 → 61/4) | note:E5 gain:0.29857864376269266 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ (61/4 → 977/64) ⇝ 31/2 | note:Bb3 gain:0.21999999999999842 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ (61/4 → 977/64) ⇝ 31/2 | note:Eb4 gain:0.21999999999999842 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ (61/4 → 977/64) ⇝ 31/2 | note:E4 gain:0.21999999999999842 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (61/4 → 977/64) ⇝ 31/2 | note:Ab4 gain:0.21999999999999842 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 61/4 ⇜ (977/64 → 489/32) ⇝ 31/2 | note:Bb3 gain:0.2907106781186514 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 61/4 ⇜ (977/64 → 489/32) ⇝ 31/2 | note:Eb4 gain:0.2907106781186514 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 61/4 ⇜ (977/64 → 489/32) ⇝ 31/2 | note:E4 gain:0.2907106781186514 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 61/4 ⇜ (977/64 → 489/32) ⇝ 31/2 | note:Ab4 gain:0.2907106781186514 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 61/4 ⇜ (489/32 → 979/64) ⇝ 31/2 | note:Bb3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 61/4 ⇜ (489/32 → 979/64) ⇝ 31/2 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 61/4 ⇜ (489/32 → 979/64) ⇝ 31/2 | note:E4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 61/4 ⇜ (489/32 → 979/64) ⇝ 31/2 | note:Ab4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 61/4 ⇜ (979/64 → 245/16) ⇝ 31/2 | note:Bb3 gain:0.2907106781186545 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 61/4 ⇜ (979/64 → 245/16) ⇝ 31/2 | note:Eb4 gain:0.2907106781186545 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 61/4 ⇜ (979/64 → 245/16) ⇝ 31/2 | note:E4 gain:0.2907106781186545 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 61/4 ⇜ (979/64 → 245/16) ⇝ 31/2 | note:Ab4 gain:0.2907106781186545 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 61/4 ⇜ (245/16 → 981/64) ⇝ 31/2 | note:Bb3 gain:0.22000000000000264 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 61/4 ⇜ (245/16 → 981/64) ⇝ 31/2 | note:Eb4 gain:0.22000000000000264 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 61/4 ⇜ (245/16 → 981/64) ⇝ 31/2 | note:E4 gain:0.22000000000000264 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 61/4 ⇜ (245/16 → 981/64) ⇝ 31/2 | note:Ab4 gain:0.22000000000000264 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 61/4 ⇜ (981/64 → 491/32) ⇝ 31/2 | note:Bb3 gain:0.14928932188134933 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 61/4 ⇜ (981/64 → 491/32) ⇝ 31/2 | note:Eb4 gain:0.14928932188134933 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 61/4 ⇜ (981/64 → 491/32) ⇝ 31/2 | note:E4 gain:0.14928932188134933 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 61/4 ⇜ (981/64 → 491/32) ⇝ 31/2 | note:Ab4 gain:0.14928932188134933 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 61/4 ⇜ (491/32 → 983/64) ⇝ 31/2 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 61/4 ⇜ (491/32 → 983/64) ⇝ 31/2 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 61/4 ⇜ (491/32 → 983/64) ⇝ 31/2 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 61/4 ⇜ (491/32 → 983/64) ⇝ 31/2 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 61/4 ⇜ (983/64 → 123/8) ⇝ 31/2 | note:Bb3 gain:0.1492893218813448 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 61/4 ⇜ (983/64 → 123/8) ⇝ 31/2 | note:Eb4 gain:0.1492893218813448 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 61/4 ⇜ (983/64 → 123/8) ⇝ 31/2 | note:E4 gain:0.1492893218813448 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 61/4 ⇜ (983/64 → 123/8) ⇝ 31/2 | note:Ab4 gain:0.1492893218813448 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 61/4 ⇜ (123/8 → 985/64) ⇝ 31/2 | note:Bb3 gain:0.2199999999999963 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 61/4 ⇜ (123/8 → 985/64) ⇝ 31/2 | note:Eb4 gain:0.2199999999999963 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 61/4 ⇜ (123/8 → 985/64) ⇝ 31/2 | note:E4 gain:0.2199999999999963 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 61/4 ⇜ (123/8 → 985/64) ⇝ 31/2 | note:Ab4 gain:0.2199999999999963 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 61/4 ⇜ (985/64 → 493/32) ⇝ 31/2 | note:Bb3 gain:0.2907106781186499 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 61/4 ⇜ (985/64 → 493/32) ⇝ 31/2 | note:Eb4 gain:0.2907106781186499 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 61/4 ⇜ (985/64 → 493/32) ⇝ 31/2 | note:E4 gain:0.2907106781186499 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 61/4 ⇜ (985/64 → 493/32) ⇝ 31/2 | note:Ab4 gain:0.2907106781186499 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 61/4 ⇜ (493/32 → 987/64) ⇝ 31/2 | note:Bb3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 61/4 ⇜ (493/32 → 987/64) ⇝ 31/2 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 61/4 ⇜ (493/32 → 987/64) ⇝ 31/2 | note:E4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 61/4 ⇜ (493/32 → 987/64) ⇝ 31/2 | note:Ab4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 61/4 ⇜ (987/64 → 247/16) ⇝ 31/2 | note:Bb3 gain:0.290710678118656 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 61/4 ⇜ (987/64 → 247/16) ⇝ 31/2 | note:Eb4 gain:0.290710678118656 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 61/4 ⇜ (987/64 → 247/16) ⇝ 31/2 | note:E4 gain:0.290710678118656 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 61/4 ⇜ (987/64 → 247/16) ⇝ 31/2 | note:Ab4 gain:0.290710678118656 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 61/4 ⇜ (247/16 → 989/64) ⇝ 31/2 | note:Bb3 gain:0.22000000000000483 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 61/4 ⇜ (247/16 → 989/64) ⇝ 31/2 | note:Eb4 gain:0.22000000000000483 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 61/4 ⇜ (247/16 → 989/64) ⇝ 31/2 | note:E4 gain:0.22000000000000483 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 61/4 ⇜ (247/16 → 989/64) ⇝ 31/2 | note:Ab4 gain:0.22000000000000483 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 61/4 ⇜ (989/64 → 495/32) ⇝ 31/2 | note:Bb3 gain:0.14928932188135083 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 61/4 ⇜ (989/64 → 495/32) ⇝ 31/2 | note:Eb4 gain:0.14928932188135083 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 61/4 ⇜ (989/64 → 495/32) ⇝ 31/2 | note:E4 gain:0.14928932188135083 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 61/4 ⇜ (989/64 → 495/32) ⇝ 31/2 | note:Ab4 gain:0.14928932188135083 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 61/4 ⇜ (495/32 → 991/64) ⇝ 31/2 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 61/4 ⇜ (495/32 → 991/64) ⇝ 31/2 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 61/4 ⇜ (495/32 → 991/64) ⇝ 31/2 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 61/4 ⇜ (495/32 → 991/64) ⇝ 31/2 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 61/4 ⇜ (991/64 → 31/2) | note:Bb3 gain:0.14928932188134328 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 61/4 ⇜ (991/64 → 31/2) | note:Eb4 gain:0.14928932188134328 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 61/4 ⇜ (991/64 → 31/2) | note:E4 gain:0.14928932188134328 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 61/4 ⇜ (991/64 → 31/2) | note:Ab4 gain:0.14928932188134328 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ (31/2 → 993/64) ⇝ 125/8 | note:C#5 gain:0.43999999999998823 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ (31/2 → 993/64) ⇝ 125/8 | note:G#5 gain:0.43999999999998823 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ (31/2 → 993/64) ⇝ 125/8 | note:B5 gain:0.43999999999998823 clip:1 s:piano release:0.1 pan:0.6342592592592593 ]", - "[ (31/2 → 993/64) ⇝ 63/4 | note:F#2 gain:0.43999999999998823 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 31/2 ⇜ (993/64 → 497/32) ⇝ 125/8 | note:C#5 gain:0.5814213562373128 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 31/2 ⇜ (993/64 → 497/32) ⇝ 125/8 | note:G#5 gain:0.5814213562373128 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 31/2 ⇜ (993/64 → 497/32) ⇝ 125/8 | note:B5 gain:0.5814213562373128 clip:1 s:piano release:0.1 pan:0.6342592592592593 ]", - "[ 31/2 ⇜ (993/64 → 497/32) ⇝ 63/4 | note:F#2 gain:0.5814213562373128 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 31/2 ⇜ (497/32 → 995/64) ⇝ 125/8 | note:C#5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 31/2 ⇜ (497/32 → 995/64) ⇝ 125/8 | note:G#5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 31/2 ⇜ (497/32 → 995/64) ⇝ 125/8 | note:B5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6342592592592593 ]", - "[ 31/2 ⇜ (497/32 → 995/64) ⇝ 63/4 | note:F#2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ (435/28 → 995/64) ⇝ 221/14 | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ (435/28 → 995/64) ⇝ 221/14 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ (435/28 → 995/64) ⇝ 221/14 | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ (435/28 → 995/64) ⇝ 221/14 | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 31/2 ⇜ (995/64 → 249/16) ⇝ 125/8 | note:C#5 gain:0.581421356237315 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 31/2 ⇜ (995/64 → 249/16) ⇝ 125/8 | note:G#5 gain:0.581421356237315 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 31/2 ⇜ (995/64 → 249/16) ⇝ 125/8 | note:B5 gain:0.581421356237315 clip:1 s:piano release:0.1 pan:0.6342592592592593 ]", - "[ 31/2 ⇜ (995/64 → 249/16) ⇝ 63/4 | note:F#2 gain:0.581421356237315 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 435/28 ⇜ (995/64 → 249/16) ⇝ 221/14 | note:70 gain:0.058142135623731495 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 435/28 ⇜ (995/64 → 249/16) ⇝ 221/14 | note:75 gain:0.058142135623731495 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 435/28 ⇜ (995/64 → 249/16) ⇝ 221/14 | note:76 gain:0.058142135623731495 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 435/28 ⇜ (995/64 → 249/16) ⇝ 221/14 | note:80 gain:0.058142135623731495 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 31/2 ⇜ (249/16 → 997/64) ⇝ 125/8 | note:C#5 gain:0.44000000000001394 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 31/2 ⇜ (249/16 → 997/64) ⇝ 125/8 | note:G#5 gain:0.44000000000001394 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 31/2 ⇜ (249/16 → 997/64) ⇝ 125/8 | note:B5 gain:0.44000000000001394 clip:1 s:piano release:0.1 pan:0.6342592592592593 ]", - "[ 31/2 ⇜ (249/16 → 997/64) ⇝ 63/4 | note:F#2 gain:0.44000000000001394 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 435/28 ⇜ (249/16 → 997/64) ⇝ 221/14 | note:70 gain:0.0440000000000014 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 435/28 ⇜ (249/16 → 997/64) ⇝ 221/14 | note:75 gain:0.0440000000000014 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 435/28 ⇜ (249/16 → 997/64) ⇝ 221/14 | note:76 gain:0.0440000000000014 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 435/28 ⇜ (249/16 → 997/64) ⇝ 221/14 | note:80 gain:0.0440000000000014 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 31/2 ⇜ (997/64 → 499/32) ⇝ 125/8 | note:C#5 gain:0.29857864376268867 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 31/2 ⇜ (997/64 → 499/32) ⇝ 125/8 | note:G#5 gain:0.29857864376268867 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 31/2 ⇜ (997/64 → 499/32) ⇝ 125/8 | note:B5 gain:0.29857864376268867 clip:1 s:piano release:0.1 pan:0.6342592592592593 ]", - "[ 31/2 ⇜ (997/64 → 499/32) ⇝ 63/4 | note:F#2 gain:0.29857864376268867 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 435/28 ⇜ (997/64 → 499/32) ⇝ 221/14 | note:70 gain:0.029857864376268868 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 435/28 ⇜ (997/64 → 499/32) ⇝ 221/14 | note:75 gain:0.029857864376268868 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 435/28 ⇜ (997/64 → 499/32) ⇝ 221/14 | note:76 gain:0.029857864376268868 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 435/28 ⇜ (997/64 → 499/32) ⇝ 221/14 | note:80 gain:0.029857864376268868 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 31/2 ⇜ (499/32 → 999/64) ⇝ 125/8 | note:C#5 gain:0.24 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 31/2 ⇜ (499/32 → 999/64) ⇝ 125/8 | note:G#5 gain:0.24 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 31/2 ⇜ (499/32 → 999/64) ⇝ 125/8 | note:B5 gain:0.24 clip:1 s:piano release:0.1 pan:0.6342592592592593 ]", - "[ 31/2 ⇜ (499/32 → 999/64) ⇝ 63/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 435/28 ⇜ (499/32 → 999/64) ⇝ 221/14 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 435/28 ⇜ (499/32 → 999/64) ⇝ 221/14 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 435/28 ⇜ (499/32 → 999/64) ⇝ 221/14 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 435/28 ⇜ (499/32 → 999/64) ⇝ 221/14 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 31/2 ⇜ (999/64 → 125/8) | note:C#5 gain:0.29857864376268356 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 31/2 ⇜ (999/64 → 125/8) | note:G#5 gain:0.29857864376268356 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 31/2 ⇜ (999/64 → 125/8) | note:B5 gain:0.29857864376268356 clip:1 s:piano release:0.1 pan:0.6342592592592593 ]", - "[ 31/2 ⇜ (999/64 → 125/8) ⇝ 63/4 | note:F#2 gain:0.29857864376268356 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 435/28 ⇜ (999/64 → 125/8) ⇝ 221/14 | note:70 gain:0.029857864376268358 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 435/28 ⇜ (999/64 → 125/8) ⇝ 221/14 | note:75 gain:0.029857864376268358 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 435/28 ⇜ (999/64 → 125/8) ⇝ 221/14 | note:76 gain:0.029857864376268358 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 435/28 ⇜ (999/64 → 125/8) ⇝ 221/14 | note:80 gain:0.029857864376268358 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 31/2 ⇜ (125/8 → 1001/64) ⇝ 63/4 | note:F#2 gain:0.4399999999999839 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 435/28 ⇜ (125/8 → 1001/64) ⇝ 221/14 | note:70 gain:0.043999999999998395 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 435/28 ⇜ (125/8 → 1001/64) ⇝ 221/14 | note:75 gain:0.043999999999998395 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 435/28 ⇜ (125/8 → 1001/64) ⇝ 221/14 | note:76 gain:0.043999999999998395 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 435/28 ⇜ (125/8 → 1001/64) ⇝ 221/14 | note:80 gain:0.043999999999998395 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 31/2 ⇜ (1001/64 → 501/32) ⇝ 63/4 | note:F#2 gain:0.5814213562373098 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 435/28 ⇜ (1001/64 → 501/32) ⇝ 221/14 | note:70 gain:0.05814213562373099 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 435/28 ⇜ (1001/64 → 501/32) ⇝ 221/14 | note:75 gain:0.05814213562373099 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 435/28 ⇜ (1001/64 → 501/32) ⇝ 221/14 | note:76 gain:0.05814213562373099 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 435/28 ⇜ (1001/64 → 501/32) ⇝ 221/14 | note:80 gain:0.05814213562373099 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 31/2 ⇜ (501/32 → 1003/64) ⇝ 63/4 | note:F#2 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 435/28 ⇜ (501/32 → 1003/64) ⇝ 221/14 | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 435/28 ⇜ (501/32 → 1003/64) ⇝ 221/14 | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 435/28 ⇜ (501/32 → 1003/64) ⇝ 221/14 | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 435/28 ⇜ (501/32 → 1003/64) ⇝ 221/14 | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 31/2 ⇜ (1003/64 → 251/16) ⇝ 63/4 | note:F#2 gain:0.5814213562373179 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 435/28 ⇜ (1003/64 → 251/16) ⇝ 221/14 | note:70 gain:0.0581421356237318 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 435/28 ⇜ (1003/64 → 251/16) ⇝ 221/14 | note:75 gain:0.0581421356237318 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 435/28 ⇜ (1003/64 → 251/16) ⇝ 221/14 | note:76 gain:0.0581421356237318 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 435/28 ⇜ (1003/64 → 251/16) ⇝ 221/14 | note:80 gain:0.0581421356237318 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 31/2 ⇜ (251/16 → 1005/64) ⇝ 63/4 | note:F#2 gain:0.4399999999999955 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 435/28 ⇜ (251/16 → 1005/64) ⇝ 221/14 | note:70 gain:0.04399999999999955 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 435/28 ⇜ (251/16 → 1005/64) ⇝ 221/14 | note:75 gain:0.04399999999999955 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 435/28 ⇜ (251/16 → 1005/64) ⇝ 221/14 | note:76 gain:0.04399999999999955 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 435/28 ⇜ (251/16 → 1005/64) ⇝ 221/14 | note:80 gain:0.04399999999999955 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 31/2 ⇜ (1005/64 → 503/32) ⇝ 63/4 | note:F#2 gain:0.2985786437626917 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 435/28 ⇜ (1005/64 → 503/32) ⇝ 221/14 | note:70 gain:0.029857864376269173 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 435/28 ⇜ (1005/64 → 503/32) ⇝ 221/14 | note:75 gain:0.029857864376269173 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 435/28 ⇜ (1005/64 → 503/32) ⇝ 221/14 | note:76 gain:0.029857864376269173 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 435/28 ⇜ (1005/64 → 503/32) ⇝ 221/14 | note:80 gain:0.029857864376269173 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 31/2 ⇜ (503/32 → 1007/64) ⇝ 63/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 435/28 ⇜ (503/32 → 1007/64) ⇝ 221/14 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 435/28 ⇜ (503/32 → 1007/64) ⇝ 221/14 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 435/28 ⇜ (503/32 → 1007/64) ⇝ 221/14 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 435/28 ⇜ (503/32 → 1007/64) ⇝ 221/14 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 31/2 ⇜ (1007/64 → 63/4) | note:F#2 gain:0.29857864376268045 clip:1 s:piano release:0.1 pan:0.4444444444444444 ]", - "[ 435/28 ⇜ (1007/64 → 63/4) ⇝ 221/14 | note:70 gain:0.029857864376268046 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 435/28 ⇜ (1007/64 → 63/4) ⇝ 221/14 | note:75 gain:0.029857864376268046 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 435/28 ⇜ (1007/64 → 63/4) ⇝ 221/14 | note:76 gain:0.029857864376268046 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 435/28 ⇜ (1007/64 → 63/4) ⇝ 221/14 | note:80 gain:0.029857864376268046 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 435/28 ⇜ (63/4 → 1009/64) ⇝ 221/14 | note:70 gain:0.04400000000000024 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 435/28 ⇜ (63/4 → 1009/64) ⇝ 221/14 | note:75 gain:0.04400000000000024 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 435/28 ⇜ (63/4 → 1009/64) ⇝ 221/14 | note:76 gain:0.04400000000000024 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 435/28 ⇜ (63/4 → 1009/64) ⇝ 221/14 | note:80 gain:0.04400000000000024 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ (63/4 → 1009/64) ⇝ 127/8 | note:C#5 gain:0.4400000000000024 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ (63/4 → 1009/64) ⇝ 127/8 | note:G#5 gain:0.4400000000000024 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ (63/4 → 1009/64) ⇝ 127/8 | note:B5 gain:0.4400000000000024 clip:1 s:piano release:0.1 pan:0.6342592592592593 ]", - "[ (63/4 → 1009/64) ⇝ 16/1 | note:Bb3 gain:0.2200000000000012 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ (63/4 → 1009/64) ⇝ 16/1 | note:Eb4 gain:0.2200000000000012 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ (63/4 → 1009/64) ⇝ 16/1 | note:E4 gain:0.2200000000000012 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ (63/4 → 1009/64) ⇝ 16/1 | note:Ab4 gain:0.2200000000000012 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 435/28 ⇜ (1009/64 → 505/32) ⇝ 221/14 | note:70 gain:0.05814213562373069 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 435/28 ⇜ (1009/64 → 505/32) ⇝ 221/14 | note:75 gain:0.05814213562373069 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 435/28 ⇜ (1009/64 → 505/32) ⇝ 221/14 | note:76 gain:0.05814213562373069 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 435/28 ⇜ (1009/64 → 505/32) ⇝ 221/14 | note:80 gain:0.05814213562373069 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 63/4 ⇜ (1009/64 → 505/32) ⇝ 127/8 | note:C#5 gain:0.5814213562373068 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 63/4 ⇜ (1009/64 → 505/32) ⇝ 127/8 | note:G#5 gain:0.5814213562373068 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 63/4 ⇜ (1009/64 → 505/32) ⇝ 127/8 | note:B5 gain:0.5814213562373068 clip:1 s:piano release:0.1 pan:0.6342592592592593 ]", - "[ 63/4 ⇜ (1009/64 → 505/32) ⇝ 16/1 | note:Bb3 gain:0.2907106781186534 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 63/4 ⇜ (1009/64 → 505/32) ⇝ 16/1 | note:Eb4 gain:0.2907106781186534 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 63/4 ⇜ (1009/64 → 505/32) ⇝ 16/1 | note:E4 gain:0.2907106781186534 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 63/4 ⇜ (1009/64 → 505/32) ⇝ 16/1 | note:Ab4 gain:0.2907106781186534 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 435/28 ⇜ (505/32 → 221/14) | note:70 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 435/28 ⇜ (505/32 → 221/14) | note:75 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 435/28 ⇜ (505/32 → 221/14) | note:76 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 435/28 ⇜ (505/32 → 221/14) | note:80 gain:0.06400000000000002 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 63/4 ⇜ (505/32 → 1011/64) ⇝ 127/8 | note:C#5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 63/4 ⇜ (505/32 → 1011/64) ⇝ 127/8 | note:G#5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 63/4 ⇜ (505/32 → 1011/64) ⇝ 127/8 | note:B5 gain:0.6400000000000001 clip:1 s:piano release:0.1 pan:0.6342592592592593 ]", - "[ 63/4 ⇜ (505/32 → 1011/64) ⇝ 16/1 | note:Bb3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 63/4 ⇜ (505/32 → 1011/64) ⇝ 16/1 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 63/4 ⇜ (505/32 → 1011/64) ⇝ 16/1 | note:E4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 63/4 ⇜ (505/32 → 1011/64) ⇝ 16/1 | note:Ab4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 63/4 ⇜ (1011/64 → 253/16) ⇝ 127/8 | note:C#5 gain:0.581421356237321 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 63/4 ⇜ (1011/64 → 253/16) ⇝ 127/8 | note:G#5 gain:0.581421356237321 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 63/4 ⇜ (1011/64 → 253/16) ⇝ 127/8 | note:B5 gain:0.581421356237321 clip:1 s:piano release:0.1 pan:0.6342592592592593 ]", - "[ 63/4 ⇜ (1011/64 → 253/16) ⇝ 16/1 | note:Bb3 gain:0.2907106781186605 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 63/4 ⇜ (1011/64 → 253/16) ⇝ 16/1 | note:Eb4 gain:0.2907106781186605 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 63/4 ⇜ (1011/64 → 253/16) ⇝ 16/1 | note:E4 gain:0.2907106781186605 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 63/4 ⇜ (1011/64 → 253/16) ⇝ 16/1 | note:Ab4 gain:0.2907106781186605 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 63/4 ⇜ (253/16 → 1013/64) ⇝ 127/8 | note:C#5 gain:0.4399999999999998 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 63/4 ⇜ (253/16 → 1013/64) ⇝ 127/8 | note:G#5 gain:0.4399999999999998 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 63/4 ⇜ (253/16 → 1013/64) ⇝ 127/8 | note:B5 gain:0.4399999999999998 clip:1 s:piano release:0.1 pan:0.6342592592592593 ]", - "[ 63/4 ⇜ (253/16 → 1013/64) ⇝ 16/1 | note:Bb3 gain:0.2199999999999999 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 63/4 ⇜ (253/16 → 1013/64) ⇝ 16/1 | note:Eb4 gain:0.2199999999999999 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 63/4 ⇜ (253/16 → 1013/64) ⇝ 16/1 | note:E4 gain:0.2199999999999999 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 63/4 ⇜ (253/16 → 1013/64) ⇝ 16/1 | note:Ab4 gain:0.2199999999999999 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 63/4 ⇜ (1013/64 → 507/32) ⇝ 127/8 | note:C#5 gain:0.2985786437626947 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 63/4 ⇜ (1013/64 → 507/32) ⇝ 127/8 | note:G#5 gain:0.2985786437626947 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 63/4 ⇜ (1013/64 → 507/32) ⇝ 127/8 | note:B5 gain:0.2985786437626947 clip:1 s:piano release:0.1 pan:0.6342592592592593 ]", - "[ 63/4 ⇜ (1013/64 → 507/32) ⇝ 16/1 | note:Bb3 gain:0.14928932188134736 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 63/4 ⇜ (1013/64 → 507/32) ⇝ 16/1 | note:Eb4 gain:0.14928932188134736 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 63/4 ⇜ (1013/64 → 507/32) ⇝ 16/1 | note:E4 gain:0.14928932188134736 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 63/4 ⇜ (1013/64 → 507/32) ⇝ 16/1 | note:Ab4 gain:0.14928932188134736 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 63/4 ⇜ (507/32 → 1015/64) ⇝ 127/8 | note:C#5 gain:0.24 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 63/4 ⇜ (507/32 → 1015/64) ⇝ 127/8 | note:G#5 gain:0.24 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 63/4 ⇜ (507/32 → 1015/64) ⇝ 127/8 | note:B5 gain:0.24 clip:1 s:piano release:0.1 pan:0.6342592592592593 ]", - "[ 63/4 ⇜ (507/32 → 1015/64) ⇝ 16/1 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 63/4 ⇜ (507/32 → 1015/64) ⇝ 16/1 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 63/4 ⇜ (507/32 → 1015/64) ⇝ 16/1 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 63/4 ⇜ (507/32 → 1015/64) ⇝ 16/1 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 63/4 ⇜ (1015/64 → 127/8) | note:C#5 gain:0.2985786437626935 clip:1 s:piano release:0.1 pan:0.587962962962963 ]", - "[ 63/4 ⇜ (1015/64 → 127/8) | note:G#5 gain:0.2985786437626935 clip:1 s:piano release:0.1 pan:0.6203703703703703 ]", - "[ 63/4 ⇜ (1015/64 → 127/8) | note:B5 gain:0.2985786437626935 clip:1 s:piano release:0.1 pan:0.6342592592592593 ]", - "[ 63/4 ⇜ (1015/64 → 127/8) ⇝ 16/1 | note:Bb3 gain:0.14928932188134675 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 63/4 ⇜ (1015/64 → 127/8) ⇝ 16/1 | note:Eb4 gain:0.14928932188134675 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 63/4 ⇜ (1015/64 → 127/8) ⇝ 16/1 | note:E4 gain:0.14928932188134675 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 63/4 ⇜ (1015/64 → 127/8) ⇝ 16/1 | note:Ab4 gain:0.14928932188134675 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 63/4 ⇜ (127/8 → 1017/64) ⇝ 16/1 | note:Bb3 gain:0.21999999999999906 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 63/4 ⇜ (127/8 → 1017/64) ⇝ 16/1 | note:Eb4 gain:0.21999999999999906 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 63/4 ⇜ (127/8 → 1017/64) ⇝ 16/1 | note:E4 gain:0.21999999999999906 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 63/4 ⇜ (127/8 → 1017/64) ⇝ 16/1 | note:Ab4 gain:0.21999999999999906 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 63/4 ⇜ (1017/64 → 509/32) ⇝ 16/1 | note:Bb3 gain:0.29071067811865187 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 63/4 ⇜ (1017/64 → 509/32) ⇝ 16/1 | note:Eb4 gain:0.29071067811865187 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 63/4 ⇜ (1017/64 → 509/32) ⇝ 16/1 | note:E4 gain:0.29071067811865187 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 63/4 ⇜ (1017/64 → 509/32) ⇝ 16/1 | note:Ab4 gain:0.29071067811865187 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 63/4 ⇜ (509/32 → 1019/64) ⇝ 16/1 | note:Bb3 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 63/4 ⇜ (509/32 → 1019/64) ⇝ 16/1 | note:Eb4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 63/4 ⇜ (509/32 → 1019/64) ⇝ 16/1 | note:E4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 63/4 ⇜ (509/32 → 1019/64) ⇝ 16/1 | note:Ab4 gain:0.32000000000000006 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 63/4 ⇜ (1019/64 → 255/16) ⇝ 16/1 | note:Bb3 gain:0.29071067811865403 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 63/4 ⇜ (1019/64 → 255/16) ⇝ 16/1 | note:Eb4 gain:0.29071067811865403 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 63/4 ⇜ (1019/64 → 255/16) ⇝ 16/1 | note:E4 gain:0.29071067811865403 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 63/4 ⇜ (1019/64 → 255/16) ⇝ 16/1 | note:Ab4 gain:0.29071067811865403 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 63/4 ⇜ (255/16 → 1021/64) ⇝ 16/1 | note:Bb3 gain:0.22000000000000208 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 63/4 ⇜ (255/16 → 1021/64) ⇝ 16/1 | note:Eb4 gain:0.22000000000000208 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 63/4 ⇜ (255/16 → 1021/64) ⇝ 16/1 | note:E4 gain:0.22000000000000208 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 63/4 ⇜ (255/16 → 1021/64) ⇝ 16/1 | note:Ab4 gain:0.22000000000000208 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 63/4 ⇜ (1021/64 → 511/32) ⇝ 16/1 | note:Bb3 gain:0.1492893218813489 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 63/4 ⇜ (1021/64 → 511/32) ⇝ 16/1 | note:Eb4 gain:0.1492893218813489 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 63/4 ⇜ (1021/64 → 511/32) ⇝ 16/1 | note:E4 gain:0.1492893218813489 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 63/4 ⇜ (1021/64 → 511/32) ⇝ 16/1 | note:Ab4 gain:0.1492893218813489 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 63/4 ⇜ (511/32 → 1023/64) ⇝ 16/1 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 63/4 ⇜ (511/32 → 1023/64) ⇝ 16/1 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 63/4 ⇜ (511/32 → 1023/64) ⇝ 16/1 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 63/4 ⇜ (511/32 → 1023/64) ⇝ 16/1 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", - "[ 63/4 ⇜ (1023/64 → 16/1) | note:Bb3 gain:0.14928932188134522 clip:1 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 63/4 ⇜ (1023/64 → 16/1) | note:Eb4 gain:0.14928932188134522 clip:1 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 63/4 ⇜ (1023/64 → 16/1) | note:E4 gain:0.14928932188134522 clip:1 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 63/4 ⇜ (1023/64 → 16/1) | note:Ab4 gain:0.14928932188134522 clip:1 s:piano release:0.1 pan:0.5648148148148149 ]", + "[ 113/8 ⇜ (455/32 → 911/64) ⇝ 57/4 | note:F#4 gain:0.24 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 113/8 ⇜ (455/32 → 911/64) ⇝ 57/4 | note:C#5 gain:0.24 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 113/8 ⇜ (455/32 → 911/64) ⇝ 57/4 | note:E5 gain:0.24 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 14/1 ⇜ (911/64 → 57/4) | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 393/28 ⇜ (911/64 → 57/4) ⇝ 100/7 | note:71 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 393/28 ⇜ (911/64 → 57/4) ⇝ 100/7 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 393/28 ⇜ (911/64 → 57/4) ⇝ 100/7 | note:77 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 393/28 ⇜ (911/64 → 57/4) ⇝ 100/7 | note:81 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 113/8 ⇜ (911/64 → 57/4) | note:F#4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 113/8 ⇜ (911/64 → 57/4) | note:C#5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 113/8 ⇜ (911/64 → 57/4) | note:E5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 393/28 ⇜ (57/4 → 913/64) ⇝ 100/7 | note:71 gain:0.044 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 393/28 ⇜ (57/4 → 913/64) ⇝ 100/7 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 393/28 ⇜ (57/4 → 913/64) ⇝ 100/7 | note:77 gain:0.044 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 393/28 ⇜ (57/4 → 913/64) ⇝ 100/7 | note:81 gain:0.044 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 393/28 ⇜ (913/64 → 457/32) ⇝ 100/7 | note:71 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 393/28 ⇜ (913/64 → 457/32) ⇝ 100/7 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 393/28 ⇜ (913/64 → 457/32) ⇝ 100/7 | note:77 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 393/28 ⇜ (913/64 → 457/32) ⇝ 100/7 | note:81 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ 393/28 ⇜ (457/32 → 100/7) | note:71 gain:0.064 clip:1 s:piano release:0.1 pan:0.578703703704 ]", + "[ 393/28 ⇜ (457/32 → 100/7) | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 393/28 ⇜ (457/32 → 100/7) | note:77 gain:0.064 clip:1 s:piano release:0.1 pan:0.606481481481 ]", + "[ 393/28 ⇜ (457/32 → 100/7) | note:81 gain:0.064 clip:1 s:piano release:0.1 pan:0.625 ]", + "[ (29/2 → 929/64) ⇝ 117/8 | note:C#5 gain:0.44 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ (29/2 → 929/64) ⇝ 117/8 | note:G#5 gain:0.44 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ (29/2 → 929/64) ⇝ 117/8 | note:B5 gain:0.44 clip:1 s:piano release:0.1 pan:0.634259259259 ]", + "[ (29/2 → 929/64) ⇝ 59/4 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ (29/2 → 929/64) ⇝ 59/4 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ (29/2 → 929/64) ⇝ 59/4 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (29/2 → 929/64) ⇝ 59/4 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ (29/2 → 929/64) ⇝ 59/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 29/2 ⇜ (929/64 → 465/32) ⇝ 117/8 | note:C#5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 29/2 ⇜ (929/64 → 465/32) ⇝ 117/8 | note:G#5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 29/2 ⇜ (929/64 → 465/32) ⇝ 117/8 | note:B5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.634259259259 ]", + "[ 29/2 ⇜ (929/64 → 465/32) ⇝ 59/4 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/2 ⇜ (929/64 → 465/32) ⇝ 59/4 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/2 ⇜ (929/64 → 465/32) ⇝ 59/4 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/2 ⇜ (929/64 → 465/32) ⇝ 59/4 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/2 ⇜ (929/64 → 465/32) ⇝ 59/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 29/2 ⇜ (465/32 → 931/64) ⇝ 117/8 | note:C#5 gain:0.64 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 29/2 ⇜ (465/32 → 931/64) ⇝ 117/8 | note:G#5 gain:0.64 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 29/2 ⇜ (465/32 → 931/64) ⇝ 117/8 | note:B5 gain:0.64 clip:1 s:piano release:0.1 pan:0.634259259259 ]", + "[ 29/2 ⇜ (465/32 → 931/64) ⇝ 59/4 | note:Bb3 gain:0.32 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/2 ⇜ (465/32 → 931/64) ⇝ 59/4 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/2 ⇜ (465/32 → 931/64) ⇝ 59/4 | note:E4 gain:0.32 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/2 ⇜ (465/32 → 931/64) ⇝ 59/4 | note:Ab4 gain:0.32 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/2 ⇜ (465/32 → 931/64) ⇝ 59/4 | note:F#2 gain:0.64 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 29/2 ⇜ (931/64 → 233/16) ⇝ 117/8 | note:C#5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 29/2 ⇜ (931/64 → 233/16) ⇝ 117/8 | note:G#5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 29/2 ⇜ (931/64 → 233/16) ⇝ 117/8 | note:B5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.634259259259 ]", + "[ 29/2 ⇜ (931/64 → 233/16) ⇝ 59/4 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/2 ⇜ (931/64 → 233/16) ⇝ 59/4 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/2 ⇜ (931/64 → 233/16) ⇝ 59/4 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/2 ⇜ (931/64 → 233/16) ⇝ 59/4 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/2 ⇜ (931/64 → 233/16) ⇝ 59/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 29/2 ⇜ (233/16 → 933/64) ⇝ 117/8 | note:C#5 gain:0.44 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 29/2 ⇜ (233/16 → 933/64) ⇝ 117/8 | note:G#5 gain:0.44 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 29/2 ⇜ (233/16 → 933/64) ⇝ 117/8 | note:B5 gain:0.44 clip:1 s:piano release:0.1 pan:0.634259259259 ]", + "[ 29/2 ⇜ (233/16 → 933/64) ⇝ 59/4 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/2 ⇜ (233/16 → 933/64) ⇝ 59/4 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/2 ⇜ (233/16 → 933/64) ⇝ 59/4 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/2 ⇜ (233/16 → 933/64) ⇝ 59/4 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/2 ⇜ (233/16 → 933/64) ⇝ 59/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 29/2 ⇜ (933/64 → 467/32) ⇝ 117/8 | note:C#5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 29/2 ⇜ (933/64 → 467/32) ⇝ 117/8 | note:G#5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 29/2 ⇜ (933/64 → 467/32) ⇝ 117/8 | note:B5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.634259259259 ]", + "[ 29/2 ⇜ (933/64 → 467/32) ⇝ 59/4 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/2 ⇜ (933/64 → 467/32) ⇝ 59/4 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/2 ⇜ (933/64 → 467/32) ⇝ 59/4 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/2 ⇜ (933/64 → 467/32) ⇝ 59/4 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/2 ⇜ (933/64 → 467/32) ⇝ 59/4 | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 29/2 ⇜ (467/32 → 935/64) ⇝ 117/8 | note:C#5 gain:0.24 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 29/2 ⇜ (467/32 → 935/64) ⇝ 117/8 | note:G#5 gain:0.24 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 29/2 ⇜ (467/32 → 935/64) ⇝ 117/8 | note:B5 gain:0.24 clip:1 s:piano release:0.1 pan:0.634259259259 ]", + "[ 29/2 ⇜ (467/32 → 935/64) ⇝ 59/4 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/2 ⇜ (467/32 → 935/64) ⇝ 59/4 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/2 ⇜ (467/32 → 935/64) ⇝ 59/4 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/2 ⇜ (467/32 → 935/64) ⇝ 59/4 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/2 ⇜ (467/32 → 935/64) ⇝ 59/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 29/2 ⇜ (935/64 → 117/8) | note:C#5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 29/2 ⇜ (935/64 → 117/8) | note:G#5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 29/2 ⇜ (935/64 → 117/8) | note:B5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.634259259259 ]", + "[ 29/2 ⇜ (935/64 → 117/8) ⇝ 59/4 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/2 ⇜ (935/64 → 117/8) ⇝ 59/4 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/2 ⇜ (935/64 → 117/8) ⇝ 59/4 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/2 ⇜ (935/64 → 117/8) ⇝ 59/4 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/2 ⇜ (935/64 → 117/8) ⇝ 59/4 | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 29/2 ⇜ (117/8 → 937/64) ⇝ 59/4 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/2 ⇜ (117/8 → 937/64) ⇝ 59/4 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/2 ⇜ (117/8 → 937/64) ⇝ 59/4 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/2 ⇜ (117/8 → 937/64) ⇝ 59/4 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/2 ⇜ (117/8 → 937/64) ⇝ 59/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 29/2 ⇜ (937/64 → 469/32) ⇝ 59/4 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/2 ⇜ (937/64 → 469/32) ⇝ 59/4 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/2 ⇜ (937/64 → 469/32) ⇝ 59/4 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/2 ⇜ (937/64 → 469/32) ⇝ 59/4 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/2 ⇜ (937/64 → 469/32) ⇝ 59/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 29/2 ⇜ (469/32 → 939/64) ⇝ 59/4 | note:Bb3 gain:0.32 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/2 ⇜ (469/32 → 939/64) ⇝ 59/4 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/2 ⇜ (469/32 → 939/64) ⇝ 59/4 | note:E4 gain:0.32 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/2 ⇜ (469/32 → 939/64) ⇝ 59/4 | note:Ab4 gain:0.32 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/2 ⇜ (469/32 → 939/64) ⇝ 59/4 | note:F#2 gain:0.64 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 29/2 ⇜ (939/64 → 235/16) ⇝ 59/4 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/2 ⇜ (939/64 → 235/16) ⇝ 59/4 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/2 ⇜ (939/64 → 235/16) ⇝ 59/4 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/2 ⇜ (939/64 → 235/16) ⇝ 59/4 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/2 ⇜ (939/64 → 235/16) ⇝ 59/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 29/2 ⇜ (235/16 → 941/64) ⇝ 59/4 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/2 ⇜ (235/16 → 941/64) ⇝ 59/4 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/2 ⇜ (235/16 → 941/64) ⇝ 59/4 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/2 ⇜ (235/16 → 941/64) ⇝ 59/4 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/2 ⇜ (235/16 → 941/64) ⇝ 59/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 29/2 ⇜ (941/64 → 471/32) ⇝ 59/4 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/2 ⇜ (941/64 → 471/32) ⇝ 59/4 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/2 ⇜ (941/64 → 471/32) ⇝ 59/4 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/2 ⇜ (941/64 → 471/32) ⇝ 59/4 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/2 ⇜ (941/64 → 471/32) ⇝ 59/4 | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 29/2 ⇜ (471/32 → 943/64) ⇝ 59/4 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/2 ⇜ (471/32 → 943/64) ⇝ 59/4 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/2 ⇜ (471/32 → 943/64) ⇝ 59/4 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/2 ⇜ (471/32 → 943/64) ⇝ 59/4 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/2 ⇜ (471/32 → 943/64) ⇝ 59/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 29/2 ⇜ (943/64 → 59/4) | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 29/2 ⇜ (943/64 → 59/4) | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/2 ⇜ (943/64 → 59/4) | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 29/2 ⇜ (943/64 → 59/4) | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 29/2 ⇜ (943/64 → 59/4) | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ (59/4 → 945/64) ⇝ 119/8 | note:F#4 gain:0.44 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ (59/4 → 945/64) ⇝ 119/8 | note:C#5 gain:0.44 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ (59/4 → 945/64) ⇝ 119/8 | note:E5 gain:0.44 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 59/4 ⇜ (945/64 → 473/32) ⇝ 119/8 | note:F#4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 59/4 ⇜ (945/64 → 473/32) ⇝ 119/8 | note:C#5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 59/4 ⇜ (945/64 → 473/32) ⇝ 119/8 | note:E5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 59/4 ⇜ (473/32 → 947/64) ⇝ 119/8 | note:F#4 gain:0.64 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 59/4 ⇜ (473/32 → 947/64) ⇝ 119/8 | note:C#5 gain:0.64 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 59/4 ⇜ (473/32 → 947/64) ⇝ 119/8 | note:E5 gain:0.64 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ (207/14 → 947/64) ⇝ 421/28 | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ (207/14 → 947/64) ⇝ 421/28 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ (207/14 → 947/64) ⇝ 421/28 | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ (207/14 → 947/64) ⇝ 421/28 | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 59/4 ⇜ (947/64 → 237/16) ⇝ 119/8 | note:F#4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 59/4 ⇜ (947/64 → 237/16) ⇝ 119/8 | note:C#5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 59/4 ⇜ (947/64 → 237/16) ⇝ 119/8 | note:E5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 207/14 ⇜ (947/64 → 237/16) ⇝ 421/28 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 207/14 ⇜ (947/64 → 237/16) ⇝ 421/28 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 207/14 ⇜ (947/64 → 237/16) ⇝ 421/28 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 207/14 ⇜ (947/64 → 237/16) ⇝ 421/28 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 59/4 ⇜ (237/16 → 949/64) ⇝ 119/8 | note:F#4 gain:0.44 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 59/4 ⇜ (237/16 → 949/64) ⇝ 119/8 | note:C#5 gain:0.44 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 59/4 ⇜ (237/16 → 949/64) ⇝ 119/8 | note:E5 gain:0.44 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 207/14 ⇜ (237/16 → 949/64) ⇝ 421/28 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 207/14 ⇜ (237/16 → 949/64) ⇝ 421/28 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 207/14 ⇜ (237/16 → 949/64) ⇝ 421/28 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 207/14 ⇜ (237/16 → 949/64) ⇝ 421/28 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 59/4 ⇜ (949/64 → 475/32) ⇝ 119/8 | note:F#4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 59/4 ⇜ (949/64 → 475/32) ⇝ 119/8 | note:C#5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 59/4 ⇜ (949/64 → 475/32) ⇝ 119/8 | note:E5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 207/14 ⇜ (949/64 → 475/32) ⇝ 421/28 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 207/14 ⇜ (949/64 → 475/32) ⇝ 421/28 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 207/14 ⇜ (949/64 → 475/32) ⇝ 421/28 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 207/14 ⇜ (949/64 → 475/32) ⇝ 421/28 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 59/4 ⇜ (475/32 → 951/64) ⇝ 119/8 | note:F#4 gain:0.24 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 59/4 ⇜ (475/32 → 951/64) ⇝ 119/8 | note:C#5 gain:0.24 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 59/4 ⇜ (475/32 → 951/64) ⇝ 119/8 | note:E5 gain:0.24 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 207/14 ⇜ (475/32 → 951/64) ⇝ 421/28 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 207/14 ⇜ (475/32 → 951/64) ⇝ 421/28 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 207/14 ⇜ (475/32 → 951/64) ⇝ 421/28 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 207/14 ⇜ (475/32 → 951/64) ⇝ 421/28 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 59/4 ⇜ (951/64 → 119/8) | note:F#4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 59/4 ⇜ (951/64 → 119/8) | note:C#5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 59/4 ⇜ (951/64 → 119/8) | note:E5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 207/14 ⇜ (951/64 → 119/8) ⇝ 421/28 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 207/14 ⇜ (951/64 → 119/8) ⇝ 421/28 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 207/14 ⇜ (951/64 → 119/8) ⇝ 421/28 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 207/14 ⇜ (951/64 → 119/8) ⇝ 421/28 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 207/14 ⇜ (119/8 → 953/64) ⇝ 421/28 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 207/14 ⇜ (119/8 → 953/64) ⇝ 421/28 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 207/14 ⇜ (119/8 → 953/64) ⇝ 421/28 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 207/14 ⇜ (119/8 → 953/64) ⇝ 421/28 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 207/14 ⇜ (953/64 → 477/32) ⇝ 421/28 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 207/14 ⇜ (953/64 → 477/32) ⇝ 421/28 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 207/14 ⇜ (953/64 → 477/32) ⇝ 421/28 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 207/14 ⇜ (953/64 → 477/32) ⇝ 421/28 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 207/14 ⇜ (477/32 → 955/64) ⇝ 421/28 | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 207/14 ⇜ (477/32 → 955/64) ⇝ 421/28 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 207/14 ⇜ (477/32 → 955/64) ⇝ 421/28 | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 207/14 ⇜ (477/32 → 955/64) ⇝ 421/28 | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 207/14 ⇜ (955/64 → 239/16) ⇝ 421/28 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 207/14 ⇜ (955/64 → 239/16) ⇝ 421/28 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 207/14 ⇜ (955/64 → 239/16) ⇝ 421/28 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 207/14 ⇜ (955/64 → 239/16) ⇝ 421/28 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 207/14 ⇜ (239/16 → 957/64) ⇝ 421/28 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 207/14 ⇜ (239/16 → 957/64) ⇝ 421/28 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 207/14 ⇜ (239/16 → 957/64) ⇝ 421/28 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 207/14 ⇜ (239/16 → 957/64) ⇝ 421/28 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 207/14 ⇜ (957/64 → 479/32) ⇝ 421/28 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 207/14 ⇜ (957/64 → 479/32) ⇝ 421/28 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 207/14 ⇜ (957/64 → 479/32) ⇝ 421/28 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 207/14 ⇜ (957/64 → 479/32) ⇝ 421/28 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 207/14 ⇜ (479/32 → 959/64) ⇝ 421/28 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 207/14 ⇜ (479/32 → 959/64) ⇝ 421/28 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 207/14 ⇜ (479/32 → 959/64) ⇝ 421/28 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 207/14 ⇜ (479/32 → 959/64) ⇝ 421/28 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 207/14 ⇜ (959/64 → 15/1) ⇝ 421/28 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 207/14 ⇜ (959/64 → 15/1) ⇝ 421/28 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 207/14 ⇜ (959/64 → 15/1) ⇝ 421/28 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 207/14 ⇜ (959/64 → 15/1) ⇝ 421/28 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 207/14 ⇜ (15/1 → 961/64) ⇝ 421/28 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 207/14 ⇜ (15/1 → 961/64) ⇝ 421/28 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 207/14 ⇜ (15/1 → 961/64) ⇝ 421/28 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 207/14 ⇜ (15/1 → 961/64) ⇝ 421/28 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ (15/1 → 961/64) ⇝ 61/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 207/14 ⇜ (961/64 → 481/32) ⇝ 421/28 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 207/14 ⇜ (961/64 → 481/32) ⇝ 421/28 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 207/14 ⇜ (961/64 → 481/32) ⇝ 421/28 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 207/14 ⇜ (961/64 → 481/32) ⇝ 421/28 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 15/1 ⇜ (961/64 → 481/32) ⇝ 61/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 207/14 ⇜ (481/32 → 421/28) | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 207/14 ⇜ (481/32 → 421/28) | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 207/14 ⇜ (481/32 → 421/28) | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 207/14 ⇜ (481/32 → 421/28) | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 15/1 ⇜ (481/32 → 963/64) ⇝ 61/4 | note:F#2 gain:0.64 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 15/1 ⇜ (963/64 → 241/16) ⇝ 61/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 15/1 ⇜ (241/16 → 965/64) ⇝ 61/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 15/1 ⇜ (965/64 → 483/32) ⇝ 61/4 | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 15/1 ⇜ (483/32 → 967/64) ⇝ 61/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 15/1 ⇜ (967/64 → 121/8) ⇝ 61/4 | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 15/1 ⇜ (121/8 → 969/64) ⇝ 61/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ (121/8 → 969/64) ⇝ 61/4 | note:F#4 gain:0.44 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ (121/8 → 969/64) ⇝ 61/4 | note:C#5 gain:0.44 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ (121/8 → 969/64) ⇝ 61/4 | note:E5 gain:0.44 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 15/1 ⇜ (969/64 → 485/32) ⇝ 61/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 121/8 ⇜ (969/64 → 485/32) ⇝ 61/4 | note:F#4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 121/8 ⇜ (969/64 → 485/32) ⇝ 61/4 | note:C#5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 121/8 ⇜ (969/64 → 485/32) ⇝ 61/4 | note:E5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 15/1 ⇜ (485/32 → 971/64) ⇝ 61/4 | note:F#2 gain:0.64 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 121/8 ⇜ (485/32 → 971/64) ⇝ 61/4 | note:F#4 gain:0.64 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 121/8 ⇜ (485/32 → 971/64) ⇝ 61/4 | note:C#5 gain:0.64 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 121/8 ⇜ (485/32 → 971/64) ⇝ 61/4 | note:E5 gain:0.64 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 15/1 ⇜ (971/64 → 243/16) ⇝ 61/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 121/8 ⇜ (971/64 → 243/16) ⇝ 61/4 | note:F#4 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 121/8 ⇜ (971/64 → 243/16) ⇝ 61/4 | note:C#5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 121/8 ⇜ (971/64 → 243/16) ⇝ 61/4 | note:E5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 15/1 ⇜ (243/16 → 973/64) ⇝ 61/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 121/8 ⇜ (243/16 → 973/64) ⇝ 61/4 | note:F#4 gain:0.44 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 121/8 ⇜ (243/16 → 973/64) ⇝ 61/4 | note:C#5 gain:0.44 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 121/8 ⇜ (243/16 → 973/64) ⇝ 61/4 | note:E5 gain:0.44 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 15/1 ⇜ (973/64 → 487/32) ⇝ 61/4 | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 121/8 ⇜ (973/64 → 487/32) ⇝ 61/4 | note:F#4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 121/8 ⇜ (973/64 → 487/32) ⇝ 61/4 | note:C#5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 121/8 ⇜ (973/64 → 487/32) ⇝ 61/4 | note:E5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 15/1 ⇜ (487/32 → 975/64) ⇝ 61/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 121/8 ⇜ (487/32 → 975/64) ⇝ 61/4 | note:F#4 gain:0.24 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 121/8 ⇜ (487/32 → 975/64) ⇝ 61/4 | note:C#5 gain:0.24 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 121/8 ⇜ (487/32 → 975/64) ⇝ 61/4 | note:E5 gain:0.24 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 15/1 ⇜ (975/64 → 61/4) | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 121/8 ⇜ (975/64 → 61/4) | note:F#4 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.555555555556 ]", + "[ 121/8 ⇜ (975/64 → 61/4) | note:C#5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 121/8 ⇜ (975/64 → 61/4) | note:E5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ (61/4 → 977/64) ⇝ 31/2 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ (61/4 → 977/64) ⇝ 31/2 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ (61/4 → 977/64) ⇝ 31/2 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (61/4 → 977/64) ⇝ 31/2 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 61/4 ⇜ (977/64 → 489/32) ⇝ 31/2 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 61/4 ⇜ (977/64 → 489/32) ⇝ 31/2 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 61/4 ⇜ (977/64 → 489/32) ⇝ 31/2 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 61/4 ⇜ (977/64 → 489/32) ⇝ 31/2 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 61/4 ⇜ (489/32 → 979/64) ⇝ 31/2 | note:Bb3 gain:0.32 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 61/4 ⇜ (489/32 → 979/64) ⇝ 31/2 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 61/4 ⇜ (489/32 → 979/64) ⇝ 31/2 | note:E4 gain:0.32 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 61/4 ⇜ (489/32 → 979/64) ⇝ 31/2 | note:Ab4 gain:0.32 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 61/4 ⇜ (979/64 → 245/16) ⇝ 31/2 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 61/4 ⇜ (979/64 → 245/16) ⇝ 31/2 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 61/4 ⇜ (979/64 → 245/16) ⇝ 31/2 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 61/4 ⇜ (979/64 → 245/16) ⇝ 31/2 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 61/4 ⇜ (245/16 → 981/64) ⇝ 31/2 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 61/4 ⇜ (245/16 → 981/64) ⇝ 31/2 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 61/4 ⇜ (245/16 → 981/64) ⇝ 31/2 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 61/4 ⇜ (245/16 → 981/64) ⇝ 31/2 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 61/4 ⇜ (981/64 → 491/32) ⇝ 31/2 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 61/4 ⇜ (981/64 → 491/32) ⇝ 31/2 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 61/4 ⇜ (981/64 → 491/32) ⇝ 31/2 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 61/4 ⇜ (981/64 → 491/32) ⇝ 31/2 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 61/4 ⇜ (491/32 → 983/64) ⇝ 31/2 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 61/4 ⇜ (491/32 → 983/64) ⇝ 31/2 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 61/4 ⇜ (491/32 → 983/64) ⇝ 31/2 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 61/4 ⇜ (491/32 → 983/64) ⇝ 31/2 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 61/4 ⇜ (983/64 → 123/8) ⇝ 31/2 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 61/4 ⇜ (983/64 → 123/8) ⇝ 31/2 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 61/4 ⇜ (983/64 → 123/8) ⇝ 31/2 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 61/4 ⇜ (983/64 → 123/8) ⇝ 31/2 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 61/4 ⇜ (123/8 → 985/64) ⇝ 31/2 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 61/4 ⇜ (123/8 → 985/64) ⇝ 31/2 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 61/4 ⇜ (123/8 → 985/64) ⇝ 31/2 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 61/4 ⇜ (123/8 → 985/64) ⇝ 31/2 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 61/4 ⇜ (985/64 → 493/32) ⇝ 31/2 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 61/4 ⇜ (985/64 → 493/32) ⇝ 31/2 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 61/4 ⇜ (985/64 → 493/32) ⇝ 31/2 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 61/4 ⇜ (985/64 → 493/32) ⇝ 31/2 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 61/4 ⇜ (493/32 → 987/64) ⇝ 31/2 | note:Bb3 gain:0.32 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 61/4 ⇜ (493/32 → 987/64) ⇝ 31/2 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 61/4 ⇜ (493/32 → 987/64) ⇝ 31/2 | note:E4 gain:0.32 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 61/4 ⇜ (493/32 → 987/64) ⇝ 31/2 | note:Ab4 gain:0.32 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 61/4 ⇜ (987/64 → 247/16) ⇝ 31/2 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 61/4 ⇜ (987/64 → 247/16) ⇝ 31/2 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 61/4 ⇜ (987/64 → 247/16) ⇝ 31/2 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 61/4 ⇜ (987/64 → 247/16) ⇝ 31/2 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 61/4 ⇜ (247/16 → 989/64) ⇝ 31/2 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 61/4 ⇜ (247/16 → 989/64) ⇝ 31/2 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 61/4 ⇜ (247/16 → 989/64) ⇝ 31/2 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 61/4 ⇜ (247/16 → 989/64) ⇝ 31/2 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 61/4 ⇜ (989/64 → 495/32) ⇝ 31/2 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 61/4 ⇜ (989/64 → 495/32) ⇝ 31/2 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 61/4 ⇜ (989/64 → 495/32) ⇝ 31/2 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 61/4 ⇜ (989/64 → 495/32) ⇝ 31/2 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 61/4 ⇜ (495/32 → 991/64) ⇝ 31/2 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 61/4 ⇜ (495/32 → 991/64) ⇝ 31/2 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 61/4 ⇜ (495/32 → 991/64) ⇝ 31/2 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 61/4 ⇜ (495/32 → 991/64) ⇝ 31/2 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 61/4 ⇜ (991/64 → 31/2) | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 61/4 ⇜ (991/64 → 31/2) | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 61/4 ⇜ (991/64 → 31/2) | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 61/4 ⇜ (991/64 → 31/2) | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ (31/2 → 993/64) ⇝ 125/8 | note:C#5 gain:0.44 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ (31/2 → 993/64) ⇝ 125/8 | note:G#5 gain:0.44 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ (31/2 → 993/64) ⇝ 125/8 | note:B5 gain:0.44 clip:1 s:piano release:0.1 pan:0.634259259259 ]", + "[ (31/2 → 993/64) ⇝ 63/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 31/2 ⇜ (993/64 → 497/32) ⇝ 125/8 | note:C#5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 31/2 ⇜ (993/64 → 497/32) ⇝ 125/8 | note:G#5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 31/2 ⇜ (993/64 → 497/32) ⇝ 125/8 | note:B5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.634259259259 ]", + "[ 31/2 ⇜ (993/64 → 497/32) ⇝ 63/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 31/2 ⇜ (497/32 → 995/64) ⇝ 125/8 | note:C#5 gain:0.64 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 31/2 ⇜ (497/32 → 995/64) ⇝ 125/8 | note:G#5 gain:0.64 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 31/2 ⇜ (497/32 → 995/64) ⇝ 125/8 | note:B5 gain:0.64 clip:1 s:piano release:0.1 pan:0.634259259259 ]", + "[ 31/2 ⇜ (497/32 → 995/64) ⇝ 63/4 | note:F#2 gain:0.64 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ (435/28 → 995/64) ⇝ 221/14 | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ (435/28 → 995/64) ⇝ 221/14 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ (435/28 → 995/64) ⇝ 221/14 | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ (435/28 → 995/64) ⇝ 221/14 | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 31/2 ⇜ (995/64 → 249/16) ⇝ 125/8 | note:C#5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 31/2 ⇜ (995/64 → 249/16) ⇝ 125/8 | note:G#5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 31/2 ⇜ (995/64 → 249/16) ⇝ 125/8 | note:B5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.634259259259 ]", + "[ 31/2 ⇜ (995/64 → 249/16) ⇝ 63/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 435/28 ⇜ (995/64 → 249/16) ⇝ 221/14 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 435/28 ⇜ (995/64 → 249/16) ⇝ 221/14 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 435/28 ⇜ (995/64 → 249/16) ⇝ 221/14 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 435/28 ⇜ (995/64 → 249/16) ⇝ 221/14 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 31/2 ⇜ (249/16 → 997/64) ⇝ 125/8 | note:C#5 gain:0.44 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 31/2 ⇜ (249/16 → 997/64) ⇝ 125/8 | note:G#5 gain:0.44 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 31/2 ⇜ (249/16 → 997/64) ⇝ 125/8 | note:B5 gain:0.44 clip:1 s:piano release:0.1 pan:0.634259259259 ]", + "[ 31/2 ⇜ (249/16 → 997/64) ⇝ 63/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 435/28 ⇜ (249/16 → 997/64) ⇝ 221/14 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 435/28 ⇜ (249/16 → 997/64) ⇝ 221/14 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 435/28 ⇜ (249/16 → 997/64) ⇝ 221/14 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 435/28 ⇜ (249/16 → 997/64) ⇝ 221/14 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 31/2 ⇜ (997/64 → 499/32) ⇝ 125/8 | note:C#5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 31/2 ⇜ (997/64 → 499/32) ⇝ 125/8 | note:G#5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 31/2 ⇜ (997/64 → 499/32) ⇝ 125/8 | note:B5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.634259259259 ]", + "[ 31/2 ⇜ (997/64 → 499/32) ⇝ 63/4 | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 435/28 ⇜ (997/64 → 499/32) ⇝ 221/14 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 435/28 ⇜ (997/64 → 499/32) ⇝ 221/14 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 435/28 ⇜ (997/64 → 499/32) ⇝ 221/14 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 435/28 ⇜ (997/64 → 499/32) ⇝ 221/14 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 31/2 ⇜ (499/32 → 999/64) ⇝ 125/8 | note:C#5 gain:0.24 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 31/2 ⇜ (499/32 → 999/64) ⇝ 125/8 | note:G#5 gain:0.24 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 31/2 ⇜ (499/32 → 999/64) ⇝ 125/8 | note:B5 gain:0.24 clip:1 s:piano release:0.1 pan:0.634259259259 ]", + "[ 31/2 ⇜ (499/32 → 999/64) ⇝ 63/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 435/28 ⇜ (499/32 → 999/64) ⇝ 221/14 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 435/28 ⇜ (499/32 → 999/64) ⇝ 221/14 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 435/28 ⇜ (499/32 → 999/64) ⇝ 221/14 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 435/28 ⇜ (499/32 → 999/64) ⇝ 221/14 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 31/2 ⇜ (999/64 → 125/8) | note:C#5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 31/2 ⇜ (999/64 → 125/8) | note:G#5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 31/2 ⇜ (999/64 → 125/8) | note:B5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.634259259259 ]", + "[ 31/2 ⇜ (999/64 → 125/8) ⇝ 63/4 | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 435/28 ⇜ (999/64 → 125/8) ⇝ 221/14 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 435/28 ⇜ (999/64 → 125/8) ⇝ 221/14 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 435/28 ⇜ (999/64 → 125/8) ⇝ 221/14 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 435/28 ⇜ (999/64 → 125/8) ⇝ 221/14 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 31/2 ⇜ (125/8 → 1001/64) ⇝ 63/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 435/28 ⇜ (125/8 → 1001/64) ⇝ 221/14 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 435/28 ⇜ (125/8 → 1001/64) ⇝ 221/14 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 435/28 ⇜ (125/8 → 1001/64) ⇝ 221/14 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 435/28 ⇜ (125/8 → 1001/64) ⇝ 221/14 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 31/2 ⇜ (1001/64 → 501/32) ⇝ 63/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 435/28 ⇜ (1001/64 → 501/32) ⇝ 221/14 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 435/28 ⇜ (1001/64 → 501/32) ⇝ 221/14 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 435/28 ⇜ (1001/64 → 501/32) ⇝ 221/14 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 435/28 ⇜ (1001/64 → 501/32) ⇝ 221/14 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 31/2 ⇜ (501/32 → 1003/64) ⇝ 63/4 | note:F#2 gain:0.64 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 435/28 ⇜ (501/32 → 1003/64) ⇝ 221/14 | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 435/28 ⇜ (501/32 → 1003/64) ⇝ 221/14 | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 435/28 ⇜ (501/32 → 1003/64) ⇝ 221/14 | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 435/28 ⇜ (501/32 → 1003/64) ⇝ 221/14 | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 31/2 ⇜ (1003/64 → 251/16) ⇝ 63/4 | note:F#2 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 435/28 ⇜ (1003/64 → 251/16) ⇝ 221/14 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 435/28 ⇜ (1003/64 → 251/16) ⇝ 221/14 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 435/28 ⇜ (1003/64 → 251/16) ⇝ 221/14 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 435/28 ⇜ (1003/64 → 251/16) ⇝ 221/14 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 31/2 ⇜ (251/16 → 1005/64) ⇝ 63/4 | note:F#2 gain:0.44 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 435/28 ⇜ (251/16 → 1005/64) ⇝ 221/14 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 435/28 ⇜ (251/16 → 1005/64) ⇝ 221/14 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 435/28 ⇜ (251/16 → 1005/64) ⇝ 221/14 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 435/28 ⇜ (251/16 → 1005/64) ⇝ 221/14 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 31/2 ⇜ (1005/64 → 503/32) ⇝ 63/4 | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 435/28 ⇜ (1005/64 → 503/32) ⇝ 221/14 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 435/28 ⇜ (1005/64 → 503/32) ⇝ 221/14 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 435/28 ⇜ (1005/64 → 503/32) ⇝ 221/14 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 435/28 ⇜ (1005/64 → 503/32) ⇝ 221/14 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 31/2 ⇜ (503/32 → 1007/64) ⇝ 63/4 | note:F#2 gain:0.24 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 435/28 ⇜ (503/32 → 1007/64) ⇝ 221/14 | note:70 gain:0.024 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 435/28 ⇜ (503/32 → 1007/64) ⇝ 221/14 | note:75 gain:0.024 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 435/28 ⇜ (503/32 → 1007/64) ⇝ 221/14 | note:76 gain:0.024 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 435/28 ⇜ (503/32 → 1007/64) ⇝ 221/14 | note:80 gain:0.024 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 31/2 ⇜ (1007/64 → 63/4) | note:F#2 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.444444444444 ]", + "[ 435/28 ⇜ (1007/64 → 63/4) ⇝ 221/14 | note:70 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 435/28 ⇜ (1007/64 → 63/4) ⇝ 221/14 | note:75 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 435/28 ⇜ (1007/64 → 63/4) ⇝ 221/14 | note:76 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 435/28 ⇜ (1007/64 → 63/4) ⇝ 221/14 | note:80 gain:0.029857864376 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 435/28 ⇜ (63/4 → 1009/64) ⇝ 221/14 | note:70 gain:0.044 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 435/28 ⇜ (63/4 → 1009/64) ⇝ 221/14 | note:75 gain:0.044 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 435/28 ⇜ (63/4 → 1009/64) ⇝ 221/14 | note:76 gain:0.044 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 435/28 ⇜ (63/4 → 1009/64) ⇝ 221/14 | note:80 gain:0.044 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ (63/4 → 1009/64) ⇝ 127/8 | note:C#5 gain:0.44 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ (63/4 → 1009/64) ⇝ 127/8 | note:G#5 gain:0.44 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ (63/4 → 1009/64) ⇝ 127/8 | note:B5 gain:0.44 clip:1 s:piano release:0.1 pan:0.634259259259 ]", + "[ (63/4 → 1009/64) ⇝ 16/1 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ (63/4 → 1009/64) ⇝ 16/1 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ (63/4 → 1009/64) ⇝ 16/1 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ (63/4 → 1009/64) ⇝ 16/1 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 435/28 ⇜ (1009/64 → 505/32) ⇝ 221/14 | note:70 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 435/28 ⇜ (1009/64 → 505/32) ⇝ 221/14 | note:75 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 435/28 ⇜ (1009/64 → 505/32) ⇝ 221/14 | note:76 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 435/28 ⇜ (1009/64 → 505/32) ⇝ 221/14 | note:80 gain:0.058142135624 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 63/4 ⇜ (1009/64 → 505/32) ⇝ 127/8 | note:C#5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 63/4 ⇜ (1009/64 → 505/32) ⇝ 127/8 | note:G#5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 63/4 ⇜ (1009/64 → 505/32) ⇝ 127/8 | note:B5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.634259259259 ]", + "[ 63/4 ⇜ (1009/64 → 505/32) ⇝ 16/1 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 63/4 ⇜ (1009/64 → 505/32) ⇝ 16/1 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 63/4 ⇜ (1009/64 → 505/32) ⇝ 16/1 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 63/4 ⇜ (1009/64 → 505/32) ⇝ 16/1 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 435/28 ⇜ (505/32 → 221/14) | note:70 gain:0.064 clip:1 s:piano release:0.1 pan:0.574074074074 ]", + "[ 435/28 ⇜ (505/32 → 221/14) | note:75 gain:0.064 clip:1 s:piano release:0.1 pan:0.597222222222 ]", + "[ 435/28 ⇜ (505/32 → 221/14) | note:76 gain:0.064 clip:1 s:piano release:0.1 pan:0.601851851852 ]", + "[ 435/28 ⇜ (505/32 → 221/14) | note:80 gain:0.064 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 63/4 ⇜ (505/32 → 1011/64) ⇝ 127/8 | note:C#5 gain:0.64 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 63/4 ⇜ (505/32 → 1011/64) ⇝ 127/8 | note:G#5 gain:0.64 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 63/4 ⇜ (505/32 → 1011/64) ⇝ 127/8 | note:B5 gain:0.64 clip:1 s:piano release:0.1 pan:0.634259259259 ]", + "[ 63/4 ⇜ (505/32 → 1011/64) ⇝ 16/1 | note:Bb3 gain:0.32 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 63/4 ⇜ (505/32 → 1011/64) ⇝ 16/1 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 63/4 ⇜ (505/32 → 1011/64) ⇝ 16/1 | note:E4 gain:0.32 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 63/4 ⇜ (505/32 → 1011/64) ⇝ 16/1 | note:Ab4 gain:0.32 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 63/4 ⇜ (1011/64 → 253/16) ⇝ 127/8 | note:C#5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 63/4 ⇜ (1011/64 → 253/16) ⇝ 127/8 | note:G#5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 63/4 ⇜ (1011/64 → 253/16) ⇝ 127/8 | note:B5 gain:0.581421356237 clip:1 s:piano release:0.1 pan:0.634259259259 ]", + "[ 63/4 ⇜ (1011/64 → 253/16) ⇝ 16/1 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 63/4 ⇜ (1011/64 → 253/16) ⇝ 16/1 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 63/4 ⇜ (1011/64 → 253/16) ⇝ 16/1 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 63/4 ⇜ (1011/64 → 253/16) ⇝ 16/1 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 63/4 ⇜ (253/16 → 1013/64) ⇝ 127/8 | note:C#5 gain:0.44 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 63/4 ⇜ (253/16 → 1013/64) ⇝ 127/8 | note:G#5 gain:0.44 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 63/4 ⇜ (253/16 → 1013/64) ⇝ 127/8 | note:B5 gain:0.44 clip:1 s:piano release:0.1 pan:0.634259259259 ]", + "[ 63/4 ⇜ (253/16 → 1013/64) ⇝ 16/1 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 63/4 ⇜ (253/16 → 1013/64) ⇝ 16/1 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 63/4 ⇜ (253/16 → 1013/64) ⇝ 16/1 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 63/4 ⇜ (253/16 → 1013/64) ⇝ 16/1 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 63/4 ⇜ (1013/64 → 507/32) ⇝ 127/8 | note:C#5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 63/4 ⇜ (1013/64 → 507/32) ⇝ 127/8 | note:G#5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 63/4 ⇜ (1013/64 → 507/32) ⇝ 127/8 | note:B5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.634259259259 ]", + "[ 63/4 ⇜ (1013/64 → 507/32) ⇝ 16/1 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 63/4 ⇜ (1013/64 → 507/32) ⇝ 16/1 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 63/4 ⇜ (1013/64 → 507/32) ⇝ 16/1 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 63/4 ⇜ (1013/64 → 507/32) ⇝ 16/1 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 63/4 ⇜ (507/32 → 1015/64) ⇝ 127/8 | note:C#5 gain:0.24 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 63/4 ⇜ (507/32 → 1015/64) ⇝ 127/8 | note:G#5 gain:0.24 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 63/4 ⇜ (507/32 → 1015/64) ⇝ 127/8 | note:B5 gain:0.24 clip:1 s:piano release:0.1 pan:0.634259259259 ]", + "[ 63/4 ⇜ (507/32 → 1015/64) ⇝ 16/1 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 63/4 ⇜ (507/32 → 1015/64) ⇝ 16/1 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 63/4 ⇜ (507/32 → 1015/64) ⇝ 16/1 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 63/4 ⇜ (507/32 → 1015/64) ⇝ 16/1 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 63/4 ⇜ (1015/64 → 127/8) | note:C#5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.587962962963 ]", + "[ 63/4 ⇜ (1015/64 → 127/8) | note:G#5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.62037037037 ]", + "[ 63/4 ⇜ (1015/64 → 127/8) | note:B5 gain:0.298578643763 clip:1 s:piano release:0.1 pan:0.634259259259 ]", + "[ 63/4 ⇜ (1015/64 → 127/8) ⇝ 16/1 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 63/4 ⇜ (1015/64 → 127/8) ⇝ 16/1 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 63/4 ⇜ (1015/64 → 127/8) ⇝ 16/1 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 63/4 ⇜ (1015/64 → 127/8) ⇝ 16/1 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 63/4 ⇜ (127/8 → 1017/64) ⇝ 16/1 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 63/4 ⇜ (127/8 → 1017/64) ⇝ 16/1 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 63/4 ⇜ (127/8 → 1017/64) ⇝ 16/1 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 63/4 ⇜ (127/8 → 1017/64) ⇝ 16/1 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 63/4 ⇜ (1017/64 → 509/32) ⇝ 16/1 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 63/4 ⇜ (1017/64 → 509/32) ⇝ 16/1 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 63/4 ⇜ (1017/64 → 509/32) ⇝ 16/1 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 63/4 ⇜ (1017/64 → 509/32) ⇝ 16/1 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 63/4 ⇜ (509/32 → 1019/64) ⇝ 16/1 | note:Bb3 gain:0.32 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 63/4 ⇜ (509/32 → 1019/64) ⇝ 16/1 | note:Eb4 gain:0.32 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 63/4 ⇜ (509/32 → 1019/64) ⇝ 16/1 | note:E4 gain:0.32 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 63/4 ⇜ (509/32 → 1019/64) ⇝ 16/1 | note:Ab4 gain:0.32 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 63/4 ⇜ (1019/64 → 255/16) ⇝ 16/1 | note:Bb3 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 63/4 ⇜ (1019/64 → 255/16) ⇝ 16/1 | note:Eb4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 63/4 ⇜ (1019/64 → 255/16) ⇝ 16/1 | note:E4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 63/4 ⇜ (1019/64 → 255/16) ⇝ 16/1 | note:Ab4 gain:0.290710678119 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 63/4 ⇜ (255/16 → 1021/64) ⇝ 16/1 | note:Bb3 gain:0.22 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 63/4 ⇜ (255/16 → 1021/64) ⇝ 16/1 | note:Eb4 gain:0.22 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 63/4 ⇜ (255/16 → 1021/64) ⇝ 16/1 | note:E4 gain:0.22 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 63/4 ⇜ (255/16 → 1021/64) ⇝ 16/1 | note:Ab4 gain:0.22 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 63/4 ⇜ (1021/64 → 511/32) ⇝ 16/1 | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 63/4 ⇜ (1021/64 → 511/32) ⇝ 16/1 | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 63/4 ⇜ (1021/64 → 511/32) ⇝ 16/1 | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 63/4 ⇜ (1021/64 → 511/32) ⇝ 16/1 | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 63/4 ⇜ (511/32 → 1023/64) ⇝ 16/1 | note:Bb3 gain:0.12 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 63/4 ⇜ (511/32 → 1023/64) ⇝ 16/1 | note:Eb4 gain:0.12 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 63/4 ⇜ (511/32 → 1023/64) ⇝ 16/1 | note:E4 gain:0.12 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 63/4 ⇜ (511/32 → 1023/64) ⇝ 16/1 | note:Ab4 gain:0.12 clip:1 s:piano release:0.1 pan:0.564814814815 ]", + "[ 63/4 ⇜ (1023/64 → 16/1) | note:Bb3 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.518518518519 ]", + "[ 63/4 ⇜ (1023/64 → 16/1) | note:Eb4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.541666666667 ]", + "[ 63/4 ⇜ (1023/64 → 16/1) | note:E4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.546296296296 ]", + "[ 63/4 ⇜ (1023/64 → 16/1) | note:Ab4 gain:0.149289321881 clip:1 s:piano release:0.1 pan:0.564814814815 ]", ] `; exports[`renders tunes > tune: festivalOfFingers3 1`] = ` [ - "[ -1/2 ⇜ (0/1 → 1/6) | gain:0.125015148781768 clip:1 note:D5 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ -1/6 ⇜ (0/1 → 1/6) | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ -1/6 ⇜ (0/1 → 1/6) | clip:1 gain:0.125 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ -1/3 ⇜ (0/1 → 1/3) | gain:0.16667274737749818 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 0/1 → 1/3 | clip:1 gain:1 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ 0/1 → 1/3 | clip:1 gain:0.25 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ -3/2 ⇜ (0/1 → 1/2) | gain:0.25074164191519466 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037037 ]", - "[ -3/2 ⇜ (0/1 → 1/2) | gain:0.25074164191519466 clip:1 note:F4 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ -3/2 ⇜ (0/1 → 1/2) | gain:0.25074164191519466 clip:1 note:C5 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ -1/2 ⇜ (0/1 → 1/2) | gain:0.250030297563536 clip:1 note:D5 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ -1/2 ⇜ (0/1 → 1/2) | gain:0.125015148781768 clip:1 note:E7 s:piano release:0.1 pan:0.712962962962963 ]", - "[ -1/6 ⇜ (0/1 → 1/2) | gain:0.25000115828778147 clip:1 note:D3 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ 0/1 → 2/3 | gain:0.5 clip:1 note:D2 s:piano release:0.1 pan:0.42592592592592593 ]", - "[ -1/1 ⇜ (0/1 → 1/1) | gain:0.16682060947840208 clip:1 note:D5 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ -1/1 ⇜ (0/1 → 1/1) | gain:0.16682060947840208 clip:1 note:F5 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ -1/1 ⇜ (0/1 → 1/1) | gain:0.16682060947840208 clip:1 note:C6 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ -1/2 ⇜ (0/1 → 1/1) ⇝ 3/2 | gain:0.125015148781768 clip:1 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ -1/2 ⇜ (0/1 → 1/1) ⇝ 3/2 | gain:0.125015148781768 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037037 ]", - "[ -1/2 ⇜ (0/1 → 1/1) ⇝ 3/2 | gain:0.125015148781768 clip:1 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ 0/1 → 1/1 | gain:0.5 clip:1 note:E4 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 0/1 → 1/1 | gain:0.16666666666666666 clip:1 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ (0/1 → 1/1) ⇝ 2/1 | gain:0.5 clip:1 note:D3 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ (0/1 → 1/1) ⇝ 2/1 | gain:0.5 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ (0/1 → 1/1) ⇝ 2/1 | gain:0.5 clip:1 note:C4 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 1/6 → 1/2 | clip:1 gain:0.5 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ 1/6 → 1/2 | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 1/6 → 5/6 | gain:0.12500057809125337 clip:1 note:D5 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 1/3 → 2/3 | clip:1 gain:1 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 1/3 → 2/3 | clip:1 gain:0.25 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ 1/3 → 1/1 | gain:0.16667273632535057 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 1/2 → 5/6 | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 1/2 → 5/6 | clip:1 gain:0.125 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ (1/2 → 1/1) ⇝ 7/6 | gain:0.25003024249544364 clip:1 note:D3 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ (1/2 → 1/1) ⇝ 3/2 | gain:0.25003024249544364 clip:1 note:E5 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ (1/2 → 1/1) ⇝ 3/2 | gain:0.12501512124772182 clip:1 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ (1/2 → 1/1) ⇝ 5/2 | gain:0.25003024249544364 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037037 ]", - "[ (1/2 → 1/1) ⇝ 5/2 | gain:0.25003024249544364 clip:1 note:F4 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (1/2 → 1/1) ⇝ 5/2 | gain:0.25003024249544364 clip:1 note:C5 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 2/3 → 1/1 | clip:1 gain:1 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ 2/3 → 1/1 | clip:1 gain:0.25 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ (2/3 → 1/1) ⇝ 4/3 | gain:0.5001410914263706 clip:1 note:D2 s:piano release:0.1 pan:0.42592592592592593 ]", - "[ (5/6 → 1/1) ⇝ 7/6 | clip:1 gain:0.5 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ (5/6 → 1/1) ⇝ 7/6 | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ (5/6 → 1/1) ⇝ 3/2 | gain:0.12506778837733018 clip:1 note:D5 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 1/2 ⇜ (1/1 → 7/6) | gain:0.25003024249544364 clip:1 note:D3 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ 5/6 ⇜ (1/1 → 7/6) | clip:1 gain:0.5 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ 5/6 ⇜ (1/1 → 7/6) | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 2/3 ⇜ (1/1 → 4/3) | gain:0.5001410914263706 clip:1 note:D2 s:piano release:0.1 pan:0.42592592592592593 ]", - "[ 1/1 → 4/3 | clip:1 gain:1 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 1/1 → 4/3 | clip:1 gain:0.25 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ -1/2 ⇜ (1/1 → 3/2) | gain:0.125015148781768 clip:1 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ -1/2 ⇜ (1/1 → 3/2) | gain:0.125015148781768 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037037 ]", - "[ -1/2 ⇜ (1/1 → 3/2) | gain:0.125015148781768 clip:1 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ 1/2 ⇜ (1/1 → 3/2) | gain:0.25003024249544364 clip:1 note:E5 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 1/2 ⇜ (1/1 → 3/2) | gain:0.12501512124772182 clip:1 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ 5/6 ⇜ (1/1 → 3/2) | gain:0.12506778837733018 clip:1 note:D5 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 1/1 → 5/3 | gain:0.16682032967580462 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 0/1 ⇜ (1/1 → 2/1) | gain:0.5 clip:1 note:D3 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ 0/1 ⇜ (1/1 → 2/1) | gain:0.5 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 0/1 ⇜ (1/1 → 2/1) | gain:0.5 clip:1 note:C4 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 1/2 ⇜ (1/1 → 2/1) ⇝ 5/2 | gain:0.25003024249544364 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 1/2 ⇜ (1/1 → 2/1) ⇝ 5/2 | gain:0.25003024249544364 clip:1 note:F4 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 1/2 ⇜ (1/1 → 2/1) ⇝ 5/2 | gain:0.25003024249544364 clip:1 note:C5 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 1/1 → 2/1 | gain:0.5004609890274139 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 1/1 → 2/1 | gain:0.16682032967580462 clip:1 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ (1/1 → 2/1) ⇝ 3/1 | gain:0.16682032967580462 clip:1 note:D5 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (1/1 → 2/1) ⇝ 3/1 | gain:0.16682032967580462 clip:1 note:F5 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ (1/1 → 2/1) ⇝ 3/1 | gain:0.16682032967580462 clip:1 note:C6 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 7/6 → 3/2 | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 7/6 → 3/2 | clip:1 gain:0.125 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ 7/6 → 11/6 | gain:0.250360063340037 clip:1 note:D3 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ 4/3 → 5/3 | clip:1 gain:1 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ 4/3 → 5/3 | clip:1 gain:0.25 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 4/3 → 2/1 | gain:0.5010573244293617 clip:1 note:D2 s:piano release:0.1 pan:0.42592592592592593 ]", - "[ 3/2 → 11/6 | clip:1 gain:0.5 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ 3/2 → 11/6 | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ (3/2 → 2/1) ⇝ 13/6 | gain:0.12537014696271603 clip:1 note:D5 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (3/2 → 2/1) ⇝ 5/2 | gain:0.25074029392543207 clip:1 note:D5 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (3/2 → 2/1) ⇝ 5/2 | gain:0.12537014696271603 clip:1 note:E7 s:piano release:0.1 pan:0.712962962962963 ]", - "[ (3/2 → 2/1) ⇝ 7/2 | gain:0.12537014696271603 clip:1 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ (3/2 → 2/1) ⇝ 7/2 | gain:0.12537014696271603 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037037 ]", - "[ (3/2 → 2/1) ⇝ 7/2 | gain:0.12537014696271603 clip:1 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ 5/3 → 2/1 | clip:1 gain:1 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 5/3 → 2/1 | clip:1 gain:0.25 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ (5/3 → 2/1) ⇝ 7/3 | gain:0.16733239616152812 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037037 ]", - "[ (11/6 → 2/1) ⇝ 13/6 | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ (11/6 → 2/1) ⇝ 13/6 | clip:1 gain:0.125 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ (11/6 → 2/1) ⇝ 5/2 | gain:0.2513068410929158 clip:1 note:D3 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ 3/2 ⇜ (2/1 → 13/6) | gain:0.12537014696271603 clip:1 note:G5 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 11/6 ⇜ (2/1 → 13/6) | clip:1 gain:0.5 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ 11/6 ⇜ (2/1 → 13/6) | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 5/3 ⇜ (2/1 → 7/3) | gain:0.16733239616152812 clip:1 note:G4 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 2/1 → 7/3 | clip:1 gain:1 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 2/1 → 7/3 | clip:1 gain:0.25 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ 1/2 ⇜ (2/1 → 5/2) | gain:0.25003024249544364 clip:1 note:G4 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 1/2 ⇜ (2/1 → 5/2) | gain:0.25003024249544364 clip:1 note:B4 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 1/2 ⇜ (2/1 → 5/2) | gain:0.25003024249544364 clip:1 note:F5 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 3/2 ⇜ (2/1 → 5/2) | gain:0.25074029392543207 clip:1 note:G5 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 3/2 ⇜ (2/1 → 5/2) | gain:0.12537014696271603 clip:1 note:A7 s:piano release:0.1 pan:0.7361111111111112 ]", - "[ 11/6 ⇜ (2/1 → 5/2) | gain:0.2513068410929158 clip:1 note:G3 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 2/1 → 8/3 | gain:0.5033359274761097 clip:1 note:G2 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 1/1 ⇜ (2/1 → 3/1) | gain:0.16682032967580462 clip:1 note:G5 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 1/1 ⇜ (2/1 → 3/1) | gain:0.16682032967580462 clip:1 note:B5 s:piano release:0.1 pan:0.6342592592592593 ]", - "[ 1/1 ⇜ (2/1 → 3/1) | gain:0.16682032967580462 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037037 ]", - "[ 3/2 ⇜ (2/1 → 3/1) ⇝ 7/2 | gain:0.12537014696271603 clip:1 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 3/2 ⇜ (2/1 → 3/1) ⇝ 7/2 | gain:0.12537014696271603 clip:1 note:B6 s:piano release:0.1 pan:0.6898148148148149 ]", - "[ 3/2 ⇜ (2/1 → 3/1) ⇝ 7/2 | gain:0.12537014696271603 clip:1 note:F7 s:piano release:0.1 pan:0.7175925925925926 ]", - "[ 2/1 → 3/1 | gain:0.5033359274761097 clip:1 note:A4 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 2/1 → 3/1 | gain:0.16777864249203656 clip:1 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ (2/1 → 3/1) ⇝ 4/1 | gain:0.5033359274761097 clip:1 note:G3 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ (2/1 → 3/1) ⇝ 4/1 | gain:0.5033359274761097 clip:1 note:B3 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ (2/1 → 3/1) ⇝ 4/1 | gain:0.5033359274761097 clip:1 note:F4 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 13/6 → 5/2 | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 13/6 → 5/2 | clip:1 gain:0.125 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ 13/6 → 17/6 | gain:0.12604227597350195 clip:1 note:G5 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 7/3 → 8/3 | clip:1 gain:1 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ 7/3 → 8/3 | clip:1 gain:0.25 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 7/3 → 3/1 | gain:0.1683725767820298 clip:1 note:G4 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/2 → 17/6 | clip:1 gain:0.5 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ 5/2 → 17/6 | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ (5/2 → 3/1) ⇝ 19/6 | gain:0.2530928417288911 clip:1 note:G3 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ (5/2 → 3/1) ⇝ 7/2 | gain:0.2530928417288911 clip:1 note:A5 s:piano release:0.1 pan:0.625 ]", - "[ (5/2 → 3/1) ⇝ 7/2 | gain:0.12654642086444556 clip:1 note:G7 s:piano release:0.1 pan:0.7268518518518519 ]", - "[ (5/2 → 3/1) ⇝ 9/2 | gain:0.2530928417288911 clip:1 note:G4 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (5/2 → 3/1) ⇝ 9/2 | gain:0.2530928417288911 clip:1 note:B4 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ (5/2 → 3/1) ⇝ 9/2 | gain:0.2530928417288911 clip:1 note:F5 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 8/3 → 3/1 | clip:1 gain:1 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 8/3 → 3/1 | clip:1 gain:0.25 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ (8/3 → 3/1) ⇝ 10/3 | gain:0.5073762159242674 clip:1 note:G2 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ (17/6 → 3/1) ⇝ 19/6 | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ (17/6 → 3/1) ⇝ 19/6 | clip:1 gain:0.125 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ (17/6 → 3/1) ⇝ 7/2 | gain:0.12717299371534235 clip:1 note:G5 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 5/2 ⇜ (3/1 → 19/6) | gain:0.2530928417288911 clip:1 note:G3 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 17/6 ⇜ (3/1 → 19/6) | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 17/6 ⇜ (3/1 → 19/6) | clip:1 gain:0.125 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ 8/3 ⇜ (3/1 → 10/3) | gain:0.5073762159242674 clip:1 note:G2 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 3/1 → 10/3 | clip:1 gain:1 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ 3/1 → 10/3 | clip:1 gain:0.25 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 3/2 ⇜ (3/1 → 7/2) | gain:0.12537014696271603 clip:1 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 3/2 ⇜ (3/1 → 7/2) | gain:0.12537014696271603 clip:1 note:B6 s:piano release:0.1 pan:0.6898148148148149 ]", - "[ 3/2 ⇜ (3/1 → 7/2) | gain:0.12537014696271603 clip:1 note:F7 s:piano release:0.1 pan:0.7175925925925926 ]", - "[ 5/2 ⇜ (3/1 → 7/2) | gain:0.2530928417288911 clip:1 note:A5 s:piano release:0.1 pan:0.625 ]", - "[ 5/2 ⇜ (3/1 → 7/2) | gain:0.12654642086444556 clip:1 note:G7 s:piano release:0.1 pan:0.7268518518518519 ]", - "[ 17/6 ⇜ (3/1 → 7/2) | gain:0.12717299371534235 clip:1 note:G5 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 3/1 → 11/3 | gain:0.17004500671881523 clip:1 note:G4 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 2/1 ⇜ (3/1 → 4/1) | gain:0.5033359274761097 clip:1 note:G3 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 2/1 ⇜ (3/1 → 4/1) | gain:0.5033359274761097 clip:1 note:B3 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 2/1 ⇜ (3/1 → 4/1) | gain:0.5033359274761097 clip:1 note:F4 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 5/2 ⇜ (3/1 → 4/1) ⇝ 9/2 | gain:0.2530928417288911 clip:1 note:G4 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 5/2 ⇜ (3/1 → 4/1) ⇝ 9/2 | gain:0.2530928417288911 clip:1 note:B4 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 5/2 ⇜ (3/1 → 4/1) ⇝ 9/2 | gain:0.2530928417288911 clip:1 note:F5 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 3/1 → 4/1 | gain:0.5101350201564457 clip:1 note:G4 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 3/1 → 4/1 | gain:0.17004500671881523 clip:1 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ (3/1 → 4/1) ⇝ 5/1 | gain:0.17004500671881523 clip:1 note:G5 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ (3/1 → 4/1) ⇝ 5/1 | gain:0.17004500671881523 clip:1 note:B5 s:piano release:0.1 pan:0.6342592592592593 ]", - "[ (3/1 → 4/1) ⇝ 5/1 | gain:0.17004500671881523 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037037 ]", - "[ 19/6 → 7/2 | clip:1 gain:0.5 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ 19/6 → 7/2 | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 19/6 → 23/6 | gain:0.25585342140963807 clip:1 note:G3 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 10/3 → 11/3 | clip:1 gain:1 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 10/3 → 11/3 | clip:1 gain:0.25 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ 10/3 → 4/1 | gain:0.5134083833329526 clip:1 note:G2 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 7/2 → 23/6 | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 7/2 → 23/6 | clip:1 gain:0.125 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ (7/2 → 4/1) ⇝ 25/6 | gain:0.12881001250119212 clip:1 note:G5 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ (7/2 → 4/1) ⇝ 9/2 | gain:0.25762002500238423 clip:1 note:G5 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ (7/2 → 4/1) ⇝ 9/2 | gain:0.12881001250119212 clip:1 note:A7 s:piano release:0.1 pan:0.7361111111111112 ]", - "[ (7/2 → 4/1) ⇝ 11/2 | gain:0.12881001250119212 clip:1 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ (7/2 → 4/1) ⇝ 11/2 | gain:0.12881001250119212 clip:1 note:B6 s:piano release:0.1 pan:0.6898148148148149 ]", - "[ (7/2 → 4/1) ⇝ 11/2 | gain:0.12881001250119212 clip:1 note:F7 s:piano release:0.1 pan:0.7175925925925926 ]", - "[ 11/3 → 4/1 | clip:1 gain:1 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ 11/3 → 4/1 | clip:1 gain:0.25 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ (11/3 → 4/1) ⇝ 13/3 | gain:0.17240057910570294 clip:1 note:G4 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (23/6 → 4/1) ⇝ 25/6 | clip:1 gain:0.5 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ (23/6 → 4/1) ⇝ 25/6 | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ (23/6 → 4/1) ⇝ 9/2 | gain:0.2596464221391696 clip:1 note:G3 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 7/2 ⇜ (4/1 → 25/6) | gain:0.12881001250119212 clip:1 note:C5 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 23/6 ⇜ (4/1 → 25/6) | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 23/6 ⇜ (4/1 → 25/6) | clip:1 gain:0.125 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ 11/3 ⇜ (4/1 → 13/3) | gain:0.17240057910570294 clip:1 note:C4 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 4/1 → 13/3 | clip:1 gain:1 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ 4/1 → 13/3 | clip:1 gain:0.25 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 5/2 ⇜ (4/1 → 9/2) | gain:0.2530928417288911 clip:1 note:C4 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 5/2 ⇜ (4/1 → 9/2) | gain:0.2530928417288911 clip:1 note:Eb4 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 5/2 ⇜ (4/1 → 9/2) | gain:0.2530928417288911 clip:1 note:Bb4 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 7/2 ⇜ (4/1 → 9/2) | gain:0.25762002500238423 clip:1 note:C5 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 7/2 ⇜ (4/1 → 9/2) | gain:0.12881001250119212 clip:1 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ 23/6 ⇜ (4/1 → 9/2) | gain:0.2596464221391696 clip:1 note:C3 s:piano release:0.1 pan:0.4722222222222222 ]", - "[ 4/1 → 14/3 | gain:0.5215122927736957 clip:1 note:C2 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 3/1 ⇜ (4/1 → 5/1) | gain:0.17004500671881523 clip:1 note:C5 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 3/1 ⇜ (4/1 → 5/1) | gain:0.17004500671881523 clip:1 note:Eb5 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 3/1 ⇜ (4/1 → 5/1) | gain:0.17004500671881523 clip:1 note:Bb5 s:piano release:0.1 pan:0.6296296296296297 ]", - "[ 7/2 ⇜ (4/1 → 5/1) ⇝ 11/2 | gain:0.12881001250119212 clip:1 note:C6 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 7/2 ⇜ (4/1 → 5/1) ⇝ 11/2 | gain:0.12881001250119212 clip:1 note:Eb6 s:piano release:0.1 pan:0.6527777777777778 ]", - "[ 7/2 ⇜ (4/1 → 5/1) ⇝ 11/2 | gain:0.12881001250119212 clip:1 note:Bb6 s:piano release:0.1 pan:0.6851851851851851 ]", - "[ 4/1 → 5/1 | gain:0.5215122927736957 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 4/1 → 5/1 | gain:0.17383743092456522 clip:1 note:C6 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ (4/1 → 5/1) ⇝ 6/1 | gain:0.5215122927736957 clip:1 note:C3 s:piano release:0.1 pan:0.4722222222222222 ]", - "[ (4/1 → 5/1) ⇝ 6/1 | gain:0.5215122927736957 clip:1 note:Eb3 s:piano release:0.1 pan:0.4861111111111111 ]", - "[ (4/1 → 5/1) ⇝ 6/1 | gain:0.5215122927736957 clip:1 note:Bb3 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 25/6 → 9/2 | clip:1 gain:0.5 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ 25/6 → 9/2 | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 25/6 → 29/6 | gain:0.1309646364790436 clip:1 note:C5 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 13/3 → 14/3 | clip:1 gain:1 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 13/3 → 14/3 | clip:1 gain:0.25 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ 13/3 → 5/1 | gain:0.17544320879914047 clip:1 note:C4 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 9/2 → 29/6 | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 9/2 → 29/6 | clip:1 gain:0.125 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ (9/2 → 5/1) ⇝ 31/6 | gain:0.26446156741931076 clip:1 note:C3 s:piano release:0.1 pan:0.4722222222222222 ]", - "[ (9/2 → 5/1) ⇝ 11/2 | gain:0.26446156741931076 clip:1 note:D5 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (9/2 → 5/1) ⇝ 11/2 | gain:0.13223078370965538 clip:1 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ (9/2 → 5/1) ⇝ 13/2 | gain:0.26446156741931076 clip:1 note:C4 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ (9/2 → 5/1) ⇝ 13/2 | gain:0.26446156741931076 clip:1 note:Eb4 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ (9/2 → 5/1) ⇝ 13/2 | gain:0.26446156741931076 clip:1 note:Bb4 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 14/3 → 5/1 | clip:1 gain:1 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ 14/3 → 5/1 | clip:1 gain:0.25 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ (14/3 → 5/1) ⇝ 16/3 | gain:0.5316362681413888 clip:1 note:C2 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ (29/6 → 5/1) ⇝ 31/6 | clip:1 gain:0.5 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ (29/6 → 5/1) ⇝ 31/6 | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ (29/6 → 5/1) ⇝ 11/2 | gain:0.13361645945966383 clip:1 note:C5 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 9/2 ⇜ (5/1 → 31/6) | gain:0.26446156741931076 clip:1 note:C3 s:piano release:0.1 pan:0.4722222222222222 ]", - "[ 29/6 ⇜ (5/1 → 31/6) | clip:1 gain:0.5 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ 29/6 ⇜ (5/1 → 31/6) | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 14/3 ⇜ (5/1 → 16/3) | gain:0.5316362681413888 clip:1 note:C2 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 5/1 → 16/3 | clip:1 gain:1 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 5/1 → 16/3 | clip:1 gain:0.25 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ 7/2 ⇜ (5/1 → 11/2) | gain:0.12881001250119212 clip:1 note:C6 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 7/2 ⇜ (5/1 → 11/2) | gain:0.12881001250119212 clip:1 note:Eb6 s:piano release:0.1 pan:0.6527777777777778 ]", - "[ 7/2 ⇜ (5/1 → 11/2) | gain:0.12881001250119212 clip:1 note:Bb6 s:piano release:0.1 pan:0.6851851851851851 ]", - "[ 9/2 ⇜ (5/1 → 11/2) | gain:0.26446156741931076 clip:1 note:D5 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 9/2 ⇜ (5/1 → 11/2) | gain:0.13223078370965538 clip:1 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ 29/6 ⇜ (5/1 → 11/2) | gain:0.13361645945966383 clip:1 note:C5 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 5/1 → 17/3 | gain:0.17913609614852058 clip:1 note:C4 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 4/1 ⇜ (5/1 → 6/1) | gain:0.5215122927736957 clip:1 note:C3 s:piano release:0.1 pan:0.4722222222222222 ]", - "[ 4/1 ⇜ (5/1 → 6/1) | gain:0.5215122927736957 clip:1 note:Eb3 s:piano release:0.1 pan:0.4861111111111111 ]", - "[ 4/1 ⇜ (5/1 → 6/1) | gain:0.5215122927736957 clip:1 note:Bb3 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 9/2 ⇜ (5/1 → 6/1) ⇝ 13/2 | gain:0.26446156741931076 clip:1 note:C4 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 9/2 ⇜ (5/1 → 6/1) ⇝ 13/2 | gain:0.26446156741931076 clip:1 note:Eb4 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 9/2 ⇜ (5/1 → 6/1) ⇝ 13/2 | gain:0.26446156741931076 clip:1 note:Bb4 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 5/1 → 6/1 | gain:0.5374082884455618 clip:1 note:C4 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 5/1 → 6/1 | gain:0.17913609614852058 clip:1 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ (5/1 → 6/1) ⇝ 7/1 | gain:0.17913609614852058 clip:1 note:C5 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ (5/1 → 6/1) ⇝ 7/1 | gain:0.17913609614852058 clip:1 note:Eb5 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ (5/1 → 6/1) ⇝ 7/1 | gain:0.17913609614852058 clip:1 note:Bb5 s:piano release:0.1 pan:0.6296296296296297 ]", - "[ 31/6 → 11/2 | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 31/6 → 11/2 | clip:1 gain:0.125 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ 31/6 → 35/6 | gain:0.270229857905173 clip:1 note:C3 s:piano release:0.1 pan:0.4722222222222222 ]", - "[ 16/3 → 17/3 | clip:1 gain:1 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ 16/3 → 17/3 | clip:1 gain:0.25 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 16/3 → 6/1 | gain:0.5436158854652334 clip:1 note:C2 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 11/2 → 35/6 | clip:1 gain:0.5 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ 11/2 → 35/6 | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ (11/2 → 6/1) ⇝ 37/6 | gain:0.1367180627443315 clip:1 note:C5 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ (11/2 → 6/1) ⇝ 13/2 | gain:0.273436125488663 clip:1 note:C5 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ (11/2 → 6/1) ⇝ 13/2 | gain:0.1367180627443315 clip:1 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ (11/2 → 6/1) ⇝ 15/2 | gain:0.1367180627443315 clip:1 note:C6 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ (11/2 → 6/1) ⇝ 15/2 | gain:0.1367180627443315 clip:1 note:Eb6 s:piano release:0.1 pan:0.6527777777777778 ]", - "[ (11/2 → 6/1) ⇝ 15/2 | gain:0.1367180627443315 clip:1 note:Bb6 s:piano release:0.1 pan:0.6851851851851851 ]", - "[ 17/3 → 6/1 | clip:1 gain:1 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 17/3 → 6/1 | clip:1 gain:0.25 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ (17/3 → 6/1) ⇝ 19/3 | gain:0.18340799076649741 clip:1 note:C4 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ (35/6 → 6/1) ⇝ 37/6 | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ (35/6 → 6/1) ⇝ 37/6 | clip:1 gain:0.125 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ (35/6 → 6/1) ⇝ 13/2 | gain:0.2768329670606284 clip:1 note:C3 s:piano release:0.1 pan:0.4722222222222222 ]", - "[ 11/2 ⇜ (6/1 → 37/6) | gain:0.1367180627443315 clip:1 note:F5 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 35/6 ⇜ (6/1 → 37/6) | clip:1 gain:0.5 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ 35/6 ⇜ (6/1 → 37/6) | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 17/3 ⇜ (6/1 → 19/3) | gain:0.18340799076649741 clip:1 note:F4 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 6/1 → 19/3 | clip:1 gain:1 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 6/1 → 19/3 | clip:1 gain:0.25 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ 9/2 ⇜ (6/1 → 13/2) | gain:0.26446156741931076 clip:1 note:F4 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 9/2 ⇜ (6/1 → 13/2) | gain:0.26446156741931076 clip:1 note:A4 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 9/2 ⇜ (6/1 → 13/2) | gain:0.26446156741931076 clip:1 note:Eb5 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 11/2 ⇜ (6/1 → 13/2) | gain:0.273436125488663 clip:1 note:F5 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 11/2 ⇜ (6/1 → 13/2) | gain:0.1367180627443315 clip:1 note:G7 s:piano release:0.1 pan:0.7268518518518519 ]", - "[ 35/6 ⇜ (6/1 → 13/2) | gain:0.2768329670606284 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 6/1 → 20/3 | gain:0.5571927642196897 clip:1 note:F2 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 5/1 ⇜ (6/1 → 7/1) | gain:0.17913609614852058 clip:1 note:F5 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 5/1 ⇜ (6/1 → 7/1) | gain:0.17913609614852058 clip:1 note:A5 s:piano release:0.1 pan:0.625 ]", - "[ 5/1 ⇜ (6/1 → 7/1) | gain:0.17913609614852058 clip:1 note:Eb6 s:piano release:0.1 pan:0.6527777777777778 ]", - "[ 11/2 ⇜ (6/1 → 7/1) ⇝ 15/2 | gain:0.1367180627443315 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037037 ]", - "[ 11/2 ⇜ (6/1 → 7/1) ⇝ 15/2 | gain:0.1367180627443315 clip:1 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 11/2 ⇜ (6/1 → 7/1) ⇝ 15/2 | gain:0.1367180627443315 clip:1 note:Eb7 s:piano release:0.1 pan:0.7083333333333333 ]", - "[ 6/1 → 7/1 | gain:0.5571927642196897 clip:1 note:G4 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 6/1 → 7/1 | gain:0.18573092140656322 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037037 ]", - "[ (6/1 → 7/1) ⇝ 8/1 | gain:0.5571927642196897 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ (6/1 → 7/1) ⇝ 8/1 | gain:0.5571927642196897 clip:1 note:A3 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ (6/1 → 7/1) ⇝ 8/1 | gain:0.5571927642196897 clip:1 note:Eb4 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 37/6 → 13/2 | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 37/6 → 13/2 | clip:1 gain:0.125 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ 37/6 → 41/6 | gain:0.14019971295257413 clip:1 note:F5 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 19/3 → 20/3 | clip:1 gain:1 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ 19/3 → 20/3 | clip:1 gain:0.25 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 19/3 → 7/1 | gain:0.18815945529930245 clip:1 note:F4 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 13/2 → 41/6 | clip:1 gain:0.5 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ 13/2 → 41/6 | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ (13/2 → 7/1) ⇝ 43/6 | gain:0.2841126368137835 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ (13/2 → 7/1) ⇝ 15/2 | gain:0.2841126368137835 clip:1 note:G5 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ (13/2 → 7/1) ⇝ 15/2 | gain:0.14205631840689176 clip:1 note:F7 s:piano release:0.1 pan:0.7175925925925926 ]", - "[ (13/2 → 7/1) ⇝ 17/2 | gain:0.2841126368137835 clip:1 note:F4 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (13/2 → 7/1) ⇝ 17/2 | gain:0.2841126368137835 clip:1 note:A4 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (13/2 → 7/1) ⇝ 17/2 | gain:0.2841126368137835 clip:1 note:Eb5 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 20/3 → 7/1 | clip:1 gain:1 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 20/3 → 7/1 | clip:1 gain:0.25 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ (20/3 → 7/1) ⇝ 22/3 | gain:0.5720333586354239 clip:1 note:F2 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ (41/6 → 7/1) ⇝ 43/6 | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ (41/6 → 7/1) ⇝ 43/6 | clip:1 gain:0.125 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ (41/6 → 7/1) ⇝ 15/2 | gain:0.14397405984990516 clip:1 note:F5 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 13/2 ⇜ (7/1 → 43/6) | gain:0.2841126368137835 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 41/6 ⇜ (7/1 → 43/6) | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 41/6 ⇜ (7/1 → 43/6) | clip:1 gain:0.125 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ 20/3 ⇜ (7/1 → 22/3) | gain:0.5720333586354239 clip:1 note:F2 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 7/1 → 22/3 | clip:1 gain:1 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ 7/1 → 22/3 | clip:1 gain:0.25 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 11/2 ⇜ (7/1 → 15/2) | gain:0.1367180627443315 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037037 ]", - "[ 11/2 ⇜ (7/1 → 15/2) | gain:0.1367180627443315 clip:1 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 11/2 ⇜ (7/1 → 15/2) | gain:0.1367180627443315 clip:1 note:Eb7 s:piano release:0.1 pan:0.7083333333333333 ]", - "[ 13/2 ⇜ (7/1 → 15/2) | gain:0.2841126368137835 clip:1 note:G5 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 13/2 ⇜ (7/1 → 15/2) | gain:0.14205631840689176 clip:1 note:F7 s:piano release:0.1 pan:0.7175925925925926 ]", - "[ 41/6 ⇜ (7/1 → 15/2) | gain:0.14397405984990516 clip:1 note:F5 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 7/1 → 23/3 | gain:0.19326912919706085 clip:1 note:F4 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 6/1 ⇜ (7/1 → 8/1) | gain:0.5571927642196897 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 6/1 ⇜ (7/1 → 8/1) | gain:0.5571927642196897 clip:1 note:A3 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 6/1 ⇜ (7/1 → 8/1) | gain:0.5571927642196897 clip:1 note:Eb4 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 13/2 ⇜ (7/1 → 8/1) ⇝ 17/2 | gain:0.2841126368137835 clip:1 note:F4 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 13/2 ⇜ (7/1 → 8/1) ⇝ 17/2 | gain:0.2841126368137835 clip:1 note:A4 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 13/2 ⇜ (7/1 → 8/1) ⇝ 17/2 | gain:0.2841126368137835 clip:1 note:Eb5 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 7/1 → 8/1 | gain:0.5798073875911826 clip:1 note:F4 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 7/1 → 8/1 | gain:0.19326912919706085 clip:1 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ (7/1 → 8/1) ⇝ 9/1 | gain:0.19326912919706085 clip:1 note:F5 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ (7/1 → 8/1) ⇝ 9/1 | gain:0.19326912919706085 clip:1 note:A5 s:piano release:0.1 pan:0.625 ]", - "[ (7/1 → 8/1) ⇝ 9/1 | gain:0.19326912919706085 clip:1 note:Eb6 s:piano release:0.1 pan:0.6527777777777778 ]", - "[ 43/6 → 15/2 | clip:1 gain:0.5 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ 43/6 → 15/2 | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 43/6 → 47/6 | gain:0.29188007321245396 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 22/3 → 23/3 | clip:1 gain:1 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 22/3 → 23/3 | clip:1 gain:0.25 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ 22/3 → 8/1 | gain:0.5877477490102575 clip:1 note:F2 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 15/2 → 47/6 | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 15/2 → 47/6 | clip:1 gain:0.125 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ (15/2 → 8/1) ⇝ 49/6 | gain:0.14794083417556103 clip:1 note:F5 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ (15/2 → 8/1) ⇝ 17/2 | gain:0.29588166835112206 clip:1 note:F5 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ (15/2 → 8/1) ⇝ 17/2 | gain:0.14794083417556103 clip:1 note:G7 s:piano release:0.1 pan:0.7268518518518519 ]", - "[ (15/2 → 8/1) ⇝ 19/2 | gain:0.14794083417556103 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037037 ]", - "[ (15/2 → 8/1) ⇝ 19/2 | gain:0.14794083417556103 clip:1 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ (15/2 → 8/1) ⇝ 19/2 | gain:0.14794083417556103 clip:1 note:Eb7 s:piano release:0.1 pan:0.7083333333333333 ]", - "[ 23/3 → 8/1 | clip:1 gain:1 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ 23/3 → 8/1 | clip:1 gain:0.25 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ (23/3 → 8/1) ⇝ 25/3 | gain:0.19859999248410734 clip:1 note:F4 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (47/6 → 8/1) ⇝ 49/6 | clip:1 gain:0.5 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ (47/6 → 8/1) ⇝ 49/6 | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ (47/6 → 8/1) ⇝ 17/2 | gain:0.2999253420796384 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 15/2 ⇜ (8/1 → 49/6) | gain:0.14794083417556103 clip:1 note:D5 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 47/6 ⇜ (8/1 → 49/6) | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 47/6 ⇜ (8/1 → 49/6) | clip:1 gain:0.125 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ 23/3 ⇜ (8/1 → 25/3) | gain:0.19859999248410734 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 8/1 → 25/3 | clip:1 gain:1 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ 8/1 → 25/3 | clip:1 gain:0.25 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 13/2 ⇜ (8/1 → 17/2) | gain:0.2841126368137835 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 13/2 ⇜ (8/1 → 17/2) | gain:0.2841126368137835 clip:1 note:F4 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 13/2 ⇜ (8/1 → 17/2) | gain:0.2841126368137835 clip:1 note:C5 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 15/2 ⇜ (8/1 → 17/2) | gain:0.29588166835112206 clip:1 note:D5 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 15/2 ⇜ (8/1 → 17/2) | gain:0.14794083417556103 clip:1 note:E7 s:piano release:0.1 pan:0.712962962962963 ]", - "[ 47/6 ⇜ (8/1 → 17/2) | gain:0.2999253420796384 clip:1 note:D3 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ 8/1 → 26/3 | gain:0.6039084330201149 clip:1 note:D2 s:piano release:0.1 pan:0.42592592592592593 ]", - "[ 7/1 ⇜ (8/1 → 9/1) | gain:0.19326912919706085 clip:1 note:D5 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 7/1 ⇜ (8/1 → 9/1) | gain:0.19326912919706085 clip:1 note:F5 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 7/1 ⇜ (8/1 → 9/1) | gain:0.19326912919706085 clip:1 note:C6 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 15/2 ⇜ (8/1 → 9/1) ⇝ 19/2 | gain:0.14794083417556103 clip:1 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ 15/2 ⇜ (8/1 → 9/1) ⇝ 19/2 | gain:0.14794083417556103 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037037 ]", - "[ 15/2 ⇜ (8/1 → 9/1) ⇝ 19/2 | gain:0.14794083417556103 clip:1 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ 8/1 → 9/1 | gain:0.6039084330201149 clip:1 note:E4 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 8/1 → 9/1 | gain:0.20130281100670494 clip:1 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ (8/1 → 9/1) ⇝ 10/1 | gain:0.6039084330201149 clip:1 note:D3 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ (8/1 → 9/1) ⇝ 10/1 | gain:0.6039084330201149 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ (8/1 → 9/1) ⇝ 10/1 | gain:0.6039084330201149 clip:1 note:C4 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 49/6 → 17/2 | clip:1 gain:0.5 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ 49/6 → 17/2 | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 49/6 → 53/6 | gain:0.15199154547023824 clip:1 note:D5 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 25/3 → 26/3 | clip:1 gain:1 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 25/3 → 26/3 | clip:1 gain:0.25 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ 25/3 → 9/1 | gain:0.2040056295293026 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 17/2 → 53/6 | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 17/2 → 53/6 | clip:1 gain:0.125 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ (17/2 → 9/1) ⇝ 55/6 | gain:0.3080267646689928 clip:1 note:D3 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ (17/2 → 9/1) ⇝ 19/2 | gain:0.3080267646689928 clip:1 note:E5 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ (17/2 → 9/1) ⇝ 19/2 | gain:0.1540133823344964 clip:1 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ (17/2 → 9/1) ⇝ 21/2 | gain:0.3080267646689928 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037037 ]", - "[ (17/2 → 9/1) ⇝ 21/2 | gain:0.3080267646689928 clip:1 note:F4 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (17/2 → 9/1) ⇝ 21/2 | gain:0.3080267646689928 clip:1 note:C5 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 26/3 → 9/1 | clip:1 gain:1 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ 26/3 → 9/1 | clip:1 gain:0.25 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ (26/3 → 9/1) ⇝ 28/3 | gain:0.6200691170299722 clip:1 note:D2 s:piano release:0.1 pan:0.42592592592592593 ]", - "[ (53/6 → 9/1) ⇝ 55/6 | clip:1 gain:0.5 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ (53/6 → 9/1) ⇝ 55/6 | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ (53/6 → 9/1) ⇝ 19/2 | gain:0.15601417990383046 clip:1 note:D5 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 17/2 ⇜ (9/1 → 55/6) | gain:0.3080267646689928 clip:1 note:D3 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ 53/6 ⇜ (9/1 → 55/6) | clip:1 gain:0.5 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ 53/6 ⇜ (9/1 → 55/6) | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 26/3 ⇜ (9/1 → 28/3) | gain:0.6200691170299722 clip:1 note:D2 s:piano release:0.1 pan:0.42592592592592593 ]", - "[ 9/1 → 28/3 | clip:1 gain:1 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 9/1 → 28/3 | clip:1 gain:0.25 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ 15/2 ⇜ (9/1 → 19/2) | gain:0.14794083417556103 clip:1 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ 15/2 ⇜ (9/1 → 19/2) | gain:0.14794083417556103 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037037 ]", - "[ 15/2 ⇜ (9/1 → 19/2) | gain:0.14794083417556103 clip:1 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ 17/2 ⇜ (9/1 → 19/2) | gain:0.3080267646689928 clip:1 note:E5 s:piano release:0.1 pan:0.6018518518518519 ]", - "[ 17/2 ⇜ (9/1 → 19/2) | gain:0.1540133823344964 clip:1 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ 53/6 ⇜ (9/1 → 19/2) | gain:0.15601417990383046 clip:1 note:D5 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 9/1 → 29/3 | gain:0.20933649281634908 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 8/1 ⇜ (9/1 → 10/1) | gain:0.6039084330201149 clip:1 note:D3 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ 8/1 ⇜ (9/1 → 10/1) | gain:0.6039084330201149 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 8/1 ⇜ (9/1 → 10/1) | gain:0.6039084330201149 clip:1 note:C4 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 17/2 ⇜ (9/1 → 10/1) ⇝ 21/2 | gain:0.3080267646689928 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 17/2 ⇜ (9/1 → 10/1) ⇝ 21/2 | gain:0.3080267646689928 clip:1 note:F4 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 17/2 ⇜ (9/1 → 10/1) ⇝ 21/2 | gain:0.3080267646689928 clip:1 note:C5 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 9/1 → 10/1 | gain:0.6280094784490473 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 9/1 → 10/1 | gain:0.20933649281634908 clip:1 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ (9/1 → 10/1) ⇝ 11/1 | gain:0.20933649281634908 clip:1 note:D5 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (9/1 → 10/1) ⇝ 11/1 | gain:0.20933649281634908 clip:1 note:F5 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ (9/1 → 10/1) ⇝ 11/1 | gain:0.20933649281634908 clip:1 note:C6 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 55/6 → 19/2 | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 55/6 → 19/2 | clip:1 gain:0.125 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ 55/6 → 59/6 | gain:0.31596031332030455 clip:1 note:D3 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ 28/3 → 29/3 | clip:1 gain:1 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ 28/3 → 29/3 | clip:1 gain:0.25 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 28/3 → 10/1 | gain:0.6357835074048058 clip:1 note:D2 s:piano release:0.1 pan:0.42592592592592593 ]", - "[ 19/2 → 59/6 | clip:1 gain:0.5 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ 19/2 → 59/6 | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ (19/2 → 10/1) ⇝ 61/6 | gain:0.1598978981031657 clip:1 note:D5 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (19/2 → 10/1) ⇝ 21/2 | gain:0.3197957962063314 clip:1 note:D5 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (19/2 → 10/1) ⇝ 21/2 | gain:0.1598978981031657 clip:1 note:E7 s:piano release:0.1 pan:0.712962962962963 ]", - "[ (19/2 → 10/1) ⇝ 23/2 | gain:0.1598978981031657 clip:1 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ (19/2 → 10/1) ⇝ 23/2 | gain:0.1598978981031657 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037037 ]", - "[ (19/2 → 10/1) ⇝ 23/2 | gain:0.1598978981031657 clip:1 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ 29/3 → 10/1 | clip:1 gain:1 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 29/3 → 10/1 | clip:1 gain:0.25 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ (29/3 → 10/1) ⇝ 31/3 | gain:0.21444616671410743 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037037 ]", - "[ (59/6 → 10/1) ⇝ 61/6 | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ (59/6 → 10/1) ⇝ 61/6 | clip:1 gain:0.125 note:E6 s:piano release:0.1 pan:0.6574074074074074 ]", - "[ (59/6 → 10/1) ⇝ 21/2 | gain:0.32350900711496666 clip:1 note:D3 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ 19/2 ⇜ (10/1 → 61/6) | gain:0.1598978981031657 clip:1 note:G5 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 59/6 ⇜ (10/1 → 61/6) | clip:1 gain:0.5 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ 59/6 ⇜ (10/1 → 61/6) | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 29/3 ⇜ (10/1 → 31/3) | gain:0.21444616671410743 clip:1 note:G4 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 10/1 → 31/3 | clip:1 gain:1 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 10/1 → 31/3 | clip:1 gain:0.25 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ 17/2 ⇜ (10/1 → 21/2) | gain:0.3080267646689928 clip:1 note:G4 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 17/2 ⇜ (10/1 → 21/2) | gain:0.3080267646689928 clip:1 note:B4 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 17/2 ⇜ (10/1 → 21/2) | gain:0.3080267646689928 clip:1 note:F5 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 19/2 ⇜ (10/1 → 21/2) | gain:0.3197957962063314 clip:1 note:G5 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 19/2 ⇜ (10/1 → 21/2) | gain:0.1598978981031657 clip:1 note:A7 s:piano release:0.1 pan:0.7361111111111112 ]", - "[ 59/6 ⇜ (10/1 → 21/2) | gain:0.32350900711496666 clip:1 note:G3 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 10/1 → 32/3 | gain:0.6506241018205401 clip:1 note:G2 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 9/1 ⇜ (10/1 → 11/1) | gain:0.20933649281634908 clip:1 note:G5 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 9/1 ⇜ (10/1 → 11/1) | gain:0.20933649281634908 clip:1 note:B5 s:piano release:0.1 pan:0.6342592592592593 ]", - "[ 9/1 ⇜ (10/1 → 11/1) | gain:0.20933649281634908 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037037 ]", - "[ 19/2 ⇜ (10/1 → 11/1) ⇝ 23/2 | gain:0.1598978981031657 clip:1 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 19/2 ⇜ (10/1 → 11/1) ⇝ 23/2 | gain:0.1598978981031657 clip:1 note:B6 s:piano release:0.1 pan:0.6898148148148149 ]", - "[ 19/2 ⇜ (10/1 → 11/1) ⇝ 23/2 | gain:0.1598978981031657 clip:1 note:F7 s:piano release:0.1 pan:0.7175925925925926 ]", - "[ 10/1 → 11/1 | gain:0.6506241018205401 clip:1 note:A4 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 10/1 → 11/1 | gain:0.2168747006068467 clip:1 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ (10/1 → 11/1) ⇝ 12/1 | gain:0.6506241018205401 clip:1 note:G3 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ (10/1 → 11/1) ⇝ 12/1 | gain:0.6506241018205401 clip:1 note:B3 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ (10/1 → 11/1) ⇝ 12/1 | gain:0.6506241018205401 clip:1 note:F4 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 61/6 → 21/2 | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 61/6 → 21/2 | clip:1 gain:0.125 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ 61/6 → 65/6 | gain:0.16353773297974325 clip:1 note:G5 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 31/3 → 32/3 | clip:1 gain:1 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ 31/3 → 32/3 | clip:1 gain:0.25 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 31/3 → 11/1 | gain:0.21919763124691255 clip:1 note:G4 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 21/2 → 65/6 | clip:1 gain:0.5 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ 21/2 → 65/6 | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ (21/2 → 11/1) ⇝ 67/6 | gain:0.3304723075314519 clip:1 note:G3 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ (21/2 → 11/1) ⇝ 23/2 | gain:0.3304723075314519 clip:1 note:A5 s:piano release:0.1 pan:0.625 ]", - "[ (21/2 → 11/1) ⇝ 23/2 | gain:0.16523615376572595 clip:1 note:G7 s:piano release:0.1 pan:0.7268518518518519 ]", - "[ (21/2 → 11/1) ⇝ 25/2 | gain:0.3304723075314519 clip:1 note:G4 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (21/2 → 11/1) ⇝ 25/2 | gain:0.3304723075314519 clip:1 note:B4 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ (21/2 → 11/1) ⇝ 25/2 | gain:0.3304723075314519 clip:1 note:F5 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 32/3 → 11/1 | clip:1 gain:1 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 32/3 → 11/1 | clip:1 gain:0.25 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ (32/3 → 11/1) ⇝ 34/3 | gain:0.6642009805749963 clip:1 note:G2 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ (65/6 → 11/1) ⇝ 67/6 | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ (65/6 → 11/1) ⇝ 67/6 | clip:1 gain:0.125 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ (65/6 → 11/1) ⇝ 23/2 | gain:0.16683928755747093 clip:1 note:G5 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 21/2 ⇜ (11/1 → 67/6) | gain:0.3304723075314519 clip:1 note:G3 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 65/6 ⇜ (11/1 → 67/6) | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 65/6 ⇜ (11/1 → 67/6) | clip:1 gain:0.125 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ 32/3 ⇜ (11/1 → 34/3) | gain:0.6642009805749963 clip:1 note:G2 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 11/1 → 34/3 | clip:1 gain:1 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ 11/1 → 34/3 | clip:1 gain:0.25 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 19/2 ⇜ (11/1 → 23/2) | gain:0.1598978981031657 clip:1 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 19/2 ⇜ (11/1 → 23/2) | gain:0.1598978981031657 clip:1 note:B6 s:piano release:0.1 pan:0.6898148148148149 ]", - "[ 19/2 ⇜ (11/1 → 23/2) | gain:0.1598978981031657 clip:1 note:F7 s:piano release:0.1 pan:0.7175925925925926 ]", - "[ 21/2 ⇜ (11/1 → 23/2) | gain:0.3304723075314519 clip:1 note:A5 s:piano release:0.1 pan:0.625 ]", - "[ 21/2 ⇜ (11/1 → 23/2) | gain:0.16523615376572595 clip:1 note:G7 s:piano release:0.1 pan:0.7268518518518519 ]", - "[ 65/6 ⇜ (11/1 → 23/2) | gain:0.16683928755747093 clip:1 note:G5 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 11/1 → 35/3 | gain:0.22346952586488933 clip:1 note:G4 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 10/1 ⇜ (11/1 → 12/1) | gain:0.6506241018205401 clip:1 note:G3 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 10/1 ⇜ (11/1 → 12/1) | gain:0.6506241018205401 clip:1 note:B3 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 10/1 ⇜ (11/1 → 12/1) | gain:0.6506241018205401 clip:1 note:F4 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 21/2 ⇜ (11/1 → 12/1) ⇝ 25/2 | gain:0.3304723075314519 clip:1 note:G4 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 21/2 ⇜ (11/1 → 12/1) ⇝ 25/2 | gain:0.3304723075314519 clip:1 note:B4 s:piano release:0.1 pan:0.5787037037037037 ]", - "[ 21/2 ⇜ (11/1 → 12/1) ⇝ 25/2 | gain:0.3304723075314519 clip:1 note:F5 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 11/1 → 12/1 | gain:0.670408577594668 clip:1 note:G4 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 11/1 → 12/1 | gain:0.22346952586488933 clip:1 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ (11/1 → 12/1) ⇝ 13/1 | gain:0.22346952586488933 clip:1 note:G5 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ (11/1 → 12/1) ⇝ 13/1 | gain:0.22346952586488933 clip:1 note:B5 s:piano release:0.1 pan:0.6342592592592593 ]", - "[ (11/1 → 12/1) ⇝ 13/1 | gain:0.22346952586488933 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037037 ]", - "[ 67/6 → 23/2 | clip:1 gain:0.5 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ 67/6 → 23/2 | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 67/6 → 71/6 | gain:0.3366755141007872 clip:1 note:G3 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 34/3 → 35/3 | clip:1 gain:1 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 34/3 → 35/3 | clip:1 gain:0.25 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ 34/3 → 12/1 | gain:0.6761805978988411 clip:1 note:G2 s:piano release:0.1 pan:0.44907407407407407 ]", - "[ 23/2 → 71/6 | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 23/2 → 71/6 | clip:1 gain:0.125 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ (23/2 → 12/1) ⇝ 73/6 | gain:0.16972343280040209 clip:1 note:G5 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ (23/2 → 12/1) ⇝ 25/2 | gain:0.33944686560080417 clip:1 note:G5 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ (23/2 → 12/1) ⇝ 25/2 | gain:0.16972343280040209 clip:1 note:A7 s:piano release:0.1 pan:0.7361111111111112 ]", - "[ (23/2 → 12/1) ⇝ 27/2 | gain:0.16972343280040209 clip:1 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ (23/2 → 12/1) ⇝ 27/2 | gain:0.16972343280040209 clip:1 note:B6 s:piano release:0.1 pan:0.6898148148148149 ]", - "[ (23/2 → 12/1) ⇝ 27/2 | gain:0.16972343280040209 clip:1 note:F7 s:piano release:0.1 pan:0.7175925925925926 ]", - "[ 35/3 → 12/1 | clip:1 gain:1 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ 35/3 → 12/1 | clip:1 gain:0.25 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ (35/3 → 12/1) ⇝ 37/3 | gain:0.22716241321426947 clip:1 note:G4 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ (71/6 → 12/1) ⇝ 73/6 | clip:1 gain:0.5 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ (71/6 → 12/1) ⇝ 73/6 | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ (71/6 → 12/1) ⇝ 25/2 | gain:0.34197916006202767 clip:1 note:G3 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 23/2 ⇜ (12/1 → 73/6) | gain:0.16972343280040209 clip:1 note:C5 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 71/6 ⇜ (12/1 → 73/6) | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 71/6 ⇜ (12/1 → 73/6) | clip:1 gain:0.125 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ 35/3 ⇜ (12/1 → 37/3) | gain:0.22716241321426947 clip:1 note:C4 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 12/1 → 37/3 | clip:1 gain:1 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ 12/1 → 37/3 | clip:1 gain:0.25 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 21/2 ⇜ (12/1 → 25/2) | gain:0.3304723075314519 clip:1 note:C4 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 21/2 ⇜ (12/1 → 25/2) | gain:0.3304723075314519 clip:1 note:Eb4 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 21/2 ⇜ (12/1 → 25/2) | gain:0.3304723075314519 clip:1 note:Bb4 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 23/2 ⇜ (12/1 → 25/2) | gain:0.33944686560080417 clip:1 note:C5 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 23/2 ⇜ (12/1 → 25/2) | gain:0.16972343280040209 clip:1 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ 71/6 ⇜ (12/1 → 25/2) | gain:0.34197916006202767 clip:1 note:C3 s:piano release:0.1 pan:0.4722222222222222 ]", - "[ 12/1 → 38/3 | gain:0.6863045732665342 clip:1 note:C2 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 11/1 ⇜ (12/1 → 13/1) | gain:0.22346952586488933 clip:1 note:C5 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 11/1 ⇜ (12/1 → 13/1) | gain:0.22346952586488933 clip:1 note:Eb5 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 11/1 ⇜ (12/1 → 13/1) | gain:0.22346952586488933 clip:1 note:Bb5 s:piano release:0.1 pan:0.6296296296296297 ]", - "[ 23/2 ⇜ (12/1 → 13/1) ⇝ 27/2 | gain:0.16972343280040209 clip:1 note:C6 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 23/2 ⇜ (12/1 → 13/1) ⇝ 27/2 | gain:0.16972343280040209 clip:1 note:Eb6 s:piano release:0.1 pan:0.6527777777777778 ]", - "[ 23/2 ⇜ (12/1 → 13/1) ⇝ 27/2 | gain:0.16972343280040209 clip:1 note:Bb6 s:piano release:0.1 pan:0.6851851851851851 ]", - "[ 12/1 → 13/1 | gain:0.6863045732665342 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 12/1 → 13/1 | gain:0.22876819108884472 clip:1 note:C6 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ (12/1 → 13/1) ⇝ 14/1 | gain:0.6863045732665342 clip:1 note:C3 s:piano release:0.1 pan:0.4722222222222222 ]", - "[ (12/1 → 13/1) ⇝ 14/1 | gain:0.6863045732665342 clip:1 note:Eb3 s:piano release:0.1 pan:0.4861111111111111 ]", - "[ (12/1 → 13/1) ⇝ 14/1 | gain:0.6863045732665342 clip:1 note:Bb3 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 73/6 → 25/2 | clip:1 gain:0.5 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ 73/6 → 25/2 | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 73/6 → 77/6 | gain:0.17213100544047263 clip:1 note:C5 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 37/3 → 38/3 | clip:1 gain:1 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 37/3 → 38/3 | clip:1 gain:0.25 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ 37/3 → 13/1 | gain:0.230205042907707 clip:1 note:C4 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 25/2 → 77/6 | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 25/2 → 77/6 | clip:1 gain:0.125 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ (25/2 → 13/1) ⇝ 79/6 | gain:0.34628840801773064 clip:1 note:C3 s:piano release:0.1 pan:0.4722222222222222 ]", - "[ (25/2 → 13/1) ⇝ 27/2 | gain:0.34628840801773064 clip:1 note:D5 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ (25/2 → 13/1) ⇝ 27/2 | gain:0.17314420400886532 clip:1 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ (25/2 → 13/1) ⇝ 29/2 | gain:0.34628840801773064 clip:1 note:C4 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ (25/2 → 13/1) ⇝ 29/2 | gain:0.34628840801773064 clip:1 note:Eb4 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ (25/2 → 13/1) ⇝ 29/2 | gain:0.34628840801773064 clip:1 note:Bb4 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 38/3 → 13/1 | clip:1 gain:1 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ 38/3 → 13/1 | clip:1 gain:0.25 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ (38/3 → 13/1) ⇝ 40/3 | gain:0.6944084827072773 clip:1 note:C2 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ (77/6 → 13/1) ⇝ 79/6 | clip:1 gain:0.5 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ (77/6 → 13/1) ⇝ 79/6 | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ (77/6 → 13/1) ⇝ 27/2 | gain:0.17402750580523843 clip:1 note:C5 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 25/2 ⇜ (13/1 → 79/6) | gain:0.34628840801773064 clip:1 note:C3 s:piano release:0.1 pan:0.4722222222222222 ]", - "[ 77/6 ⇜ (13/1 → 79/6) | clip:1 gain:0.5 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ 77/6 ⇜ (13/1 → 79/6) | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 38/3 ⇜ (13/1 → 40/3) | gain:0.6944084827072773 clip:1 note:C2 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 13/1 → 40/3 | clip:1 gain:1 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 13/1 → 40/3 | clip:1 gain:0.25 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ 23/2 ⇜ (13/1 → 27/2) | gain:0.16972343280040209 clip:1 note:C6 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ 23/2 ⇜ (13/1 → 27/2) | gain:0.16972343280040209 clip:1 note:Eb6 s:piano release:0.1 pan:0.6527777777777778 ]", - "[ 23/2 ⇜ (13/1 → 27/2) | gain:0.16972343280040209 clip:1 note:Bb6 s:piano release:0.1 pan:0.6851851851851851 ]", - "[ 25/2 ⇜ (13/1 → 27/2) | gain:0.34628840801773064 clip:1 note:D5 s:piano release:0.1 pan:0.5925925925925926 ]", - "[ 25/2 ⇜ (13/1 → 27/2) | gain:0.17314420400886532 clip:1 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ 77/6 ⇜ (13/1 → 27/2) | gain:0.17402750580523843 clip:1 note:C5 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ 13/1 → 41/3 | gain:0.23256061529459465 clip:1 note:C4 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 12/1 ⇜ (13/1 → 14/1) | gain:0.6863045732665342 clip:1 note:C3 s:piano release:0.1 pan:0.4722222222222222 ]", - "[ 12/1 ⇜ (13/1 → 14/1) | gain:0.6863045732665342 clip:1 note:Eb3 s:piano release:0.1 pan:0.4861111111111111 ]", - "[ 12/1 ⇜ (13/1 → 14/1) | gain:0.6863045732665342 clip:1 note:Bb3 s:piano release:0.1 pan:0.5185185185185186 ]", - "[ 25/2 ⇜ (13/1 → 14/1) ⇝ 29/2 | gain:0.34628840801773064 clip:1 note:C4 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 25/2 ⇜ (13/1 → 14/1) ⇝ 29/2 | gain:0.34628840801773064 clip:1 note:Eb4 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 25/2 ⇜ (13/1 → 14/1) ⇝ 29/2 | gain:0.34628840801773064 clip:1 note:Bb4 s:piano release:0.1 pan:0.5740740740740741 ]", - "[ 13/1 → 14/1 | gain:0.697681845883784 clip:1 note:C4 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ 13/1 → 14/1 | gain:0.23256061529459465 clip:1 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ (13/1 → 14/1) ⇝ 15/1 | gain:0.23256061529459465 clip:1 note:C5 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ (13/1 → 14/1) ⇝ 15/1 | gain:0.23256061529459465 clip:1 note:Eb5 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ (13/1 → 14/1) ⇝ 15/1 | gain:0.23256061529459465 clip:1 note:Bb5 s:piano release:0.1 pan:0.6296296296296297 ]", - "[ 79/6 → 27/2 | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 79/6 → 27/2 | clip:1 gain:0.125 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ 79/6 → 83/6 | gain:0.3495624455894302 clip:1 note:C3 s:piano release:0.1 pan:0.4722222222222222 ]", - "[ 40/3 → 41/3 | clip:1 gain:1 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ 40/3 → 41/3 | clip:1 gain:0.25 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 40/3 → 14/1 | gain:0.7004406501159622 clip:1 note:C2 s:piano release:0.1 pan:0.41666666666666663 ]", - "[ 27/2 → 83/6 | clip:1 gain:0.5 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ 27/2 → 83/6 | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ (27/2 → 14/1) ⇝ 85/6 | gain:0.17540779564561187 clip:1 note:C5 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ (27/2 → 14/1) ⇝ 29/2 | gain:0.35081559129122375 clip:1 note:C5 s:piano release:0.1 pan:0.5833333333333333 ]", - "[ (27/2 → 14/1) ⇝ 29/2 | gain:0.17540779564561187 clip:1 note:D7 s:piano release:0.1 pan:0.7037037037037037 ]", - "[ (27/2 → 14/1) ⇝ 31/2 | gain:0.17540779564561187 clip:1 note:C6 s:piano release:0.1 pan:0.6388888888888888 ]", - "[ (27/2 → 14/1) ⇝ 31/2 | gain:0.17540779564561187 clip:1 note:Eb6 s:piano release:0.1 pan:0.6527777777777778 ]", - "[ (27/2 → 14/1) ⇝ 31/2 | gain:0.17540779564561187 clip:1 note:Bb6 s:piano release:0.1 pan:0.6851851851851851 ]", - "[ 41/3 → 14/1 | clip:1 gain:1 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 41/3 → 14/1 | clip:1 gain:0.25 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ (41/3 → 14/1) ⇝ 43/3 | gain:0.23423304523138017 clip:1 note:C4 s:piano release:0.1 pan:0.5277777777777778 ]", - "[ (83/6 → 14/1) ⇝ 85/6 | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ (83/6 → 14/1) ⇝ 85/6 | clip:1 gain:0.125 note:D6 s:piano release:0.1 pan:0.6481481481481481 ]", - "[ (83/6 → 14/1) ⇝ 29/2 | gain:0.3518238810731109 clip:1 note:C3 s:piano release:0.1 pan:0.4722222222222222 ]", - "[ 27/2 ⇜ (14/1 → 85/6) | gain:0.17540779564561187 clip:1 note:F5 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 83/6 ⇜ (14/1 → 85/6) | clip:1 gain:0.5 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ 83/6 ⇜ (14/1 → 85/6) | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 41/3 ⇜ (14/1 → 43/3) | gain:0.23423304523138017 clip:1 note:F4 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 14/1 → 43/3 | clip:1 gain:1 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 14/1 → 43/3 | clip:1 gain:0.25 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ 25/2 ⇜ (14/1 → 29/2) | gain:0.34628840801773064 clip:1 note:F4 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 25/2 ⇜ (14/1 → 29/2) | gain:0.34628840801773064 clip:1 note:A4 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 25/2 ⇜ (14/1 → 29/2) | gain:0.34628840801773064 clip:1 note:Eb5 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 27/2 ⇜ (14/1 → 29/2) | gain:0.35081559129122375 clip:1 note:F5 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 27/2 ⇜ (14/1 → 29/2) | gain:0.17540779564561187 clip:1 note:G7 s:piano release:0.1 pan:0.7268518518518519 ]", - "[ 83/6 ⇜ (14/1 → 29/2) | gain:0.3518238810731109 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 14/1 → 44/3 | gain:0.7044809385641202 clip:1 note:F2 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 13/1 ⇜ (14/1 → 15/1) | gain:0.23256061529459465 clip:1 note:F5 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 13/1 ⇜ (14/1 → 15/1) | gain:0.23256061529459465 clip:1 note:A5 s:piano release:0.1 pan:0.625 ]", - "[ 13/1 ⇜ (14/1 → 15/1) | gain:0.23256061529459465 clip:1 note:Eb6 s:piano release:0.1 pan:0.6527777777777778 ]", - "[ 27/2 ⇜ (14/1 → 15/1) ⇝ 31/2 | gain:0.17540779564561187 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037037 ]", - "[ 27/2 ⇜ (14/1 → 15/1) ⇝ 31/2 | gain:0.17540779564561187 clip:1 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 27/2 ⇜ (14/1 → 15/1) ⇝ 31/2 | gain:0.17540779564561187 clip:1 note:Eb7 s:piano release:0.1 pan:0.7083333333333333 ]", - "[ 14/1 → 15/1 | gain:0.7044809385641202 clip:1 note:G4 s:piano release:0.1 pan:0.5601851851851851 ]", - "[ 14/1 → 15/1 | gain:0.23482697952137338 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037037 ]", - "[ (14/1 → 15/1) ⇝ 16/1 | gain:0.7044809385641202 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ (14/1 → 15/1) ⇝ 16/1 | gain:0.7044809385641202 clip:1 note:A3 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ (14/1 → 15/1) ⇝ 16/1 | gain:0.7044809385641202 clip:1 note:Eb4 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 85/6 → 29/2 | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 85/6 → 29/2 | clip:1 gain:0.125 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ 85/6 → 89/6 | gain:0.17630079596359954 clip:1 note:F5 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 43/3 → 44/3 | clip:1 gain:1 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ 43/3 → 44/3 | clip:1 gain:0.25 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 43/3 → 15/1 | gain:0.23527322585188176 clip:1 note:F4 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 29/2 → 89/6 | clip:1 gain:0.5 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ 29/2 → 89/6 | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ (29/2 → 15/1) ⇝ 91/6 | gain:0.35316813909468286 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ (29/2 → 15/1) ⇝ 31/2 | gain:0.35316813909468286 clip:1 note:G5 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ (29/2 → 15/1) ⇝ 31/2 | gain:0.17658406954734143 clip:1 note:F7 s:piano release:0.1 pan:0.7175925925925926 ]", - "[ (29/2 → 15/1) ⇝ 33/2 | gain:0.35316813909468286 clip:1 note:F4 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (29/2 → 15/1) ⇝ 33/2 | gain:0.35316813909468286 clip:1 note:A4 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ (29/2 → 15/1) ⇝ 33/2 | gain:0.35316813909468286 clip:1 note:Eb5 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 44/3 → 15/1 | clip:1 gain:1 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 44/3 → 15/1 | clip:1 gain:0.25 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ (44/3 → 15/1) ⇝ 46/3 | gain:0.7067595416108681 clip:1 note:F2 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ (89/6 → 15/1) ⇝ 91/6 | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ (89/6 → 15/1) ⇝ 91/6 | clip:1 gain:0.125 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ (89/6 → 15/1) ⇝ 31/2 | gain:0.17677418484003904 clip:1 note:F5 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 29/2 ⇜ (15/1 → 91/6) | gain:0.35316813909468286 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 89/6 ⇜ (15/1 → 91/6) | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 89/6 ⇜ (15/1 → 91/6) | clip:1 gain:0.125 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ 44/3 ⇜ (15/1 → 46/3) | gain:0.7067595416108681 clip:1 note:F2 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 15/1 → 46/3 | clip:1 gain:1 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ 15/1 → 46/3 | clip:1 gain:0.25 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 27/2 ⇜ (15/1 → 31/2) | gain:0.17540779564561187 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037037 ]", - "[ 27/2 ⇜ (15/1 → 31/2) | gain:0.17540779564561187 clip:1 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ 27/2 ⇜ (15/1 → 31/2) | gain:0.17540779564561187 clip:1 note:Eb7 s:piano release:0.1 pan:0.7083333333333333 ]", - "[ 29/2 ⇜ (15/1 → 31/2) | gain:0.35316813909468286 clip:1 note:G5 s:piano release:0.1 pan:0.6157407407407407 ]", - "[ 29/2 ⇜ (15/1 → 31/2) | gain:0.17658406954734143 clip:1 note:F7 s:piano release:0.1 pan:0.7175925925925926 ]", - "[ 89/6 ⇜ (15/1 → 31/2) | gain:0.17677418484003904 clip:1 note:F5 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ 15/1 → 47/3 | gain:0.23578529233760528 clip:1 note:F4 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 14/1 ⇜ (15/1 → 16/1) | gain:0.7044809385641202 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 14/1 ⇜ (15/1 → 16/1) | gain:0.7044809385641202 clip:1 note:A3 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 14/1 ⇜ (15/1 → 16/1) | gain:0.7044809385641202 clip:1 note:Eb4 s:piano release:0.1 pan:0.5416666666666667 ]", - "[ 29/2 ⇜ (15/1 → 16/1) ⇝ 33/2 | gain:0.35316813909468286 clip:1 note:F4 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 29/2 ⇜ (15/1 → 16/1) ⇝ 33/2 | gain:0.35316813909468286 clip:1 note:A4 s:piano release:0.1 pan:0.5694444444444444 ]", - "[ 29/2 ⇜ (15/1 → 16/1) ⇝ 33/2 | gain:0.35316813909468286 clip:1 note:Eb5 s:piano release:0.1 pan:0.5972222222222222 ]", - "[ 15/1 → 16/1 | gain:0.7073558770128159 clip:1 note:F4 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ 15/1 → 16/1 | gain:0.23578529233760528 clip:1 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ (15/1 → 16/1) ⇝ 17/1 | gain:0.23578529233760528 clip:1 note:F5 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ (15/1 → 16/1) ⇝ 17/1 | gain:0.23578529233760528 clip:1 note:A5 s:piano release:0.1 pan:0.625 ]", - "[ (15/1 → 16/1) ⇝ 17/1 | gain:0.23578529233760528 clip:1 note:Eb6 s:piano release:0.1 pan:0.6527777777777778 ]", - "[ 91/6 → 31/2 | clip:1 gain:0.5 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ 91/6 → 31/2 | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 91/6 → 95/6 | gain:0.35377285626545446 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037037035 ]", - "[ 46/3 → 47/3 | clip:1 gain:1 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 46/3 → 47/3 | clip:1 gain:0.25 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ 46/3 → 16/1 | gain:0.7076757746138589 clip:1 note:F2 s:piano release:0.1 pan:0.4398148148148148 ]", - "[ 31/2 → 95/6 | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ 31/2 → 95/6 | clip:1 gain:0.125 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ (31/2 → 16/1) ⇝ 97/6 | gain:0.17693909526233562 clip:1 note:F5 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ (31/2 → 16/1) ⇝ 33/2 | gain:0.35387819052467123 clip:1 note:F5 s:piano release:0.1 pan:0.6064814814814814 ]", - "[ (31/2 → 16/1) ⇝ 33/2 | gain:0.17693909526233562 clip:1 note:G7 s:piano release:0.1 pan:0.7268518518518519 ]", - "[ (31/2 → 16/1) ⇝ 35/2 | gain:0.17693909526233562 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037037 ]", - "[ (31/2 → 16/1) ⇝ 35/2 | gain:0.17693909526233562 clip:1 note:A6 s:piano release:0.1 pan:0.6805555555555556 ]", - "[ (31/2 → 16/1) ⇝ 35/2 | gain:0.17693909526233562 clip:1 note:Eb7 s:piano release:0.1 pan:0.7083333333333333 ]", - "[ 47/3 → 16/1 | clip:1 gain:1 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ 47/3 → 16/1 | clip:1 gain:0.25 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ (47/3 → 16/1) ⇝ 49/3 | gain:0.2359328856880594 clip:1 note:F4 s:piano release:0.1 pan:0.5509259259259259 ]", - "[ (95/6 → 16/1) ⇝ 97/6 | clip:1 gain:0.5 note:C7 s:piano release:0.1 pan:0.6944444444444444 ]", - "[ (95/6 → 16/1) ⇝ 97/6 | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.6712962962962963 ]", - "[ (95/6 → 16/1) ⇝ 33/2 | gain:0.3539072768376083 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037037035 ]", + "[ -1/2 ⇜ (0/1 → 1/6) | gain:0.125015148782 clip:1 note:D5 s:piano release:0.1 pan:0.592592592593 ]", + "[ -1/6 ⇜ (0/1 → 1/6) | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ -1/6 ⇜ (0/1 → 1/6) | clip:1 gain:0.125 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ -1/3 ⇜ (0/1 → 1/3) | gain:0.166672747377 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037 ]", + "[ 0/1 → 1/3 | clip:1 gain:1 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ 0/1 → 1/3 | clip:1 gain:0.25 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ -3/2 ⇜ (0/1 → 1/2) | gain:0.250741641915 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037 ]", + "[ -3/2 ⇜ (0/1 → 1/2) | gain:0.250741641915 clip:1 note:F4 s:piano release:0.1 pan:0.550925925926 ]", + "[ -3/2 ⇜ (0/1 → 1/2) | gain:0.250741641915 clip:1 note:C5 s:piano release:0.1 pan:0.583333333333 ]", + "[ -1/2 ⇜ (0/1 → 1/2) | gain:0.250030297564 clip:1 note:D5 s:piano release:0.1 pan:0.592592592593 ]", + "[ -1/2 ⇜ (0/1 → 1/2) | gain:0.125015148782 clip:1 note:E7 s:piano release:0.1 pan:0.712962962963 ]", + "[ -1/6 ⇜ (0/1 → 1/2) | gain:0.250001158288 clip:1 note:D3 s:piano release:0.1 pan:0.481481481481 ]", + "[ 0/1 → 2/3 | gain:0.5 clip:1 note:D2 s:piano release:0.1 pan:0.425925925926 ]", + "[ -1/1 ⇜ (0/1 → 1/1) | gain:0.166820609478 clip:1 note:D5 s:piano release:0.1 pan:0.592592592593 ]", + "[ -1/1 ⇜ (0/1 → 1/1) | gain:0.166820609478 clip:1 note:F5 s:piano release:0.1 pan:0.606481481481 ]", + "[ -1/1 ⇜ (0/1 → 1/1) | gain:0.166820609478 clip:1 note:C6 s:piano release:0.1 pan:0.638888888889 ]", + "[ -1/2 ⇜ (0/1 → 1/1) ⇝ 3/2 | gain:0.125015148782 clip:1 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ -1/2 ⇜ (0/1 → 1/1) ⇝ 3/2 | gain:0.125015148782 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037 ]", + "[ -1/2 ⇜ (0/1 → 1/1) ⇝ 3/2 | gain:0.125015148782 clip:1 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ 0/1 → 1/1 | gain:0.5 clip:1 note:E4 s:piano release:0.1 pan:0.546296296296 ]", + "[ 0/1 → 1/1 | gain:0.166666666667 clip:1 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ (0/1 → 1/1) ⇝ 2/1 | gain:0.5 clip:1 note:D3 s:piano release:0.1 pan:0.481481481481 ]", + "[ (0/1 → 1/1) ⇝ 2/1 | gain:0.5 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037 ]", + "[ (0/1 → 1/1) ⇝ 2/1 | gain:0.5 clip:1 note:C4 s:piano release:0.1 pan:0.527777777778 ]", + "[ 1/6 → 1/2 | clip:1 gain:0.5 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ 1/6 → 1/2 | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 1/6 → 5/6 | gain:0.125000578091 clip:1 note:D5 s:piano release:0.1 pan:0.592592592593 ]", + "[ 1/3 → 2/3 | clip:1 gain:1 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 1/3 → 2/3 | clip:1 gain:0.25 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ 1/3 → 1/1 | gain:0.166672736325 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037 ]", + "[ 1/2 → 5/6 | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 1/2 → 5/6 | clip:1 gain:0.125 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ (1/2 → 1/1) ⇝ 7/6 | gain:0.250030242495 clip:1 note:D3 s:piano release:0.1 pan:0.481481481481 ]", + "[ (1/2 → 1/1) ⇝ 3/2 | gain:0.250030242495 clip:1 note:E5 s:piano release:0.1 pan:0.601851851852 ]", + "[ (1/2 → 1/1) ⇝ 3/2 | gain:0.125015121248 clip:1 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ (1/2 → 1/1) ⇝ 5/2 | gain:0.250030242495 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037 ]", + "[ (1/2 → 1/1) ⇝ 5/2 | gain:0.250030242495 clip:1 note:F4 s:piano release:0.1 pan:0.550925925926 ]", + "[ (1/2 → 1/1) ⇝ 5/2 | gain:0.250030242495 clip:1 note:C5 s:piano release:0.1 pan:0.583333333333 ]", + "[ 2/3 → 1/1 | clip:1 gain:1 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ 2/3 → 1/1 | clip:1 gain:0.25 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ (2/3 → 1/1) ⇝ 4/3 | gain:0.500141091426 clip:1 note:D2 s:piano release:0.1 pan:0.425925925926 ]", + "[ (5/6 → 1/1) ⇝ 7/6 | clip:1 gain:0.5 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ (5/6 → 1/1) ⇝ 7/6 | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ (5/6 → 1/1) ⇝ 3/2 | gain:0.125067788377 clip:1 note:D5 s:piano release:0.1 pan:0.592592592593 ]", + "[ 1/2 ⇜ (1/1 → 7/6) | gain:0.250030242495 clip:1 note:D3 s:piano release:0.1 pan:0.481481481481 ]", + "[ 5/6 ⇜ (1/1 → 7/6) | clip:1 gain:0.5 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ 5/6 ⇜ (1/1 → 7/6) | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 2/3 ⇜ (1/1 → 4/3) | gain:0.500141091426 clip:1 note:D2 s:piano release:0.1 pan:0.425925925926 ]", + "[ 1/1 → 4/3 | clip:1 gain:1 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 1/1 → 4/3 | clip:1 gain:0.25 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ -1/2 ⇜ (1/1 → 3/2) | gain:0.125015148782 clip:1 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ -1/2 ⇜ (1/1 → 3/2) | gain:0.125015148782 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037 ]", + "[ -1/2 ⇜ (1/1 → 3/2) | gain:0.125015148782 clip:1 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ 1/2 ⇜ (1/1 → 3/2) | gain:0.250030242495 clip:1 note:E5 s:piano release:0.1 pan:0.601851851852 ]", + "[ 1/2 ⇜ (1/1 → 3/2) | gain:0.125015121248 clip:1 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ 5/6 ⇜ (1/1 → 3/2) | gain:0.125067788377 clip:1 note:D5 s:piano release:0.1 pan:0.592592592593 ]", + "[ 1/1 → 5/3 | gain:0.166820329676 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037 ]", + "[ 0/1 ⇜ (1/1 → 2/1) | gain:0.5 clip:1 note:D3 s:piano release:0.1 pan:0.481481481481 ]", + "[ 0/1 ⇜ (1/1 → 2/1) | gain:0.5 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037 ]", + "[ 0/1 ⇜ (1/1 → 2/1) | gain:0.5 clip:1 note:C4 s:piano release:0.1 pan:0.527777777778 ]", + "[ 1/2 ⇜ (1/1 → 2/1) ⇝ 5/2 | gain:0.250030242495 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037 ]", + "[ 1/2 ⇜ (1/1 → 2/1) ⇝ 5/2 | gain:0.250030242495 clip:1 note:F4 s:piano release:0.1 pan:0.550925925926 ]", + "[ 1/2 ⇜ (1/1 → 2/1) ⇝ 5/2 | gain:0.250030242495 clip:1 note:C5 s:piano release:0.1 pan:0.583333333333 ]", + "[ 1/1 → 2/1 | gain:0.500460989027 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037 ]", + "[ 1/1 → 2/1 | gain:0.166820329676 clip:1 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ (1/1 → 2/1) ⇝ 3/1 | gain:0.166820329676 clip:1 note:D5 s:piano release:0.1 pan:0.592592592593 ]", + "[ (1/1 → 2/1) ⇝ 3/1 | gain:0.166820329676 clip:1 note:F5 s:piano release:0.1 pan:0.606481481481 ]", + "[ (1/1 → 2/1) ⇝ 3/1 | gain:0.166820329676 clip:1 note:C6 s:piano release:0.1 pan:0.638888888889 ]", + "[ 7/6 → 3/2 | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 7/6 → 3/2 | clip:1 gain:0.125 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ 7/6 → 11/6 | gain:0.25036006334 clip:1 note:D3 s:piano release:0.1 pan:0.481481481481 ]", + "[ 4/3 → 5/3 | clip:1 gain:1 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ 4/3 → 5/3 | clip:1 gain:0.25 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 4/3 → 2/1 | gain:0.501057324429 clip:1 note:D2 s:piano release:0.1 pan:0.425925925926 ]", + "[ 3/2 → 11/6 | clip:1 gain:0.5 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ 3/2 → 11/6 | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ (3/2 → 2/1) ⇝ 13/6 | gain:0.125370146963 clip:1 note:D5 s:piano release:0.1 pan:0.592592592593 ]", + "[ (3/2 → 2/1) ⇝ 5/2 | gain:0.250740293925 clip:1 note:D5 s:piano release:0.1 pan:0.592592592593 ]", + "[ (3/2 → 2/1) ⇝ 5/2 | gain:0.125370146963 clip:1 note:E7 s:piano release:0.1 pan:0.712962962963 ]", + "[ (3/2 → 2/1) ⇝ 7/2 | gain:0.125370146963 clip:1 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ (3/2 → 2/1) ⇝ 7/2 | gain:0.125370146963 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037 ]", + "[ (3/2 → 2/1) ⇝ 7/2 | gain:0.125370146963 clip:1 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ 5/3 → 2/1 | clip:1 gain:1 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 5/3 → 2/1 | clip:1 gain:0.25 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ (5/3 → 2/1) ⇝ 7/3 | gain:0.167332396162 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037 ]", + "[ (11/6 → 2/1) ⇝ 13/6 | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ (11/6 → 2/1) ⇝ 13/6 | clip:1 gain:0.125 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ (11/6 → 2/1) ⇝ 5/2 | gain:0.251306841093 clip:1 note:D3 s:piano release:0.1 pan:0.481481481481 ]", + "[ 3/2 ⇜ (2/1 → 13/6) | gain:0.125370146963 clip:1 note:G5 s:piano release:0.1 pan:0.615740740741 ]", + "[ 11/6 ⇜ (2/1 → 13/6) | clip:1 gain:0.5 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ 11/6 ⇜ (2/1 → 13/6) | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 5/3 ⇜ (2/1 → 7/3) | gain:0.167332396162 clip:1 note:G4 s:piano release:0.1 pan:0.560185185185 ]", + "[ 2/1 → 7/3 | clip:1 gain:1 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 2/1 → 7/3 | clip:1 gain:0.25 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ 1/2 ⇜ (2/1 → 5/2) | gain:0.250030242495 clip:1 note:G4 s:piano release:0.1 pan:0.560185185185 ]", + "[ 1/2 ⇜ (2/1 → 5/2) | gain:0.250030242495 clip:1 note:B4 s:piano release:0.1 pan:0.578703703704 ]", + "[ 1/2 ⇜ (2/1 → 5/2) | gain:0.250030242495 clip:1 note:F5 s:piano release:0.1 pan:0.606481481481 ]", + "[ 3/2 ⇜ (2/1 → 5/2) | gain:0.250740293925 clip:1 note:G5 s:piano release:0.1 pan:0.615740740741 ]", + "[ 3/2 ⇜ (2/1 → 5/2) | gain:0.125370146963 clip:1 note:A7 s:piano release:0.1 pan:0.736111111111 ]", + "[ 11/6 ⇜ (2/1 → 5/2) | gain:0.251306841093 clip:1 note:G3 s:piano release:0.1 pan:0.50462962963 ]", + "[ 2/1 → 8/3 | gain:0.503335927476 clip:1 note:G2 s:piano release:0.1 pan:0.449074074074 ]", + "[ 1/1 ⇜ (2/1 → 3/1) | gain:0.166820329676 clip:1 note:G5 s:piano release:0.1 pan:0.615740740741 ]", + "[ 1/1 ⇜ (2/1 → 3/1) | gain:0.166820329676 clip:1 note:B5 s:piano release:0.1 pan:0.634259259259 ]", + "[ 1/1 ⇜ (2/1 → 3/1) | gain:0.166820329676 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037 ]", + "[ 3/2 ⇜ (2/1 → 3/1) ⇝ 7/2 | gain:0.125370146963 clip:1 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 3/2 ⇜ (2/1 → 3/1) ⇝ 7/2 | gain:0.125370146963 clip:1 note:B6 s:piano release:0.1 pan:0.689814814815 ]", + "[ 3/2 ⇜ (2/1 → 3/1) ⇝ 7/2 | gain:0.125370146963 clip:1 note:F7 s:piano release:0.1 pan:0.717592592593 ]", + "[ 2/1 → 3/1 | gain:0.503335927476 clip:1 note:A4 s:piano release:0.1 pan:0.569444444444 ]", + "[ 2/1 → 3/1 | gain:0.167778642492 clip:1 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ (2/1 → 3/1) ⇝ 4/1 | gain:0.503335927476 clip:1 note:G3 s:piano release:0.1 pan:0.50462962963 ]", + "[ (2/1 → 3/1) ⇝ 4/1 | gain:0.503335927476 clip:1 note:B3 s:piano release:0.1 pan:0.523148148148 ]", + "[ (2/1 → 3/1) ⇝ 4/1 | gain:0.503335927476 clip:1 note:F4 s:piano release:0.1 pan:0.550925925926 ]", + "[ 13/6 → 5/2 | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 13/6 → 5/2 | clip:1 gain:0.125 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ 13/6 → 17/6 | gain:0.126042275974 clip:1 note:G5 s:piano release:0.1 pan:0.615740740741 ]", + "[ 7/3 → 8/3 | clip:1 gain:1 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ 7/3 → 8/3 | clip:1 gain:0.25 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 7/3 → 3/1 | gain:0.168372576782 clip:1 note:G4 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/2 → 17/6 | clip:1 gain:0.5 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ 5/2 → 17/6 | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ (5/2 → 3/1) ⇝ 19/6 | gain:0.253092841729 clip:1 note:G3 s:piano release:0.1 pan:0.50462962963 ]", + "[ (5/2 → 3/1) ⇝ 7/2 | gain:0.253092841729 clip:1 note:A5 s:piano release:0.1 pan:0.625 ]", + "[ (5/2 → 3/1) ⇝ 7/2 | gain:0.126546420864 clip:1 note:G7 s:piano release:0.1 pan:0.726851851852 ]", + "[ (5/2 → 3/1) ⇝ 9/2 | gain:0.253092841729 clip:1 note:G4 s:piano release:0.1 pan:0.560185185185 ]", + "[ (5/2 → 3/1) ⇝ 9/2 | gain:0.253092841729 clip:1 note:B4 s:piano release:0.1 pan:0.578703703704 ]", + "[ (5/2 → 3/1) ⇝ 9/2 | gain:0.253092841729 clip:1 note:F5 s:piano release:0.1 pan:0.606481481481 ]", + "[ 8/3 → 3/1 | clip:1 gain:1 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 8/3 → 3/1 | clip:1 gain:0.25 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ (8/3 → 3/1) ⇝ 10/3 | gain:0.507376215924 clip:1 note:G2 s:piano release:0.1 pan:0.449074074074 ]", + "[ (17/6 → 3/1) ⇝ 19/6 | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ (17/6 → 3/1) ⇝ 19/6 | clip:1 gain:0.125 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ (17/6 → 3/1) ⇝ 7/2 | gain:0.127172993715 clip:1 note:G5 s:piano release:0.1 pan:0.615740740741 ]", + "[ 5/2 ⇜ (3/1 → 19/6) | gain:0.253092841729 clip:1 note:G3 s:piano release:0.1 pan:0.50462962963 ]", + "[ 17/6 ⇜ (3/1 → 19/6) | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 17/6 ⇜ (3/1 → 19/6) | clip:1 gain:0.125 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ 8/3 ⇜ (3/1 → 10/3) | gain:0.507376215924 clip:1 note:G2 s:piano release:0.1 pan:0.449074074074 ]", + "[ 3/1 → 10/3 | clip:1 gain:1 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ 3/1 → 10/3 | clip:1 gain:0.25 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 3/2 ⇜ (3/1 → 7/2) | gain:0.125370146963 clip:1 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 3/2 ⇜ (3/1 → 7/2) | gain:0.125370146963 clip:1 note:B6 s:piano release:0.1 pan:0.689814814815 ]", + "[ 3/2 ⇜ (3/1 → 7/2) | gain:0.125370146963 clip:1 note:F7 s:piano release:0.1 pan:0.717592592593 ]", + "[ 5/2 ⇜ (3/1 → 7/2) | gain:0.253092841729 clip:1 note:A5 s:piano release:0.1 pan:0.625 ]", + "[ 5/2 ⇜ (3/1 → 7/2) | gain:0.126546420864 clip:1 note:G7 s:piano release:0.1 pan:0.726851851852 ]", + "[ 17/6 ⇜ (3/1 → 7/2) | gain:0.127172993715 clip:1 note:G5 s:piano release:0.1 pan:0.615740740741 ]", + "[ 3/1 → 11/3 | gain:0.170045006719 clip:1 note:G4 s:piano release:0.1 pan:0.560185185185 ]", + "[ 2/1 ⇜ (3/1 → 4/1) | gain:0.503335927476 clip:1 note:G3 s:piano release:0.1 pan:0.50462962963 ]", + "[ 2/1 ⇜ (3/1 → 4/1) | gain:0.503335927476 clip:1 note:B3 s:piano release:0.1 pan:0.523148148148 ]", + "[ 2/1 ⇜ (3/1 → 4/1) | gain:0.503335927476 clip:1 note:F4 s:piano release:0.1 pan:0.550925925926 ]", + "[ 5/2 ⇜ (3/1 → 4/1) ⇝ 9/2 | gain:0.253092841729 clip:1 note:G4 s:piano release:0.1 pan:0.560185185185 ]", + "[ 5/2 ⇜ (3/1 → 4/1) ⇝ 9/2 | gain:0.253092841729 clip:1 note:B4 s:piano release:0.1 pan:0.578703703704 ]", + "[ 5/2 ⇜ (3/1 → 4/1) ⇝ 9/2 | gain:0.253092841729 clip:1 note:F5 s:piano release:0.1 pan:0.606481481481 ]", + "[ 3/1 → 4/1 | gain:0.510135020156 clip:1 note:G4 s:piano release:0.1 pan:0.560185185185 ]", + "[ 3/1 → 4/1 | gain:0.170045006719 clip:1 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ (3/1 → 4/1) ⇝ 5/1 | gain:0.170045006719 clip:1 note:G5 s:piano release:0.1 pan:0.615740740741 ]", + "[ (3/1 → 4/1) ⇝ 5/1 | gain:0.170045006719 clip:1 note:B5 s:piano release:0.1 pan:0.634259259259 ]", + "[ (3/1 → 4/1) ⇝ 5/1 | gain:0.170045006719 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037 ]", + "[ 19/6 → 7/2 | clip:1 gain:0.5 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ 19/6 → 7/2 | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 19/6 → 23/6 | gain:0.25585342141 clip:1 note:G3 s:piano release:0.1 pan:0.50462962963 ]", + "[ 10/3 → 11/3 | clip:1 gain:1 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 10/3 → 11/3 | clip:1 gain:0.25 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ 10/3 → 4/1 | gain:0.513408383333 clip:1 note:G2 s:piano release:0.1 pan:0.449074074074 ]", + "[ 7/2 → 23/6 | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 7/2 → 23/6 | clip:1 gain:0.125 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ (7/2 → 4/1) ⇝ 25/6 | gain:0.128810012501 clip:1 note:G5 s:piano release:0.1 pan:0.615740740741 ]", + "[ (7/2 → 4/1) ⇝ 9/2 | gain:0.257620025002 clip:1 note:G5 s:piano release:0.1 pan:0.615740740741 ]", + "[ (7/2 → 4/1) ⇝ 9/2 | gain:0.128810012501 clip:1 note:A7 s:piano release:0.1 pan:0.736111111111 ]", + "[ (7/2 → 4/1) ⇝ 11/2 | gain:0.128810012501 clip:1 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ (7/2 → 4/1) ⇝ 11/2 | gain:0.128810012501 clip:1 note:B6 s:piano release:0.1 pan:0.689814814815 ]", + "[ (7/2 → 4/1) ⇝ 11/2 | gain:0.128810012501 clip:1 note:F7 s:piano release:0.1 pan:0.717592592593 ]", + "[ 11/3 → 4/1 | clip:1 gain:1 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ 11/3 → 4/1 | clip:1 gain:0.25 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ (11/3 → 4/1) ⇝ 13/3 | gain:0.172400579106 clip:1 note:G4 s:piano release:0.1 pan:0.560185185185 ]", + "[ (23/6 → 4/1) ⇝ 25/6 | clip:1 gain:0.5 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ (23/6 → 4/1) ⇝ 25/6 | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ (23/6 → 4/1) ⇝ 9/2 | gain:0.259646422139 clip:1 note:G3 s:piano release:0.1 pan:0.50462962963 ]", + "[ 7/2 ⇜ (4/1 → 25/6) | gain:0.128810012501 clip:1 note:C5 s:piano release:0.1 pan:0.583333333333 ]", + "[ 23/6 ⇜ (4/1 → 25/6) | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 23/6 ⇜ (4/1 → 25/6) | clip:1 gain:0.125 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ 11/3 ⇜ (4/1 → 13/3) | gain:0.172400579106 clip:1 note:C4 s:piano release:0.1 pan:0.527777777778 ]", + "[ 4/1 → 13/3 | clip:1 gain:1 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ 4/1 → 13/3 | clip:1 gain:0.25 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 5/2 ⇜ (4/1 → 9/2) | gain:0.253092841729 clip:1 note:C4 s:piano release:0.1 pan:0.527777777778 ]", + "[ 5/2 ⇜ (4/1 → 9/2) | gain:0.253092841729 clip:1 note:Eb4 s:piano release:0.1 pan:0.541666666667 ]", + "[ 5/2 ⇜ (4/1 → 9/2) | gain:0.253092841729 clip:1 note:Bb4 s:piano release:0.1 pan:0.574074074074 ]", + "[ 7/2 ⇜ (4/1 → 9/2) | gain:0.257620025002 clip:1 note:C5 s:piano release:0.1 pan:0.583333333333 ]", + "[ 7/2 ⇜ (4/1 → 9/2) | gain:0.128810012501 clip:1 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ 23/6 ⇜ (4/1 → 9/2) | gain:0.259646422139 clip:1 note:C3 s:piano release:0.1 pan:0.472222222222 ]", + "[ 4/1 → 14/3 | gain:0.521512292774 clip:1 note:C2 s:piano release:0.1 pan:0.416666666667 ]", + "[ 3/1 ⇜ (4/1 → 5/1) | gain:0.170045006719 clip:1 note:C5 s:piano release:0.1 pan:0.583333333333 ]", + "[ 3/1 ⇜ (4/1 → 5/1) | gain:0.170045006719 clip:1 note:Eb5 s:piano release:0.1 pan:0.597222222222 ]", + "[ 3/1 ⇜ (4/1 → 5/1) | gain:0.170045006719 clip:1 note:Bb5 s:piano release:0.1 pan:0.62962962963 ]", + "[ 7/2 ⇜ (4/1 → 5/1) ⇝ 11/2 | gain:0.128810012501 clip:1 note:C6 s:piano release:0.1 pan:0.638888888889 ]", + "[ 7/2 ⇜ (4/1 → 5/1) ⇝ 11/2 | gain:0.128810012501 clip:1 note:Eb6 s:piano release:0.1 pan:0.652777777778 ]", + "[ 7/2 ⇜ (4/1 → 5/1) ⇝ 11/2 | gain:0.128810012501 clip:1 note:Bb6 s:piano release:0.1 pan:0.685185185185 ]", + "[ 4/1 → 5/1 | gain:0.521512292774 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037 ]", + "[ 4/1 → 5/1 | gain:0.173837430925 clip:1 note:C6 s:piano release:0.1 pan:0.638888888889 ]", + "[ (4/1 → 5/1) ⇝ 6/1 | gain:0.521512292774 clip:1 note:C3 s:piano release:0.1 pan:0.472222222222 ]", + "[ (4/1 → 5/1) ⇝ 6/1 | gain:0.521512292774 clip:1 note:Eb3 s:piano release:0.1 pan:0.486111111111 ]", + "[ (4/1 → 5/1) ⇝ 6/1 | gain:0.521512292774 clip:1 note:Bb3 s:piano release:0.1 pan:0.518518518519 ]", + "[ 25/6 → 9/2 | clip:1 gain:0.5 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ 25/6 → 9/2 | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 25/6 → 29/6 | gain:0.130964636479 clip:1 note:C5 s:piano release:0.1 pan:0.583333333333 ]", + "[ 13/3 → 14/3 | clip:1 gain:1 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 13/3 → 14/3 | clip:1 gain:0.25 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ 13/3 → 5/1 | gain:0.175443208799 clip:1 note:C4 s:piano release:0.1 pan:0.527777777778 ]", + "[ 9/2 → 29/6 | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 9/2 → 29/6 | clip:1 gain:0.125 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ (9/2 → 5/1) ⇝ 31/6 | gain:0.264461567419 clip:1 note:C3 s:piano release:0.1 pan:0.472222222222 ]", + "[ (9/2 → 5/1) ⇝ 11/2 | gain:0.264461567419 clip:1 note:D5 s:piano release:0.1 pan:0.592592592593 ]", + "[ (9/2 → 5/1) ⇝ 11/2 | gain:0.13223078371 clip:1 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ (9/2 → 5/1) ⇝ 13/2 | gain:0.264461567419 clip:1 note:C4 s:piano release:0.1 pan:0.527777777778 ]", + "[ (9/2 → 5/1) ⇝ 13/2 | gain:0.264461567419 clip:1 note:Eb4 s:piano release:0.1 pan:0.541666666667 ]", + "[ (9/2 → 5/1) ⇝ 13/2 | gain:0.264461567419 clip:1 note:Bb4 s:piano release:0.1 pan:0.574074074074 ]", + "[ 14/3 → 5/1 | clip:1 gain:1 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ 14/3 → 5/1 | clip:1 gain:0.25 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ (14/3 → 5/1) ⇝ 16/3 | gain:0.531636268141 clip:1 note:C2 s:piano release:0.1 pan:0.416666666667 ]", + "[ (29/6 → 5/1) ⇝ 31/6 | clip:1 gain:0.5 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ (29/6 → 5/1) ⇝ 31/6 | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ (29/6 → 5/1) ⇝ 11/2 | gain:0.13361645946 clip:1 note:C5 s:piano release:0.1 pan:0.583333333333 ]", + "[ 9/2 ⇜ (5/1 → 31/6) | gain:0.264461567419 clip:1 note:C3 s:piano release:0.1 pan:0.472222222222 ]", + "[ 29/6 ⇜ (5/1 → 31/6) | clip:1 gain:0.5 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ 29/6 ⇜ (5/1 → 31/6) | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 14/3 ⇜ (5/1 → 16/3) | gain:0.531636268141 clip:1 note:C2 s:piano release:0.1 pan:0.416666666667 ]", + "[ 5/1 → 16/3 | clip:1 gain:1 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 5/1 → 16/3 | clip:1 gain:0.25 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ 7/2 ⇜ (5/1 → 11/2) | gain:0.128810012501 clip:1 note:C6 s:piano release:0.1 pan:0.638888888889 ]", + "[ 7/2 ⇜ (5/1 → 11/2) | gain:0.128810012501 clip:1 note:Eb6 s:piano release:0.1 pan:0.652777777778 ]", + "[ 7/2 ⇜ (5/1 → 11/2) | gain:0.128810012501 clip:1 note:Bb6 s:piano release:0.1 pan:0.685185185185 ]", + "[ 9/2 ⇜ (5/1 → 11/2) | gain:0.264461567419 clip:1 note:D5 s:piano release:0.1 pan:0.592592592593 ]", + "[ 9/2 ⇜ (5/1 → 11/2) | gain:0.13223078371 clip:1 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ 29/6 ⇜ (5/1 → 11/2) | gain:0.13361645946 clip:1 note:C5 s:piano release:0.1 pan:0.583333333333 ]", + "[ 5/1 → 17/3 | gain:0.179136096149 clip:1 note:C4 s:piano release:0.1 pan:0.527777777778 ]", + "[ 4/1 ⇜ (5/1 → 6/1) | gain:0.521512292774 clip:1 note:C3 s:piano release:0.1 pan:0.472222222222 ]", + "[ 4/1 ⇜ (5/1 → 6/1) | gain:0.521512292774 clip:1 note:Eb3 s:piano release:0.1 pan:0.486111111111 ]", + "[ 4/1 ⇜ (5/1 → 6/1) | gain:0.521512292774 clip:1 note:Bb3 s:piano release:0.1 pan:0.518518518519 ]", + "[ 9/2 ⇜ (5/1 → 6/1) ⇝ 13/2 | gain:0.264461567419 clip:1 note:C4 s:piano release:0.1 pan:0.527777777778 ]", + "[ 9/2 ⇜ (5/1 → 6/1) ⇝ 13/2 | gain:0.264461567419 clip:1 note:Eb4 s:piano release:0.1 pan:0.541666666667 ]", + "[ 9/2 ⇜ (5/1 → 6/1) ⇝ 13/2 | gain:0.264461567419 clip:1 note:Bb4 s:piano release:0.1 pan:0.574074074074 ]", + "[ 5/1 → 6/1 | gain:0.537408288446 clip:1 note:C4 s:piano release:0.1 pan:0.527777777778 ]", + "[ 5/1 → 6/1 | gain:0.179136096149 clip:1 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ (5/1 → 6/1) ⇝ 7/1 | gain:0.179136096149 clip:1 note:C5 s:piano release:0.1 pan:0.583333333333 ]", + "[ (5/1 → 6/1) ⇝ 7/1 | gain:0.179136096149 clip:1 note:Eb5 s:piano release:0.1 pan:0.597222222222 ]", + "[ (5/1 → 6/1) ⇝ 7/1 | gain:0.179136096149 clip:1 note:Bb5 s:piano release:0.1 pan:0.62962962963 ]", + "[ 31/6 → 11/2 | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 31/6 → 11/2 | clip:1 gain:0.125 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ 31/6 → 35/6 | gain:0.270229857905 clip:1 note:C3 s:piano release:0.1 pan:0.472222222222 ]", + "[ 16/3 → 17/3 | clip:1 gain:1 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ 16/3 → 17/3 | clip:1 gain:0.25 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 16/3 → 6/1 | gain:0.543615885465 clip:1 note:C2 s:piano release:0.1 pan:0.416666666667 ]", + "[ 11/2 → 35/6 | clip:1 gain:0.5 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ 11/2 → 35/6 | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ (11/2 → 6/1) ⇝ 37/6 | gain:0.136718062744 clip:1 note:C5 s:piano release:0.1 pan:0.583333333333 ]", + "[ (11/2 → 6/1) ⇝ 13/2 | gain:0.273436125489 clip:1 note:C5 s:piano release:0.1 pan:0.583333333333 ]", + "[ (11/2 → 6/1) ⇝ 13/2 | gain:0.136718062744 clip:1 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ (11/2 → 6/1) ⇝ 15/2 | gain:0.136718062744 clip:1 note:C6 s:piano release:0.1 pan:0.638888888889 ]", + "[ (11/2 → 6/1) ⇝ 15/2 | gain:0.136718062744 clip:1 note:Eb6 s:piano release:0.1 pan:0.652777777778 ]", + "[ (11/2 → 6/1) ⇝ 15/2 | gain:0.136718062744 clip:1 note:Bb6 s:piano release:0.1 pan:0.685185185185 ]", + "[ 17/3 → 6/1 | clip:1 gain:1 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 17/3 → 6/1 | clip:1 gain:0.25 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ (17/3 → 6/1) ⇝ 19/3 | gain:0.183407990766 clip:1 note:C4 s:piano release:0.1 pan:0.527777777778 ]", + "[ (35/6 → 6/1) ⇝ 37/6 | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ (35/6 → 6/1) ⇝ 37/6 | clip:1 gain:0.125 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ (35/6 → 6/1) ⇝ 13/2 | gain:0.276832967061 clip:1 note:C3 s:piano release:0.1 pan:0.472222222222 ]", + "[ 11/2 ⇜ (6/1 → 37/6) | gain:0.136718062744 clip:1 note:F5 s:piano release:0.1 pan:0.606481481481 ]", + "[ 35/6 ⇜ (6/1 → 37/6) | clip:1 gain:0.5 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ 35/6 ⇜ (6/1 → 37/6) | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 17/3 ⇜ (6/1 → 19/3) | gain:0.183407990766 clip:1 note:F4 s:piano release:0.1 pan:0.550925925926 ]", + "[ 6/1 → 19/3 | clip:1 gain:1 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 6/1 → 19/3 | clip:1 gain:0.25 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ 9/2 ⇜ (6/1 → 13/2) | gain:0.264461567419 clip:1 note:F4 s:piano release:0.1 pan:0.550925925926 ]", + "[ 9/2 ⇜ (6/1 → 13/2) | gain:0.264461567419 clip:1 note:A4 s:piano release:0.1 pan:0.569444444444 ]", + "[ 9/2 ⇜ (6/1 → 13/2) | gain:0.264461567419 clip:1 note:Eb5 s:piano release:0.1 pan:0.597222222222 ]", + "[ 11/2 ⇜ (6/1 → 13/2) | gain:0.273436125489 clip:1 note:F5 s:piano release:0.1 pan:0.606481481481 ]", + "[ 11/2 ⇜ (6/1 → 13/2) | gain:0.136718062744 clip:1 note:G7 s:piano release:0.1 pan:0.726851851852 ]", + "[ 35/6 ⇜ (6/1 → 13/2) | gain:0.276832967061 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037 ]", + "[ 6/1 → 20/3 | gain:0.55719276422 clip:1 note:F2 s:piano release:0.1 pan:0.439814814815 ]", + "[ 5/1 ⇜ (6/1 → 7/1) | gain:0.179136096149 clip:1 note:F5 s:piano release:0.1 pan:0.606481481481 ]", + "[ 5/1 ⇜ (6/1 → 7/1) | gain:0.179136096149 clip:1 note:A5 s:piano release:0.1 pan:0.625 ]", + "[ 5/1 ⇜ (6/1 → 7/1) | gain:0.179136096149 clip:1 note:Eb6 s:piano release:0.1 pan:0.652777777778 ]", + "[ 11/2 ⇜ (6/1 → 7/1) ⇝ 15/2 | gain:0.136718062744 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037 ]", + "[ 11/2 ⇜ (6/1 → 7/1) ⇝ 15/2 | gain:0.136718062744 clip:1 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 11/2 ⇜ (6/1 → 7/1) ⇝ 15/2 | gain:0.136718062744 clip:1 note:Eb7 s:piano release:0.1 pan:0.708333333333 ]", + "[ 6/1 → 7/1 | gain:0.55719276422 clip:1 note:G4 s:piano release:0.1 pan:0.560185185185 ]", + "[ 6/1 → 7/1 | gain:0.185730921407 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037 ]", + "[ (6/1 → 7/1) ⇝ 8/1 | gain:0.55719276422 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037 ]", + "[ (6/1 → 7/1) ⇝ 8/1 | gain:0.55719276422 clip:1 note:A3 s:piano release:0.1 pan:0.513888888889 ]", + "[ (6/1 → 7/1) ⇝ 8/1 | gain:0.55719276422 clip:1 note:Eb4 s:piano release:0.1 pan:0.541666666667 ]", + "[ 37/6 → 13/2 | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 37/6 → 13/2 | clip:1 gain:0.125 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ 37/6 → 41/6 | gain:0.140199712953 clip:1 note:F5 s:piano release:0.1 pan:0.606481481481 ]", + "[ 19/3 → 20/3 | clip:1 gain:1 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ 19/3 → 20/3 | clip:1 gain:0.25 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 19/3 → 7/1 | gain:0.188159455299 clip:1 note:F4 s:piano release:0.1 pan:0.550925925926 ]", + "[ 13/2 → 41/6 | clip:1 gain:0.5 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ 13/2 → 41/6 | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ (13/2 → 7/1) ⇝ 43/6 | gain:0.284112636814 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037 ]", + "[ (13/2 → 7/1) ⇝ 15/2 | gain:0.284112636814 clip:1 note:G5 s:piano release:0.1 pan:0.615740740741 ]", + "[ (13/2 → 7/1) ⇝ 15/2 | gain:0.142056318407 clip:1 note:F7 s:piano release:0.1 pan:0.717592592593 ]", + "[ (13/2 → 7/1) ⇝ 17/2 | gain:0.284112636814 clip:1 note:F4 s:piano release:0.1 pan:0.550925925926 ]", + "[ (13/2 → 7/1) ⇝ 17/2 | gain:0.284112636814 clip:1 note:A4 s:piano release:0.1 pan:0.569444444444 ]", + "[ (13/2 → 7/1) ⇝ 17/2 | gain:0.284112636814 clip:1 note:Eb5 s:piano release:0.1 pan:0.597222222222 ]", + "[ 20/3 → 7/1 | clip:1 gain:1 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 20/3 → 7/1 | clip:1 gain:0.25 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ (20/3 → 7/1) ⇝ 22/3 | gain:0.572033358635 clip:1 note:F2 s:piano release:0.1 pan:0.439814814815 ]", + "[ (41/6 → 7/1) ⇝ 43/6 | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ (41/6 → 7/1) ⇝ 43/6 | clip:1 gain:0.125 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ (41/6 → 7/1) ⇝ 15/2 | gain:0.14397405985 clip:1 note:F5 s:piano release:0.1 pan:0.606481481481 ]", + "[ 13/2 ⇜ (7/1 → 43/6) | gain:0.284112636814 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037 ]", + "[ 41/6 ⇜ (7/1 → 43/6) | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 41/6 ⇜ (7/1 → 43/6) | clip:1 gain:0.125 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ 20/3 ⇜ (7/1 → 22/3) | gain:0.572033358635 clip:1 note:F2 s:piano release:0.1 pan:0.439814814815 ]", + "[ 7/1 → 22/3 | clip:1 gain:1 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ 7/1 → 22/3 | clip:1 gain:0.25 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 11/2 ⇜ (7/1 → 15/2) | gain:0.136718062744 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037 ]", + "[ 11/2 ⇜ (7/1 → 15/2) | gain:0.136718062744 clip:1 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 11/2 ⇜ (7/1 → 15/2) | gain:0.136718062744 clip:1 note:Eb7 s:piano release:0.1 pan:0.708333333333 ]", + "[ 13/2 ⇜ (7/1 → 15/2) | gain:0.284112636814 clip:1 note:G5 s:piano release:0.1 pan:0.615740740741 ]", + "[ 13/2 ⇜ (7/1 → 15/2) | gain:0.142056318407 clip:1 note:F7 s:piano release:0.1 pan:0.717592592593 ]", + "[ 41/6 ⇜ (7/1 → 15/2) | gain:0.14397405985 clip:1 note:F5 s:piano release:0.1 pan:0.606481481481 ]", + "[ 7/1 → 23/3 | gain:0.193269129197 clip:1 note:F4 s:piano release:0.1 pan:0.550925925926 ]", + "[ 6/1 ⇜ (7/1 → 8/1) | gain:0.55719276422 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037 ]", + "[ 6/1 ⇜ (7/1 → 8/1) | gain:0.55719276422 clip:1 note:A3 s:piano release:0.1 pan:0.513888888889 ]", + "[ 6/1 ⇜ (7/1 → 8/1) | gain:0.55719276422 clip:1 note:Eb4 s:piano release:0.1 pan:0.541666666667 ]", + "[ 13/2 ⇜ (7/1 → 8/1) ⇝ 17/2 | gain:0.284112636814 clip:1 note:F4 s:piano release:0.1 pan:0.550925925926 ]", + "[ 13/2 ⇜ (7/1 → 8/1) ⇝ 17/2 | gain:0.284112636814 clip:1 note:A4 s:piano release:0.1 pan:0.569444444444 ]", + "[ 13/2 ⇜ (7/1 → 8/1) ⇝ 17/2 | gain:0.284112636814 clip:1 note:Eb5 s:piano release:0.1 pan:0.597222222222 ]", + "[ 7/1 → 8/1 | gain:0.579807387591 clip:1 note:F4 s:piano release:0.1 pan:0.550925925926 ]", + "[ 7/1 → 8/1 | gain:0.193269129197 clip:1 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ (7/1 → 8/1) ⇝ 9/1 | gain:0.193269129197 clip:1 note:F5 s:piano release:0.1 pan:0.606481481481 ]", + "[ (7/1 → 8/1) ⇝ 9/1 | gain:0.193269129197 clip:1 note:A5 s:piano release:0.1 pan:0.625 ]", + "[ (7/1 → 8/1) ⇝ 9/1 | gain:0.193269129197 clip:1 note:Eb6 s:piano release:0.1 pan:0.652777777778 ]", + "[ 43/6 → 15/2 | clip:1 gain:0.5 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ 43/6 → 15/2 | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 43/6 → 47/6 | gain:0.291880073212 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037 ]", + "[ 22/3 → 23/3 | clip:1 gain:1 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 22/3 → 23/3 | clip:1 gain:0.25 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ 22/3 → 8/1 | gain:0.58774774901 clip:1 note:F2 s:piano release:0.1 pan:0.439814814815 ]", + "[ 15/2 → 47/6 | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 15/2 → 47/6 | clip:1 gain:0.125 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ (15/2 → 8/1) ⇝ 49/6 | gain:0.147940834176 clip:1 note:F5 s:piano release:0.1 pan:0.606481481481 ]", + "[ (15/2 → 8/1) ⇝ 17/2 | gain:0.295881668351 clip:1 note:F5 s:piano release:0.1 pan:0.606481481481 ]", + "[ (15/2 → 8/1) ⇝ 17/2 | gain:0.147940834176 clip:1 note:G7 s:piano release:0.1 pan:0.726851851852 ]", + "[ (15/2 → 8/1) ⇝ 19/2 | gain:0.147940834176 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037 ]", + "[ (15/2 → 8/1) ⇝ 19/2 | gain:0.147940834176 clip:1 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ (15/2 → 8/1) ⇝ 19/2 | gain:0.147940834176 clip:1 note:Eb7 s:piano release:0.1 pan:0.708333333333 ]", + "[ 23/3 → 8/1 | clip:1 gain:1 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ 23/3 → 8/1 | clip:1 gain:0.25 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ (23/3 → 8/1) ⇝ 25/3 | gain:0.198599992484 clip:1 note:F4 s:piano release:0.1 pan:0.550925925926 ]", + "[ (47/6 → 8/1) ⇝ 49/6 | clip:1 gain:0.5 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ (47/6 → 8/1) ⇝ 49/6 | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ (47/6 → 8/1) ⇝ 17/2 | gain:0.29992534208 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037 ]", + "[ 15/2 ⇜ (8/1 → 49/6) | gain:0.147940834176 clip:1 note:D5 s:piano release:0.1 pan:0.592592592593 ]", + "[ 47/6 ⇜ (8/1 → 49/6) | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 47/6 ⇜ (8/1 → 49/6) | clip:1 gain:0.125 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ 23/3 ⇜ (8/1 → 25/3) | gain:0.198599992484 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037 ]", + "[ 8/1 → 25/3 | clip:1 gain:1 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ 8/1 → 25/3 | clip:1 gain:0.25 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 13/2 ⇜ (8/1 → 17/2) | gain:0.284112636814 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037 ]", + "[ 13/2 ⇜ (8/1 → 17/2) | gain:0.284112636814 clip:1 note:F4 s:piano release:0.1 pan:0.550925925926 ]", + "[ 13/2 ⇜ (8/1 → 17/2) | gain:0.284112636814 clip:1 note:C5 s:piano release:0.1 pan:0.583333333333 ]", + "[ 15/2 ⇜ (8/1 → 17/2) | gain:0.295881668351 clip:1 note:D5 s:piano release:0.1 pan:0.592592592593 ]", + "[ 15/2 ⇜ (8/1 → 17/2) | gain:0.147940834176 clip:1 note:E7 s:piano release:0.1 pan:0.712962962963 ]", + "[ 47/6 ⇜ (8/1 → 17/2) | gain:0.29992534208 clip:1 note:D3 s:piano release:0.1 pan:0.481481481481 ]", + "[ 8/1 → 26/3 | gain:0.60390843302 clip:1 note:D2 s:piano release:0.1 pan:0.425925925926 ]", + "[ 7/1 ⇜ (8/1 → 9/1) | gain:0.193269129197 clip:1 note:D5 s:piano release:0.1 pan:0.592592592593 ]", + "[ 7/1 ⇜ (8/1 → 9/1) | gain:0.193269129197 clip:1 note:F5 s:piano release:0.1 pan:0.606481481481 ]", + "[ 7/1 ⇜ (8/1 → 9/1) | gain:0.193269129197 clip:1 note:C6 s:piano release:0.1 pan:0.638888888889 ]", + "[ 15/2 ⇜ (8/1 → 9/1) ⇝ 19/2 | gain:0.147940834176 clip:1 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ 15/2 ⇜ (8/1 → 9/1) ⇝ 19/2 | gain:0.147940834176 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037 ]", + "[ 15/2 ⇜ (8/1 → 9/1) ⇝ 19/2 | gain:0.147940834176 clip:1 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ 8/1 → 9/1 | gain:0.60390843302 clip:1 note:E4 s:piano release:0.1 pan:0.546296296296 ]", + "[ 8/1 → 9/1 | gain:0.201302811007 clip:1 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ (8/1 → 9/1) ⇝ 10/1 | gain:0.60390843302 clip:1 note:D3 s:piano release:0.1 pan:0.481481481481 ]", + "[ (8/1 → 9/1) ⇝ 10/1 | gain:0.60390843302 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037 ]", + "[ (8/1 → 9/1) ⇝ 10/1 | gain:0.60390843302 clip:1 note:C4 s:piano release:0.1 pan:0.527777777778 ]", + "[ 49/6 → 17/2 | clip:1 gain:0.5 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ 49/6 → 17/2 | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 49/6 → 53/6 | gain:0.15199154547 clip:1 note:D5 s:piano release:0.1 pan:0.592592592593 ]", + "[ 25/3 → 26/3 | clip:1 gain:1 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 25/3 → 26/3 | clip:1 gain:0.25 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ 25/3 → 9/1 | gain:0.204005629529 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037 ]", + "[ 17/2 → 53/6 | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 17/2 → 53/6 | clip:1 gain:0.125 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ (17/2 → 9/1) ⇝ 55/6 | gain:0.308026764669 clip:1 note:D3 s:piano release:0.1 pan:0.481481481481 ]", + "[ (17/2 → 9/1) ⇝ 19/2 | gain:0.308026764669 clip:1 note:E5 s:piano release:0.1 pan:0.601851851852 ]", + "[ (17/2 → 9/1) ⇝ 19/2 | gain:0.154013382334 clip:1 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ (17/2 → 9/1) ⇝ 21/2 | gain:0.308026764669 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037 ]", + "[ (17/2 → 9/1) ⇝ 21/2 | gain:0.308026764669 clip:1 note:F4 s:piano release:0.1 pan:0.550925925926 ]", + "[ (17/2 → 9/1) ⇝ 21/2 | gain:0.308026764669 clip:1 note:C5 s:piano release:0.1 pan:0.583333333333 ]", + "[ 26/3 → 9/1 | clip:1 gain:1 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ 26/3 → 9/1 | clip:1 gain:0.25 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ (26/3 → 9/1) ⇝ 28/3 | gain:0.62006911703 clip:1 note:D2 s:piano release:0.1 pan:0.425925925926 ]", + "[ (53/6 → 9/1) ⇝ 55/6 | clip:1 gain:0.5 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ (53/6 → 9/1) ⇝ 55/6 | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ (53/6 → 9/1) ⇝ 19/2 | gain:0.156014179904 clip:1 note:D5 s:piano release:0.1 pan:0.592592592593 ]", + "[ 17/2 ⇜ (9/1 → 55/6) | gain:0.308026764669 clip:1 note:D3 s:piano release:0.1 pan:0.481481481481 ]", + "[ 53/6 ⇜ (9/1 → 55/6) | clip:1 gain:0.5 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ 53/6 ⇜ (9/1 → 55/6) | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 26/3 ⇜ (9/1 → 28/3) | gain:0.62006911703 clip:1 note:D2 s:piano release:0.1 pan:0.425925925926 ]", + "[ 9/1 → 28/3 | clip:1 gain:1 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 9/1 → 28/3 | clip:1 gain:0.25 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ 15/2 ⇜ (9/1 → 19/2) | gain:0.147940834176 clip:1 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ 15/2 ⇜ (9/1 → 19/2) | gain:0.147940834176 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037 ]", + "[ 15/2 ⇜ (9/1 → 19/2) | gain:0.147940834176 clip:1 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ 17/2 ⇜ (9/1 → 19/2) | gain:0.308026764669 clip:1 note:E5 s:piano release:0.1 pan:0.601851851852 ]", + "[ 17/2 ⇜ (9/1 → 19/2) | gain:0.154013382334 clip:1 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ 53/6 ⇜ (9/1 → 19/2) | gain:0.156014179904 clip:1 note:D5 s:piano release:0.1 pan:0.592592592593 ]", + "[ 9/1 → 29/3 | gain:0.209336492816 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037 ]", + "[ 8/1 ⇜ (9/1 → 10/1) | gain:0.60390843302 clip:1 note:D3 s:piano release:0.1 pan:0.481481481481 ]", + "[ 8/1 ⇜ (9/1 → 10/1) | gain:0.60390843302 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037 ]", + "[ 8/1 ⇜ (9/1 → 10/1) | gain:0.60390843302 clip:1 note:C4 s:piano release:0.1 pan:0.527777777778 ]", + "[ 17/2 ⇜ (9/1 → 10/1) ⇝ 21/2 | gain:0.308026764669 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037 ]", + "[ 17/2 ⇜ (9/1 → 10/1) ⇝ 21/2 | gain:0.308026764669 clip:1 note:F4 s:piano release:0.1 pan:0.550925925926 ]", + "[ 17/2 ⇜ (9/1 → 10/1) ⇝ 21/2 | gain:0.308026764669 clip:1 note:C5 s:piano release:0.1 pan:0.583333333333 ]", + "[ 9/1 → 10/1 | gain:0.628009478449 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037 ]", + "[ 9/1 → 10/1 | gain:0.209336492816 clip:1 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ (9/1 → 10/1) ⇝ 11/1 | gain:0.209336492816 clip:1 note:D5 s:piano release:0.1 pan:0.592592592593 ]", + "[ (9/1 → 10/1) ⇝ 11/1 | gain:0.209336492816 clip:1 note:F5 s:piano release:0.1 pan:0.606481481481 ]", + "[ (9/1 → 10/1) ⇝ 11/1 | gain:0.209336492816 clip:1 note:C6 s:piano release:0.1 pan:0.638888888889 ]", + "[ 55/6 → 19/2 | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 55/6 → 19/2 | clip:1 gain:0.125 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ 55/6 → 59/6 | gain:0.31596031332 clip:1 note:D3 s:piano release:0.1 pan:0.481481481481 ]", + "[ 28/3 → 29/3 | clip:1 gain:1 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ 28/3 → 29/3 | clip:1 gain:0.25 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 28/3 → 10/1 | gain:0.635783507405 clip:1 note:D2 s:piano release:0.1 pan:0.425925925926 ]", + "[ 19/2 → 59/6 | clip:1 gain:0.5 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ 19/2 → 59/6 | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ (19/2 → 10/1) ⇝ 61/6 | gain:0.159897898103 clip:1 note:D5 s:piano release:0.1 pan:0.592592592593 ]", + "[ (19/2 → 10/1) ⇝ 21/2 | gain:0.319795796206 clip:1 note:D5 s:piano release:0.1 pan:0.592592592593 ]", + "[ (19/2 → 10/1) ⇝ 21/2 | gain:0.159897898103 clip:1 note:E7 s:piano release:0.1 pan:0.712962962963 ]", + "[ (19/2 → 10/1) ⇝ 23/2 | gain:0.159897898103 clip:1 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ (19/2 → 10/1) ⇝ 23/2 | gain:0.159897898103 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037 ]", + "[ (19/2 → 10/1) ⇝ 23/2 | gain:0.159897898103 clip:1 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ 29/3 → 10/1 | clip:1 gain:1 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 29/3 → 10/1 | clip:1 gain:0.25 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ (29/3 → 10/1) ⇝ 31/3 | gain:0.214446166714 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037 ]", + "[ (59/6 → 10/1) ⇝ 61/6 | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ (59/6 → 10/1) ⇝ 61/6 | clip:1 gain:0.125 note:E6 s:piano release:0.1 pan:0.657407407407 ]", + "[ (59/6 → 10/1) ⇝ 21/2 | gain:0.323509007115 clip:1 note:D3 s:piano release:0.1 pan:0.481481481481 ]", + "[ 19/2 ⇜ (10/1 → 61/6) | gain:0.159897898103 clip:1 note:G5 s:piano release:0.1 pan:0.615740740741 ]", + "[ 59/6 ⇜ (10/1 → 61/6) | clip:1 gain:0.5 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ 59/6 ⇜ (10/1 → 61/6) | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 29/3 ⇜ (10/1 → 31/3) | gain:0.214446166714 clip:1 note:G4 s:piano release:0.1 pan:0.560185185185 ]", + "[ 10/1 → 31/3 | clip:1 gain:1 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 10/1 → 31/3 | clip:1 gain:0.25 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ 17/2 ⇜ (10/1 → 21/2) | gain:0.308026764669 clip:1 note:G4 s:piano release:0.1 pan:0.560185185185 ]", + "[ 17/2 ⇜ (10/1 → 21/2) | gain:0.308026764669 clip:1 note:B4 s:piano release:0.1 pan:0.578703703704 ]", + "[ 17/2 ⇜ (10/1 → 21/2) | gain:0.308026764669 clip:1 note:F5 s:piano release:0.1 pan:0.606481481481 ]", + "[ 19/2 ⇜ (10/1 → 21/2) | gain:0.319795796206 clip:1 note:G5 s:piano release:0.1 pan:0.615740740741 ]", + "[ 19/2 ⇜ (10/1 → 21/2) | gain:0.159897898103 clip:1 note:A7 s:piano release:0.1 pan:0.736111111111 ]", + "[ 59/6 ⇜ (10/1 → 21/2) | gain:0.323509007115 clip:1 note:G3 s:piano release:0.1 pan:0.50462962963 ]", + "[ 10/1 → 32/3 | gain:0.650624101821 clip:1 note:G2 s:piano release:0.1 pan:0.449074074074 ]", + "[ 9/1 ⇜ (10/1 → 11/1) | gain:0.209336492816 clip:1 note:G5 s:piano release:0.1 pan:0.615740740741 ]", + "[ 9/1 ⇜ (10/1 → 11/1) | gain:0.209336492816 clip:1 note:B5 s:piano release:0.1 pan:0.634259259259 ]", + "[ 9/1 ⇜ (10/1 → 11/1) | gain:0.209336492816 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037 ]", + "[ 19/2 ⇜ (10/1 → 11/1) ⇝ 23/2 | gain:0.159897898103 clip:1 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 19/2 ⇜ (10/1 → 11/1) ⇝ 23/2 | gain:0.159897898103 clip:1 note:B6 s:piano release:0.1 pan:0.689814814815 ]", + "[ 19/2 ⇜ (10/1 → 11/1) ⇝ 23/2 | gain:0.159897898103 clip:1 note:F7 s:piano release:0.1 pan:0.717592592593 ]", + "[ 10/1 → 11/1 | gain:0.650624101821 clip:1 note:A4 s:piano release:0.1 pan:0.569444444444 ]", + "[ 10/1 → 11/1 | gain:0.216874700607 clip:1 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ (10/1 → 11/1) ⇝ 12/1 | gain:0.650624101821 clip:1 note:G3 s:piano release:0.1 pan:0.50462962963 ]", + "[ (10/1 → 11/1) ⇝ 12/1 | gain:0.650624101821 clip:1 note:B3 s:piano release:0.1 pan:0.523148148148 ]", + "[ (10/1 → 11/1) ⇝ 12/1 | gain:0.650624101821 clip:1 note:F4 s:piano release:0.1 pan:0.550925925926 ]", + "[ 61/6 → 21/2 | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 61/6 → 21/2 | clip:1 gain:0.125 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ 61/6 → 65/6 | gain:0.16353773298 clip:1 note:G5 s:piano release:0.1 pan:0.615740740741 ]", + "[ 31/3 → 32/3 | clip:1 gain:1 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ 31/3 → 32/3 | clip:1 gain:0.25 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 31/3 → 11/1 | gain:0.219197631247 clip:1 note:G4 s:piano release:0.1 pan:0.560185185185 ]", + "[ 21/2 → 65/6 | clip:1 gain:0.5 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ 21/2 → 65/6 | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ (21/2 → 11/1) ⇝ 67/6 | gain:0.330472307531 clip:1 note:G3 s:piano release:0.1 pan:0.50462962963 ]", + "[ (21/2 → 11/1) ⇝ 23/2 | gain:0.330472307531 clip:1 note:A5 s:piano release:0.1 pan:0.625 ]", + "[ (21/2 → 11/1) ⇝ 23/2 | gain:0.165236153766 clip:1 note:G7 s:piano release:0.1 pan:0.726851851852 ]", + "[ (21/2 → 11/1) ⇝ 25/2 | gain:0.330472307531 clip:1 note:G4 s:piano release:0.1 pan:0.560185185185 ]", + "[ (21/2 → 11/1) ⇝ 25/2 | gain:0.330472307531 clip:1 note:B4 s:piano release:0.1 pan:0.578703703704 ]", + "[ (21/2 → 11/1) ⇝ 25/2 | gain:0.330472307531 clip:1 note:F5 s:piano release:0.1 pan:0.606481481481 ]", + "[ 32/3 → 11/1 | clip:1 gain:1 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 32/3 → 11/1 | clip:1 gain:0.25 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ (32/3 → 11/1) ⇝ 34/3 | gain:0.664200980575 clip:1 note:G2 s:piano release:0.1 pan:0.449074074074 ]", + "[ (65/6 → 11/1) ⇝ 67/6 | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ (65/6 → 11/1) ⇝ 67/6 | clip:1 gain:0.125 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ (65/6 → 11/1) ⇝ 23/2 | gain:0.166839287557 clip:1 note:G5 s:piano release:0.1 pan:0.615740740741 ]", + "[ 21/2 ⇜ (11/1 → 67/6) | gain:0.330472307531 clip:1 note:G3 s:piano release:0.1 pan:0.50462962963 ]", + "[ 65/6 ⇜ (11/1 → 67/6) | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 65/6 ⇜ (11/1 → 67/6) | clip:1 gain:0.125 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ 32/3 ⇜ (11/1 → 34/3) | gain:0.664200980575 clip:1 note:G2 s:piano release:0.1 pan:0.449074074074 ]", + "[ 11/1 → 34/3 | clip:1 gain:1 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ 11/1 → 34/3 | clip:1 gain:0.25 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 19/2 ⇜ (11/1 → 23/2) | gain:0.159897898103 clip:1 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 19/2 ⇜ (11/1 → 23/2) | gain:0.159897898103 clip:1 note:B6 s:piano release:0.1 pan:0.689814814815 ]", + "[ 19/2 ⇜ (11/1 → 23/2) | gain:0.159897898103 clip:1 note:F7 s:piano release:0.1 pan:0.717592592593 ]", + "[ 21/2 ⇜ (11/1 → 23/2) | gain:0.330472307531 clip:1 note:A5 s:piano release:0.1 pan:0.625 ]", + "[ 21/2 ⇜ (11/1 → 23/2) | gain:0.165236153766 clip:1 note:G7 s:piano release:0.1 pan:0.726851851852 ]", + "[ 65/6 ⇜ (11/1 → 23/2) | gain:0.166839287557 clip:1 note:G5 s:piano release:0.1 pan:0.615740740741 ]", + "[ 11/1 → 35/3 | gain:0.223469525865 clip:1 note:G4 s:piano release:0.1 pan:0.560185185185 ]", + "[ 10/1 ⇜ (11/1 → 12/1) | gain:0.650624101821 clip:1 note:G3 s:piano release:0.1 pan:0.50462962963 ]", + "[ 10/1 ⇜ (11/1 → 12/1) | gain:0.650624101821 clip:1 note:B3 s:piano release:0.1 pan:0.523148148148 ]", + "[ 10/1 ⇜ (11/1 → 12/1) | gain:0.650624101821 clip:1 note:F4 s:piano release:0.1 pan:0.550925925926 ]", + "[ 21/2 ⇜ (11/1 → 12/1) ⇝ 25/2 | gain:0.330472307531 clip:1 note:G4 s:piano release:0.1 pan:0.560185185185 ]", + "[ 21/2 ⇜ (11/1 → 12/1) ⇝ 25/2 | gain:0.330472307531 clip:1 note:B4 s:piano release:0.1 pan:0.578703703704 ]", + "[ 21/2 ⇜ (11/1 → 12/1) ⇝ 25/2 | gain:0.330472307531 clip:1 note:F5 s:piano release:0.1 pan:0.606481481481 ]", + "[ 11/1 → 12/1 | gain:0.670408577595 clip:1 note:G4 s:piano release:0.1 pan:0.560185185185 ]", + "[ 11/1 → 12/1 | gain:0.223469525865 clip:1 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ (11/1 → 12/1) ⇝ 13/1 | gain:0.223469525865 clip:1 note:G5 s:piano release:0.1 pan:0.615740740741 ]", + "[ (11/1 → 12/1) ⇝ 13/1 | gain:0.223469525865 clip:1 note:B5 s:piano release:0.1 pan:0.634259259259 ]", + "[ (11/1 → 12/1) ⇝ 13/1 | gain:0.223469525865 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037 ]", + "[ 67/6 → 23/2 | clip:1 gain:0.5 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ 67/6 → 23/2 | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 67/6 → 71/6 | gain:0.336675514101 clip:1 note:G3 s:piano release:0.1 pan:0.50462962963 ]", + "[ 34/3 → 35/3 | clip:1 gain:1 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 34/3 → 35/3 | clip:1 gain:0.25 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ 34/3 → 12/1 | gain:0.676180597899 clip:1 note:G2 s:piano release:0.1 pan:0.449074074074 ]", + "[ 23/2 → 71/6 | clip:1 gain:0.5 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 23/2 → 71/6 | clip:1 gain:0.125 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ (23/2 → 12/1) ⇝ 73/6 | gain:0.1697234328 clip:1 note:G5 s:piano release:0.1 pan:0.615740740741 ]", + "[ (23/2 → 12/1) ⇝ 25/2 | gain:0.339446865601 clip:1 note:G5 s:piano release:0.1 pan:0.615740740741 ]", + "[ (23/2 → 12/1) ⇝ 25/2 | gain:0.1697234328 clip:1 note:A7 s:piano release:0.1 pan:0.736111111111 ]", + "[ (23/2 → 12/1) ⇝ 27/2 | gain:0.1697234328 clip:1 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ (23/2 → 12/1) ⇝ 27/2 | gain:0.1697234328 clip:1 note:B6 s:piano release:0.1 pan:0.689814814815 ]", + "[ (23/2 → 12/1) ⇝ 27/2 | gain:0.1697234328 clip:1 note:F7 s:piano release:0.1 pan:0.717592592593 ]", + "[ 35/3 → 12/1 | clip:1 gain:1 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ 35/3 → 12/1 | clip:1 gain:0.25 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ (35/3 → 12/1) ⇝ 37/3 | gain:0.227162413214 clip:1 note:G4 s:piano release:0.1 pan:0.560185185185 ]", + "[ (71/6 → 12/1) ⇝ 73/6 | clip:1 gain:0.5 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ (71/6 → 12/1) ⇝ 73/6 | clip:1 gain:0.125 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ (71/6 → 12/1) ⇝ 25/2 | gain:0.341979160062 clip:1 note:G3 s:piano release:0.1 pan:0.50462962963 ]", + "[ 23/2 ⇜ (12/1 → 73/6) | gain:0.1697234328 clip:1 note:C5 s:piano release:0.1 pan:0.583333333333 ]", + "[ 71/6 ⇜ (12/1 → 73/6) | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 71/6 ⇜ (12/1 → 73/6) | clip:1 gain:0.125 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ 35/3 ⇜ (12/1 → 37/3) | gain:0.227162413214 clip:1 note:C4 s:piano release:0.1 pan:0.527777777778 ]", + "[ 12/1 → 37/3 | clip:1 gain:1 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ 12/1 → 37/3 | clip:1 gain:0.25 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 21/2 ⇜ (12/1 → 25/2) | gain:0.330472307531 clip:1 note:C4 s:piano release:0.1 pan:0.527777777778 ]", + "[ 21/2 ⇜ (12/1 → 25/2) | gain:0.330472307531 clip:1 note:Eb4 s:piano release:0.1 pan:0.541666666667 ]", + "[ 21/2 ⇜ (12/1 → 25/2) | gain:0.330472307531 clip:1 note:Bb4 s:piano release:0.1 pan:0.574074074074 ]", + "[ 23/2 ⇜ (12/1 → 25/2) | gain:0.339446865601 clip:1 note:C5 s:piano release:0.1 pan:0.583333333333 ]", + "[ 23/2 ⇜ (12/1 → 25/2) | gain:0.1697234328 clip:1 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ 71/6 ⇜ (12/1 → 25/2) | gain:0.341979160062 clip:1 note:C3 s:piano release:0.1 pan:0.472222222222 ]", + "[ 12/1 → 38/3 | gain:0.686304573267 clip:1 note:C2 s:piano release:0.1 pan:0.416666666667 ]", + "[ 11/1 ⇜ (12/1 → 13/1) | gain:0.223469525865 clip:1 note:C5 s:piano release:0.1 pan:0.583333333333 ]", + "[ 11/1 ⇜ (12/1 → 13/1) | gain:0.223469525865 clip:1 note:Eb5 s:piano release:0.1 pan:0.597222222222 ]", + "[ 11/1 ⇜ (12/1 → 13/1) | gain:0.223469525865 clip:1 note:Bb5 s:piano release:0.1 pan:0.62962962963 ]", + "[ 23/2 ⇜ (12/1 → 13/1) ⇝ 27/2 | gain:0.1697234328 clip:1 note:C6 s:piano release:0.1 pan:0.638888888889 ]", + "[ 23/2 ⇜ (12/1 → 13/1) ⇝ 27/2 | gain:0.1697234328 clip:1 note:Eb6 s:piano release:0.1 pan:0.652777777778 ]", + "[ 23/2 ⇜ (12/1 → 13/1) ⇝ 27/2 | gain:0.1697234328 clip:1 note:Bb6 s:piano release:0.1 pan:0.685185185185 ]", + "[ 12/1 → 13/1 | gain:0.686304573267 clip:1 note:D4 s:piano release:0.1 pan:0.537037037037 ]", + "[ 12/1 → 13/1 | gain:0.228768191089 clip:1 note:C6 s:piano release:0.1 pan:0.638888888889 ]", + "[ (12/1 → 13/1) ⇝ 14/1 | gain:0.686304573267 clip:1 note:C3 s:piano release:0.1 pan:0.472222222222 ]", + "[ (12/1 → 13/1) ⇝ 14/1 | gain:0.686304573267 clip:1 note:Eb3 s:piano release:0.1 pan:0.486111111111 ]", + "[ (12/1 → 13/1) ⇝ 14/1 | gain:0.686304573267 clip:1 note:Bb3 s:piano release:0.1 pan:0.518518518519 ]", + "[ 73/6 → 25/2 | clip:1 gain:0.5 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ 73/6 → 25/2 | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 73/6 → 77/6 | gain:0.17213100544 clip:1 note:C5 s:piano release:0.1 pan:0.583333333333 ]", + "[ 37/3 → 38/3 | clip:1 gain:1 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 37/3 → 38/3 | clip:1 gain:0.25 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ 37/3 → 13/1 | gain:0.230205042908 clip:1 note:C4 s:piano release:0.1 pan:0.527777777778 ]", + "[ 25/2 → 77/6 | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 25/2 → 77/6 | clip:1 gain:0.125 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ (25/2 → 13/1) ⇝ 79/6 | gain:0.346288408018 clip:1 note:C3 s:piano release:0.1 pan:0.472222222222 ]", + "[ (25/2 → 13/1) ⇝ 27/2 | gain:0.346288408018 clip:1 note:D5 s:piano release:0.1 pan:0.592592592593 ]", + "[ (25/2 → 13/1) ⇝ 27/2 | gain:0.173144204009 clip:1 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ (25/2 → 13/1) ⇝ 29/2 | gain:0.346288408018 clip:1 note:C4 s:piano release:0.1 pan:0.527777777778 ]", + "[ (25/2 → 13/1) ⇝ 29/2 | gain:0.346288408018 clip:1 note:Eb4 s:piano release:0.1 pan:0.541666666667 ]", + "[ (25/2 → 13/1) ⇝ 29/2 | gain:0.346288408018 clip:1 note:Bb4 s:piano release:0.1 pan:0.574074074074 ]", + "[ 38/3 → 13/1 | clip:1 gain:1 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ 38/3 → 13/1 | clip:1 gain:0.25 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ (38/3 → 13/1) ⇝ 40/3 | gain:0.694408482707 clip:1 note:C2 s:piano release:0.1 pan:0.416666666667 ]", + "[ (77/6 → 13/1) ⇝ 79/6 | clip:1 gain:0.5 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ (77/6 → 13/1) ⇝ 79/6 | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ (77/6 → 13/1) ⇝ 27/2 | gain:0.174027505805 clip:1 note:C5 s:piano release:0.1 pan:0.583333333333 ]", + "[ 25/2 ⇜ (13/1 → 79/6) | gain:0.346288408018 clip:1 note:C3 s:piano release:0.1 pan:0.472222222222 ]", + "[ 77/6 ⇜ (13/1 → 79/6) | clip:1 gain:0.5 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ 77/6 ⇜ (13/1 → 79/6) | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 38/3 ⇜ (13/1 → 40/3) | gain:0.694408482707 clip:1 note:C2 s:piano release:0.1 pan:0.416666666667 ]", + "[ 13/1 → 40/3 | clip:1 gain:1 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 13/1 → 40/3 | clip:1 gain:0.25 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ 23/2 ⇜ (13/1 → 27/2) | gain:0.1697234328 clip:1 note:C6 s:piano release:0.1 pan:0.638888888889 ]", + "[ 23/2 ⇜ (13/1 → 27/2) | gain:0.1697234328 clip:1 note:Eb6 s:piano release:0.1 pan:0.652777777778 ]", + "[ 23/2 ⇜ (13/1 → 27/2) | gain:0.1697234328 clip:1 note:Bb6 s:piano release:0.1 pan:0.685185185185 ]", + "[ 25/2 ⇜ (13/1 → 27/2) | gain:0.346288408018 clip:1 note:D5 s:piano release:0.1 pan:0.592592592593 ]", + "[ 25/2 ⇜ (13/1 → 27/2) | gain:0.173144204009 clip:1 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ 77/6 ⇜ (13/1 → 27/2) | gain:0.174027505805 clip:1 note:C5 s:piano release:0.1 pan:0.583333333333 ]", + "[ 13/1 → 41/3 | gain:0.232560615295 clip:1 note:C4 s:piano release:0.1 pan:0.527777777778 ]", + "[ 12/1 ⇜ (13/1 → 14/1) | gain:0.686304573267 clip:1 note:C3 s:piano release:0.1 pan:0.472222222222 ]", + "[ 12/1 ⇜ (13/1 → 14/1) | gain:0.686304573267 clip:1 note:Eb3 s:piano release:0.1 pan:0.486111111111 ]", + "[ 12/1 ⇜ (13/1 → 14/1) | gain:0.686304573267 clip:1 note:Bb3 s:piano release:0.1 pan:0.518518518519 ]", + "[ 25/2 ⇜ (13/1 → 14/1) ⇝ 29/2 | gain:0.346288408018 clip:1 note:C4 s:piano release:0.1 pan:0.527777777778 ]", + "[ 25/2 ⇜ (13/1 → 14/1) ⇝ 29/2 | gain:0.346288408018 clip:1 note:Eb4 s:piano release:0.1 pan:0.541666666667 ]", + "[ 25/2 ⇜ (13/1 → 14/1) ⇝ 29/2 | gain:0.346288408018 clip:1 note:Bb4 s:piano release:0.1 pan:0.574074074074 ]", + "[ 13/1 → 14/1 | gain:0.697681845884 clip:1 note:C4 s:piano release:0.1 pan:0.527777777778 ]", + "[ 13/1 → 14/1 | gain:0.232560615295 clip:1 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ (13/1 → 14/1) ⇝ 15/1 | gain:0.232560615295 clip:1 note:C5 s:piano release:0.1 pan:0.583333333333 ]", + "[ (13/1 → 14/1) ⇝ 15/1 | gain:0.232560615295 clip:1 note:Eb5 s:piano release:0.1 pan:0.597222222222 ]", + "[ (13/1 → 14/1) ⇝ 15/1 | gain:0.232560615295 clip:1 note:Bb5 s:piano release:0.1 pan:0.62962962963 ]", + "[ 79/6 → 27/2 | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 79/6 → 27/2 | clip:1 gain:0.125 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ 79/6 → 83/6 | gain:0.349562445589 clip:1 note:C3 s:piano release:0.1 pan:0.472222222222 ]", + "[ 40/3 → 41/3 | clip:1 gain:1 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ 40/3 → 41/3 | clip:1 gain:0.25 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 40/3 → 14/1 | gain:0.700440650116 clip:1 note:C2 s:piano release:0.1 pan:0.416666666667 ]", + "[ 27/2 → 83/6 | clip:1 gain:0.5 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ 27/2 → 83/6 | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ (27/2 → 14/1) ⇝ 85/6 | gain:0.175407795646 clip:1 note:C5 s:piano release:0.1 pan:0.583333333333 ]", + "[ (27/2 → 14/1) ⇝ 29/2 | gain:0.350815591291 clip:1 note:C5 s:piano release:0.1 pan:0.583333333333 ]", + "[ (27/2 → 14/1) ⇝ 29/2 | gain:0.175407795646 clip:1 note:D7 s:piano release:0.1 pan:0.703703703704 ]", + "[ (27/2 → 14/1) ⇝ 31/2 | gain:0.175407795646 clip:1 note:C6 s:piano release:0.1 pan:0.638888888889 ]", + "[ (27/2 → 14/1) ⇝ 31/2 | gain:0.175407795646 clip:1 note:Eb6 s:piano release:0.1 pan:0.652777777778 ]", + "[ (27/2 → 14/1) ⇝ 31/2 | gain:0.175407795646 clip:1 note:Bb6 s:piano release:0.1 pan:0.685185185185 ]", + "[ 41/3 → 14/1 | clip:1 gain:1 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 41/3 → 14/1 | clip:1 gain:0.25 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ (41/3 → 14/1) ⇝ 43/3 | gain:0.234233045231 clip:1 note:C4 s:piano release:0.1 pan:0.527777777778 ]", + "[ (83/6 → 14/1) ⇝ 85/6 | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ (83/6 → 14/1) ⇝ 85/6 | clip:1 gain:0.125 note:D6 s:piano release:0.1 pan:0.648148148148 ]", + "[ (83/6 → 14/1) ⇝ 29/2 | gain:0.351823881073 clip:1 note:C3 s:piano release:0.1 pan:0.472222222222 ]", + "[ 27/2 ⇜ (14/1 → 85/6) | gain:0.175407795646 clip:1 note:F5 s:piano release:0.1 pan:0.606481481481 ]", + "[ 83/6 ⇜ (14/1 → 85/6) | clip:1 gain:0.5 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ 83/6 ⇜ (14/1 → 85/6) | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 41/3 ⇜ (14/1 → 43/3) | gain:0.234233045231 clip:1 note:F4 s:piano release:0.1 pan:0.550925925926 ]", + "[ 14/1 → 43/3 | clip:1 gain:1 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 14/1 → 43/3 | clip:1 gain:0.25 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ 25/2 ⇜ (14/1 → 29/2) | gain:0.346288408018 clip:1 note:F4 s:piano release:0.1 pan:0.550925925926 ]", + "[ 25/2 ⇜ (14/1 → 29/2) | gain:0.346288408018 clip:1 note:A4 s:piano release:0.1 pan:0.569444444444 ]", + "[ 25/2 ⇜ (14/1 → 29/2) | gain:0.346288408018 clip:1 note:Eb5 s:piano release:0.1 pan:0.597222222222 ]", + "[ 27/2 ⇜ (14/1 → 29/2) | gain:0.350815591291 clip:1 note:F5 s:piano release:0.1 pan:0.606481481481 ]", + "[ 27/2 ⇜ (14/1 → 29/2) | gain:0.175407795646 clip:1 note:G7 s:piano release:0.1 pan:0.726851851852 ]", + "[ 83/6 ⇜ (14/1 → 29/2) | gain:0.351823881073 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037 ]", + "[ 14/1 → 44/3 | gain:0.704480938564 clip:1 note:F2 s:piano release:0.1 pan:0.439814814815 ]", + "[ 13/1 ⇜ (14/1 → 15/1) | gain:0.232560615295 clip:1 note:F5 s:piano release:0.1 pan:0.606481481481 ]", + "[ 13/1 ⇜ (14/1 → 15/1) | gain:0.232560615295 clip:1 note:A5 s:piano release:0.1 pan:0.625 ]", + "[ 13/1 ⇜ (14/1 → 15/1) | gain:0.232560615295 clip:1 note:Eb6 s:piano release:0.1 pan:0.652777777778 ]", + "[ 27/2 ⇜ (14/1 → 15/1) ⇝ 31/2 | gain:0.175407795646 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037 ]", + "[ 27/2 ⇜ (14/1 → 15/1) ⇝ 31/2 | gain:0.175407795646 clip:1 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 27/2 ⇜ (14/1 → 15/1) ⇝ 31/2 | gain:0.175407795646 clip:1 note:Eb7 s:piano release:0.1 pan:0.708333333333 ]", + "[ 14/1 → 15/1 | gain:0.704480938564 clip:1 note:G4 s:piano release:0.1 pan:0.560185185185 ]", + "[ 14/1 → 15/1 | gain:0.234826979521 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037 ]", + "[ (14/1 → 15/1) ⇝ 16/1 | gain:0.704480938564 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037 ]", + "[ (14/1 → 15/1) ⇝ 16/1 | gain:0.704480938564 clip:1 note:A3 s:piano release:0.1 pan:0.513888888889 ]", + "[ (14/1 → 15/1) ⇝ 16/1 | gain:0.704480938564 clip:1 note:Eb4 s:piano release:0.1 pan:0.541666666667 ]", + "[ 85/6 → 29/2 | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 85/6 → 29/2 | clip:1 gain:0.125 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ 85/6 → 89/6 | gain:0.176300795964 clip:1 note:F5 s:piano release:0.1 pan:0.606481481481 ]", + "[ 43/3 → 44/3 | clip:1 gain:1 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ 43/3 → 44/3 | clip:1 gain:0.25 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 43/3 → 15/1 | gain:0.235273225852 clip:1 note:F4 s:piano release:0.1 pan:0.550925925926 ]", + "[ 29/2 → 89/6 | clip:1 gain:0.5 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ 29/2 → 89/6 | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ (29/2 → 15/1) ⇝ 91/6 | gain:0.353168139095 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037 ]", + "[ (29/2 → 15/1) ⇝ 31/2 | gain:0.353168139095 clip:1 note:G5 s:piano release:0.1 pan:0.615740740741 ]", + "[ (29/2 → 15/1) ⇝ 31/2 | gain:0.176584069547 clip:1 note:F7 s:piano release:0.1 pan:0.717592592593 ]", + "[ (29/2 → 15/1) ⇝ 33/2 | gain:0.353168139095 clip:1 note:F4 s:piano release:0.1 pan:0.550925925926 ]", + "[ (29/2 → 15/1) ⇝ 33/2 | gain:0.353168139095 clip:1 note:A4 s:piano release:0.1 pan:0.569444444444 ]", + "[ (29/2 → 15/1) ⇝ 33/2 | gain:0.353168139095 clip:1 note:Eb5 s:piano release:0.1 pan:0.597222222222 ]", + "[ 44/3 → 15/1 | clip:1 gain:1 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 44/3 → 15/1 | clip:1 gain:0.25 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ (44/3 → 15/1) ⇝ 46/3 | gain:0.706759541611 clip:1 note:F2 s:piano release:0.1 pan:0.439814814815 ]", + "[ (89/6 → 15/1) ⇝ 91/6 | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ (89/6 → 15/1) ⇝ 91/6 | clip:1 gain:0.125 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ (89/6 → 15/1) ⇝ 31/2 | gain:0.17677418484 clip:1 note:F5 s:piano release:0.1 pan:0.606481481481 ]", + "[ 29/2 ⇜ (15/1 → 91/6) | gain:0.353168139095 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037 ]", + "[ 89/6 ⇜ (15/1 → 91/6) | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 89/6 ⇜ (15/1 → 91/6) | clip:1 gain:0.125 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ 44/3 ⇜ (15/1 → 46/3) | gain:0.706759541611 clip:1 note:F2 s:piano release:0.1 pan:0.439814814815 ]", + "[ 15/1 → 46/3 | clip:1 gain:1 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ 15/1 → 46/3 | clip:1 gain:0.25 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 27/2 ⇜ (15/1 → 31/2) | gain:0.175407795646 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037 ]", + "[ 27/2 ⇜ (15/1 → 31/2) | gain:0.175407795646 clip:1 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ 27/2 ⇜ (15/1 → 31/2) | gain:0.175407795646 clip:1 note:Eb7 s:piano release:0.1 pan:0.708333333333 ]", + "[ 29/2 ⇜ (15/1 → 31/2) | gain:0.353168139095 clip:1 note:G5 s:piano release:0.1 pan:0.615740740741 ]", + "[ 29/2 ⇜ (15/1 → 31/2) | gain:0.176584069547 clip:1 note:F7 s:piano release:0.1 pan:0.717592592593 ]", + "[ 89/6 ⇜ (15/1 → 31/2) | gain:0.17677418484 clip:1 note:F5 s:piano release:0.1 pan:0.606481481481 ]", + "[ 15/1 → 47/3 | gain:0.235785292338 clip:1 note:F4 s:piano release:0.1 pan:0.550925925926 ]", + "[ 14/1 ⇜ (15/1 → 16/1) | gain:0.704480938564 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037 ]", + "[ 14/1 ⇜ (15/1 → 16/1) | gain:0.704480938564 clip:1 note:A3 s:piano release:0.1 pan:0.513888888889 ]", + "[ 14/1 ⇜ (15/1 → 16/1) | gain:0.704480938564 clip:1 note:Eb4 s:piano release:0.1 pan:0.541666666667 ]", + "[ 29/2 ⇜ (15/1 → 16/1) ⇝ 33/2 | gain:0.353168139095 clip:1 note:F4 s:piano release:0.1 pan:0.550925925926 ]", + "[ 29/2 ⇜ (15/1 → 16/1) ⇝ 33/2 | gain:0.353168139095 clip:1 note:A4 s:piano release:0.1 pan:0.569444444444 ]", + "[ 29/2 ⇜ (15/1 → 16/1) ⇝ 33/2 | gain:0.353168139095 clip:1 note:Eb5 s:piano release:0.1 pan:0.597222222222 ]", + "[ 15/1 → 16/1 | gain:0.707355877013 clip:1 note:F4 s:piano release:0.1 pan:0.550925925926 ]", + "[ 15/1 → 16/1 | gain:0.235785292338 clip:1 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ (15/1 → 16/1) ⇝ 17/1 | gain:0.235785292338 clip:1 note:F5 s:piano release:0.1 pan:0.606481481481 ]", + "[ (15/1 → 16/1) ⇝ 17/1 | gain:0.235785292338 clip:1 note:A5 s:piano release:0.1 pan:0.625 ]", + "[ (15/1 → 16/1) ⇝ 17/1 | gain:0.235785292338 clip:1 note:Eb6 s:piano release:0.1 pan:0.652777777778 ]", + "[ 91/6 → 31/2 | clip:1 gain:0.5 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ 91/6 → 31/2 | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 91/6 → 95/6 | gain:0.353772856265 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037 ]", + "[ 46/3 → 47/3 | clip:1 gain:1 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 46/3 → 47/3 | clip:1 gain:0.25 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ 46/3 → 16/1 | gain:0.707675774614 clip:1 note:F2 s:piano release:0.1 pan:0.439814814815 ]", + "[ 31/2 → 95/6 | clip:1 gain:0.5 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ 31/2 → 95/6 | clip:1 gain:0.125 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ (31/2 → 16/1) ⇝ 97/6 | gain:0.176939095262 clip:1 note:F5 s:piano release:0.1 pan:0.606481481481 ]", + "[ (31/2 → 16/1) ⇝ 33/2 | gain:0.353878190525 clip:1 note:F5 s:piano release:0.1 pan:0.606481481481 ]", + "[ (31/2 → 16/1) ⇝ 33/2 | gain:0.176939095262 clip:1 note:G7 s:piano release:0.1 pan:0.726851851852 ]", + "[ (31/2 → 16/1) ⇝ 35/2 | gain:0.176939095262 clip:1 note:F6 s:piano release:0.1 pan:0.662037037037 ]", + "[ (31/2 → 16/1) ⇝ 35/2 | gain:0.176939095262 clip:1 note:A6 s:piano release:0.1 pan:0.680555555556 ]", + "[ (31/2 → 16/1) ⇝ 35/2 | gain:0.176939095262 clip:1 note:Eb7 s:piano release:0.1 pan:0.708333333333 ]", + "[ 47/3 → 16/1 | clip:1 gain:1 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ 47/3 → 16/1 | clip:1 gain:0.25 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ (47/3 → 16/1) ⇝ 49/3 | gain:0.235932885688 clip:1 note:F4 s:piano release:0.1 pan:0.550925925926 ]", + "[ (95/6 → 16/1) ⇝ 97/6 | clip:1 gain:0.5 note:C7 s:piano release:0.1 pan:0.694444444444 ]", + "[ (95/6 → 16/1) ⇝ 97/6 | clip:1 gain:0.125 note:G6 s:piano release:0.1 pan:0.671296296296 ]", + "[ (95/6 → 16/1) ⇝ 33/2 | gain:0.353907276838 clip:1 note:F3 s:piano release:0.1 pan:0.49537037037 ]", ] `; @@ -6897,20 +6897,20 @@ exports[`renders tunes > tune: flatrave 1`] = ` [ "[ 0/1 → 1/8 | s:hh n:1 speed:0.5 delay:0.5 end:0.02 bank:RolandTR909 room:0.5 gain:0.4 ]", "[ 0/1 → 1/2 | s:bd bank:RolandTR909 ]", - "[ 1/8 → 1/4 | s:hh n:1 end:0.02000058072071123 bank:RolandTR909 room:0.5 gain:0.4 ]", - "[ 1/8 → 1/4 | s:hh n:1 end:0.02000058072071123 bank:RolandTR909 room:0.5 gain:0.4 ]", + "[ 1/8 → 1/4 | s:hh n:1 end:0.020000580721 bank:RolandTR909 room:0.5 gain:0.4 ]", + "[ 1/8 → 1/4 | s:hh n:1 end:0.020000580721 bank:RolandTR909 room:0.5 gain:0.4 ]", "[ 1/8 → 1/4 | note:G1 s:sawtooth decay:0.1 sustain:0 lpattack:0.1 lpenv:-4 cutoff:800 resonance:8 ]", - "[ 1/4 → 3/8 | s:hh n:1 end:0.02000453637431655 bank:RolandTR909 room:0.5 gain:0.4 ]", - "[ 1/4 → 3/8 | s:hh n:1 end:0.02000453637431655 bank:RolandTR909 room:0.5 gain:0.4 ]", + "[ 1/4 → 3/8 | s:hh n:1 end:0.020004536374 bank:RolandTR909 room:0.5 gain:0.4 ]", + "[ 1/4 → 3/8 | s:hh n:1 end:0.020004536374 bank:RolandTR909 room:0.5 gain:0.4 ]", "[ 1/4 → 3/8 | note:G1 s:sawtooth decay:0.1 sustain:0 lpattack:0.1 lpenv:-4 cutoff:800 resonance:8 ]", - "[ 3/8 → 1/2 | s:hh n:1 end:0.02001494577056579 bank:RolandTR909 room:0.5 gain:0.4 ]", + "[ 3/8 → 1/2 | s:hh n:1 end:0.020014945771 bank:RolandTR909 room:0.5 gain:0.4 ]", "[ 1/2 → 5/8 | note:G1 s:sawtooth decay:0.1 sustain:0 lpattack:0.1 lpenv:-4 cutoff:800 resonance:8 ]", "[ 1/2 → 1/1 | s:bd bank:RolandTR909 ]", "[ 1/2 → 1/1 | s:cp bank:RolandTR909 ]", "[ 1/2 → 1/1 | s:sd bank:RolandTR909 ]", "[ 5/8 → 3/4 | note:G1 s:sawtooth decay:0.1 sustain:0 lpattack:0.1 lpenv:-4 cutoff:800 resonance:8 ]", - "[ 7/8 → 1/1 | s:hh n:1 end:0.020171942481159617 bank:RolandTR909 room:0.5 gain:0.4 ]", - "[ 7/8 → 1/1 | s:hh n:1 end:0.020171942481159617 bank:RolandTR909 room:0.5 gain:0.4 ]", + "[ 7/8 → 1/1 | s:hh n:1 end:0.020171942481 bank:RolandTR909 room:0.5 gain:0.4 ]", + "[ 7/8 → 1/1 | s:hh n:1 end:0.020171942481 bank:RolandTR909 room:0.5 gain:0.4 ]", "[ 7/8 → 1/1 | note:G1 s:sawtooth decay:0.1 sustain:0 lpattack:0.1 lpenv:-4 cutoff:800 resonance:8 ]", ] `; @@ -7069,118 +7069,118 @@ exports[`renders tunes > tune: giantSteps 1`] = ` exports[`renders tunes > tune: goodTimes 1`] = ` [ - "[ 0/1 → 1/4 | note:52 gain:0.48 clip:2 s:piano release:0.1 pan:0.4907407407407407 ]", - "[ 1/4 → 1/2 | note:40 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.4351851851851852 ]", - "[ 1/2 → 3/4 | note:52 gain:0.48 clip:2 s:piano release:0.1 pan:0.4907407407407407 ]", - "[ 1/2 → 3/4 | note:55 gain:0.48 clip:2 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 1/2 → 3/4 | note:59 gain:0.48 clip:2 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 1/2 → 3/4 | note:40 gain:0.48 clip:2 s:piano release:0.1 pan:0.4351851851851852 ]", - "[ 1/1 → 5/4 | note:55 gain:0.48 clip:2 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 1/1 → 5/4 | note:59 gain:0.48 clip:2 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 1/1 → 5/4 | note:40 gain:0.48 clip:2 s:piano release:0.1 pan:0.4351851851851852 ]", - "[ 5/4 → 3/2 | note:52 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.4907407407407407 ]", - "[ 5/4 → 3/2 | note:40 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.4351851851851852 ]", - "[ 7/4 → 2/1 | note:55 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 7/4 → 2/1 | note:59 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 7/4 → 2/1 | note:40 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.4351851851851852 ]", + "[ 0/1 → 1/4 | note:52 gain:0.48 clip:2 s:piano release:0.1 pan:0.490740740741 ]", + "[ 1/4 → 1/2 | note:40 gain:0.56 clip:2 s:piano release:0.1 pan:0.435185185185 ]", + "[ 1/2 → 3/4 | note:52 gain:0.48 clip:2 s:piano release:0.1 pan:0.490740740741 ]", + "[ 1/2 → 3/4 | note:55 gain:0.48 clip:2 s:piano release:0.1 pan:0.50462962963 ]", + "[ 1/2 → 3/4 | note:59 gain:0.48 clip:2 s:piano release:0.1 pan:0.523148148148 ]", + "[ 1/2 → 3/4 | note:40 gain:0.48 clip:2 s:piano release:0.1 pan:0.435185185185 ]", + "[ 1/1 → 5/4 | note:55 gain:0.48 clip:2 s:piano release:0.1 pan:0.50462962963 ]", + "[ 1/1 → 5/4 | note:59 gain:0.48 clip:2 s:piano release:0.1 pan:0.523148148148 ]", + "[ 1/1 → 5/4 | note:40 gain:0.48 clip:2 s:piano release:0.1 pan:0.435185185185 ]", + "[ 5/4 → 3/2 | note:52 gain:0.56 clip:2 s:piano release:0.1 pan:0.490740740741 ]", + "[ 5/4 → 3/2 | note:40 gain:0.56 clip:2 s:piano release:0.1 pan:0.435185185185 ]", + "[ 7/4 → 2/1 | note:55 gain:0.56 clip:2 s:piano release:0.1 pan:0.50462962963 ]", + "[ 7/4 → 2/1 | note:59 gain:0.56 clip:2 s:piano release:0.1 pan:0.523148148148 ]", + "[ 7/4 → 2/1 | note:40 gain:0.56 clip:2 s:piano release:0.1 pan:0.435185185185 ]", "[ 2/1 → 9/4 | note:54 gain:0.48 clip:2 s:piano release:0.1 pan:0.5 ]", - "[ 9/4 → 5/2 | note:47 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.46759259259259256 ]", + "[ 9/4 → 5/2 | note:47 gain:0.56 clip:2 s:piano release:0.1 pan:0.467592592593 ]", "[ 5/2 → 11/4 | note:54 gain:0.48 clip:2 s:piano release:0.1 pan:0.5 ]", - "[ 5/2 → 11/4 | note:57 gain:0.48 clip:2 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 5/2 → 11/4 | note:61 gain:0.48 clip:2 s:piano release:0.1 pan:0.5324074074074074 ]", - "[ 5/2 → 11/4 | note:47 gain:0.48 clip:2 s:piano release:0.1 pan:0.46759259259259256 ]", - "[ 3/1 → 13/4 | note:57 gain:0.48 clip:2 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 3/1 → 13/4 | note:61 gain:0.48 clip:2 s:piano release:0.1 pan:0.5324074074074074 ]", - "[ 3/1 → 13/4 | note:47 gain:0.48 clip:2 s:piano release:0.1 pan:0.46759259259259256 ]", - "[ 13/4 → 7/2 | note:54 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.5 ]", - "[ 13/4 → 7/2 | note:47 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.46759259259259256 ]", - "[ 15/4 → 4/1 | note:57 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 15/4 → 4/1 | note:61 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.5324074074074074 ]", - "[ 15/4 → 4/1 | note:47 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.46759259259259256 ]", - "[ 4/1 → 17/4 | note:55 gain:0.48 clip:2 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 17/4 → 9/2 | note:40 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.4351851851851852 ]", - "[ 9/2 → 19/4 | note:55 gain:0.48 clip:2 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 9/2 → 19/4 | note:59 gain:0.48 clip:2 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 9/2 → 19/4 | note:62 gain:0.48 clip:2 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 9/2 → 19/4 | note:40 gain:0.48 clip:2 s:piano release:0.1 pan:0.4351851851851852 ]", - "[ 5/1 → 21/4 | note:59 gain:0.48 clip:2 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 5/1 → 21/4 | note:62 gain:0.48 clip:2 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 5/1 → 21/4 | note:40 gain:0.48 clip:2 s:piano release:0.1 pan:0.4351851851851852 ]", - "[ 21/4 → 11/2 | note:55 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 21/4 → 11/2 | note:40 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.4351851851851852 ]", - "[ 23/4 → 6/1 | note:59 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 23/4 → 6/1 | note:62 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 23/4 → 6/1 | note:40 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.4351851851851852 ]", - "[ 6/1 → 25/4 | note:57 gain:0.48 clip:2 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 25/4 → 13/2 | note:47 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.46759259259259256 ]", - "[ 13/2 → 27/4 | note:57 gain:0.48 clip:2 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 13/2 → 27/4 | note:61 gain:0.48 clip:2 s:piano release:0.1 pan:0.5324074074074074 ]", - "[ 13/2 → 27/4 | note:64 gain:0.48 clip:2 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 13/2 → 27/4 | note:47 gain:0.48 clip:2 s:piano release:0.1 pan:0.46759259259259256 ]", - "[ 7/1 → 29/4 | note:61 gain:0.48 clip:2 s:piano release:0.1 pan:0.5324074074074074 ]", - "[ 7/1 → 29/4 | note:64 gain:0.48 clip:2 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 7/1 → 29/4 | note:47 gain:0.48 clip:2 s:piano release:0.1 pan:0.46759259259259256 ]", - "[ 29/4 → 15/2 | note:57 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 29/4 → 15/2 | note:47 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.46759259259259256 ]", - "[ 31/4 → 8/1 | note:61 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.5324074074074074 ]", - "[ 31/4 → 8/1 | note:64 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.5462962962962963 ]", - "[ 31/4 → 8/1 | note:47 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.46759259259259256 ]", - "[ 8/1 → 33/4 | note:50 gain:0.48 clip:2 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ 33/4 → 17/2 | note:38 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.42592592592592593 ]", - "[ 17/2 → 35/4 | note:50 gain:0.48 clip:2 s:piano release:0.1 pan:0.4814814814814815 ]", + "[ 5/2 → 11/4 | note:57 gain:0.48 clip:2 s:piano release:0.1 pan:0.513888888889 ]", + "[ 5/2 → 11/4 | note:61 gain:0.48 clip:2 s:piano release:0.1 pan:0.532407407407 ]", + "[ 5/2 → 11/4 | note:47 gain:0.48 clip:2 s:piano release:0.1 pan:0.467592592593 ]", + "[ 3/1 → 13/4 | note:57 gain:0.48 clip:2 s:piano release:0.1 pan:0.513888888889 ]", + "[ 3/1 → 13/4 | note:61 gain:0.48 clip:2 s:piano release:0.1 pan:0.532407407407 ]", + "[ 3/1 → 13/4 | note:47 gain:0.48 clip:2 s:piano release:0.1 pan:0.467592592593 ]", + "[ 13/4 → 7/2 | note:54 gain:0.56 clip:2 s:piano release:0.1 pan:0.5 ]", + "[ 13/4 → 7/2 | note:47 gain:0.56 clip:2 s:piano release:0.1 pan:0.467592592593 ]", + "[ 15/4 → 4/1 | note:57 gain:0.56 clip:2 s:piano release:0.1 pan:0.513888888889 ]", + "[ 15/4 → 4/1 | note:61 gain:0.56 clip:2 s:piano release:0.1 pan:0.532407407407 ]", + "[ 15/4 → 4/1 | note:47 gain:0.56 clip:2 s:piano release:0.1 pan:0.467592592593 ]", + "[ 4/1 → 17/4 | note:55 gain:0.48 clip:2 s:piano release:0.1 pan:0.50462962963 ]", + "[ 17/4 → 9/2 | note:40 gain:0.56 clip:2 s:piano release:0.1 pan:0.435185185185 ]", + "[ 9/2 → 19/4 | note:55 gain:0.48 clip:2 s:piano release:0.1 pan:0.50462962963 ]", + "[ 9/2 → 19/4 | note:59 gain:0.48 clip:2 s:piano release:0.1 pan:0.523148148148 ]", + "[ 9/2 → 19/4 | note:62 gain:0.48 clip:2 s:piano release:0.1 pan:0.537037037037 ]", + "[ 9/2 → 19/4 | note:40 gain:0.48 clip:2 s:piano release:0.1 pan:0.435185185185 ]", + "[ 5/1 → 21/4 | note:59 gain:0.48 clip:2 s:piano release:0.1 pan:0.523148148148 ]", + "[ 5/1 → 21/4 | note:62 gain:0.48 clip:2 s:piano release:0.1 pan:0.537037037037 ]", + "[ 5/1 → 21/4 | note:40 gain:0.48 clip:2 s:piano release:0.1 pan:0.435185185185 ]", + "[ 21/4 → 11/2 | note:55 gain:0.56 clip:2 s:piano release:0.1 pan:0.50462962963 ]", + "[ 21/4 → 11/2 | note:40 gain:0.56 clip:2 s:piano release:0.1 pan:0.435185185185 ]", + "[ 23/4 → 6/1 | note:59 gain:0.56 clip:2 s:piano release:0.1 pan:0.523148148148 ]", + "[ 23/4 → 6/1 | note:62 gain:0.56 clip:2 s:piano release:0.1 pan:0.537037037037 ]", + "[ 23/4 → 6/1 | note:40 gain:0.56 clip:2 s:piano release:0.1 pan:0.435185185185 ]", + "[ 6/1 → 25/4 | note:57 gain:0.48 clip:2 s:piano release:0.1 pan:0.513888888889 ]", + "[ 25/4 → 13/2 | note:47 gain:0.56 clip:2 s:piano release:0.1 pan:0.467592592593 ]", + "[ 13/2 → 27/4 | note:57 gain:0.48 clip:2 s:piano release:0.1 pan:0.513888888889 ]", + "[ 13/2 → 27/4 | note:61 gain:0.48 clip:2 s:piano release:0.1 pan:0.532407407407 ]", + "[ 13/2 → 27/4 | note:64 gain:0.48 clip:2 s:piano release:0.1 pan:0.546296296296 ]", + "[ 13/2 → 27/4 | note:47 gain:0.48 clip:2 s:piano release:0.1 pan:0.467592592593 ]", + "[ 7/1 → 29/4 | note:61 gain:0.48 clip:2 s:piano release:0.1 pan:0.532407407407 ]", + "[ 7/1 → 29/4 | note:64 gain:0.48 clip:2 s:piano release:0.1 pan:0.546296296296 ]", + "[ 7/1 → 29/4 | note:47 gain:0.48 clip:2 s:piano release:0.1 pan:0.467592592593 ]", + "[ 29/4 → 15/2 | note:57 gain:0.56 clip:2 s:piano release:0.1 pan:0.513888888889 ]", + "[ 29/4 → 15/2 | note:47 gain:0.56 clip:2 s:piano release:0.1 pan:0.467592592593 ]", + "[ 31/4 → 8/1 | note:61 gain:0.56 clip:2 s:piano release:0.1 pan:0.532407407407 ]", + "[ 31/4 → 8/1 | note:64 gain:0.56 clip:2 s:piano release:0.1 pan:0.546296296296 ]", + "[ 31/4 → 8/1 | note:47 gain:0.56 clip:2 s:piano release:0.1 pan:0.467592592593 ]", + "[ 8/1 → 33/4 | note:50 gain:0.48 clip:2 s:piano release:0.1 pan:0.481481481481 ]", + "[ 33/4 → 17/2 | note:38 gain:0.56 clip:2 s:piano release:0.1 pan:0.425925925926 ]", + "[ 17/2 → 35/4 | note:50 gain:0.48 clip:2 s:piano release:0.1 pan:0.481481481481 ]", "[ 17/2 → 35/4 | note:54 gain:0.48 clip:2 s:piano release:0.1 pan:0.5 ]", - "[ 17/2 → 35/4 | note:57 gain:0.48 clip:2 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 17/2 → 35/4 | note:38 gain:0.48 clip:2 s:piano release:0.1 pan:0.42592592592592593 ]", + "[ 17/2 → 35/4 | note:57 gain:0.48 clip:2 s:piano release:0.1 pan:0.513888888889 ]", + "[ 17/2 → 35/4 | note:38 gain:0.48 clip:2 s:piano release:0.1 pan:0.425925925926 ]", "[ 9/1 → 37/4 | note:54 gain:0.48 clip:2 s:piano release:0.1 pan:0.5 ]", - "[ 9/1 → 37/4 | note:57 gain:0.48 clip:2 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 9/1 → 37/4 | note:38 gain:0.48 clip:2 s:piano release:0.1 pan:0.42592592592592593 ]", - "[ 37/4 → 19/2 | note:50 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.4814814814814815 ]", - "[ 37/4 → 19/2 | note:38 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.42592592592592593 ]", - "[ 39/4 → 10/1 | note:54 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.5 ]", - "[ 39/4 → 10/1 | note:57 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 39/4 → 10/1 | note:38 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.42592592592592593 ]", - "[ 10/1 → 41/4 | note:52 gain:0.48 clip:2 s:piano release:0.1 pan:0.4907407407407407 ]", - "[ 41/4 → 21/2 | note:45 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.45833333333333337 ]", - "[ 21/2 → 43/4 | note:52 gain:0.48 clip:2 s:piano release:0.1 pan:0.4907407407407407 ]", - "[ 21/2 → 43/4 | note:55 gain:0.48 clip:2 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 21/2 → 43/4 | note:59 gain:0.48 clip:2 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 21/2 → 43/4 | note:45 gain:0.48 clip:2 s:piano release:0.1 pan:0.45833333333333337 ]", - "[ 11/1 → 45/4 | note:55 gain:0.48 clip:2 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 11/1 → 45/4 | note:59 gain:0.48 clip:2 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 11/1 → 45/4 | note:45 gain:0.48 clip:2 s:piano release:0.1 pan:0.45833333333333337 ]", - "[ 45/4 → 23/2 | note:52 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.4907407407407407 ]", - "[ 45/4 → 23/2 | note:45 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.45833333333333337 ]", - "[ 47/4 → 12/1 | note:55 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 47/4 → 12/1 | note:59 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 47/4 → 12/1 | note:45 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.45833333333333337 ]", + "[ 9/1 → 37/4 | note:57 gain:0.48 clip:2 s:piano release:0.1 pan:0.513888888889 ]", + "[ 9/1 → 37/4 | note:38 gain:0.48 clip:2 s:piano release:0.1 pan:0.425925925926 ]", + "[ 37/4 → 19/2 | note:50 gain:0.56 clip:2 s:piano release:0.1 pan:0.481481481481 ]", + "[ 37/4 → 19/2 | note:38 gain:0.56 clip:2 s:piano release:0.1 pan:0.425925925926 ]", + "[ 39/4 → 10/1 | note:54 gain:0.56 clip:2 s:piano release:0.1 pan:0.5 ]", + "[ 39/4 → 10/1 | note:57 gain:0.56 clip:2 s:piano release:0.1 pan:0.513888888889 ]", + "[ 39/4 → 10/1 | note:38 gain:0.56 clip:2 s:piano release:0.1 pan:0.425925925926 ]", + "[ 10/1 → 41/4 | note:52 gain:0.48 clip:2 s:piano release:0.1 pan:0.490740740741 ]", + "[ 41/4 → 21/2 | note:45 gain:0.56 clip:2 s:piano release:0.1 pan:0.458333333333 ]", + "[ 21/2 → 43/4 | note:52 gain:0.48 clip:2 s:piano release:0.1 pan:0.490740740741 ]", + "[ 21/2 → 43/4 | note:55 gain:0.48 clip:2 s:piano release:0.1 pan:0.50462962963 ]", + "[ 21/2 → 43/4 | note:59 gain:0.48 clip:2 s:piano release:0.1 pan:0.523148148148 ]", + "[ 21/2 → 43/4 | note:45 gain:0.48 clip:2 s:piano release:0.1 pan:0.458333333333 ]", + "[ 11/1 → 45/4 | note:55 gain:0.48 clip:2 s:piano release:0.1 pan:0.50462962963 ]", + "[ 11/1 → 45/4 | note:59 gain:0.48 clip:2 s:piano release:0.1 pan:0.523148148148 ]", + "[ 11/1 → 45/4 | note:45 gain:0.48 clip:2 s:piano release:0.1 pan:0.458333333333 ]", + "[ 45/4 → 23/2 | note:52 gain:0.56 clip:2 s:piano release:0.1 pan:0.490740740741 ]", + "[ 45/4 → 23/2 | note:45 gain:0.56 clip:2 s:piano release:0.1 pan:0.458333333333 ]", + "[ 47/4 → 12/1 | note:55 gain:0.56 clip:2 s:piano release:0.1 pan:0.50462962963 ]", + "[ 47/4 → 12/1 | note:59 gain:0.56 clip:2 s:piano release:0.1 pan:0.523148148148 ]", + "[ 47/4 → 12/1 | note:45 gain:0.56 clip:2 s:piano release:0.1 pan:0.458333333333 ]", "[ 12/1 → 49/4 | note:54 gain:0.48 clip:2 s:piano release:0.1 pan:0.5 ]", - "[ 49/4 → 25/2 | note:38 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.42592592592592593 ]", + "[ 49/4 → 25/2 | note:38 gain:0.56 clip:2 s:piano release:0.1 pan:0.425925925926 ]", "[ 25/2 → 51/4 | note:54 gain:0.48 clip:2 s:piano release:0.1 pan:0.5 ]", - "[ 25/2 → 51/4 | note:57 gain:0.48 clip:2 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 25/2 → 51/4 | note:61 gain:0.48 clip:2 s:piano release:0.1 pan:0.5324074074074074 ]", - "[ 25/2 → 51/4 | note:38 gain:0.48 clip:2 s:piano release:0.1 pan:0.42592592592592593 ]", - "[ 13/1 → 53/4 | note:57 gain:0.48 clip:2 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 13/1 → 53/4 | note:61 gain:0.48 clip:2 s:piano release:0.1 pan:0.5324074074074074 ]", - "[ 13/1 → 53/4 | note:38 gain:0.48 clip:2 s:piano release:0.1 pan:0.42592592592592593 ]", - "[ 53/4 → 27/2 | note:54 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.5 ]", - "[ 53/4 → 27/2 | note:38 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.42592592592592593 ]", - "[ 55/4 → 14/1 | note:57 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.5138888888888888 ]", - "[ 55/4 → 14/1 | note:61 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.5324074074074074 ]", - "[ 55/4 → 14/1 | note:38 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.42592592592592593 ]", - "[ 14/1 → 57/4 | note:55 gain:0.48 clip:2 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 57/4 → 29/2 | note:45 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.45833333333333337 ]", - "[ 29/2 → 59/4 | note:55 gain:0.48 clip:2 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 29/2 → 59/4 | note:59 gain:0.48 clip:2 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 29/2 → 59/4 | note:62 gain:0.48 clip:2 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 29/2 → 59/4 | note:45 gain:0.48 clip:2 s:piano release:0.1 pan:0.45833333333333337 ]", - "[ 15/1 → 61/4 | note:59 gain:0.48 clip:2 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 15/1 → 61/4 | note:62 gain:0.48 clip:2 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 15/1 → 61/4 | note:45 gain:0.48 clip:2 s:piano release:0.1 pan:0.45833333333333337 ]", - "[ 61/4 → 31/2 | note:55 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.5046296296296297 ]", - "[ 61/4 → 31/2 | note:45 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.45833333333333337 ]", - "[ 63/4 → 16/1 | note:59 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.5231481481481481 ]", - "[ 63/4 → 16/1 | note:62 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.537037037037037 ]", - "[ 63/4 → 16/1 | note:45 gain:0.5599999999999999 clip:2 s:piano release:0.1 pan:0.45833333333333337 ]", + "[ 25/2 → 51/4 | note:57 gain:0.48 clip:2 s:piano release:0.1 pan:0.513888888889 ]", + "[ 25/2 → 51/4 | note:61 gain:0.48 clip:2 s:piano release:0.1 pan:0.532407407407 ]", + "[ 25/2 → 51/4 | note:38 gain:0.48 clip:2 s:piano release:0.1 pan:0.425925925926 ]", + "[ 13/1 → 53/4 | note:57 gain:0.48 clip:2 s:piano release:0.1 pan:0.513888888889 ]", + "[ 13/1 → 53/4 | note:61 gain:0.48 clip:2 s:piano release:0.1 pan:0.532407407407 ]", + "[ 13/1 → 53/4 | note:38 gain:0.48 clip:2 s:piano release:0.1 pan:0.425925925926 ]", + "[ 53/4 → 27/2 | note:54 gain:0.56 clip:2 s:piano release:0.1 pan:0.5 ]", + "[ 53/4 → 27/2 | note:38 gain:0.56 clip:2 s:piano release:0.1 pan:0.425925925926 ]", + "[ 55/4 → 14/1 | note:57 gain:0.56 clip:2 s:piano release:0.1 pan:0.513888888889 ]", + "[ 55/4 → 14/1 | note:61 gain:0.56 clip:2 s:piano release:0.1 pan:0.532407407407 ]", + "[ 55/4 → 14/1 | note:38 gain:0.56 clip:2 s:piano release:0.1 pan:0.425925925926 ]", + "[ 14/1 → 57/4 | note:55 gain:0.48 clip:2 s:piano release:0.1 pan:0.50462962963 ]", + "[ 57/4 → 29/2 | note:45 gain:0.56 clip:2 s:piano release:0.1 pan:0.458333333333 ]", + "[ 29/2 → 59/4 | note:55 gain:0.48 clip:2 s:piano release:0.1 pan:0.50462962963 ]", + "[ 29/2 → 59/4 | note:59 gain:0.48 clip:2 s:piano release:0.1 pan:0.523148148148 ]", + "[ 29/2 → 59/4 | note:62 gain:0.48 clip:2 s:piano release:0.1 pan:0.537037037037 ]", + "[ 29/2 → 59/4 | note:45 gain:0.48 clip:2 s:piano release:0.1 pan:0.458333333333 ]", + "[ 15/1 → 61/4 | note:59 gain:0.48 clip:2 s:piano release:0.1 pan:0.523148148148 ]", + "[ 15/1 → 61/4 | note:62 gain:0.48 clip:2 s:piano release:0.1 pan:0.537037037037 ]", + "[ 15/1 → 61/4 | note:45 gain:0.48 clip:2 s:piano release:0.1 pan:0.458333333333 ]", + "[ 61/4 → 31/2 | note:55 gain:0.56 clip:2 s:piano release:0.1 pan:0.50462962963 ]", + "[ 61/4 → 31/2 | note:45 gain:0.56 clip:2 s:piano release:0.1 pan:0.458333333333 ]", + "[ 63/4 → 16/1 | note:59 gain:0.56 clip:2 s:piano release:0.1 pan:0.523148148148 ]", + "[ 63/4 → 16/1 | note:62 gain:0.56 clip:2 s:piano release:0.1 pan:0.537037037037 ]", + "[ 63/4 → 16/1 | note:45 gain:0.56 clip:2 s:piano release:0.1 pan:0.458333333333 ]", ] `; @@ -7205,12 +7205,12 @@ exports[`renders tunes > tune: juxUndTollerei 1`] = ` [ "[ 0/1 → 1/4 | note:c3 s:sawtooth pan:0 cutoff:1100 lpattack:0.2 lpenv:-2 decay:0.05 sustain:0 room:0.6 delay:0.5 delaytime:0.1 delayfeedback:0.4 ]", "[ 0/1 → 1/4 | note:bb3 s:sawtooth pan:1 color:green cutoff:1100 lpattack:0.2 lpenv:-2 decay:0.05 sustain:0 room:0.6 delay:0.5 delaytime:0.1 delayfeedback:0.4 ]", - "[ 1/4 → 1/2 | note:eb3 s:sawtooth pan:0 cutoff:1275.5812898145155 lpattack:0.2 lpenv:-2 decay:0.05 sustain:0 room:0.6 delay:0.5 delaytime:0.1 delayfeedback:0.4 ]", - "[ 1/4 → 1/2 | note:g3 s:sawtooth pan:1 color:green cutoff:1275.5812898145155 lpattack:0.2 lpenv:-2 decay:0.05 sustain:0 room:0.6 delay:0.5 delaytime:0.1 delayfeedback:0.4 ]", - "[ 1/2 → 3/4 | note:g3 s:sawtooth pan:0 cutoff:1444.4150891285808 lpattack:0.2 lpenv:-2 decay:0.05 sustain:0 room:0.6 delay:0.5 delaytime:0.1 delayfeedback:0.4 ]", - "[ 1/2 → 3/4 | note:eb3 s:sawtooth pan:1 color:green cutoff:1444.4150891285808 lpattack:0.2 lpenv:-2 decay:0.05 sustain:0 room:0.6 delay:0.5 delaytime:0.1 delayfeedback:0.4 ]", - "[ (101/200 → 1/1) ⇝ 201/200 | note:55 s:triangle pan:0 cutoff:1447.6776848789743 lpattack:0.2 lpenv:-2 decay:0.05 sustain:0 room:0.6 delay:0.5 delaytime:0.1 delayfeedback:0.4 ]", - "[ (101/200 → 1/1) ⇝ 201/200 | note:65 s:triangle pan:1 color:green cutoff:1447.6776848789743 lpattack:0.2 lpenv:-2 decay:0.05 sustain:0 room:0.6 delay:0.5 delaytime:0.1 delayfeedback:0.4 ]", + "[ 1/4 → 1/2 | note:eb3 s:sawtooth pan:0 cutoff:1275.581289814515 lpattack:0.2 lpenv:-2 decay:0.05 sustain:0 room:0.6 delay:0.5 delaytime:0.1 delayfeedback:0.4 ]", + "[ 1/4 → 1/2 | note:g3 s:sawtooth pan:1 color:green cutoff:1275.581289814515 lpattack:0.2 lpenv:-2 decay:0.05 sustain:0 room:0.6 delay:0.5 delaytime:0.1 delayfeedback:0.4 ]", + "[ 1/2 → 3/4 | note:g3 s:sawtooth pan:0 cutoff:1444.415089128581 lpattack:0.2 lpenv:-2 decay:0.05 sustain:0 room:0.6 delay:0.5 delaytime:0.1 delayfeedback:0.4 ]", + "[ 1/2 → 3/4 | note:eb3 s:sawtooth pan:1 color:green cutoff:1444.415089128581 lpattack:0.2 lpenv:-2 decay:0.05 sustain:0 room:0.6 delay:0.5 delaytime:0.1 delayfeedback:0.4 ]", + "[ (101/200 → 1/1) ⇝ 201/200 | note:55 s:triangle pan:0 cutoff:1447.677684878974 lpattack:0.2 lpenv:-2 decay:0.05 sustain:0 room:0.6 delay:0.5 delaytime:0.1 delayfeedback:0.4 ]", + "[ (101/200 → 1/1) ⇝ 201/200 | note:65 s:triangle pan:1 color:green cutoff:1447.677684878974 lpattack:0.2 lpenv:-2 decay:0.05 sustain:0 room:0.6 delay:0.5 delaytime:0.1 delayfeedback:0.4 ]", "[ 3/4 → 1/1 | note:bb3 s:sawtooth pan:0 cutoff:1600.013209717642 lpattack:0.2 lpenv:-2 decay:0.05 sustain:0 room:0.6 delay:0.5 delaytime:0.1 delayfeedback:0.4 ]", "[ 3/4 → 1/1 | note:c3 s:sawtooth pan:1 color:green cutoff:1600.013209717642 lpattack:0.2 lpenv:-2 decay:0.05 sustain:0 room:0.6 delay:0.5 delaytime:0.1 delayfeedback:0.4 ]", ] @@ -7248,10 +7248,10 @@ exports[`renders tunes > tune: loungeSponge 1`] = ` exports[`renders tunes > tune: meltingsubmarine 1`] = ` [ - "[ (0/1 → 1/16) ⇝ 3/16 | note:72.0716211320497 decay:0.1 sustain:0 s:triangle gain:0.0375 ]", - "[ (0/1 → 1/16) ⇝ 3/16 | note:72.1116211320497 decay:0.1 sustain:0 s:triangle gain:0.0375 ]", - "[ 0/1 → 3/16 | note:93.00417750226859 decay:0.1 sustain:0 s:triangle gain:0.075 ]", - "[ 0/1 → 3/16 | note:93.0441775022686 decay:0.1 sustain:0 s:triangle gain:0.075 ]", + "[ (0/1 → 1/16) ⇝ 3/16 | note:72.07162113205 decay:0.1 sustain:0 s:triangle gain:0.0375 ]", + "[ (0/1 → 1/16) ⇝ 3/16 | note:72.11162113205 decay:0.1 sustain:0 s:triangle gain:0.0375 ]", + "[ 0/1 → 3/16 | note:93.004177502269 decay:0.1 sustain:0 s:triangle gain:0.075 ]", + "[ 0/1 → 3/16 | note:93.044177502269 decay:0.1 sustain:0 s:triangle gain:0.075 ]", "[ (0/1 → 1/1) ⇝ 3/2 | s:bd n:5 speed:0.7 ]", "[ (0/1 → 1/1) ⇝ 3/2 | note:33 decay:0.15 sustain:0 s:sawtooth gain:0.4 cutoff:2650 lpattack:0.1 lpenv:-2 ]", "[ (0/1 → 1/1) ⇝ 3/2 | note:33.05 decay:0.15 sustain:0 s:sawtooth gain:0.4 cutoff:2650 lpattack:0.1 lpenv:-2 ]", @@ -7263,45 +7263,45 @@ exports[`renders tunes > tune: meltingsubmarine 1`] = ` "[ (0/1 → 1/1) ⇝ 3/2 | note:67.04 s:sawtooth gain:0.16 cutoff:500 attack:1 ]", "[ (0/1 → 1/1) ⇝ 3/2 | note:71 s:sawtooth gain:0.16 cutoff:500 attack:1 ]", "[ (0/1 → 1/1) ⇝ 3/2 | note:71.04 s:sawtooth gain:0.16 cutoff:500 attack:1 ]", - "[ 0/1 ⇜ (1/16 → 3/16) | note:93.0716211320497 decay:0.1 sustain:0 s:triangle gain:0.0375 ]", - "[ 0/1 ⇜ (1/16 → 3/16) | note:93.1116211320497 decay:0.1 sustain:0 s:triangle gain:0.0375 ]", - "[ 3/16 → 3/8 | note:69.00416990934514 decay:0.1 sustain:0 s:triangle gain:0.15 ]", - "[ 3/16 → 3/8 | note:69.04416990934514 decay:0.1 sustain:0 s:triangle gain:0.15 ]", - "[ 3/16 → 3/8 | note:93.00417750226859 decay:0.1 sustain:0 s:triangle gain:0.049999999999999996 ]", - "[ 3/16 → 3/8 | note:93.0441775022686 decay:0.1 sustain:0 s:triangle gain:0.049999999999999996 ]", - "[ (3/16 → 1/1) ⇝ 27/16 | note:45.00416990934514 decay:0.15 sustain:0 s:sawtooth gain:0.4 cutoff:2913.1165188427735 lpattack:0.1 lpenv:-2 ]", - "[ (3/16 → 1/1) ⇝ 27/16 | note:45.054169909345134 decay:0.15 sustain:0 s:sawtooth gain:0.4 cutoff:2913.1165188427735 lpattack:0.1 lpenv:-2 ]", - "[ (3/8 → 1/2) ⇝ 9/16 | note:69.02689036596712 decay:0.1 sustain:0 s:triangle gain:0.15 ]", - "[ (3/8 → 1/2) ⇝ 9/16 | note:69.06689036596713 decay:0.1 sustain:0 s:triangle gain:0.15 ]", - "[ 3/8 → 9/16 | note:69.00416990934514 decay:0.1 sustain:0 s:triangle gain:0.075 ]", - "[ 3/8 → 9/16 | note:69.04416990934514 decay:0.1 sustain:0 s:triangle gain:0.075 ]", - "[ 3/8 → 9/16 | note:93.00417750226859 decay:0.1 sustain:0 s:triangle gain:0.0375 ]", - "[ 3/8 → 9/16 | note:93.0441775022686 decay:0.1 sustain:0 s:triangle gain:0.0375 ]", - "[ 3/8 → 3/4 | s:hh27 speed:0.7107561463868478 ]", - "[ 3/8 ⇜ (1/2 → 9/16) | note:72.02689036596712 decay:0.1 sustain:0 s:triangle gain:0.15 ]", - "[ 3/8 ⇜ (1/2 → 9/16) | note:72.06689036596713 decay:0.1 sustain:0 s:triangle gain:0.15 ]", - "[ (9/16 → 11/16) ⇝ 3/4 | note:69.02689036596712 decay:0.1 sustain:0 s:triangle gain:0.075 ]", - "[ (9/16 → 11/16) ⇝ 3/4 | note:69.06689036596713 decay:0.1 sustain:0 s:triangle gain:0.075 ]", - "[ 9/16 → 3/4 | note:69.00416990934514 decay:0.1 sustain:0 s:triangle gain:0.049999999999999996 ]", - "[ 9/16 → 3/4 | note:69.04416990934514 decay:0.1 sustain:0 s:triangle gain:0.049999999999999996 ]", - "[ 9/16 ⇜ (11/16 → 3/4) | note:72.02689036596712 decay:0.1 sustain:0 s:triangle gain:0.075 ]", - "[ 9/16 ⇜ (11/16 → 3/4) | note:72.06689036596713 decay:0.1 sustain:0 s:triangle gain:0.075 ]", - "[ (3/4 → 7/8) ⇝ 15/16 | note:69.02689036596712 decay:0.1 sustain:0 s:triangle gain:0.049999999999999996 ]", - "[ (3/4 → 7/8) ⇝ 15/16 | note:69.06689036596713 decay:0.1 sustain:0 s:triangle gain:0.049999999999999996 ]", - "[ 3/4 → 15/16 | note:72.12988554127514 decay:0.1 sustain:0 s:triangle gain:0.15 ]", - "[ 3/4 → 15/16 | note:72.16988554127515 decay:0.1 sustain:0 s:triangle gain:0.15 ]", - "[ 3/4 → 15/16 | note:69.00416990934514 decay:0.1 sustain:0 s:triangle gain:0.0375 ]", - "[ 3/4 → 15/16 | note:69.04416990934514 decay:0.1 sustain:0 s:triangle gain:0.0375 ]", - "[ (3/4 → 1/1) ⇝ 9/8 | s:hh27 speed:0.7519542165100574 ]", - "[ (3/4 → 1/1) ⇝ 3/2 | s:sd n:1 speed:0.7519542165100574 ]", - "[ 3/4 ⇜ (7/8 → 15/16) | note:72.02689036596712 decay:0.1 sustain:0 s:triangle gain:0.049999999999999996 ]", - "[ 3/4 ⇜ (7/8 → 15/16) | note:72.06689036596713 decay:0.1 sustain:0 s:triangle gain:0.049999999999999996 ]", - "[ (15/16 → 1/1) ⇝ 9/8 | note:72.18828012727568 decay:0.1 sustain:0 s:triangle gain:0.15 ]", - "[ (15/16 → 1/1) ⇝ 9/8 | note:72.22828012727568 decay:0.1 sustain:0 s:triangle gain:0.15 ]", - "[ (15/16 → 1/1) ⇝ 9/8 | note:72.12988554127514 decay:0.1 sustain:0 s:triangle gain:0.075 ]", - "[ (15/16 → 1/1) ⇝ 9/8 | note:72.16988554127515 decay:0.1 sustain:0 s:triangle gain:0.075 ]", - "[ (15/16 → 1/1) ⇝ 9/8 | note:69.02689036596712 decay:0.1 sustain:0 s:triangle gain:0.0375 ]", - "[ (15/16 → 1/1) ⇝ 9/8 | note:69.06689036596713 decay:0.1 sustain:0 s:triangle gain:0.0375 ]", + "[ 0/1 ⇜ (1/16 → 3/16) | note:93.07162113205 decay:0.1 sustain:0 s:triangle gain:0.0375 ]", + "[ 0/1 ⇜ (1/16 → 3/16) | note:93.11162113205 decay:0.1 sustain:0 s:triangle gain:0.0375 ]", + "[ 3/16 → 3/8 | note:69.004169909345 decay:0.1 sustain:0 s:triangle gain:0.15 ]", + "[ 3/16 → 3/8 | note:69.044169909345 decay:0.1 sustain:0 s:triangle gain:0.15 ]", + "[ 3/16 → 3/8 | note:93.004177502269 decay:0.1 sustain:0 s:triangle gain:0.05 ]", + "[ 3/16 → 3/8 | note:93.044177502269 decay:0.1 sustain:0 s:triangle gain:0.05 ]", + "[ (3/16 → 1/1) ⇝ 27/16 | note:45.004169909345 decay:0.15 sustain:0 s:sawtooth gain:0.4 cutoff:2913.116518842774 lpattack:0.1 lpenv:-2 ]", + "[ (3/16 → 1/1) ⇝ 27/16 | note:45.054169909345 decay:0.15 sustain:0 s:sawtooth gain:0.4 cutoff:2913.116518842774 lpattack:0.1 lpenv:-2 ]", + "[ (3/8 → 1/2) ⇝ 9/16 | note:69.026890365967 decay:0.1 sustain:0 s:triangle gain:0.15 ]", + "[ (3/8 → 1/2) ⇝ 9/16 | note:69.066890365967 decay:0.1 sustain:0 s:triangle gain:0.15 ]", + "[ 3/8 → 9/16 | note:69.004169909345 decay:0.1 sustain:0 s:triangle gain:0.075 ]", + "[ 3/8 → 9/16 | note:69.044169909345 decay:0.1 sustain:0 s:triangle gain:0.075 ]", + "[ 3/8 → 9/16 | note:93.004177502269 decay:0.1 sustain:0 s:triangle gain:0.0375 ]", + "[ 3/8 → 9/16 | note:93.044177502269 decay:0.1 sustain:0 s:triangle gain:0.0375 ]", + "[ 3/8 → 3/4 | s:hh27 speed:0.710756146387 ]", + "[ 3/8 ⇜ (1/2 → 9/16) | note:72.026890365967 decay:0.1 sustain:0 s:triangle gain:0.15 ]", + "[ 3/8 ⇜ (1/2 → 9/16) | note:72.066890365967 decay:0.1 sustain:0 s:triangle gain:0.15 ]", + "[ (9/16 → 11/16) ⇝ 3/4 | note:69.026890365967 decay:0.1 sustain:0 s:triangle gain:0.075 ]", + "[ (9/16 → 11/16) ⇝ 3/4 | note:69.066890365967 decay:0.1 sustain:0 s:triangle gain:0.075 ]", + "[ 9/16 → 3/4 | note:69.004169909345 decay:0.1 sustain:0 s:triangle gain:0.05 ]", + "[ 9/16 → 3/4 | note:69.044169909345 decay:0.1 sustain:0 s:triangle gain:0.05 ]", + "[ 9/16 ⇜ (11/16 → 3/4) | note:72.026890365967 decay:0.1 sustain:0 s:triangle gain:0.075 ]", + "[ 9/16 ⇜ (11/16 → 3/4) | note:72.066890365967 decay:0.1 sustain:0 s:triangle gain:0.075 ]", + "[ (3/4 → 7/8) ⇝ 15/16 | note:69.026890365967 decay:0.1 sustain:0 s:triangle gain:0.05 ]", + "[ (3/4 → 7/8) ⇝ 15/16 | note:69.066890365967 decay:0.1 sustain:0 s:triangle gain:0.05 ]", + "[ 3/4 → 15/16 | note:72.129885541275 decay:0.1 sustain:0 s:triangle gain:0.15 ]", + "[ 3/4 → 15/16 | note:72.169885541275 decay:0.1 sustain:0 s:triangle gain:0.15 ]", + "[ 3/4 → 15/16 | note:69.004169909345 decay:0.1 sustain:0 s:triangle gain:0.0375 ]", + "[ 3/4 → 15/16 | note:69.044169909345 decay:0.1 sustain:0 s:triangle gain:0.0375 ]", + "[ (3/4 → 1/1) ⇝ 9/8 | s:hh27 speed:0.75195421651 ]", + "[ (3/4 → 1/1) ⇝ 3/2 | s:sd n:1 speed:0.75195421651 ]", + "[ 3/4 ⇜ (7/8 → 15/16) | note:72.026890365967 decay:0.1 sustain:0 s:triangle gain:0.05 ]", + "[ 3/4 ⇜ (7/8 → 15/16) | note:72.066890365967 decay:0.1 sustain:0 s:triangle gain:0.05 ]", + "[ (15/16 → 1/1) ⇝ 9/8 | note:72.188280127276 decay:0.1 sustain:0 s:triangle gain:0.15 ]", + "[ (15/16 → 1/1) ⇝ 9/8 | note:72.228280127276 decay:0.1 sustain:0 s:triangle gain:0.15 ]", + "[ (15/16 → 1/1) ⇝ 9/8 | note:72.129885541275 decay:0.1 sustain:0 s:triangle gain:0.075 ]", + "[ (15/16 → 1/1) ⇝ 9/8 | note:72.169885541275 decay:0.1 sustain:0 s:triangle gain:0.075 ]", + "[ (15/16 → 1/1) ⇝ 9/8 | note:69.026890365967 decay:0.1 sustain:0 s:triangle gain:0.0375 ]", + "[ (15/16 → 1/1) ⇝ 9/8 | note:69.066890365967 decay:0.1 sustain:0 s:triangle gain:0.0375 ]", ] `; @@ -7316,74 +7316,74 @@ exports[`renders tunes > tune: orbit 1`] = ` exports[`renders tunes > tune: randomBells 1`] = ` [ - "[ -9/8 ⇜ (0/1 → 3/8) | gain:0.6 note:A3 velocity:0.5989903202280402 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", - "[ -3/4 ⇜ (0/1 → 3/4) | gain:0.6 note:C5 velocity:0.8369929669424891 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", + "[ -9/8 ⇜ (0/1 → 3/8) | gain:0.6 note:A3 velocity:0.598990320228 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", + "[ -3/4 ⇜ (0/1 → 3/4) | gain:0.6 note:C5 velocity:0.836992966942 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", "[ 0/1 → 3/2 | note:F2 s:bass clip:1 gain:0.8 ]", - "[ 0/1 → 9/4 | gain:0.6 note:D3 velocity:0.5 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", - "[ 3/8 → 21/8 | gain:0.6 note:F5 velocity:0.9213038925081491 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", - "[ 3/4 → 3/1 | gain:0.6 note:C5 velocity:0.8426077850162983 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", + "[ 0/1 → 9/4 | gain:0.6 note:D3 velocity:0.5 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", + "[ 3/8 → 21/8 | gain:0.6 note:F5 velocity:0.921303892508 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", + "[ 3/4 → 3/1 | gain:0.6 note:C5 velocity:0.842607785016 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", "[ 3/2 → 9/4 | note:F2 s:bass clip:1 gain:0.8 ]", "[ 9/4 → 3/1 | note:F2 s:bass clip:1 gain:0.8 ]", - "[ 9/4 → 9/2 | gain:0.6 note:D4 velocity:0.7006962578743696 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", - "[ 21/8 → 39/8 | gain:0.6 note:C4 velocity:0.6507943943142891 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", + "[ 9/4 → 9/2 | gain:0.6 note:D4 velocity:0.700696257874 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", + "[ 21/8 → 39/8 | gain:0.6 note:C4 velocity:0.650794394314 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", "[ 3/1 → 9/2 | note:D2 s:bass clip:1 gain:0.8 ]", - "[ 3/1 → 21/4 | gain:0.6 note:C4 velocity:0.6302403081208467 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", + "[ 3/1 → 21/4 | gain:0.6 note:C4 velocity:0.630240308121 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", "[ 9/2 → 21/4 | note:D2 s:bass clip:1 gain:0.8 ]", - "[ 9/2 → 6/1 | gain:0.6 note:A3 velocity:0.597913240082562 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", - "[ (39/8 → 6/1) ⇝ 51/8 | gain:0.6 note:D5 velocity:0.8758113365620375 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", + "[ 9/2 → 6/1 | gain:0.6 note:A3 velocity:0.597913240083 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", + "[ (39/8 → 6/1) ⇝ 51/8 | gain:0.6 note:D5 velocity:0.875811336562 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", "[ 21/4 → 6/1 | note:D2 s:bass clip:1 gain:0.8 ]", - "[ (21/4 → 6/1) ⇝ 27/4 | gain:0.6 note:D4 velocity:0.6988155404105783 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", - "[ 39/8 ⇜ (6/1 → 51/8) | gain:0.6 note:D5 velocity:0.8758113365620375 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", - "[ 21/4 ⇜ (6/1 → 27/4) | gain:0.6 note:D4 velocity:0.6988155404105783 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", + "[ (21/4 → 6/1) ⇝ 27/4 | gain:0.6 note:D4 velocity:0.698815540411 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", + "[ 39/8 ⇜ (6/1 → 51/8) | gain:0.6 note:D5 velocity:0.875811336562 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", + "[ 21/4 ⇜ (6/1 → 27/4) | gain:0.6 note:D4 velocity:0.698815540411 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", "[ 6/1 → 15/2 | note:D2 s:bass clip:1 gain:0.8 ]", - "[ 6/1 → 33/4 | gain:0.6 note:G4 velocity:0.7597710825502872 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", - "[ 51/8 → 69/8 | gain:0.6 note:G4 velocity:0.7743164440616965 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", - "[ 27/4 → 9/1 | gain:0.6 note:C5 velocity:0.8362447572872043 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", + "[ 6/1 → 33/4 | gain:0.6 note:G4 velocity:0.75977108255 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", + "[ 51/8 → 69/8 | gain:0.6 note:G4 velocity:0.774316444062 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", + "[ 27/4 → 9/1 | gain:0.6 note:C5 velocity:0.836244757287 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", "[ 15/2 → 33/4 | note:D2 s:bass clip:1 gain:0.8 ]", "[ 33/4 → 9/1 | note:D2 s:bass clip:1 gain:0.8 ]", - "[ 33/4 → 21/2 | gain:0.6 note:A3 velocity:0.5914018759503961 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", - "[ 69/8 → 87/8 | gain:0.6 note:G4 velocity:0.754063542932272 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", + "[ 33/4 → 21/2 | gain:0.6 note:A3 velocity:0.59140187595 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", + "[ 69/8 → 87/8 | gain:0.6 note:G4 velocity:0.754063542932 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", "[ 9/1 → 21/2 | note:A2 s:bass clip:1 gain:0.8 ]", - "[ 9/1 → 45/4 | gain:0.6 note:A4 velocity:0.8042040374130011 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", + "[ 9/1 → 45/4 | gain:0.6 note:A4 velocity:0.804204037413 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", "[ 21/2 → 45/4 | note:A2 s:bass clip:1 gain:0.8 ]", - "[ 21/2 → 12/1 | gain:0.6 note:A3 velocity:0.6023689480498433 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", - "[ (87/8 → 12/1) ⇝ 99/8 | gain:0.6 note:F4 velocity:0.7347871446982026 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", + "[ 21/2 → 12/1 | gain:0.6 note:A3 velocity:0.60236894805 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", + "[ (87/8 → 12/1) ⇝ 99/8 | gain:0.6 note:F4 velocity:0.734787144698 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", "[ 45/4 → 12/1 | note:A2 s:bass clip:1 gain:0.8 ]", - "[ (45/4 → 12/1) ⇝ 51/4 | gain:0.6 note:A4 velocity:0.7972785895690322 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", - "[ 87/8 ⇜ (12/1 → 99/8) | gain:0.6 note:F4 velocity:0.7347871446982026 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", - "[ 45/4 ⇜ (12/1 → 51/4) | gain:0.6 note:A4 velocity:0.7972785895690322 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", + "[ (45/4 → 12/1) ⇝ 51/4 | gain:0.6 note:A4 velocity:0.797278589569 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", + "[ 87/8 ⇜ (12/1 → 99/8) | gain:0.6 note:F4 velocity:0.734787144698 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", + "[ 45/4 ⇜ (12/1 → 51/4) | gain:0.6 note:A4 velocity:0.797278589569 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", "[ 12/1 → 27/2 | note:A2 s:bass clip:1 gain:0.8 ]", - "[ 12/1 → 57/4 | gain:0.6 note:G5 velocity:0.9797635599970818 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", - "[ 99/8 → 117/8 | gain:0.6 note:C4 velocity:0.6662392104044557 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", - "[ 51/4 → 15/1 | gain:0.6 note:F5 velocity:0.9516951469704509 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", + "[ 12/1 → 57/4 | gain:0.6 note:G5 velocity:0.979763559997 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", + "[ 99/8 → 117/8 | gain:0.6 note:C4 velocity:0.666239210404 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", + "[ 51/4 → 15/1 | gain:0.6 note:F5 velocity:0.95169514697 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", "[ 27/2 → 57/4 | note:A2 s:bass clip:1 gain:0.8 ]", "[ 57/4 → 15/1 | note:A2 s:bass clip:1 gain:0.8 ]", - "[ 57/4 → 33/2 | gain:0.6 note:F5 velocity:0.9182533202692866 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", - "[ 117/8 → 135/8 | gain:0.6 note:G3 velocity:0.5711571052670479 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", + "[ 57/4 → 33/2 | gain:0.6 note:F5 velocity:0.918253320269 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", + "[ 117/8 → 135/8 | gain:0.6 note:G3 velocity:0.571157105267 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", "[ 15/1 → 33/2 | note:G2 s:bass clip:1 gain:0.8 ]", - "[ 15/1 → 69/4 | gain:0.6 note:F4 velocity:0.7293080370873213 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", + "[ 15/1 → 69/4 | gain:0.6 note:F4 velocity:0.729308037087 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", "[ 33/2 → 69/4 | note:G2 s:bass clip:1 gain:0.8 ]", - "[ 33/2 → 18/1 | gain:0.6 note:A4 velocity:0.8166163852438331 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", - "[ (135/8 → 18/1) ⇝ 147/8 | gain:0.6 note:F5 velocity:0.9456470254808664 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", + "[ 33/2 → 18/1 | gain:0.6 note:A4 velocity:0.816616385244 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", + "[ (135/8 → 18/1) ⇝ 147/8 | gain:0.6 note:F5 velocity:0.945647025481 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", "[ 69/4 → 18/1 | note:G2 s:bass clip:1 gain:0.8 ]", - "[ (69/4 → 18/1) ⇝ 75/4 | gain:0.6 note:F3 velocity:0.5081270858645439 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", - "[ 135/8 ⇜ (18/1 → 147/8) | gain:0.6 note:F5 velocity:0.9456470254808664 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", - "[ 69/4 ⇜ (18/1 → 75/4) | gain:0.6 note:F3 velocity:0.5081270858645439 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", + "[ (69/4 → 18/1) ⇝ 75/4 | gain:0.6 note:F3 velocity:0.508127085865 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", + "[ 135/8 ⇜ (18/1 → 147/8) | gain:0.6 note:F5 velocity:0.945647025481 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", + "[ 69/4 ⇜ (18/1 → 75/4) | gain:0.6 note:F3 velocity:0.508127085865 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", "[ 18/1 → 39/2 | note:G2 s:bass clip:1 gain:0.8 ]", - "[ 18/1 → 81/4 | gain:0.6 note:A3 velocity:0.6086445553228259 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", - "[ 147/8 → 165/8 | gain:0.6 note:F3 velocity:0.5062594395130873 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", - "[ 75/4 → 21/1 | gain:0.6 note:D4 velocity:0.6716219391673803 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", + "[ 18/1 → 81/4 | gain:0.6 note:A3 velocity:0.608644555323 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", + "[ 147/8 → 165/8 | gain:0.6 note:F3 velocity:0.506259439513 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", + "[ 75/4 → 21/1 | gain:0.6 note:D4 velocity:0.671621939167 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", "[ 39/2 → 81/4 | note:G2 s:bass clip:1 gain:0.8 ]", "[ 81/4 → 21/1 | note:G2 s:bass clip:1 gain:0.8 ]", - "[ 81/4 → 45/2 | gain:0.6 note:D4 velocity:0.7043459005653858 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", - "[ 165/8 → 183/8 | gain:0.6 note:D5 velocity:0.8878388572484255 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", + "[ 81/4 → 45/2 | gain:0.6 note:D4 velocity:0.704345900565 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", + "[ 165/8 → 183/8 | gain:0.6 note:D5 velocity:0.887838857248 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", "[ 21/1 → 45/2 | note:F2 s:bass clip:1 gain:0.8 ]", - "[ 21/1 → 93/4 | gain:0.6 note:D4 velocity:0.7049744073301554 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", + "[ 21/1 → 93/4 | gain:0.6 note:D4 velocity:0.70497440733 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", "[ 45/2 → 93/4 | note:F2 s:bass clip:1 gain:0.8 ]", - "[ 45/2 → 24/1 | gain:0.6 note:D5 velocity:0.9060836611315608 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", - "[ (183/8 → 24/1) ⇝ 195/8 | gain:0.6 note:G3 velocity:0.5504462849348783 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", + "[ 45/2 → 24/1 | gain:0.6 note:D5 velocity:0.906083661132 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", + "[ (183/8 → 24/1) ⇝ 195/8 | gain:0.6 note:G3 velocity:0.550446284935 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", "[ 93/4 → 24/1 | note:F2 s:bass clip:1 gain:0.8 ]", - "[ (93/4 → 24/1) ⇝ 99/4 | gain:0.6 note:C5 velocity:0.8680832693353295 s:bell delay:0.2 delaytime:0.3333333333333333 delayfeedback:0.8 ]", + "[ (93/4 → 24/1) ⇝ 99/4 | gain:0.6 note:C5 velocity:0.868083269335 s:bell delay:0.2 delaytime:0.333333333333 delayfeedback:0.8 ]", ] `; @@ -8331,84 +8331,84 @@ exports[`renders tunes > tune: swimming 1`] = ` exports[`renders tunes > tune: undergroundPlumber 1`] = ` [ "[ -15/16 ⇜ (0/1 → 3/16) ⇝ 9/16 | gain:0.4 note:G3 clip:0.1 ]", - "[ -9/16 ⇜ (0/1 → 3/16) | gain:0.06400000000000002 note:C6 clip:0.1 ]", + "[ -9/16 ⇜ (0/1 → 3/16) | gain:0.064 note:C6 clip:0.1 ]", "[ -3/16 ⇜ (0/1 → 3/16) ⇝ 9/16 | gain:0.4 note:Eb4 clip:0.1 ]", "[ 0/1 → 3/16 | s:bd gain:0.7 ]", - "[ -3/4 ⇜ (0/1 → 3/8) ⇝ 3/4 | gain:0.16000000000000003 note:G4 clip:0.1 ]", + "[ -3/4 ⇜ (0/1 → 3/8) ⇝ 3/4 | gain:0.16 note:G4 clip:0.1 ]", "[ 0/1 → 3/8 | gain:1 note:C2 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", - "[ (0/1 → 3/8) ⇝ 3/4 | gain:0.16000000000000003 note:Eb5 clip:0.1 ]", - "[ -9/16 ⇜ (0/1 → 9/16) ⇝ 15/16 | gain:0.06400000000000002 note:G5 clip:0.1 ]", + "[ (0/1 → 3/8) ⇝ 3/4 | gain:0.16 note:Eb5 clip:0.1 ]", + "[ -9/16 ⇜ (0/1 → 9/16) ⇝ 15/16 | gain:0.064 note:G5 clip:0.1 ]", "[ 0/1 → 3/4 | gain:1 note:C3 clip:0.1 ]", "[ 0/1 → 3/2 | gain:1 note:G2 clip:0.1 ]", "[ 3/16 → 3/8 | s:bd gain:0.7 ]", "[ 3/16 → 9/16 | gain:1 note:C2 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", - "[ (3/16 → 9/16) ⇝ 15/16 | gain:0.06400000000000002 note:Eb6 clip:0.1 ]", + "[ (3/16 → 9/16) ⇝ 15/16 | gain:0.064 note:Eb6 clip:0.1 ]", "[ 3/16 → 15/16 | gain:0.4 note:C4 clip:0.1 ]", "[ (3/16 → 3/2) ⇝ 27/16 | gain:0.4 note:G3 clip:0.1 ]", "[ 3/8 → 3/4 | s:hh gain:0.7 ]", "[ 3/8 → 3/4 | gain:1 note:A1 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", - "[ 3/8 → 9/8 | gain:0.16000000000000003 note:C5 clip:0.1 ]", - "[ (3/8 → 3/2) ⇝ 15/8 | gain:0.16000000000000003 note:G4 clip:0.1 ]", + "[ 3/8 → 9/8 | gain:0.16 note:C5 clip:0.1 ]", + "[ (3/8 → 3/2) ⇝ 15/8 | gain:0.16 note:G4 clip:0.1 ]", "[ 9/16 → 15/16 | gain:1 note:A1 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", - "[ 9/16 → 21/16 | gain:0.06400000000000002 note:C6 clip:0.1 ]", - "[ (9/16 → 3/2) ⇝ 33/16 | gain:0.06400000000000002 note:G5 clip:0.1 ]", + "[ 9/16 → 21/16 | gain:0.064 note:C6 clip:0.1 ]", + "[ (9/16 → 3/2) ⇝ 33/16 | gain:0.064 note:G5 clip:0.1 ]", "[ 3/4 → 9/8 | s:sn gain:0.7 ]", "[ 3/4 → 9/8 | gain:1 note:Bb1 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", "[ 3/4 → 3/2 | gain:1 note:Eb3 clip:0.1 ]", "[ 15/16 → 21/16 | gain:1 note:Bb1 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", "[ (15/16 → 3/2) ⇝ 27/16 | gain:0.4 note:Eb4 clip:0.1 ]", "[ 9/8 → 3/2 | s:hh gain:0.7 ]", - "[ (9/8 → 3/2) ⇝ 15/8 | gain:0.16000000000000003 note:Eb5 clip:0.1 ]", - "[ (21/16 → 3/2) ⇝ 33/16 | gain:0.06400000000000002 note:Eb6 clip:0.1 ]", + "[ (9/8 → 3/2) ⇝ 15/8 | gain:0.16 note:Eb5 clip:0.1 ]", + "[ (21/16 → 3/2) ⇝ 33/16 | gain:0.064 note:Eb6 clip:0.1 ]", "[ 3/16 ⇜ (3/2 → 27/16) | gain:0.4 note:G3 clip:0.1 ]", "[ 15/16 ⇜ (3/2 → 27/16) | gain:0.4 note:Eb4 clip:0.1 ]", - "[ 3/8 ⇜ (3/2 → 15/8) | gain:0.16000000000000003 note:G4 clip:0.1 ]", + "[ 3/8 ⇜ (3/2 → 15/8) | gain:0.16 note:G4 clip:0.1 ]", "[ 9/8 ⇜ (3/2 → 15/8) | gain:1 note:C3 clip:0.1 ]", - "[ 9/8 ⇜ (3/2 → 15/8) | gain:0.16000000000000003 note:Eb5 clip:0.1 ]", + "[ 9/8 ⇜ (3/2 → 15/8) | gain:0.16 note:Eb5 clip:0.1 ]", "[ 3/2 → 15/8 | s:bd gain:0.7 ]", - "[ 9/16 ⇜ (3/2 → 33/16) | gain:0.06400000000000002 note:G5 clip:0.1 ]", - "[ 21/16 ⇜ (3/2 → 33/16) | gain:0.06400000000000002 note:Eb6 clip:0.1 ]", + "[ 9/16 ⇜ (3/2 → 33/16) | gain:0.064 note:G5 clip:0.1 ]", + "[ 21/16 ⇜ (3/2 → 33/16) | gain:0.064 note:Eb6 clip:0.1 ]", "[ 9/8 ⇜ (3/2 → 21/8) | gain:1 note:G2 clip:0.1 ]", "[ 21/16 ⇜ (27/16 → 33/16) | gain:0.4 note:C4 clip:0.1 ]", "[ 21/16 ⇜ (27/16 → 45/16) | gain:0.4 note:G3 clip:0.1 ]", - "[ 3/2 ⇜ (15/8 → 9/4) | gain:0.16000000000000003 note:C5 clip:0.1 ]", + "[ 3/2 ⇜ (15/8 → 9/4) | gain:0.16 note:C5 clip:0.1 ]", "[ 15/8 → 9/4 | s:hh gain:0.7 ]", "[ 15/8 → 21/8 | gain:1 note:Eb3 clip:0.1 ]", - "[ 3/2 ⇜ (15/8 → 3/1) | gain:0.16000000000000003 note:G4 clip:0.1 ]", - "[ 27/16 ⇜ (33/16 → 39/16) | gain:0.06400000000000002 note:C6 clip:0.1 ]", + "[ 3/2 ⇜ (15/8 → 3/1) | gain:0.16 note:G4 clip:0.1 ]", + "[ 27/16 ⇜ (33/16 → 39/16) | gain:0.064 note:C6 clip:0.1 ]", "[ 33/16 → 45/16 | gain:0.4 note:Eb4 clip:0.1 ]", - "[ 27/16 ⇜ (33/16 → 3/1) ⇝ 51/16 | gain:0.06400000000000002 note:G5 clip:0.1 ]", + "[ 27/16 ⇜ (33/16 → 3/1) ⇝ 51/16 | gain:0.064 note:G5 clip:0.1 ]", "[ 9/4 → 21/8 | s:sn gain:0.7 ]", - "[ 9/4 → 3/1 | gain:0.16000000000000003 note:Eb5 clip:0.1 ]", - "[ (39/16 → 3/1) ⇝ 51/16 | gain:0.06400000000000002 note:Eb6 clip:0.1 ]", + "[ 9/4 → 3/1 | gain:0.16 note:Eb5 clip:0.1 ]", + "[ (39/16 → 3/1) ⇝ 51/16 | gain:0.064 note:Eb6 clip:0.1 ]", "[ 21/8 → 3/1 | s:hh gain:0.7 ]", "[ (21/8 → 3/1) ⇝ 27/8 | gain:1 note:C3 clip:0.1 ]", "[ (21/8 → 3/1) ⇝ 33/8 | gain:1 note:G2 clip:0.1 ]", "[ (45/16 → 3/1) ⇝ 57/16 | gain:0.4 note:C4 clip:0.1 ]", "[ (45/16 → 3/1) ⇝ 69/16 | gain:0.4 note:G3 clip:0.1 ]", - "[ 27/16 ⇜ (3/1 → 51/16) | gain:0.06400000000000002 note:G5 clip:0.1 ]", - "[ 39/16 ⇜ (3/1 → 51/16) | gain:0.06400000000000002 note:Eb6 clip:0.1 ]", + "[ 27/16 ⇜ (3/1 → 51/16) | gain:0.064 note:G5 clip:0.1 ]", + "[ 39/16 ⇜ (3/1 → 51/16) | gain:0.064 note:Eb6 clip:0.1 ]", "[ 45/16 ⇜ (3/1 → 51/16) ⇝ 57/16 | gain:0.4 note:C4 clip:0.1 ]", "[ 45/16 ⇜ (3/1 → 51/16) ⇝ 69/16 | gain:0.4 note:G3 clip:0.1 ]", "[ 3/1 → 51/16 | s:bd gain:0.7 ]", "[ 3/1 → 27/8 | gain:1 note:C2 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", - "[ (3/1 → 27/8) ⇝ 15/4 | gain:0.16000000000000003 note:C5 clip:0.1 ]", - "[ (3/1 → 27/8) ⇝ 9/2 | gain:0.16000000000000003 note:G4 clip:0.1 ]", + "[ (3/1 → 27/8) ⇝ 15/4 | gain:0.16 note:C5 clip:0.1 ]", + "[ (3/1 → 27/8) ⇝ 9/2 | gain:0.16 note:G4 clip:0.1 ]", "[ 9/4 ⇜ (3/1 → 15/4) | gain:1 note:G2 clip:0.1 ]", "[ 3/1 → 15/4 | gain:1 note:Eb3 clip:0.1 ]", "[ 51/16 → 27/8 | s:bd gain:0.7 ]", "[ 51/16 → 57/16 | gain:1 note:C2 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", - "[ (51/16 → 57/16) ⇝ 63/16 | gain:0.06400000000000002 note:C6 clip:0.1 ]", - "[ (51/16 → 57/16) ⇝ 75/16 | gain:0.06400000000000002 note:G5 clip:0.1 ]", + "[ (51/16 → 57/16) ⇝ 63/16 | gain:0.064 note:C6 clip:0.1 ]", + "[ (51/16 → 57/16) ⇝ 75/16 | gain:0.064 note:G5 clip:0.1 ]", "[ 39/16 ⇜ (51/16 → 63/16) | gain:0.4 note:G3 clip:0.1 ]", "[ 51/16 → 63/16 | gain:0.4 note:Eb4 clip:0.1 ]", "[ 27/8 → 15/4 | s:hh gain:0.7 ]", "[ 27/8 → 15/4 | gain:1 note:A1 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", - "[ 21/8 ⇜ (27/8 → 33/8) | gain:0.16000000000000003 note:G4 clip:0.1 ]", - "[ 27/8 → 33/8 | gain:0.16000000000000003 note:Eb5 clip:0.1 ]", + "[ 21/8 ⇜ (27/8 → 33/8) | gain:0.16 note:G4 clip:0.1 ]", + "[ 27/8 → 33/8 | gain:0.16 note:Eb5 clip:0.1 ]", "[ 57/16 → 63/16 | gain:1 note:A1 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", - "[ 45/16 ⇜ (57/16 → 69/16) | gain:0.06400000000000002 note:G5 clip:0.1 ]", - "[ 57/16 → 69/16 | gain:0.06400000000000002 note:Eb6 clip:0.1 ]", + "[ 45/16 ⇜ (57/16 → 69/16) | gain:0.064 note:G5 clip:0.1 ]", + "[ 57/16 → 69/16 | gain:0.064 note:Eb6 clip:0.1 ]", "[ 15/4 → 33/8 | s:sn gain:0.7 ]", "[ 15/4 → 33/8 | gain:1 note:Bb1 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", "[ 15/4 → 9/2 | gain:1 note:C3 clip:0.1 ]", @@ -8417,117 +8417,117 @@ exports[`renders tunes > tune: undergroundPlumber 1`] = ` "[ (63/16 → 9/2) ⇝ 75/16 | gain:0.4 note:C4 clip:0.1 ]", "[ (63/16 → 9/2) ⇝ 87/16 | gain:0.4 note:G3 clip:0.1 ]", "[ 33/8 → 9/2 | s:hh gain:0.7 ]", - "[ (33/8 → 9/2) ⇝ 39/8 | gain:0.16000000000000003 note:C5 clip:0.1 ]", - "[ (33/8 → 9/2) ⇝ 45/8 | gain:0.16000000000000003 note:G4 clip:0.1 ]", - "[ (69/16 → 9/2) ⇝ 81/16 | gain:0.06400000000000002 note:C6 clip:0.1 ]", - "[ (69/16 → 9/2) ⇝ 93/16 | gain:0.06400000000000002 note:G5 clip:0.1 ]", + "[ (33/8 → 9/2) ⇝ 39/8 | gain:0.16 note:C5 clip:0.1 ]", + "[ (33/8 → 9/2) ⇝ 45/8 | gain:0.16 note:G4 clip:0.1 ]", + "[ (69/16 → 9/2) ⇝ 81/16 | gain:0.064 note:C6 clip:0.1 ]", + "[ (69/16 → 9/2) ⇝ 93/16 | gain:0.064 note:G5 clip:0.1 ]", "[ 63/16 ⇜ (9/2 → 75/16) | gain:0.4 note:C4 clip:0.1 ]", "[ 63/16 ⇜ (9/2 → 75/16) ⇝ 87/16 | gain:0.4 note:G3 clip:0.1 ]", "[ 27/8 ⇜ (9/2 → 39/8) | gain:1 note:G2 clip:0.1 ]", "[ 33/8 ⇜ (9/2 → 39/8) | gain:1 note:Eb3 clip:0.1 ]", - "[ 33/8 ⇜ (9/2 → 39/8) | gain:0.16000000000000003 note:C5 clip:0.1 ]", - "[ 33/8 ⇜ (9/2 → 39/8) ⇝ 45/8 | gain:0.16000000000000003 note:G4 clip:0.1 ]", + "[ 33/8 ⇜ (9/2 → 39/8) | gain:0.16 note:C5 clip:0.1 ]", + "[ 33/8 ⇜ (9/2 → 39/8) ⇝ 45/8 | gain:0.16 note:G4 clip:0.1 ]", "[ 9/2 → 39/8 | s:bd gain:0.7 ]", - "[ 69/16 ⇜ (9/2 → 81/16) | gain:0.06400000000000002 note:C6 clip:0.1 ]", - "[ 69/16 ⇜ (9/2 → 81/16) ⇝ 93/16 | gain:0.06400000000000002 note:G5 clip:0.1 ]", + "[ 69/16 ⇜ (9/2 → 81/16) | gain:0.064 note:C6 clip:0.1 ]", + "[ 69/16 ⇜ (9/2 → 81/16) ⇝ 93/16 | gain:0.064 note:G5 clip:0.1 ]", "[ 57/16 ⇜ (75/16 → 81/16) | gain:0.4 note:G3 clip:0.1 ]", "[ 69/16 ⇜ (75/16 → 81/16) | gain:0.4 note:Eb4 clip:0.1 ]", - "[ 15/4 ⇜ (39/8 → 21/4) | gain:0.16000000000000003 note:G4 clip:0.1 ]", - "[ 9/2 ⇜ (39/8 → 21/4) | gain:0.16000000000000003 note:Eb5 clip:0.1 ]", + "[ 15/4 ⇜ (39/8 → 21/4) | gain:0.16 note:G4 clip:0.1 ]", + "[ 9/2 ⇜ (39/8 → 21/4) | gain:0.16 note:Eb5 clip:0.1 ]", "[ 39/8 → 21/4 | s:hh gain:0.7 ]", "[ 39/8 → 45/8 | gain:1 note:C3 clip:0.1 ]", "[ (39/8 → 6/1) ⇝ 51/8 | gain:1 note:G2 clip:0.1 ]", - "[ 63/16 ⇜ (81/16 → 87/16) | gain:0.06400000000000002 note:G5 clip:0.1 ]", - "[ 75/16 ⇜ (81/16 → 87/16) | gain:0.06400000000000002 note:Eb6 clip:0.1 ]", + "[ 63/16 ⇜ (81/16 → 87/16) | gain:0.064 note:G5 clip:0.1 ]", + "[ 75/16 ⇜ (81/16 → 87/16) | gain:0.064 note:Eb6 clip:0.1 ]", "[ 81/16 → 93/16 | gain:0.4 note:C4 clip:0.1 ]", "[ (81/16 → 6/1) ⇝ 105/16 | gain:0.4 note:G3 clip:0.1 ]", "[ 21/4 → 45/8 | s:sn gain:0.7 ]", - "[ 21/4 → 6/1 | gain:0.16000000000000003 note:C5 clip:0.1 ]", - "[ (21/4 → 6/1) ⇝ 27/4 | gain:0.16000000000000003 note:G4 clip:0.1 ]", - "[ (87/16 → 6/1) ⇝ 99/16 | gain:0.06400000000000002 note:C6 clip:0.1 ]", - "[ (87/16 → 6/1) ⇝ 111/16 | gain:0.06400000000000002 note:G5 clip:0.1 ]", + "[ 21/4 → 6/1 | gain:0.16 note:C5 clip:0.1 ]", + "[ (21/4 → 6/1) ⇝ 27/4 | gain:0.16 note:G4 clip:0.1 ]", + "[ (87/16 → 6/1) ⇝ 99/16 | gain:0.064 note:C6 clip:0.1 ]", + "[ (87/16 → 6/1) ⇝ 111/16 | gain:0.064 note:G5 clip:0.1 ]", "[ 45/8 → 6/1 | s:hh gain:0.7 ]", "[ (45/8 → 6/1) ⇝ 51/8 | gain:1 note:Eb3 clip:0.1 ]", "[ (93/16 → 6/1) ⇝ 105/16 | gain:0.4 note:Eb4 clip:0.1 ]", "[ 81/16 ⇜ (6/1 → 99/16) ⇝ 105/16 | gain:0.4 note:C4 clip:0.1 ]", - "[ 87/16 ⇜ (6/1 → 99/16) | gain:0.06400000000000002 note:F6 clip:0.1 ]", + "[ 87/16 ⇜ (6/1 → 99/16) | gain:0.064 note:F6 clip:0.1 ]", "[ 93/16 ⇜ (6/1 → 99/16) ⇝ 105/16 | gain:0.4 note:Ab4 clip:0.1 ]", "[ 6/1 → 99/16 | s:bd gain:0.7 ]", - "[ 21/4 ⇜ (6/1 → 51/8) ⇝ 27/4 | gain:0.16000000000000003 note:C5 clip:0.1 ]", + "[ 21/4 ⇜ (6/1 → 51/8) ⇝ 27/4 | gain:0.16 note:C5 clip:0.1 ]", "[ 6/1 → 51/8 | gain:1 note:F2 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", - "[ (6/1 → 51/8) ⇝ 27/4 | gain:0.16000000000000003 note:Ab5 clip:0.1 ]", - "[ 87/16 ⇜ (6/1 → 105/16) ⇝ 111/16 | gain:0.06400000000000002 note:C6 clip:0.1 ]", + "[ (6/1 → 51/8) ⇝ 27/4 | gain:0.16 note:Ab5 clip:0.1 ]", + "[ 87/16 ⇜ (6/1 → 105/16) ⇝ 111/16 | gain:0.064 note:C6 clip:0.1 ]", "[ 6/1 → 27/4 | gain:1 note:F3 clip:0.1 ]", "[ 6/1 → 15/2 | gain:1 note:C3 clip:0.1 ]", "[ 99/16 → 51/8 | s:bd gain:0.7 ]", "[ 99/16 → 105/16 | gain:1 note:F2 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", - "[ (99/16 → 105/16) ⇝ 111/16 | gain:0.06400000000000002 note:Ab6 clip:0.1 ]", + "[ (99/16 → 105/16) ⇝ 111/16 | gain:0.064 note:Ab6 clip:0.1 ]", "[ 99/16 → 111/16 | gain:0.4 note:F4 clip:0.1 ]", "[ (99/16 → 15/2) ⇝ 123/16 | gain:0.4 note:C4 clip:0.1 ]", "[ 51/8 → 27/4 | s:hh gain:0.7 ]", "[ 51/8 → 27/4 | gain:1 note:D2 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", - "[ 51/8 → 57/8 | gain:0.16000000000000003 note:F5 clip:0.1 ]", - "[ (51/8 → 15/2) ⇝ 63/8 | gain:0.16000000000000003 note:C5 clip:0.1 ]", + "[ 51/8 → 57/8 | gain:0.16 note:F5 clip:0.1 ]", + "[ (51/8 → 15/2) ⇝ 63/8 | gain:0.16 note:C5 clip:0.1 ]", "[ 105/16 → 111/16 | gain:1 note:D2 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", - "[ 105/16 → 117/16 | gain:0.06400000000000002 note:F6 clip:0.1 ]", - "[ (105/16 → 15/2) ⇝ 129/16 | gain:0.06400000000000002 note:C6 clip:0.1 ]", + "[ 105/16 → 117/16 | gain:0.064 note:F6 clip:0.1 ]", + "[ (105/16 → 15/2) ⇝ 129/16 | gain:0.064 note:C6 clip:0.1 ]", "[ 27/4 → 57/8 | s:sn gain:0.7 ]", "[ 27/4 → 57/8 | gain:1 note:Eb2 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", "[ 27/4 → 15/2 | gain:1 note:Ab3 clip:0.1 ]", "[ 111/16 → 117/16 | gain:1 note:Eb2 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", "[ (111/16 → 15/2) ⇝ 123/16 | gain:0.4 note:Ab4 clip:0.1 ]", "[ 57/8 → 15/2 | s:hh gain:0.7 ]", - "[ (57/8 → 15/2) ⇝ 63/8 | gain:0.16000000000000003 note:Ab5 clip:0.1 ]", - "[ (117/16 → 15/2) ⇝ 129/16 | gain:0.06400000000000002 note:Ab6 clip:0.1 ]", + "[ (57/8 → 15/2) ⇝ 63/8 | gain:0.16 note:Ab5 clip:0.1 ]", + "[ (117/16 → 15/2) ⇝ 129/16 | gain:0.064 note:Ab6 clip:0.1 ]", "[ 99/16 ⇜ (15/2 → 123/16) | gain:0.4 note:C4 clip:0.1 ]", "[ 111/16 ⇜ (15/2 → 123/16) | gain:0.4 note:Ab4 clip:0.1 ]", - "[ 51/8 ⇜ (15/2 → 63/8) | gain:0.16000000000000003 note:C5 clip:0.1 ]", + "[ 51/8 ⇜ (15/2 → 63/8) | gain:0.16 note:C5 clip:0.1 ]", "[ 57/8 ⇜ (15/2 → 63/8) | gain:1 note:F3 clip:0.1 ]", - "[ 57/8 ⇜ (15/2 → 63/8) | gain:0.16000000000000003 note:Ab5 clip:0.1 ]", + "[ 57/8 ⇜ (15/2 → 63/8) | gain:0.16 note:Ab5 clip:0.1 ]", "[ 15/2 → 63/8 | s:bd gain:0.7 ]", - "[ 105/16 ⇜ (15/2 → 129/16) | gain:0.06400000000000002 note:C6 clip:0.1 ]", - "[ 117/16 ⇜ (15/2 → 129/16) | gain:0.06400000000000002 note:Ab6 clip:0.1 ]", + "[ 105/16 ⇜ (15/2 → 129/16) | gain:0.064 note:C6 clip:0.1 ]", + "[ 117/16 ⇜ (15/2 → 129/16) | gain:0.064 note:Ab6 clip:0.1 ]", "[ 57/8 ⇜ (15/2 → 69/8) | gain:1 note:C3 clip:0.1 ]", "[ 117/16 ⇜ (123/16 → 129/16) | gain:0.4 note:F4 clip:0.1 ]", "[ 117/16 ⇜ (123/16 → 141/16) | gain:0.4 note:C4 clip:0.1 ]", - "[ 15/2 ⇜ (63/8 → 33/4) | gain:0.16000000000000003 note:F5 clip:0.1 ]", + "[ 15/2 ⇜ (63/8 → 33/4) | gain:0.16 note:F5 clip:0.1 ]", "[ 63/8 → 33/4 | s:hh gain:0.7 ]", "[ 63/8 → 69/8 | gain:1 note:Ab3 clip:0.1 ]", - "[ 15/2 ⇜ (63/8 → 9/1) | gain:0.16000000000000003 note:C5 clip:0.1 ]", - "[ 123/16 ⇜ (129/16 → 135/16) | gain:0.06400000000000002 note:F6 clip:0.1 ]", + "[ 15/2 ⇜ (63/8 → 9/1) | gain:0.16 note:C5 clip:0.1 ]", + "[ 123/16 ⇜ (129/16 → 135/16) | gain:0.064 note:F6 clip:0.1 ]", "[ 129/16 → 141/16 | gain:0.4 note:Ab4 clip:0.1 ]", - "[ 123/16 ⇜ (129/16 → 9/1) ⇝ 147/16 | gain:0.06400000000000002 note:C6 clip:0.1 ]", + "[ 123/16 ⇜ (129/16 → 9/1) ⇝ 147/16 | gain:0.064 note:C6 clip:0.1 ]", "[ 33/4 → 69/8 | s:sn gain:0.7 ]", - "[ 33/4 → 9/1 | gain:0.16000000000000003 note:Ab5 clip:0.1 ]", - "[ (135/16 → 9/1) ⇝ 147/16 | gain:0.06400000000000002 note:Ab6 clip:0.1 ]", + "[ 33/4 → 9/1 | gain:0.16 note:Ab5 clip:0.1 ]", + "[ (135/16 → 9/1) ⇝ 147/16 | gain:0.064 note:Ab6 clip:0.1 ]", "[ 69/8 → 9/1 | s:hh gain:0.7 ]", "[ (69/8 → 9/1) ⇝ 75/8 | gain:1 note:F3 clip:0.1 ]", "[ (69/8 → 9/1) ⇝ 81/8 | gain:1 note:C3 clip:0.1 ]", "[ (141/16 → 9/1) ⇝ 153/16 | gain:0.4 note:F4 clip:0.1 ]", "[ (141/16 → 9/1) ⇝ 165/16 | gain:0.4 note:C4 clip:0.1 ]", - "[ 123/16 ⇜ (9/1 → 147/16) | gain:0.06400000000000002 note:G5 clip:0.1 ]", - "[ 135/16 ⇜ (9/1 → 147/16) | gain:0.06400000000000002 note:Eb6 clip:0.1 ]", + "[ 123/16 ⇜ (9/1 → 147/16) | gain:0.064 note:G5 clip:0.1 ]", + "[ 135/16 ⇜ (9/1 → 147/16) | gain:0.064 note:Eb6 clip:0.1 ]", "[ 141/16 ⇜ (9/1 → 147/16) ⇝ 153/16 | gain:0.4 note:C4 clip:0.1 ]", "[ 141/16 ⇜ (9/1 → 147/16) ⇝ 165/16 | gain:0.4 note:G3 clip:0.1 ]", "[ 9/1 → 147/16 | s:bd gain:0.7 ]", "[ 9/1 → 75/8 | gain:1 note:C2 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", - "[ (9/1 → 75/8) ⇝ 39/4 | gain:0.16000000000000003 note:C5 clip:0.1 ]", - "[ (9/1 → 75/8) ⇝ 21/2 | gain:0.16000000000000003 note:G4 clip:0.1 ]", + "[ (9/1 → 75/8) ⇝ 39/4 | gain:0.16 note:C5 clip:0.1 ]", + "[ (9/1 → 75/8) ⇝ 21/2 | gain:0.16 note:G4 clip:0.1 ]", "[ 33/4 ⇜ (9/1 → 39/4) | gain:1 note:G2 clip:0.1 ]", "[ 9/1 → 39/4 | gain:1 note:Eb3 clip:0.1 ]", "[ 147/16 → 75/8 | s:bd gain:0.7 ]", "[ 147/16 → 153/16 | gain:1 note:C2 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", - "[ (147/16 → 153/16) ⇝ 159/16 | gain:0.06400000000000002 note:C6 clip:0.1 ]", - "[ (147/16 → 153/16) ⇝ 171/16 | gain:0.06400000000000002 note:G5 clip:0.1 ]", + "[ (147/16 → 153/16) ⇝ 159/16 | gain:0.064 note:C6 clip:0.1 ]", + "[ (147/16 → 153/16) ⇝ 171/16 | gain:0.064 note:G5 clip:0.1 ]", "[ 135/16 ⇜ (147/16 → 159/16) | gain:0.4 note:G3 clip:0.1 ]", "[ 147/16 → 159/16 | gain:0.4 note:Eb4 clip:0.1 ]", "[ 75/8 → 39/4 | s:hh gain:0.7 ]", "[ 75/8 → 39/4 | gain:1 note:A1 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", - "[ 69/8 ⇜ (75/8 → 81/8) | gain:0.16000000000000003 note:G4 clip:0.1 ]", - "[ 75/8 → 81/8 | gain:0.16000000000000003 note:Eb5 clip:0.1 ]", + "[ 69/8 ⇜ (75/8 → 81/8) | gain:0.16 note:G4 clip:0.1 ]", + "[ 75/8 → 81/8 | gain:0.16 note:Eb5 clip:0.1 ]", "[ 153/16 → 159/16 | gain:1 note:A1 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", - "[ 141/16 ⇜ (153/16 → 165/16) | gain:0.06400000000000002 note:G5 clip:0.1 ]", - "[ 153/16 → 165/16 | gain:0.06400000000000002 note:Eb6 clip:0.1 ]", + "[ 141/16 ⇜ (153/16 → 165/16) | gain:0.064 note:G5 clip:0.1 ]", + "[ 153/16 → 165/16 | gain:0.064 note:Eb6 clip:0.1 ]", "[ 39/4 → 81/8 | s:sn gain:0.7 ]", "[ 39/4 → 81/8 | gain:1 note:Bb1 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", "[ 39/4 → 21/2 | gain:1 note:C3 clip:0.1 ]", @@ -8536,117 +8536,117 @@ exports[`renders tunes > tune: undergroundPlumber 1`] = ` "[ (159/16 → 21/2) ⇝ 171/16 | gain:0.4 note:C4 clip:0.1 ]", "[ (159/16 → 21/2) ⇝ 183/16 | gain:0.4 note:G3 clip:0.1 ]", "[ 81/8 → 21/2 | s:hh gain:0.7 ]", - "[ (81/8 → 21/2) ⇝ 87/8 | gain:0.16000000000000003 note:C5 clip:0.1 ]", - "[ (81/8 → 21/2) ⇝ 93/8 | gain:0.16000000000000003 note:G4 clip:0.1 ]", - "[ (165/16 → 21/2) ⇝ 177/16 | gain:0.06400000000000002 note:C6 clip:0.1 ]", - "[ (165/16 → 21/2) ⇝ 189/16 | gain:0.06400000000000002 note:G5 clip:0.1 ]", + "[ (81/8 → 21/2) ⇝ 87/8 | gain:0.16 note:C5 clip:0.1 ]", + "[ (81/8 → 21/2) ⇝ 93/8 | gain:0.16 note:G4 clip:0.1 ]", + "[ (165/16 → 21/2) ⇝ 177/16 | gain:0.064 note:C6 clip:0.1 ]", + "[ (165/16 → 21/2) ⇝ 189/16 | gain:0.064 note:G5 clip:0.1 ]", "[ 159/16 ⇜ (21/2 → 171/16) | gain:0.4 note:C4 clip:0.1 ]", "[ 159/16 ⇜ (21/2 → 171/16) ⇝ 183/16 | gain:0.4 note:G3 clip:0.1 ]", "[ 75/8 ⇜ (21/2 → 87/8) | gain:1 note:G2 clip:0.1 ]", "[ 81/8 ⇜ (21/2 → 87/8) | gain:1 note:Eb3 clip:0.1 ]", - "[ 81/8 ⇜ (21/2 → 87/8) | gain:0.16000000000000003 note:C5 clip:0.1 ]", - "[ 81/8 ⇜ (21/2 → 87/8) ⇝ 93/8 | gain:0.16000000000000003 note:G4 clip:0.1 ]", + "[ 81/8 ⇜ (21/2 → 87/8) | gain:0.16 note:C5 clip:0.1 ]", + "[ 81/8 ⇜ (21/2 → 87/8) ⇝ 93/8 | gain:0.16 note:G4 clip:0.1 ]", "[ 21/2 → 87/8 | s:bd gain:0.7 ]", - "[ 165/16 ⇜ (21/2 → 177/16) | gain:0.06400000000000002 note:C6 clip:0.1 ]", - "[ 165/16 ⇜ (21/2 → 177/16) ⇝ 189/16 | gain:0.06400000000000002 note:G5 clip:0.1 ]", + "[ 165/16 ⇜ (21/2 → 177/16) | gain:0.064 note:C6 clip:0.1 ]", + "[ 165/16 ⇜ (21/2 → 177/16) ⇝ 189/16 | gain:0.064 note:G5 clip:0.1 ]", "[ 153/16 ⇜ (171/16 → 177/16) | gain:0.4 note:G3 clip:0.1 ]", "[ 165/16 ⇜ (171/16 → 177/16) | gain:0.4 note:Eb4 clip:0.1 ]", - "[ 39/4 ⇜ (87/8 → 45/4) | gain:0.16000000000000003 note:G4 clip:0.1 ]", - "[ 21/2 ⇜ (87/8 → 45/4) | gain:0.16000000000000003 note:Eb5 clip:0.1 ]", + "[ 39/4 ⇜ (87/8 → 45/4) | gain:0.16 note:G4 clip:0.1 ]", + "[ 21/2 ⇜ (87/8 → 45/4) | gain:0.16 note:Eb5 clip:0.1 ]", "[ 87/8 → 45/4 | s:hh gain:0.7 ]", "[ 87/8 → 93/8 | gain:1 note:C3 clip:0.1 ]", "[ (87/8 → 12/1) ⇝ 99/8 | gain:1 note:G2 clip:0.1 ]", - "[ 159/16 ⇜ (177/16 → 183/16) | gain:0.06400000000000002 note:G5 clip:0.1 ]", - "[ 171/16 ⇜ (177/16 → 183/16) | gain:0.06400000000000002 note:Eb6 clip:0.1 ]", + "[ 159/16 ⇜ (177/16 → 183/16) | gain:0.064 note:G5 clip:0.1 ]", + "[ 171/16 ⇜ (177/16 → 183/16) | gain:0.064 note:Eb6 clip:0.1 ]", "[ 177/16 → 189/16 | gain:0.4 note:C4 clip:0.1 ]", "[ (177/16 → 12/1) ⇝ 201/16 | gain:0.4 note:G3 clip:0.1 ]", "[ 45/4 → 93/8 | s:sn gain:0.7 ]", - "[ 45/4 → 12/1 | gain:0.16000000000000003 note:C5 clip:0.1 ]", - "[ (45/4 → 12/1) ⇝ 51/4 | gain:0.16000000000000003 note:G4 clip:0.1 ]", - "[ (183/16 → 12/1) ⇝ 195/16 | gain:0.06400000000000002 note:C6 clip:0.1 ]", - "[ (183/16 → 12/1) ⇝ 207/16 | gain:0.06400000000000002 note:G5 clip:0.1 ]", + "[ 45/4 → 12/1 | gain:0.16 note:C5 clip:0.1 ]", + "[ (45/4 → 12/1) ⇝ 51/4 | gain:0.16 note:G4 clip:0.1 ]", + "[ (183/16 → 12/1) ⇝ 195/16 | gain:0.064 note:C6 clip:0.1 ]", + "[ (183/16 → 12/1) ⇝ 207/16 | gain:0.064 note:G5 clip:0.1 ]", "[ 93/8 → 12/1 | s:hh gain:0.7 ]", "[ (93/8 → 12/1) ⇝ 99/8 | gain:1 note:Eb3 clip:0.1 ]", "[ (189/16 → 12/1) ⇝ 201/16 | gain:0.4 note:Eb4 clip:0.1 ]", "[ 177/16 ⇜ (12/1 → 195/16) ⇝ 201/16 | gain:0.4 note:D4 clip:0.1 ]", - "[ 183/16 ⇜ (12/1 → 195/16) | gain:0.06400000000000002 note:G6 clip:0.1 ]", + "[ 183/16 ⇜ (12/1 → 195/16) | gain:0.064 note:G6 clip:0.1 ]", "[ 189/16 ⇜ (12/1 → 195/16) ⇝ 201/16 | gain:0.4 note:Bb4 clip:0.1 ]", "[ 12/1 → 195/16 | s:bd gain:0.7 ]", - "[ 45/4 ⇜ (12/1 → 99/8) ⇝ 51/4 | gain:0.16000000000000003 note:D5 clip:0.1 ]", + "[ 45/4 ⇜ (12/1 → 99/8) ⇝ 51/4 | gain:0.16 note:D5 clip:0.1 ]", "[ 12/1 → 99/8 | gain:1 note:G2 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", - "[ (12/1 → 99/8) ⇝ 51/4 | gain:0.16000000000000003 note:Bb5 clip:0.1 ]", - "[ 183/16 ⇜ (12/1 → 201/16) ⇝ 207/16 | gain:0.06400000000000002 note:D6 clip:0.1 ]", + "[ (12/1 → 99/8) ⇝ 51/4 | gain:0.16 note:Bb5 clip:0.1 ]", + "[ 183/16 ⇜ (12/1 → 201/16) ⇝ 207/16 | gain:0.064 note:D6 clip:0.1 ]", "[ 12/1 → 51/4 | gain:1 note:G3 clip:0.1 ]", "[ 12/1 → 27/2 | gain:1 note:D3 clip:0.1 ]", "[ 195/16 → 99/8 | s:bd gain:0.7 ]", "[ 195/16 → 201/16 | gain:1 note:G2 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", - "[ (195/16 → 201/16) ⇝ 207/16 | gain:0.06400000000000002 note:Bb6 clip:0.1 ]", + "[ (195/16 → 201/16) ⇝ 207/16 | gain:0.064 note:Bb6 clip:0.1 ]", "[ 195/16 → 207/16 | gain:0.4 note:G4 clip:0.1 ]", "[ (195/16 → 27/2) ⇝ 219/16 | gain:0.4 note:D4 clip:0.1 ]", "[ 99/8 → 51/4 | s:hh gain:0.7 ]", "[ 99/8 → 51/4 | gain:1 note:E2 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", - "[ 99/8 → 105/8 | gain:0.16000000000000003 note:G5 clip:0.1 ]", - "[ (99/8 → 27/2) ⇝ 111/8 | gain:0.16000000000000003 note:D5 clip:0.1 ]", + "[ 99/8 → 105/8 | gain:0.16 note:G5 clip:0.1 ]", + "[ (99/8 → 27/2) ⇝ 111/8 | gain:0.16 note:D5 clip:0.1 ]", "[ 201/16 → 207/16 | gain:1 note:E2 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", - "[ 201/16 → 213/16 | gain:0.06400000000000002 note:G6 clip:0.1 ]", - "[ (201/16 → 27/2) ⇝ 225/16 | gain:0.06400000000000002 note:D6 clip:0.1 ]", + "[ 201/16 → 213/16 | gain:0.064 note:G6 clip:0.1 ]", + "[ (201/16 → 27/2) ⇝ 225/16 | gain:0.064 note:D6 clip:0.1 ]", "[ 51/4 → 105/8 | s:sn gain:0.7 ]", "[ 51/4 → 105/8 | gain:1 note:F2 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", "[ 51/4 → 27/2 | gain:1 note:Bb3 clip:0.1 ]", "[ 207/16 → 213/16 | gain:1 note:F2 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", "[ (207/16 → 27/2) ⇝ 219/16 | gain:0.4 note:Bb4 clip:0.1 ]", "[ 105/8 → 27/2 | s:hh gain:0.7 ]", - "[ (105/8 → 27/2) ⇝ 111/8 | gain:0.16000000000000003 note:Bb5 clip:0.1 ]", - "[ (213/16 → 27/2) ⇝ 225/16 | gain:0.06400000000000002 note:Bb6 clip:0.1 ]", + "[ (105/8 → 27/2) ⇝ 111/8 | gain:0.16 note:Bb5 clip:0.1 ]", + "[ (213/16 → 27/2) ⇝ 225/16 | gain:0.064 note:Bb6 clip:0.1 ]", "[ 195/16 ⇜ (27/2 → 219/16) | gain:0.4 note:D4 clip:0.1 ]", "[ 207/16 ⇜ (27/2 → 219/16) | gain:0.4 note:Bb4 clip:0.1 ]", - "[ 99/8 ⇜ (27/2 → 111/8) | gain:0.16000000000000003 note:D5 clip:0.1 ]", + "[ 99/8 ⇜ (27/2 → 111/8) | gain:0.16 note:D5 clip:0.1 ]", "[ 105/8 ⇜ (27/2 → 111/8) | gain:1 note:G3 clip:0.1 ]", - "[ 105/8 ⇜ (27/2 → 111/8) | gain:0.16000000000000003 note:Bb5 clip:0.1 ]", + "[ 105/8 ⇜ (27/2 → 111/8) | gain:0.16 note:Bb5 clip:0.1 ]", "[ 27/2 → 111/8 | s:bd gain:0.7 ]", - "[ 201/16 ⇜ (27/2 → 225/16) | gain:0.06400000000000002 note:D6 clip:0.1 ]", - "[ 213/16 ⇜ (27/2 → 225/16) | gain:0.06400000000000002 note:Bb6 clip:0.1 ]", + "[ 201/16 ⇜ (27/2 → 225/16) | gain:0.064 note:D6 clip:0.1 ]", + "[ 213/16 ⇜ (27/2 → 225/16) | gain:0.064 note:Bb6 clip:0.1 ]", "[ 105/8 ⇜ (27/2 → 117/8) | gain:1 note:D3 clip:0.1 ]", "[ 213/16 ⇜ (219/16 → 225/16) | gain:0.4 note:G4 clip:0.1 ]", "[ 213/16 ⇜ (219/16 → 237/16) | gain:0.4 note:D4 clip:0.1 ]", - "[ 27/2 ⇜ (111/8 → 57/4) | gain:0.16000000000000003 note:G5 clip:0.1 ]", + "[ 27/2 ⇜ (111/8 → 57/4) | gain:0.16 note:G5 clip:0.1 ]", "[ 111/8 → 57/4 | s:hh gain:0.7 ]", "[ 111/8 → 117/8 | gain:1 note:Bb3 clip:0.1 ]", - "[ 27/2 ⇜ (111/8 → 15/1) | gain:0.16000000000000003 note:D5 clip:0.1 ]", - "[ 219/16 ⇜ (225/16 → 231/16) | gain:0.06400000000000002 note:G6 clip:0.1 ]", + "[ 27/2 ⇜ (111/8 → 15/1) | gain:0.16 note:D5 clip:0.1 ]", + "[ 219/16 ⇜ (225/16 → 231/16) | gain:0.064 note:G6 clip:0.1 ]", "[ 225/16 → 237/16 | gain:0.4 note:Bb4 clip:0.1 ]", - "[ 219/16 ⇜ (225/16 → 15/1) ⇝ 243/16 | gain:0.06400000000000002 note:D6 clip:0.1 ]", + "[ 219/16 ⇜ (225/16 → 15/1) ⇝ 243/16 | gain:0.064 note:D6 clip:0.1 ]", "[ 57/4 → 117/8 | s:sn gain:0.7 ]", - "[ 57/4 → 15/1 | gain:0.16000000000000003 note:Bb5 clip:0.1 ]", - "[ (231/16 → 15/1) ⇝ 243/16 | gain:0.06400000000000002 note:Bb6 clip:0.1 ]", + "[ 57/4 → 15/1 | gain:0.16 note:Bb5 clip:0.1 ]", + "[ (231/16 → 15/1) ⇝ 243/16 | gain:0.064 note:Bb6 clip:0.1 ]", "[ 117/8 → 15/1 | s:hh gain:0.7 ]", "[ (117/8 → 15/1) ⇝ 123/8 | gain:1 note:G3 clip:0.1 ]", "[ (117/8 → 15/1) ⇝ 129/8 | gain:1 note:D3 clip:0.1 ]", "[ (237/16 → 15/1) ⇝ 249/16 | gain:0.4 note:G4 clip:0.1 ]", "[ (237/16 → 15/1) ⇝ 261/16 | gain:0.4 note:D4 clip:0.1 ]", - "[ 219/16 ⇜ (15/1 → 243/16) | gain:0.06400000000000002 note:C6 clip:0.1 ]", - "[ 231/16 ⇜ (15/1 → 243/16) | gain:0.06400000000000002 note:Ab6 clip:0.1 ]", + "[ 219/16 ⇜ (15/1 → 243/16) | gain:0.064 note:C6 clip:0.1 ]", + "[ 231/16 ⇜ (15/1 → 243/16) | gain:0.064 note:Ab6 clip:0.1 ]", "[ 237/16 ⇜ (15/1 → 243/16) ⇝ 249/16 | gain:0.4 note:F4 clip:0.1 ]", "[ 237/16 ⇜ (15/1 → 243/16) ⇝ 261/16 | gain:0.4 note:C4 clip:0.1 ]", "[ 15/1 → 243/16 | s:bd gain:0.7 ]", "[ 15/1 → 123/8 | gain:1 note:F2 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", - "[ (15/1 → 123/8) ⇝ 63/4 | gain:0.16000000000000003 note:F5 clip:0.1 ]", - "[ (15/1 → 123/8) ⇝ 33/2 | gain:0.16000000000000003 note:C5 clip:0.1 ]", + "[ (15/1 → 123/8) ⇝ 63/4 | gain:0.16 note:F5 clip:0.1 ]", + "[ (15/1 → 123/8) ⇝ 33/2 | gain:0.16 note:C5 clip:0.1 ]", "[ 57/4 ⇜ (15/1 → 63/4) | gain:1 note:C3 clip:0.1 ]", "[ 15/1 → 63/4 | gain:1 note:Ab3 clip:0.1 ]", "[ 243/16 → 123/8 | s:bd gain:0.7 ]", "[ 243/16 → 249/16 | gain:1 note:F2 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", - "[ (243/16 → 249/16) ⇝ 255/16 | gain:0.06400000000000002 note:F6 clip:0.1 ]", - "[ (243/16 → 249/16) ⇝ 267/16 | gain:0.06400000000000002 note:C6 clip:0.1 ]", + "[ (243/16 → 249/16) ⇝ 255/16 | gain:0.064 note:F6 clip:0.1 ]", + "[ (243/16 → 249/16) ⇝ 267/16 | gain:0.064 note:C6 clip:0.1 ]", "[ 231/16 ⇜ (243/16 → 255/16) | gain:0.4 note:C4 clip:0.1 ]", "[ 243/16 → 255/16 | gain:0.4 note:Ab4 clip:0.1 ]", "[ 123/8 → 63/4 | s:hh gain:0.7 ]", "[ 123/8 → 63/4 | gain:1 note:D2 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", - "[ 117/8 ⇜ (123/8 → 129/8) | gain:0.16000000000000003 note:C5 clip:0.1 ]", - "[ 123/8 → 129/8 | gain:0.16000000000000003 note:Ab5 clip:0.1 ]", + "[ 117/8 ⇜ (123/8 → 129/8) | gain:0.16 note:C5 clip:0.1 ]", + "[ 123/8 → 129/8 | gain:0.16 note:Ab5 clip:0.1 ]", "[ 249/16 → 255/16 | gain:1 note:D2 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", - "[ 237/16 ⇜ (249/16 → 261/16) | gain:0.06400000000000002 note:C6 clip:0.1 ]", - "[ 249/16 → 261/16 | gain:0.06400000000000002 note:Ab6 clip:0.1 ]", + "[ 237/16 ⇜ (249/16 → 261/16) | gain:0.064 note:C6 clip:0.1 ]", + "[ 249/16 → 261/16 | gain:0.064 note:Ab6 clip:0.1 ]", "[ 63/4 → 129/8 | s:sn gain:0.7 ]", "[ 63/4 → 129/8 | gain:1 note:Eb2 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", "[ 63/4 → 33/2 | gain:1 note:F3 clip:0.1 ]", @@ -8655,81 +8655,81 @@ exports[`renders tunes > tune: undergroundPlumber 1`] = ` "[ (255/16 → 33/2) ⇝ 267/16 | gain:0.4 note:F4 clip:0.1 ]", "[ (255/16 → 33/2) ⇝ 279/16 | gain:0.4 note:C4 clip:0.1 ]", "[ 129/8 → 33/2 | s:hh gain:0.7 ]", - "[ (129/8 → 33/2) ⇝ 135/8 | gain:0.16000000000000003 note:F5 clip:0.1 ]", - "[ (129/8 → 33/2) ⇝ 141/8 | gain:0.16000000000000003 note:C5 clip:0.1 ]", - "[ (261/16 → 33/2) ⇝ 273/16 | gain:0.06400000000000002 note:F6 clip:0.1 ]", - "[ (261/16 → 33/2) ⇝ 285/16 | gain:0.06400000000000002 note:C6 clip:0.1 ]", + "[ (129/8 → 33/2) ⇝ 135/8 | gain:0.16 note:F5 clip:0.1 ]", + "[ (129/8 → 33/2) ⇝ 141/8 | gain:0.16 note:C5 clip:0.1 ]", + "[ (261/16 → 33/2) ⇝ 273/16 | gain:0.064 note:F6 clip:0.1 ]", + "[ (261/16 → 33/2) ⇝ 285/16 | gain:0.064 note:C6 clip:0.1 ]", "[ 255/16 ⇜ (33/2 → 267/16) | gain:0.4 note:F4 clip:0.1 ]", "[ 255/16 ⇜ (33/2 → 267/16) ⇝ 279/16 | gain:0.4 note:C4 clip:0.1 ]", "[ 123/8 ⇜ (33/2 → 135/8) | gain:1 note:C3 clip:0.1 ]", "[ 129/8 ⇜ (33/2 → 135/8) | gain:1 note:Ab3 clip:0.1 ]", - "[ 129/8 ⇜ (33/2 → 135/8) | gain:0.16000000000000003 note:F5 clip:0.1 ]", - "[ 129/8 ⇜ (33/2 → 135/8) ⇝ 141/8 | gain:0.16000000000000003 note:C5 clip:0.1 ]", + "[ 129/8 ⇜ (33/2 → 135/8) | gain:0.16 note:F5 clip:0.1 ]", + "[ 129/8 ⇜ (33/2 → 135/8) ⇝ 141/8 | gain:0.16 note:C5 clip:0.1 ]", "[ 33/2 → 135/8 | s:bd gain:0.7 ]", - "[ 261/16 ⇜ (33/2 → 273/16) | gain:0.06400000000000002 note:F6 clip:0.1 ]", - "[ 261/16 ⇜ (33/2 → 273/16) ⇝ 285/16 | gain:0.06400000000000002 note:C6 clip:0.1 ]", + "[ 261/16 ⇜ (33/2 → 273/16) | gain:0.064 note:F6 clip:0.1 ]", + "[ 261/16 ⇜ (33/2 → 273/16) ⇝ 285/16 | gain:0.064 note:C6 clip:0.1 ]", "[ 249/16 ⇜ (267/16 → 273/16) | gain:0.4 note:C4 clip:0.1 ]", "[ 261/16 ⇜ (267/16 → 273/16) | gain:0.4 note:Ab4 clip:0.1 ]", - "[ 63/4 ⇜ (135/8 → 69/4) | gain:0.16000000000000003 note:C5 clip:0.1 ]", - "[ 33/2 ⇜ (135/8 → 69/4) | gain:0.16000000000000003 note:Ab5 clip:0.1 ]", + "[ 63/4 ⇜ (135/8 → 69/4) | gain:0.16 note:C5 clip:0.1 ]", + "[ 33/2 ⇜ (135/8 → 69/4) | gain:0.16 note:Ab5 clip:0.1 ]", "[ 135/8 → 69/4 | s:hh gain:0.7 ]", "[ 135/8 → 141/8 | gain:1 note:F3 clip:0.1 ]", "[ (135/8 → 18/1) ⇝ 147/8 | gain:1 note:C3 clip:0.1 ]", - "[ 255/16 ⇜ (273/16 → 279/16) | gain:0.06400000000000002 note:C6 clip:0.1 ]", - "[ 267/16 ⇜ (273/16 → 279/16) | gain:0.06400000000000002 note:Ab6 clip:0.1 ]", + "[ 255/16 ⇜ (273/16 → 279/16) | gain:0.064 note:C6 clip:0.1 ]", + "[ 267/16 ⇜ (273/16 → 279/16) | gain:0.064 note:Ab6 clip:0.1 ]", "[ 273/16 → 285/16 | gain:0.4 note:F4 clip:0.1 ]", "[ (273/16 → 18/1) ⇝ 297/16 | gain:0.4 note:C4 clip:0.1 ]", "[ 69/4 → 141/8 | s:sn gain:0.7 ]", - "[ 69/4 → 18/1 | gain:0.16000000000000003 note:F5 clip:0.1 ]", - "[ (69/4 → 18/1) ⇝ 75/4 | gain:0.16000000000000003 note:C5 clip:0.1 ]", - "[ (279/16 → 18/1) ⇝ 291/16 | gain:0.06400000000000002 note:F6 clip:0.1 ]", - "[ (279/16 → 18/1) ⇝ 303/16 | gain:0.06400000000000002 note:C6 clip:0.1 ]", + "[ 69/4 → 18/1 | gain:0.16 note:F5 clip:0.1 ]", + "[ (69/4 → 18/1) ⇝ 75/4 | gain:0.16 note:C5 clip:0.1 ]", + "[ (279/16 → 18/1) ⇝ 291/16 | gain:0.064 note:F6 clip:0.1 ]", + "[ (279/16 → 18/1) ⇝ 303/16 | gain:0.064 note:C6 clip:0.1 ]", "[ 141/8 → 18/1 | s:hh gain:0.7 ]", "[ (141/8 → 18/1) ⇝ 147/8 | gain:1 note:Ab3 clip:0.1 ]", "[ (285/16 → 18/1) ⇝ 297/16 | gain:0.4 note:Ab4 clip:0.1 ]", "[ 273/16 ⇜ (18/1 → 291/16) ⇝ 297/16 | gain:0.4 note:G3 clip:0.1 ]", - "[ 279/16 ⇜ (18/1 → 291/16) | gain:0.06400000000000002 note:C6 clip:0.1 ]", + "[ 279/16 ⇜ (18/1 → 291/16) | gain:0.064 note:C6 clip:0.1 ]", "[ 285/16 ⇜ (18/1 → 291/16) ⇝ 297/16 | gain:0.4 note:Eb4 clip:0.1 ]", "[ 18/1 → 291/16 | s:bd gain:0.7 ]", - "[ 69/4 ⇜ (18/1 → 147/8) ⇝ 75/4 | gain:0.16000000000000003 note:G4 clip:0.1 ]", + "[ 69/4 ⇜ (18/1 → 147/8) ⇝ 75/4 | gain:0.16 note:G4 clip:0.1 ]", "[ 18/1 → 147/8 | gain:1 note:C2 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", - "[ (18/1 → 147/8) ⇝ 75/4 | gain:0.16000000000000003 note:Eb5 clip:0.1 ]", - "[ 279/16 ⇜ (18/1 → 297/16) ⇝ 303/16 | gain:0.06400000000000002 note:G5 clip:0.1 ]", + "[ (18/1 → 147/8) ⇝ 75/4 | gain:0.16 note:Eb5 clip:0.1 ]", + "[ 279/16 ⇜ (18/1 → 297/16) ⇝ 303/16 | gain:0.064 note:G5 clip:0.1 ]", "[ 18/1 → 75/4 | gain:1 note:C3 clip:0.1 ]", "[ 18/1 → 39/2 | gain:1 note:G2 clip:0.1 ]", "[ 291/16 → 147/8 | s:bd gain:0.7 ]", "[ 291/16 → 297/16 | gain:1 note:C2 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", - "[ (291/16 → 297/16) ⇝ 303/16 | gain:0.06400000000000002 note:Eb6 clip:0.1 ]", + "[ (291/16 → 297/16) ⇝ 303/16 | gain:0.064 note:Eb6 clip:0.1 ]", "[ 291/16 → 303/16 | gain:0.4 note:C4 clip:0.1 ]", "[ (291/16 → 39/2) ⇝ 315/16 | gain:0.4 note:G3 clip:0.1 ]", "[ 147/8 → 75/4 | s:hh gain:0.7 ]", "[ 147/8 → 75/4 | gain:1 note:A1 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", - "[ 147/8 → 153/8 | gain:0.16000000000000003 note:C5 clip:0.1 ]", - "[ (147/8 → 39/2) ⇝ 159/8 | gain:0.16000000000000003 note:G4 clip:0.1 ]", + "[ 147/8 → 153/8 | gain:0.16 note:C5 clip:0.1 ]", + "[ (147/8 → 39/2) ⇝ 159/8 | gain:0.16 note:G4 clip:0.1 ]", "[ 297/16 → 303/16 | gain:1 note:A1 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", - "[ 297/16 → 309/16 | gain:0.06400000000000002 note:C6 clip:0.1 ]", - "[ (297/16 → 39/2) ⇝ 321/16 | gain:0.06400000000000002 note:G5 clip:0.1 ]", + "[ 297/16 → 309/16 | gain:0.064 note:C6 clip:0.1 ]", + "[ (297/16 → 39/2) ⇝ 321/16 | gain:0.064 note:G5 clip:0.1 ]", "[ 75/4 → 153/8 | s:sn gain:0.7 ]", "[ 75/4 → 153/8 | gain:1 note:Bb1 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", "[ 75/4 → 39/2 | gain:1 note:Eb3 clip:0.1 ]", "[ 303/16 → 309/16 | gain:1 note:Bb1 s:square clip:0.4 cutoff:400 decay:0.12 sustain:0 ]", "[ (303/16 → 39/2) ⇝ 315/16 | gain:0.4 note:Eb4 clip:0.1 ]", "[ 153/8 → 39/2 | s:hh gain:0.7 ]", - "[ (153/8 → 39/2) ⇝ 159/8 | gain:0.16000000000000003 note:Eb5 clip:0.1 ]", - "[ (309/16 → 39/2) ⇝ 321/16 | gain:0.06400000000000002 note:Eb6 clip:0.1 ]", + "[ (153/8 → 39/2) ⇝ 159/8 | gain:0.16 note:Eb5 clip:0.1 ]", + "[ (309/16 → 39/2) ⇝ 321/16 | gain:0.064 note:Eb6 clip:0.1 ]", "[ 291/16 ⇜ (39/2 → 315/16) | gain:0.4 note:G3 clip:0.1 ]", "[ 303/16 ⇜ (39/2 → 315/16) | gain:0.4 note:Eb4 clip:0.1 ]", - "[ 147/8 ⇜ (39/2 → 159/8) | gain:0.16000000000000003 note:G4 clip:0.1 ]", + "[ 147/8 ⇜ (39/2 → 159/8) | gain:0.16 note:G4 clip:0.1 ]", "[ 153/8 ⇜ (39/2 → 159/8) | gain:1 note:C3 clip:0.1 ]", - "[ 153/8 ⇜ (39/2 → 159/8) | gain:0.16000000000000003 note:Eb5 clip:0.1 ]", + "[ 153/8 ⇜ (39/2 → 159/8) | gain:0.16 note:Eb5 clip:0.1 ]", "[ 39/2 → 159/8 | s:bd gain:0.7 ]", - "[ 297/16 ⇜ (39/2 → 20/1) ⇝ 321/16 | gain:0.06400000000000002 note:G5 clip:0.1 ]", + "[ 297/16 ⇜ (39/2 → 20/1) ⇝ 321/16 | gain:0.064 note:G5 clip:0.1 ]", "[ 153/8 ⇜ (39/2 → 20/1) ⇝ 165/8 | gain:1 note:G2 clip:0.1 ]", - "[ 309/16 ⇜ (39/2 → 20/1) ⇝ 321/16 | gain:0.06400000000000002 note:Eb6 clip:0.1 ]", + "[ 309/16 ⇜ (39/2 → 20/1) ⇝ 321/16 | gain:0.064 note:Eb6 clip:0.1 ]", "[ 309/16 ⇜ (315/16 → 20/1) ⇝ 321/16 | gain:0.4 note:C4 clip:0.1 ]", "[ 309/16 ⇜ (315/16 → 20/1) ⇝ 333/16 | gain:0.4 note:G3 clip:0.1 ]", - "[ 39/2 ⇜ (159/8 → 20/1) ⇝ 81/4 | gain:0.16000000000000003 note:C5 clip:0.1 ]", - "[ 39/2 ⇜ (159/8 → 20/1) ⇝ 21/1 | gain:0.16000000000000003 note:G4 clip:0.1 ]", + "[ 39/2 ⇜ (159/8 → 20/1) ⇝ 81/4 | gain:0.16 note:C5 clip:0.1 ]", + "[ 39/2 ⇜ (159/8 → 20/1) ⇝ 21/1 | gain:0.16 note:G4 clip:0.1 ]", "[ (159/8 → 20/1) ⇝ 81/4 | s:hh gain:0.7 ]", "[ (159/8 → 20/1) ⇝ 165/8 | gain:1 note:Eb3 clip:0.1 ]", ] @@ -8737,22 +8737,22 @@ exports[`renders tunes > tune: undergroundPlumber 1`] = ` exports[`renders tunes > tune: waa2 1`] = ` [ - "[ -1/4 ⇜ (0/1 → 1/4) | note:48 clip:1.1023401198483869 s:sawtooth cutoff:3991.573271676344 gain:0.5 room:0.5 lpattack:0.125 lpenv:-2 vib:8 vibmod:0.125 fanchor:0.25 ]", - "[ -1/4 ⇜ (0/1 → 1/4) | note:64 clip:1.1023401198483869 s:sawtooth cutoff:3991.573271676344 gain:0.5 room:0.5 lpattack:0.125 lpenv:-2 vib:8 vibmod:0.125 fanchor:0.25 ]", + "[ -1/4 ⇜ (0/1 → 1/4) | note:48 clip:1.102340119848 s:sawtooth cutoff:3991.573271676344 gain:0.5 room:0.5 lpattack:0.125 lpenv:-2 vib:8 vibmod:0.125 fanchor:0.25 ]", + "[ -1/4 ⇜ (0/1 → 1/4) | note:64 clip:1.102340119848 s:sawtooth cutoff:3991.573271676344 gain:0.5 room:0.5 lpattack:0.125 lpenv:-2 vib:8 vibmod:0.125 fanchor:0.25 ]", "[ (0/1 → 1/4) ⇝ 1/2 | note:62 clip:1.15 s:sawtooth cutoff:4000 gain:0.5 room:0.5 lpattack:0.125 lpenv:-2 vib:8 vibmod:0.125 fanchor:0.25 ]", "[ (0/1 → 1/4) ⇝ 1/2 | note:43 clip:1.15 s:sawtooth cutoff:4000 gain:0.5 room:0.5 lpattack:0.125 lpenv:-2 vib:8 vibmod:0.125 fanchor:0.25 ]", "[ 0/1 ⇜ (1/4 → 1/2) | note:62 clip:1.15 s:square cutoff:4000 gain:0.5 room:0.5 lpattack:0.125 lpenv:-2 vib:8 vibmod:0.125 fanchor:0.25 ]", "[ 0/1 ⇜ (1/4 → 1/2) | note:43 clip:1.15 s:square cutoff:4000 gain:0.5 room:0.5 lpattack:0.125 lpenv:-2 vib:8 vibmod:0.125 fanchor:0.25 ]", - "[ (1/4 → 1/2) ⇝ 3/4 | note:74 clip:1.197659880151613 s:square cutoff:3991.5732716763446 gain:0.5 room:0.5 lpattack:0.125 lpenv:-2 vib:8 vibmod:0.125 fanchor:0.25 ]", - "[ (1/4 → 1/2) ⇝ 3/4 | note:55 clip:1.197659880151613 s:square cutoff:3991.5732716763446 gain:0.5 room:0.5 lpattack:0.125 lpenv:-2 vib:8 vibmod:0.125 fanchor:0.25 ]", - "[ 1/4 ⇜ (1/2 → 3/4) | note:74 clip:1.197659880151613 s:sawtooth cutoff:3991.5732716763446 gain:0.5 room:0.5 lpattack:0.125 lpenv:-2 vib:8 vibmod:0.125 fanchor:0.25 ]", - "[ 1/4 ⇜ (1/2 → 3/4) | note:55 clip:1.197659880151613 s:sawtooth cutoff:3991.5732716763446 gain:0.5 room:0.5 lpattack:0.125 lpenv:-2 vib:8 vibmod:0.125 fanchor:0.25 ]", - "[ 1/2 → 3/4 | note:50 clip:1.2451698046878117 s:sawtooth cutoff:3966.3742407056534 gain:0.5 room:0.5 lpattack:0.125 lpenv:-2 vib:8 vibmod:0.125 fanchor:0.25 ]", - "[ (1/2 → 3/4) ⇝ 1/1 | note:69 clip:1.2451698046878117 s:sawtooth cutoff:3966.3742407056534 gain:0.5 room:0.5 lpattack:0.125 lpenv:-2 vib:8 vibmod:0.125 fanchor:0.25 ]", - "[ 1/2 ⇜ (3/4 → 1/1) | note:69 clip:1.2451698046878117 s:square cutoff:3966.3742407056534 gain:0.5 room:0.5 lpattack:0.125 lpenv:-2 vib:8 vibmod:0.125 fanchor:0.25 ]", - "[ 3/4 → 1/1 | note:41 clip:1.292380289809026 s:square cutoff:3924.645587531366 gain:0.5 room:0.5 lpattack:0.125 lpenv:-2 vib:8 vibmod:0.125 fanchor:0.25 ]", - "[ 3/4 → 1/1 | note:62 clip:1.292380289809026 s:square cutoff:3924.645587531366 gain:0.5 room:0.5 lpattack:0.125 lpenv:-2 vib:8 vibmod:0.125 fanchor:0.25 ]", - "[ (3/4 → 1/1) ⇝ 5/4 | note:81 clip:1.292380289809026 s:square cutoff:3924.645587531366 gain:0.5 room:0.5 lpattack:0.125 lpenv:-2 vib:8 vibmod:0.125 fanchor:0.25 ]", + "[ (1/4 → 1/2) ⇝ 3/4 | note:74 clip:1.197659880152 s:square cutoff:3991.573271676345 gain:0.5 room:0.5 lpattack:0.125 lpenv:-2 vib:8 vibmod:0.125 fanchor:0.25 ]", + "[ (1/4 → 1/2) ⇝ 3/4 | note:55 clip:1.197659880152 s:square cutoff:3991.573271676345 gain:0.5 room:0.5 lpattack:0.125 lpenv:-2 vib:8 vibmod:0.125 fanchor:0.25 ]", + "[ 1/4 ⇜ (1/2 → 3/4) | note:74 clip:1.197659880152 s:sawtooth cutoff:3991.573271676345 gain:0.5 room:0.5 lpattack:0.125 lpenv:-2 vib:8 vibmod:0.125 fanchor:0.25 ]", + "[ 1/4 ⇜ (1/2 → 3/4) | note:55 clip:1.197659880152 s:sawtooth cutoff:3991.573271676345 gain:0.5 room:0.5 lpattack:0.125 lpenv:-2 vib:8 vibmod:0.125 fanchor:0.25 ]", + "[ 1/2 → 3/4 | note:50 clip:1.245169804688 s:sawtooth cutoff:3966.374240705653 gain:0.5 room:0.5 lpattack:0.125 lpenv:-2 vib:8 vibmod:0.125 fanchor:0.25 ]", + "[ (1/2 → 3/4) ⇝ 1/1 | note:69 clip:1.245169804688 s:sawtooth cutoff:3966.374240705653 gain:0.5 room:0.5 lpattack:0.125 lpenv:-2 vib:8 vibmod:0.125 fanchor:0.25 ]", + "[ 1/2 ⇜ (3/4 → 1/1) | note:69 clip:1.245169804688 s:square cutoff:3966.374240705653 gain:0.5 room:0.5 lpattack:0.125 lpenv:-2 vib:8 vibmod:0.125 fanchor:0.25 ]", + "[ 3/4 → 1/1 | note:41 clip:1.292380289809 s:square cutoff:3924.645587531366 gain:0.5 room:0.5 lpattack:0.125 lpenv:-2 vib:8 vibmod:0.125 fanchor:0.25 ]", + "[ 3/4 → 1/1 | note:62 clip:1.292380289809 s:square cutoff:3924.645587531366 gain:0.5 room:0.5 lpattack:0.125 lpenv:-2 vib:8 vibmod:0.125 fanchor:0.25 ]", + "[ (3/4 → 1/1) ⇝ 5/4 | note:81 clip:1.292380289809 s:square cutoff:3924.645587531366 gain:0.5 room:0.5 lpattack:0.125 lpenv:-2 vib:8 vibmod:0.125 fanchor:0.25 ]", ] `; diff --git a/test/tunes.test.mjs b/test/tunes.test.mjs index 7e3c346aa..94d9fae0b 100644 --- a/test/tunes.test.mjs +++ b/test/tunes.test.mjs @@ -4,11 +4,25 @@ import { describe, it } from 'vitest'; const tuneKeys = Object.keys(tunes); +// Node 24 tightened Number→string rounding; clamp decimals so snapshots stay stable across engines. +const roundFloatStrings = (input, precision = 12) => { + // if matches a decimal number ex: 12.34, -0.5, 0.123, 99.0, 1.932093850293 + const regex = /-?\d+\.\d+/g; + return input.replace(regex, (match) => { + // converts the literal to a number, performs round to nearest (ties to even) + // at the requested precision, and returns the rounded decimal string + const rounded = Number(match).toFixed(precision); + // trims trailing zeros (and a dangling dot) after rounding, so the displayed string looks tidy + return rounded.replace(/\.?0+$/, '').replace(/\.$/, ''); + }); +}; + describe('renders tunes', () => { tuneKeys.forEach((key) => { it(`tune: ${key}`, async ({ expect }) => { const haps = await queryCode(tunes[key], testCycles[key] || 1); - expect(haps).toMatchSnapshot(); + const normalized = haps.map((hap) => roundFloatStrings(hap)); + expect(normalized).toMatchSnapshot(); }); }); }); diff --git a/tools/dbpatch/package.json b/tools/dbpatch/package.json index 52f5520f8..3ee042ad9 100644 --- a/tools/dbpatch/package.json +++ b/tools/dbpatch/package.json @@ -1,5 +1,8 @@ { "dependencies": { "csv": "^6.3.11" + }, + "engines": { + "node": ">=18.0.0" } } diff --git a/website/package.json b/website/package.json index 87f4025e4..6f5539dd6 100644 --- a/website/package.json +++ b/website/package.json @@ -75,5 +75,8 @@ "sharp": "^0.33.5", "workbox-window": "^7.3.0", "vite-plugin-bundle-audioworklet": "workspace:*" + }, + "engines": { + "node": ">=18.0.0" } } From 79875ebc50f73b5adc72c1971be35e008cb3f14a Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Wed, 5 Nov 2025 01:26:36 -0500 Subject: [PATCH 322/335] fix branch --- packages/xen/tunejs.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/xen/tunejs.js b/packages/xen/tunejs.js index 5806cf596..9f4253709 100644 --- a/packages/xen/tunejs.js +++ b/packages/xen/tunejs.js @@ -41,7 +41,6 @@ Tune.prototype.tonicize = function(newTonic) { this.tonic = newTonic } - /* Return data in the mode you are in (freq, ratio, or midi) */ Tune.prototype.note = function(input,octave){ From a3f82f90a9c57033df1e9bf3f6ad377626d94b00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C5=BD=C3=A1ra?= Date: Thu, 6 Nov 2025 08:15:55 +0100 Subject: [PATCH 323/335] test fix --- test/__snapshots__/examples.test.mjs.snap | 37 +++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index a27c5a6bc..818c0270a 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -9214,6 +9214,43 @@ exports[`runs examples > example "scale" example index 4 1`] = ` ] `; +exports[`runs examples > example "scale" example index 5 1`] = ` +[ + "[ 0/1 → 1/8 | note:C3 ]", + "[ 1/8 → 1/4 | note:C3 ]", + "[ 1/4 → 3/8 | note:D3 ]", + "[ 3/8 → 1/2 | note:Eb3 ]", + "[ 1/2 → 5/8 | note:E3 ]", + "[ 5/8 → 3/4 | note:G3 ]", + "[ 3/4 → 7/8 | note:A3 ]", + "[ 7/8 → 1/1 | note:C4 ]", + "[ 1/1 → 9/8 | note:C3 ]", + "[ 9/8 → 5/4 | note:C3 ]", + "[ 5/4 → 11/8 | note:D3 ]", + "[ 11/8 → 3/2 | note:Eb3 ]", + "[ 3/2 → 13/8 | note:E3 ]", + "[ 13/8 → 7/4 | note:G3 ]", + "[ 7/4 → 15/8 | note:A3 ]", + "[ 15/8 → 2/1 | note:C4 ]", + "[ 2/1 → 17/8 | note:C3 ]", + "[ 17/8 → 9/4 | note:C3 ]", + "[ 9/4 → 19/8 | note:D3 ]", + "[ 19/8 → 5/2 | note:Eb3 ]", + "[ 5/2 → 21/8 | note:E3 ]", + "[ 21/8 → 11/4 | note:G3 ]", + "[ 11/4 → 23/8 | note:A3 ]", + "[ 23/8 → 3/1 | note:C4 ]", + "[ 3/1 → 25/8 | note:C3 ]", + "[ 25/8 → 13/4 | note:C3 ]", + "[ 13/4 → 27/8 | note:D3 ]", + "[ 27/8 → 7/2 | note:Eb3 ]", + "[ 7/2 → 29/8 | note:E3 ]", + "[ 29/8 → 15/4 | note:G3 ]", + "[ 15/4 → 31/8 | note:A3 ]", + "[ 31/8 → 4/1 | note:C4 ]", +] +`; + exports[`runs examples > example "scaleTranspose" example index 0 1`] = ` [ "[ 0/1 → 1/2 | note:C3 ]", From 1b37f1ed1ddc5bafedbd9037369cfc446e35c4fd Mon Sep 17 00:00:00 2001 From: PepsiiMan Date: Thu, 6 Nov 2025 15:33:06 +0100 Subject: [PATCH 324/335] soundAlias example fix --- website/src/pages/learn/samples.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/pages/learn/samples.mdx b/website/src/pages/learn/samples.mdx index 201d57dfa..6a2f0cb95 100644 --- a/website/src/pages/learn/samples.mdx +++ b/website/src/pages/learn/samples.mdx @@ -63,7 +63,7 @@ You can also create custom aliases for existing sounds using the `soundAlias` fu From 3e7ae880430a547f6fa70ae88b392966d02d71c6 Mon Sep 17 00:00:00 2001 From: drhayes Date: Mon, 10 Nov 2025 17:02:55 +0100 Subject: [PATCH 325/335] Fix typo: 'studel' -> 'strudel' --- website/src/pages/technical-manual/project-start.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/pages/technical-manual/project-start.mdx b/website/src/pages/technical-manual/project-start.mdx index 4a269d1b9..b9a4ab0e6 100644 --- a/website/src/pages/technical-manual/project-start.mdx +++ b/website/src/pages/technical-manual/project-start.mdx @@ -32,7 +32,7 @@ There are 3 quick ways to embed strudel in your website: ### Inside an iframe -Using an iframe is the most easy way to embed a studel tune. +Using an iframe is the most easy way to embed a strudel tune. You can embed any pattern of your choice via an iframe and the URL of the pattern of your choice: ```html From 3c6de3be6d571bdcda0a19246d74d854fccaea22 Mon Sep 17 00:00:00 2001 From: Aria Date: Wed, 12 Nov 2025 10:48:20 -0600 Subject: [PATCH 326/335] First pass of worklets optimizations --- packages/superdough/worklets.mjs | 183 ++++++++++++++----------------- 1 file changed, 84 insertions(+), 99 deletions(-) diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 7d7ef8e2a..b004ef3ab 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -6,13 +6,26 @@ import OLAProcessor from './ola-processor'; import FFT from './fft.js'; import { getDistortionAlgorithm } from './helpers.mjs'; +const blockSize = 128; +const PI = Math.PI; +const TWO_PI = 2 * PI; +const INVSR = 1 / sampleRate; + const clamp = (num, min, max) => Math.min(Math.max(num, min), max); const mod = (n, m) => ((n % m) + m) % m; const lerp = (a, b, n) => n * (b - a) + a; const pv = (arr, n) => arr[n] ?? arr[0]; const frac = (x) => x - Math.floor(x); -const ffloor = (x) => x | 0; // fast floor for non-negative +// Fast integer ops for non-negative values +const ffloor = (x) => x | 0; +const fround = (x) => ffloor(x + 0.5); +const fceil = (x) => ffloor(x + 1); + +const fast_tanh = (x) => { + const x2 = x * x; + return (x * (27.0 + x2)) / (27.0 + 9.0 * x2); +}; const getUnisonDetune = (unison, detune, voiceIndex) => { if (unison < 2) { return 0; @@ -32,7 +45,6 @@ function wrapPhase(phase, maxPhase = 1) { } return phase; } -const blockSize = 128; // Smooth waveshape near discontinuities to remove frequencies above Nyquist and prevent aliasing // referenced from https://www.kvraudio.com/forum/viewtopic.php?t=375517 function polyBlep(phase, dt) { @@ -66,7 +78,7 @@ const waveshapes = { return phase / skew; }, sine(phase) { - return Math.sin(Math.PI * 2 * phase) * 0.5 + 0.5; + return Math.sin(TWO_PI * phase) * 0.5 + 0.5; }, ramp(phase) { return phase; @@ -100,12 +112,6 @@ const waveshapes = { return v - polyBlep(phase, dt); }, }; -function getParamValue(block, param) { - if (param.length > 1) { - return param[block]; - } - return param[0]; -} const waveShapeNames = Object.keys(waveshapes); class LFOProcessor extends AudioWorkletProcessor { @@ -167,7 +173,7 @@ class LFOProcessor extends AudioWorkletProcessor { if (this.phase == null) { this.phase = mod(time * frequency + phaseoffset, 1); } - const dt = frequency / sampleRate; + const dt = frequency * INVSR; for (let n = 0; n < blockSize; n++) { for (let i = 0; i < output.length; i++) { let modval = (waveshapes[shape](this.phase, skew) + dcoffset) * depth; @@ -293,8 +299,8 @@ class TwoPoleFilter { // Out of bound values can produce NaNs resonance = clamp(resonance, 0, 1); cutoff = clamp(cutoff, 0, sampleRate / 2 - 1); - const c = clamp(2 * Math.sin(cutoff * (_PI / sampleRate)), 0, 1.14); - const r = Math.pow(0.5, (resonance + 0.125) / 0.125); + const c = clamp(2 * Math.sin(cutoff * PI * INVSR), 0, 1.14); + const r = Math.pow(0.5, 8 * resonance + 1); const mrc = 1 - r * c; this.s0 = mrc * this.s0 - c * this.s1 + c * s; // bpf this.s1 = mrc * this.s1 + c * this.s0; // lpf @@ -353,11 +359,6 @@ class DJFProcessor extends AudioWorkletProcessor { } registerProcessor('djf-processor', DJFProcessor); -function fast_tanh(x) { - const x2 = x * x; - return (x * (27.0 + x2)) / (27.0 + 9.0 * x2); -} -const _PI = 3.14159265359; //adapted from https://github.com/TheBouteillacBear/webaudioworklet-wasm?tab=MIT-1-ov-file class LadderProcessor extends AudioWorkletProcessor { static get parameterDescriptors() { @@ -395,7 +396,7 @@ class LadderProcessor extends AudioWorkletProcessor { const drive = clamp(Math.exp(parameters.drive[0]), 0.1, 2000); let cutoff = parameters.frequency[0]; - cutoff = (cutoff * 2 * _PI) / sampleRate; + cutoff = cutoff * TWO_PI * INVSR; cutoff = cutoff > 1 ? 1 : cutoff; const k = Math.min(8, resonance * 0.13); @@ -545,7 +546,7 @@ class SuperSawOscillatorProcessor extends AudioWorkletProcessor { const freqVoice = applySemitoneDetuneToFrequency(freq, getUnisonDetune(voices, freqspread, n)); // We must wrap this here because it is passed into sawblep below which // has domain [0, 1] - const dt = mod(freqVoice / sampleRate, 1); + const dt = mod(freqVoice * INVSR, 1); this.phase[n] = this.phase[n] ?? Math.random(); const v = waveshapes.sawblep(this.phase[n], dt); @@ -564,12 +565,16 @@ registerProcessor('supersaw-oscillator', SuperSawOscillatorProcessor); // Phase Vocoder sourced from https://github.com/olvb/phaze/tree/master?tab=readme-ov-file const BUFFERED_BLOCK_SIZE = 2048; +const hannCache = new Map(); function genHannWindow(length) { - let win = new Float32Array(length); - for (var i = 0; i < length; i++) { - win[i] = 0.5 * (1 - Math.cos((2 * Math.PI * i) / length)); + if (!hannCache.has(length)) { + const win = new Float32Array(length); + for (let i = 0; i < length; i++) { + win[i] = 0.5 * (1 - Math.cos((TWO_PI * i) / length)); + } + hannCache.set(length, win); } - return win; + return hannCache.get(length); } class PhaseVocoderProcessor extends OLAProcessor { @@ -587,11 +592,14 @@ class PhaseVocoderProcessor extends OLAProcessor { blockSize: BUFFERED_BLOCK_SIZE, }; super(options); - - this.fftSize = this.blockSize; this.timeCursor = 0; - - this.hannWindow = genHannWindow(this.blockSize); + this.fftSize = this.blockSize; + this.invfftSize = 1 / this.fftSize; + this.hannWindow = genHannWindow(this.fftSize); + // rescale hann window (empirically sounds nicer) + for (let i = 0; i < this.hannWindow.length; i++) { + this.hannWindow[i] *= 1.62; + } // prepare FFT and pre-allocate buffers this.fft = new FFT(this.fftSize); this.freqComplexBuffer = this.fft.createComplexArray(); @@ -604,54 +612,45 @@ class PhaseVocoderProcessor extends OLAProcessor { processOLA(inputs, outputs, parameters) { // no automation, take last value - let pitchFactor = parameters.pitchFactor[parameters.pitchFactor.length - 1]; - if (pitchFactor < 0) { pitchFactor = pitchFactor * 0.25; } pitchFactor = Math.max(0, pitchFactor + 1); - - for (var i = 0; i < this.nbInputs; i++) { - for (var j = 0; j < inputs[i].length; j++) { - // big assumption here: output is symetric to input - var input = inputs[i][j]; - var output = outputs[i][j]; - + for (let i = 0; i < this.nbInputs; i++) { + for (let j = 0; j < inputs[i].length; j++) { + const input = inputs[i][j]; + const output = outputs[i][j]; this.applyHannWindow(input); - this.fft.realTransform(this.freqComplexBuffer, input); - this.computeMagnitudes(); this.findPeaks(); this.shiftPeaks(pitchFactor); - this.fft.completeSpectrum(this.freqComplexBufferShifted); this.fft.inverseTransform(this.timeComplexBuffer, this.freqComplexBufferShifted); this.fft.fromComplexArray(this.timeComplexBuffer, output); this.applyHannWindow(output); } } - this.timeCursor += this.hopSize; } /** Apply Hann window in-place */ applyHannWindow(input) { - for (var i = 0; i < this.blockSize; i++) { - input[i] = input[i] * this.hannWindow[i] * 1.62; + for (let i = 0; i < this.blockSize; i++) { + input[i] *= this.hannWindow[i]; } } /** Compute squared magnitudes for peak finding **/ computeMagnitudes() { - var i = 0, + let i = 0, j = 0; while (i < this.magnitudes.length) { - let real = this.freqComplexBuffer[j]; - let imag = this.freqComplexBuffer[j + 1]; + const real = this.freqComplexBuffer[j]; + const imag = this.freqComplexBuffer[j + 1]; // no need to sqrt for peak finding - this.magnitudes[i] = real ** 2 + imag ** 2; + this.magnitudes[i] = real * real + imag * imag; i += 1; j += 2; } @@ -660,12 +659,10 @@ class PhaseVocoderProcessor extends OLAProcessor { /** Find peaks in spectrum magnitudes **/ findPeaks() { this.nbPeaks = 0; - var i = 2; - let end = this.magnitudes.length - 2; - + let i = 2; + const end = this.magnitudes.length - 2; while (i < end) { - let mag = this.magnitudes[i]; - + const mag = this.magnitudes[i]; if (this.magnitudes[i - 1] >= mag || this.magnitudes[i - 2] >= mag) { i++; continue; @@ -674,7 +671,6 @@ class PhaseVocoderProcessor extends OLAProcessor { i++; continue; } - this.peakIndexes[this.nbPeaks] = i; this.nbPeaks++; i += 2; @@ -685,53 +681,44 @@ class PhaseVocoderProcessor extends OLAProcessor { shiftPeaks(pitchFactor) { // zero-fill new spectrum this.freqComplexBufferShifted.fill(0); - - for (var i = 0; i < this.nbPeaks; i++) { - let peakIndex = this.peakIndexes[i]; - let peakIndexShifted = Math.round(peakIndex * pitchFactor); - + for (let i = 0; i < this.nbPeaks; i++) { + const peakIndex = this.peakIndexes[i]; + const peakIndexShifted = fround(peakIndex * pitchFactor); if (peakIndexShifted > this.magnitudes.length) { break; } - // find region of influence - var startIndex = 0; - var endIndex = this.fftSize; + let startIndex = 0; + let endIndex = this.fftSize; if (i > 0) { - let peakIndexBefore = this.peakIndexes[i - 1]; - startIndex = peakIndex - Math.floor((peakIndex - peakIndexBefore) / 2); + startIndex = peakIndex - fround((peakIndex - this.peakIndexes[i - 1]) / 2); } if (i < this.nbPeaks - 1) { - let peakIndexAfter = this.peakIndexes[i + 1]; - endIndex = peakIndex + Math.ceil((peakIndexAfter - peakIndex) / 2); + endIndex = peakIndex + fceil((this.peakIndexes[i + 1] - peakIndex) / 2); } - // shift whole region of influence around peak to shifted peak - let startOffset = startIndex - peakIndex; - let endOffset = endIndex - peakIndex; - for (var j = startOffset; j < endOffset; j++) { - let binIndex = peakIndex + j; - let binIndexShifted = peakIndexShifted + j; - + const startOffset = startIndex - peakIndex; + const endOffset = endIndex - peakIndex; + const omegaDelta = TWO_PI * this.invfftSize * (binIndexShifted - binIndex); + const phaseShiftReal = Math.cos(omegaDelta * this.timeCursor); + const phaseShiftImag = Math.sin(omegaDelta * this.timeCursor); + for (let j = startOffset; j < endOffset; j++) { + const binIndex = peakIndex + j; + const binIndexShifted = peakIndexShifted + j; if (binIndexShifted >= this.magnitudes.length) { break; } - // apply phase correction - let omegaDelta = (2 * Math.PI * (binIndexShifted - binIndex)) / this.fftSize; - let phaseShiftReal = Math.cos(omegaDelta * this.timeCursor); - let phaseShiftImag = Math.sin(omegaDelta * this.timeCursor); + const indexReal = 2 * binIndex; + const indexImag = indexReal + 1; + const valueReal = this.freqComplexBuffer[indexReal]; + const valueImag = this.freqComplexBuffer[indexImag]; - let indexReal = binIndex * 2; - let indexImag = indexReal + 1; - let valueReal = this.freqComplexBuffer[indexReal]; - let valueImag = this.freqComplexBuffer[indexImag]; + const valueShiftedReal = valueReal * phaseShiftReal - valueImag * phaseShiftImag; + const valueShiftedImag = valueReal * phaseShiftImag + valueImag * phaseShiftReal; - let valueShiftedReal = valueReal * phaseShiftReal - valueImag * phaseShiftImag; - let valueShiftedImag = valueReal * phaseShiftImag + valueImag * phaseShiftReal; - - let indexShiftedReal = binIndexShifted * 2; - let indexShiftedImag = indexShiftedReal + 1; + const indexShiftedReal = 2 * binIndexShifted; + const indexShiftedImag = indexShiftedReal + 1; this.freqComplexBufferShifted[indexShiftedReal] += valueShiftedReal; this.freqComplexBufferShifted[indexShiftedImag] += valueShiftedImag; } @@ -745,11 +732,10 @@ registerProcessor('phase-vocoder-processor', PhaseVocoderProcessor); class PulseOscillatorProcessor extends AudioWorkletProcessor { constructor() { super(); - this.pi = _PI; - this.phi = -this.pi; // phase + this.phi = -PI; // phase this.Y0 = 0; // feedback memories this.Y1 = 0; - this.PW = this.pi; // pulse width + this.PW = PI; // pulse width this.B = 2.3; // feedback coefficient this.dphif = 0; // filtered phase increment this.envf = 0; // filtered envelope @@ -806,9 +792,9 @@ class PulseOscillatorProcessor extends AudioWorkletProcessor { dphi; for (let i = 0; i < (output[0].length ?? 0); i++) { - const pw = (1 - clamp(getParamValue(i, params.pulsewidth), -0.99, 0.99)) * this.pi; - const detune = getParamValue(i, params.detune); - const freq = applySemitoneDetuneToFrequency(getParamValue(i, params.frequency), detune / 100); + const pw = (1 - clamp(pv(params.pulsewidth, i), -0.99, 0.99)) * this.pi; + const detune = pv(params.detune, i); + const freq = applySemitoneDetuneToFrequency(pv(params.frequency, i), detune / 100); dphi = freq * (this.pi / (sampleRate * 0.5)); // phase increment this.dphif += 0.1 * (dphi - this.dphif); @@ -958,9 +944,9 @@ class ByteBeatProcessor extends AudioWorkletProcessor { } const output = outputs[0]; for (let i = 0; i < output[0].length; i++) { - const detune = getParamValue(i, params.detune); - const freq = applySemitoneDetuneToFrequency(getParamValue(i, params.frequency), detune / 100); - let local_t = (this.t / (sampleRate / 256)) * freq + this.initialOffset; + const detune = pv(params.detune, i); + const freq = applySemitoneDetuneToFrequency(pv(params.frequency, i), detune / 100); + let local_t = 256 * this.t * INVSR * freq + this.initialOffset; const funcValue = this.func(local_t); let signal = (funcValue & 255) / 127.5 - 1; const out = signal * 0.2; @@ -1067,7 +1053,6 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { this.frameLen = 0; this.numFrames = 0; this.phase = []; - this.invSR = 1 / sampleRate; this.port.onmessage = (e) => { const { type, payload } = e.data || {}; @@ -1104,7 +1089,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { _toBits(amt, min = 2, max = 12) { const b = max + (min - max) * amt; - return { b, n: Math.round(Math.pow(2, b)) }; + return { b, n: fround(Math.pow(2, b)) }; } _warpPhase(phase, amt, mode) { @@ -1139,7 +1124,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { } case WarpMode.FOLD: { const K = 7; - const k = 1 + Math.max(1, Math.round(K * amt)); + const k = 1 + Math.max(1, fround(K * amt)); return Math.abs(frac(k * phase) - 0.5) * 2; } case WarpMode.PWM: { @@ -1175,7 +1160,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { } case WarpMode.BINARY: { let { b } = this._toBits(amt, 3); - b = Math.round(b); + b = fround(b); const n = 1 << b; const idx = ffloor(phase * n); const ridx = bitReverse(idx, b); @@ -1209,7 +1194,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { case WarpMode.LOGISTIC: { let x = phase; const r = 3.6 + 0.4 * amt; - const iters = 1 + Math.round(2 * amt); + const iters = 1 + fround(2 * amt); for (let i = 0; i < iters; i++) x = r * x * (1 - x); return clamp(x, 0, 1); } @@ -1296,7 +1281,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { gainR = gain1; } const fVoice = applySemitoneDetuneToFrequency(f, getUnisonDetune(voices, freqspread, n)); // voice detune - const dPhase = fVoice * this.invSR; + const dPhase = fVoice * INVSR; const level = this._chooseMip(dPhase); const table = this.tables[level]; From aabf122161fbc0e2a276f0618498c26c27531bc8 Mon Sep 17 00:00:00 2001 From: Aria Date: Wed, 12 Nov 2025 11:53:38 -0600 Subject: [PATCH 327/335] Further optimizations, including detuner --- packages/superdough/worklets.mjs | 71 ++++++++++++++++---------------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index b004ef3ab..46f22d979 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -21,44 +21,42 @@ const frac = (x) => x - Math.floor(x); const ffloor = (x) => x | 0; const fround = (x) => ffloor(x + 0.5); const fceil = (x) => ffloor(x + 1); +const ffrac = (x) => x - ffloor(x); const fast_tanh = (x) => { const x2 = x * x; return (x * (27.0 + x2)) / (27.0 + 9.0 * x2); }; -const getUnisonDetune = (unison, detune, voiceIndex) => { + +// Optimized per-voice detuner which precomputes constants +const getDetuner = (unison, detune) => { if (unison < 2) { - return 0; + return (_voiceIdx) => 0; } - return lerp(-detune * 0.5, detune * 0.5, voiceIndex / (unison - 1)); + const scale = detune / (unison - 1); + const center = detune * 0.5; + return (voiceIdx) => voiceIdx * scale - center; }; + const applySemitoneDetuneToFrequency = (frequency, detune) => { return frequency * Math.pow(2, detune / 12); }; -// Restrict phase to the range [0, maxPhase) via wrapping -function wrapPhase(phase, maxPhase = 1) { - if (phase >= maxPhase) { - phase -= maxPhase; - } else if (phase < 0) { - phase += maxPhase; - } - return phase; -} // Smooth waveshape near discontinuities to remove frequencies above Nyquist and prevent aliasing // referenced from https://www.kvraudio.com/forum/viewtopic.php?t=375517 function polyBlep(phase, dt) { dt = Math.min(dt, 1 - dt); + const invdt = 1 / dt; // Start of cycle if (phase < dt) { - phase /= dt; + phase *= invdt; // 2 * (phase - phase^2/2 - 0.5) return phase + phase - phase * phase - 1; } // End of cycle else if (phase > 1 - dt) { - phase = (phase - 1) / dt; + phase = (phase - 1) * invdt; // 2 * (phase^2/2 + phase + 0.5) return phase * phase + phase + phase + 1; } @@ -171,7 +169,7 @@ class LFOProcessor extends AudioWorkletProcessor { const blockSize = output[0].length ?? 0; if (this.phase == null) { - this.phase = mod(time * frequency + phaseoffset, 1); + this.phase = ffrac(time * frequency + phaseoffset); } const dt = frequency * INVSR; for (let n = 0; n < blockSize; n++) { @@ -533,6 +531,7 @@ class SuperSawOscillatorProcessor extends AudioWorkletProcessor { let freq = pv(params.frequency, i); // Main detuning freq = applySemitoneDetuneToFrequency(freq, detune / 100); + const detuner = getDetuner(voices, freqspread); for (let n = 0; n < voices; n++) { const isOdd = (n & 1) == 1; let gainL = gain1; @@ -543,17 +542,17 @@ class SuperSawOscillatorProcessor extends AudioWorkletProcessor { gainR = gain1; } // Individual voice detuning - const freqVoice = applySemitoneDetuneToFrequency(freq, getUnisonDetune(voices, freqspread, n)); + const freqVoice = applySemitoneDetuneToFrequency(freq, detuner(n)); // We must wrap this here because it is passed into sawblep below which // has domain [0, 1] - const dt = mod(freqVoice * INVSR, 1); + const dt = ffrac(freqVoice * INVSR); this.phase[n] = this.phase[n] ?? Math.random(); const v = waveshapes.sawblep(this.phase[n], dt); - output[0][i] = output[0][i] + v * gainL; - output[1][i] = output[1][i] + v * gainR; + output[0][i] += v * gainL; + output[1][i] += v * gainR; - this.phase[n] = wrapPhase(this.phase[n] + dt); + this.phase[n] = ffrac(this.phase[n] + dt); } } return true; @@ -699,7 +698,7 @@ class PhaseVocoderProcessor extends OLAProcessor { // shift whole region of influence around peak to shifted peak const startOffset = startIndex - peakIndex; const endOffset = endIndex - peakIndex; - const omegaDelta = TWO_PI * this.invfftSize * (binIndexShifted - binIndex); + const omegaDelta = TWO_PI * this.invfftSize * (peakIndexShifted - peakIndex); const phaseShiftReal = Math.cos(omegaDelta * this.timeCursor); const phaseShiftImag = Math.sin(omegaDelta * this.timeCursor); for (let j = startOffset; j < endOffset; j++) { @@ -792,11 +791,11 @@ class PulseOscillatorProcessor extends AudioWorkletProcessor { dphi; for (let i = 0; i < (output[0].length ?? 0); i++) { - const pw = (1 - clamp(pv(params.pulsewidth, i), -0.99, 0.99)) * this.pi; + const pw = (1 - clamp(pv(params.pulsewidth, i), -0.99, 0.99)) * PI; const detune = pv(params.detune, i); const freq = applySemitoneDetuneToFrequency(pv(params.frequency, i), detune / 100); - dphi = freq * (this.pi / (sampleRate * 0.5)); // phase increment + dphi = freq * (PI / (sampleRate * 0.5)); // phase increment this.dphif += 0.1 * (dphi - this.dphif); env *= 0.9998; // exponential decay envelope @@ -808,7 +807,7 @@ class PulseOscillatorProcessor extends AudioWorkletProcessor { // Waveform generation (half-Tomisawa oscillators) this.phi += this.dphif; // phase increment - if (this.phi >= this.pi) this.phi -= 2 * this.pi; // phase wrapping + if (this.phi >= PI) this.phi -= TWO_PI; // phase wrapping // First half-Tomisawa generator let out0 = Math.cos(this.phi + this.B * this.Y0); // self-phase modulation @@ -847,13 +846,13 @@ const chyx = { } }, /*sin that loops every 128 "steps", instead of every pi steps*/ sinf: function (x) { - return Math.sin(x / (128 / Math.PI)); + return Math.sin((x * PI) / 128); }, /*cos that loops every 128 "steps", instead of every pi steps*/ cosf: function (x) { - return Math.cos(x / (128 / Math.PI)); + return Math.cos((x * PI) / 128); }, /*tan that loops every 128 "steps", instead of every pi steps*/ tanf: function (x) { - return Math.tan(x / (128 / Math.PI)); + return Math.tan((x * PI) / 128); }, /*converts t into a string composed of it's bits, regex's that*/ regG: function (t, X) { return X.test(t.toString(2)); @@ -986,6 +985,7 @@ export const WarpMode = Object.freeze({ SIGMOID: 19, FRACTAL: 20, FLIP: 21, + MODULAR: 22, }); function hash32(u) { @@ -1125,7 +1125,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { case WarpMode.FOLD: { const K = 7; const k = 1 + Math.max(1, fround(K * amt)); - return Math.abs(frac(k * phase) - 0.5) * 2; + return Math.abs(ffrac(k * phase) - 0.5) * 2; } case WarpMode.PWM: { const w = clamp(0.5 + 0.49 * (2 * amt - 1), 0, 1); @@ -1135,12 +1135,12 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { case WarpMode.ORBIT: { const depth = 0.5 * amt; const n = 3; - return frac(phase + depth * Math.sin(2 * Math.PI * n * phase)); + return frac(phase + depth * Math.sin(TWO_PI * n * phase)); } case WarpMode.SPIN: { const depth = 0.5 * amt; const { n } = this._toBits(amt, 1, 6); - return frac(phase + depth * Math.sin(2 * Math.PI * n * phase)); + return frac(phase + depth * Math.sin(TWO_PI * n * phase)); } case WarpMode.CHAOS: { const r = 3.7 + 0.3 * amt; @@ -1169,8 +1169,8 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { case WarpMode.MODULAR: { const { n } = this._toBits(amt); const depth = 0.5 * amt; - const jump = frac(phase * n) / n; - return frac(phase + depth * jump); + const jump = ffrac(phase * n) / n; + return ffrac(phase + depth * jump); } case WarpMode.BROWNIAN: { const disp = 0.25 * amt * brownian(64 * phase, 4); @@ -1207,7 +1207,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { return (y - y0) / (y1 - y0); } case WarpMode.FRACTAL: { - const d = 0.5 * Math.sin(2 * Math.PI * phase) * amt; + const d = 0.5 * Math.sin(TWO_PI * phase) * amt; return frac(phase + d); } case WarpMode.FLIP: { @@ -1271,6 +1271,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { let f = pv(parameters.frequency, i); f = applySemitoneDetuneToFrequency(f, detune / 100); // overall detune const normalizer = 1 / Math.sqrt(voices); + const detuner = getDetuner(voices, freqspread); for (let n = 0; n < voices; n++) { const isOdd = (n & 1) == 1; let gainL = gain1; @@ -1280,7 +1281,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { gainL = gain2; gainR = gain1; } - const fVoice = applySemitoneDetuneToFrequency(f, getUnisonDetune(voices, freqspread, n)); // voice detune + const fVoice = applySemitoneDetuneToFrequency(f, detuner(n)); // voice detune const dPhase = fVoice * INVSR; const level = this._chooseMip(dPhase); const table = this.tables[level]; @@ -1296,7 +1297,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { } outL[i] += s * gainL * normalizer; outR[i] += s * gainR * normalizer; - this.phase[n] = wrapPhase(this.phase[n] + dPhase); + this.phase[n] = ffrac(this.phase[n] + dPhase); } } return true; From be3a88b09c69fa92e501fc2d0ca3939fed3670ae Mon Sep 17 00:00:00 2001 From: Aria Date: Wed, 12 Nov 2025 12:23:40 -0600 Subject: [PATCH 328/335] Optimize phase wrap; make voices k-rate --- packages/superdough/worklets.mjs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 46f22d979..06c917751 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -507,6 +507,7 @@ class SuperSawOscillatorProcessor extends AudioWorkletProcessor { name: 'voices', defaultValue: 5, min: 1, + automationRate: 'k-rate', }, ]; } @@ -518,12 +519,10 @@ class SuperSawOscillatorProcessor extends AudioWorkletProcessor { // this.port.postMessage({ type: 'onended' }); return false; } - const output = outputs[0]; - + const voices = pv(params.voices, 0); // k-rate for (let i = 0; i < output[0].length; i++) { const detune = pv(params.detune, i); - const voices = pv(params.voices, i); const freqspread = pv(params.freqspread, i); const panspread = pv(params.panspread, i) * 0.5 + 0.5; const gain1 = Math.sqrt(1 - panspread); @@ -552,7 +551,9 @@ class SuperSawOscillatorProcessor extends AudioWorkletProcessor { output[0][i] += v * gainL; output[1][i] += v * gainR; - this.phase[n] = ffrac(this.phase[n] + dt); + let pn = this.phase[n] + dt; + if (pn >= 1.0) pn -= 1.0; + this.phase[n] = pn; } } return true; From f8c9425569b252d31590ade391834ba7b5ce1211 Mon Sep 17 00:00:00 2001 From: Aria Date: Wed, 12 Nov 2025 13:13:37 -0600 Subject: [PATCH 329/335] Simplify spread --- packages/superdough/worklets.mjs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 06c917751..038f59697 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -525,21 +525,13 @@ class SuperSawOscillatorProcessor extends AudioWorkletProcessor { const detune = pv(params.detune, i); const freqspread = pv(params.freqspread, i); const panspread = pv(params.panspread, i) * 0.5 + 0.5; - const gain1 = Math.sqrt(1 - panspread); - const gain2 = Math.sqrt(panspread); + let gainL = Math.sqrt(1 - panspread); + let gainR = Math.sqrt(panspread); let freq = pv(params.frequency, i); // Main detuning freq = applySemitoneDetuneToFrequency(freq, detune / 100); const detuner = getDetuner(voices, freqspread); for (let n = 0; n < voices; n++) { - const isOdd = (n & 1) == 1; - let gainL = gain1; - let gainR = gain2; - // invert right and left gain - if (isOdd) { - gainL = gain2; - gainR = gain1; - } // Individual voice detuning const freqVoice = applySemitoneDetuneToFrequency(freq, detuner(n)); // We must wrap this here because it is passed into sawblep below which @@ -554,6 +546,9 @@ class SuperSawOscillatorProcessor extends AudioWorkletProcessor { let pn = this.phase[n] + dt; if (pn >= 1.0) pn -= 1.0; this.phase[n] = pn; + // invert right and left gain + gainL = gainR; + gainR = gainL; } } return true; From 157b05536ad6600fffa81aba590209f24e403a93 Mon Sep 17 00:00:00 2001 From: Aria Date: Wed, 12 Nov 2025 13:36:01 -0600 Subject: [PATCH 330/335] Final cleanup --- packages/superdough/worklets.mjs | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 038f59697..51a025d6d 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -591,10 +591,6 @@ class PhaseVocoderProcessor extends OLAProcessor { this.fftSize = this.blockSize; this.invfftSize = 1 / this.fftSize; this.hannWindow = genHannWindow(this.fftSize); - // rescale hann window (empirically sounds nicer) - for (let i = 0; i < this.hannWindow.length; i++) { - this.hannWindow[i] *= 1.62; - } // prepare FFT and pre-allocate buffers this.fft = new FFT(this.fftSize); this.freqComplexBuffer = this.fft.createComplexArray(); @@ -633,7 +629,7 @@ class PhaseVocoderProcessor extends OLAProcessor { /** Apply Hann window in-place */ applyHannWindow(input) { for (let i = 0; i < this.blockSize; i++) { - input[i] *= this.hannWindow[i]; + input[i] *= this.hannWindow[i] * 1.62; } } @@ -791,7 +787,7 @@ class PulseOscillatorProcessor extends AudioWorkletProcessor { const detune = pv(params.detune, i); const freq = applySemitoneDetuneToFrequency(pv(params.frequency, i), detune / 100); - dphi = freq * (PI / (sampleRate * 0.5)); // phase increment + dphi = freq * TWO_PI * INVSR; // phase increment this.dphif += 0.1 * (dphi - this.dphif); env *= 0.9998; // exponential decay envelope @@ -981,7 +977,6 @@ export const WarpMode = Object.freeze({ SIGMOID: 19, FRACTAL: 20, FLIP: 21, - MODULAR: 22, }); function hash32(u) { @@ -1162,12 +1157,6 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { const ridx = bitReverse(idx, b); return ridx / n; } - case WarpMode.MODULAR: { - const { n } = this._toBits(amt); - const depth = 0.5 * amt; - const jump = ffrac(phase * n) / n; - return ffrac(phase + depth * jump); - } case WarpMode.BROWNIAN: { const disp = 0.25 * amt * brownian(64 * phase, 4); return frac(phase + disp); From 2875814a36b4bdec88d738f191bfe494dbd3d95a Mon Sep 17 00:00:00 2001 From: Aria Date: Wed, 12 Nov 2025 13:56:14 -0600 Subject: [PATCH 331/335] Square instead of self-multiply; more voices; more cleanup --- packages/superdough/worklets.mjs | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 51a025d6d..5a96246fe 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -24,7 +24,7 @@ const fceil = (x) => ffloor(x + 1); const ffrac = (x) => x - ffloor(x); const fast_tanh = (x) => { - const x2 = x * x; + const x2 = x ** 2; return (x * (27.0 + x2)) / (27.0 + 9.0 * x2); }; @@ -50,17 +50,13 @@ function polyBlep(phase, dt) { // Start of cycle if (phase < dt) { phase *= invdt; - // 2 * (phase - phase^2/2 - 0.5) - return phase + phase - phase * phase - 1; + return 2 * phase - phase ** 2 - 1; } - // End of cycle else if (phase > 1 - dt) { phase = (phase - 1) * invdt; - // 2 * (phase^2/2 + phase + 0.5) - return phase * phase + phase + phase + 1; + return phase ** 2 + 2 * phase + 1; } - // 0 otherwise else { return 0; @@ -520,7 +516,7 @@ class SuperSawOscillatorProcessor extends AudioWorkletProcessor { return false; } const output = outputs[0]; - const voices = pv(params.voices, 0); // k-rate + const voices = params.voices[0]; // k-rate for (let i = 0; i < output[0].length; i++) { const detune = pv(params.detune, i); const freqspread = pv(params.freqspread, i); @@ -641,7 +637,7 @@ class PhaseVocoderProcessor extends OLAProcessor { const real = this.freqComplexBuffer[j]; const imag = this.freqComplexBuffer[j + 1]; // no need to sqrt for peak finding - this.magnitudes[i] = real * real + imag * imag; + this.magnitudes[i] = real ** 2 + imag ** 2; i += 1; j += 2; } @@ -1033,7 +1029,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { { name: 'position', defaultValue: 0, min: 0, max: 1 }, { name: 'warp', defaultValue: 0, min: 0, max: 1 }, { name: 'warpMode', defaultValue: 0 }, - { name: 'voices', defaultValue: 1, min: 1 }, + { name: 'voices', defaultValue: 1, min: 1, automationRate: 'k-rate' }, { name: 'panspread', defaultValue: 0.7, min: 0, max: 1 }, { name: 'phaserand', defaultValue: 0, min: 0, max: 1 }, ]; @@ -1106,7 +1102,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { return amt < 0.5 ? this._warpPhase(phase, 1 - 2 * amt, 3) : this._warpPhase(phase, 2 * amt - 1, 2); } case WarpMode.SYNC: { - const syncRatio = Math.pow(16, amt * amt); + const syncRatio = Math.pow(16, amt ** 2); return (phase * syncRatio) % 1; } case WarpMode.QUANT: { @@ -1142,7 +1138,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { const isPrime = (n) => { if (n < 2) return false; if (n % 2 === 0) return n === 2; - for (let d = 3; d * d <= n; d += 2) if (n % d === 0) return false; + for (let d = 3; d ** 2 <= n; d += 2) if (n % d === 0) return false; return true; }; let { n } = this._toBits(amt, 3); @@ -1239,6 +1235,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { if (outR !== outL) outR.set(outL); return true; } + const voices = parameters.voices[0]; // k-rate for (let i = 0; i < outL.length; i++) { const detune = pv(parameters.detune, i); const freqspread = pv(parameters.freqspread, i); @@ -1248,7 +1245,6 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor { const frac = idx - fIdx; const warpAmount = clamp(pv(parameters.warp, i), 0, 1); const warpMode = pv(parameters.warpMode, i); - const voices = pv(parameters.voices, i); const phaseRand = clamp(pv(parameters.phaserand, i), 0, 1); const panspread = voices > 1 ? clamp(pv(parameters.panspread, i), 0, 1) : 0; const gain1 = Math.sqrt(0.5 - 0.5 * panspread); From 22807b383374b8ba3cb1048c0615252ceb2c803f Mon Sep 17 00:00:00 2001 From: Aria Date: Fri, 14 Nov 2025 16:05:09 -0600 Subject: [PATCH 332/335] Use weak references for sound sources --- packages/superdough/superdough.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index b59e3ae05..4827ffbd3 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -481,7 +481,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) // oldest audio nodes will be destroyed if maximum polyphony is exceeded for (let i = 0; i <= activeSoundSources.size - maxPolyphony; i++) { const ch = activeSoundSources.entries().next(); - const source = ch.value[1]; + const source = ch.value[1].deref(); const chainID = ch.value[0]; const endTime = t + 0.25; source?.node?.gain?.linearRampToValueAtTime(0, endTime); @@ -513,7 +513,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) if (soundHandle) { sourceNode = soundHandle.node; - activeSoundSources.set(chainID, soundHandle); + activeSoundSources.set(chainID, new WeakRef(soundHandle)); // allow GC } } else { throw new Error(`sound ${s} not found! Is it loaded?`); From 3e05525dc29666e9fc5222790dbe825f03a6b5b4 Mon Sep 17 00:00:00 2001 From: jeromew Date: Fri, 14 Nov 2025 22:06:39 +0000 Subject: [PATCH 333/335] [perf] disconnect `send` effect AudioNode when `room` is used --- packages/superdough/superdough.mjs | 3 ++- packages/superdough/superdoughoutput.mjs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index b59e3ae05..16ae3cecc 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -708,7 +708,8 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) roomIR = await loadBuffer(url, ac, ir, 0); } orbitBus.getReverb(roomsize, roomfade, roomlp, roomdim, roomIR, irspeed, irbegin); - orbitBus.sendReverb(post, room); + const send = orbitBus.sendReverb(post, room); + audioNodes.push(send); } if (djf != null) { diff --git a/packages/superdough/superdoughoutput.mjs b/packages/superdough/superdoughoutput.mjs index afe91e71e..a4235efd0 100644 --- a/packages/superdough/superdoughoutput.mjs +++ b/packages/superdough/superdoughoutput.mjs @@ -78,7 +78,7 @@ export class Orbit { return this.reverbNode; } sendReverb(node, amount) { - effectSend(node, this.reverbNode, amount); + return effectSend(node, this.reverbNode, amount); } sendDelay(node, amount) { From 92d87093e0b0a322801238f9d10ebe2a448af678 Mon Sep 17 00:00:00 2001 From: jeromew Date: Sat, 15 Nov 2025 13:39:24 +0000 Subject: [PATCH 334/335] [perf] disconnect Offline AudioNode connections in generateReverb --- packages/superdough/reverbGen.mjs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/superdough/reverbGen.mjs b/packages/superdough/reverbGen.mjs index d2533cae4..bb050874c 100644 --- a/packages/superdough/reverbGen.mjs +++ b/packages/superdough/reverbGen.mjs @@ -104,6 +104,8 @@ var applyGradualLowpass = function (input, lpFreqStart, lpFreqEnd, lpFreqEndAt, player.start(); context.oncomplete = function (event) { callback(event.renderedBuffer); + filter.disconnect(); + player.disconnect(); }; context.startRendering(); From 3962558c094f1a1a98cacedc4f8cf94c228eb202 Mon Sep 17 00:00:00 2001 From: Aria Date: Sun, 16 Nov 2025 13:12:47 -0600 Subject: [PATCH 335/335] Some final tweaks --- packages/superdough/worklets.mjs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 5a96246fe..6e2b47e75 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -825,13 +825,12 @@ const chyx = { /*bit reverse*/ br: function (x, size = 8) { if (size > 32) { throw new Error('br() Size cannot be greater than 32'); - } else { - let result = 0; - for (let idx = 0; idx < size - 0; idx++) { - result += chyx.bitC(x, 2 ** idx, 2 ** (size - (idx + 1))); - } - return result; } + let result = 0; + for (let idx = 0; idx < size; idx++) { + result |= chyx.bitC(x, 1 << idx, 1 << (size - (idx + 1))); + } + return result; }, /*sin that loops every 128 "steps", instead of every pi steps*/ sinf: function (x) { return Math.sin((x * PI) / 128); @@ -842,7 +841,7 @@ const chyx = { /*tan that loops every 128 "steps", instead of every pi steps*/ tanf: function (x) { return Math.tan((x * PI) / 128); }, - /*converts t into a string composed of it's bits, regex's that*/ regG: function (t, X) { + /*converts t into a string composed of its bits; regexes that*/ regG: function (t, X) { return X.test(t.toString(2)); }, }; @@ -850,7 +849,7 @@ const chyx = { // Create shortened Math functions let mathParams, byteBeatHelperFuncs; function getByteBeatFunc(codetext) { - if ((mathParams || byteBeatHelperFuncs) == null) { + if (mathParams == null) { mathParams = Object.getOwnPropertyNames(Math); byteBeatHelperFuncs = mathParams.map((k) => Math[k]); const chyxNames = Object.getOwnPropertyNames(chyx); @@ -883,7 +882,7 @@ class ByteBeatProcessor extends AudioWorkletProcessor { this.func = getByteBeatFunc(codeText); }; - this.initialOffset = null; + this.initialOffset = 0; this.t = null; this.func = null; } @@ -930,18 +929,19 @@ class ByteBeatProcessor extends AudioWorkletProcessor { this.t = params.begin[0] * sampleRate; } const output = outputs[0]; + const scale = 256 * INVSR; for (let i = 0; i < output[0].length; i++) { const detune = pv(params.detune, i); const freq = applySemitoneDetuneToFrequency(pv(params.frequency, i), detune / 100); - let local_t = 256 * this.t * INVSR * freq + this.initialOffset; + const local_t = scale * freq * this.t + this.initialOffset; const funcValue = this.func(local_t); - let signal = (funcValue & 255) / 127.5 - 1; - const out = signal * 0.2; + const signal = (funcValue & 255) / 127.5 - 1; + //prevent speaker blowout via clipping if threshold exceeds + const out = clamp(signal * 0.2, -0.4, 0.4); for (let c = 0; c < output.length; c++) { - //prevent speaker blowout via clipping if threshold exceeds - output[c][i] = clamp(out, -0.4, 0.4); + output[c][i] = out; } - this.t = this.t + 1; + this.t++; } return true; // keep the audio processing going