```

```

### Für Elise | EP1

My first take on the piano contest: I simply re-implemented an old electric piano of mine.

```// Für Elise | EP1. Created by Alexis THIBAULT 2023

// In this ditty, I reproduce a simple Electric Piano sound,
// "FM Electric Piano (sound)"
// It was more or less copied from the classic EP1 patch of the Yamaha DX7,
// although it lacks the "bite" at high velocity.

// -- EDIT Added some feedback FM for the "bite"/"bark"!
const USE_BARK = true;

const TWOPI = 2.0 * Math.PI;
const msin = (ft, m) => Math.sin(TWOPI * ft + m);
const exp = Math.exp;
const pow = Math.pow;
const sin = Math.sin;
const log2 = Math.log2;
const smoothstep = (a,b,t) => clamp01((t-a)/(b-a));

const piano = synth.def(class {
constructor(options) {
// freq : frequency of note
// t : time since beginning of note
// nuance : 1 is mezzo-forte, smaller is piano, larger is forte
this.t = 0;
this.freq = midi_to_hz(options.note);
this.nuance = 0.1 * 20**options.velocity;
// Pan the attack depending on which note it is
this.panDir = clamp(log2(this.freq/400.)/2., -1., 1.); // -1 is left, 1 is right

// Saving some coefficients for better performance
this.freqAmp = pow(440./this.freq, 0.5);
this.a30 = 1; this.da30 = exp(-30.*ditty.dt/this.freqAmp);
this.a4 = 1; this.da4 = exp(-4.*ditty.dt/this.freqAmp);
this.a05 = 1; this.da05 = exp(-0.5*ditty.dt/this.freqAmp);
this.a1 = 1; this.da1 = exp(-1*ditty.dt/this.freqAmp);

// Feedback FM
this.fbv = 0; // Last value of the synth
this.fbphase = 0;
}
process(note, env, tick, options) {
this.t += ditty.dt; var t = this.t;
this.a30 *= this.da30;
this.a4 *= this.da4;
this.a05 *= this.da05;
this.a1 *= this.da1;

// Feedback FM update
var feedback = this.nuance;
var fbAmp = 2.5 * this.nuance * this.nuance * this.a1;
this.fbphase += ditty.dt * this.freq;
// The next value depends on the last value
this.fbv = sin(2*Math.PI*this.fbphase + this.fbv * feedback) * fbAmp;

var f0 = [this.freq*0.998, this.freq*1.002];
var sig = [0,0];
var envv = env.value;

for(var i=0; i<2; i++) { // Left and right
// Glassy attack : slightly sharp,
// modulated at 14 * base frequency with a sharply decaying envelope
// and with a relatively fast decay
var glass = msin((f0[i]+3.)*t, msin(14.*f0[i]*t,0.) * this.a30 * this.nuance) * this.a4  * this.nuance;
//glass = sin(glass); // Distort at high nuances
if(USE_BARK) {
glass += this.fbv;
}

// Body of the sound : perfectly in tune,
// index of modulation depends on nuance and is boosted a bit for low notes
var body = msin(f0[i]*t, msin(f0[i]*t,0.) * this.a05 * this.nuance * this.freqAmp) * this.a1 * this.nuance;

var pan = 0.5 - 0.5 * this.panDir * (1 - 2*i);
//var env = 0.05 * smoothstep(0.,0.001,t);
sig[i] = (glass*pan + body) * 0.1 * env.value;
}

return sig;
}
}, {
attack: 0.001,
sustain: 1,
release: 0.3,
velocity: 0.5
});

// ******************************************************************

// Forked from "Für Elise | Piano Contest". Created by Reinder Nijhoff 2023
// https://dittytoy.net/ditty/cb751b4b3b
//
// It would be fun to start an ongoing, informal piano competition. You can fork this ditty and write
// your loops, synths, and filters to play the Für Elise with the best-sounding piano sound possible.
//
// I want to participate in this competition, but I need to learn more about sound synthesis.
// Therefore, it will be appreciated if you all share tips and links to resources about sound synthesis
// in the comments of this ditty so we can all learn from it..
//

ditty.bpm = 60;

const numWorkers = 4; // increase number of workers when performance is low
const fürEliseData = fürElise();

for (let i=0; i<numWorkers; i++) {
loop( () => {
fürEliseData.notes.forEach( (n, index) => {
sleep(second_to_tick(n.dt));

if (index % numWorkers === i % numWorkers) {

const duration = n.sustain ? Math.max(n.duration, Math.min(7,n.sustainMaxDuration)) : n.duration;
piano.play(n.midi, {
velocity: n.velocity,
duration: second_to_tick(duration)
});

}
});

}, { name: `Piano \${i}`, sync: fürEliseData.duration, amp: 0.5 });
}

//
// Use this data. The data contains each note's velocity, duration, and time and whether the sustain pedal is active.
// The data is based on a midi file by: https://www.patreon.com/rousseau
// You can find the recording of the midi file here: https://youtu.be/wfF0zHeU3Zs
//

function fürElise() {
const data = {notes:[76,.2,1.02,.496,75,.15,1.22,.496,76,.15,1.39,.512,75,.15,1.55,.512,76,.16,1.71,.543,71,.15,1.87,.528,74,.16,2.03,.52,72,.19,2.19,.535,69,.17,2.36,.52,45,.21,2.36,.52,52,.29,2.54,.496,57,.1,2.71,.528,60,.15,2.88,.52,64,.14,3.05,.496,69,.16,3.2,.551,40,.13,3.36,.551,71,.14,3.36,.559,52,.17,3.54,.528,56,.07,3.71,.488,64,.17,3.88,.504,68,.15,4.03,.543,71,.18,4.21,.535,45,.21,4.36,.52,72,.27,4.38,.583,52,.2,4.57,.457,57,.16,4.74,.52,64,.13,4.94,.496,76,.17,5.1,.575,75,.15,5.28,.575,76,.18,5.44,.551,75,.17,5.6,.575,76,.17,5.77,.551,71,.15,5.94,.504,74,.16,6.09,.52,72,.2,6.25,.504,45,.18,6.42,.52,69,.15,6.42,.496,52,.28,6.6,.504,57,.1,6.78,.496,60,.18,6.93,.504,64,.15,7.1,.512,69,.19,7.27,.528,40,.1,7.42,.535,71,.16,7.43,.583,52,.19,7.6,.496,56,.08,7.8,.488,64,.19,7.98,.488,72,.18,8.17,.543,71,.2,8.36,.496,69,.49,8.56,.48,45,.23,8.58,.496,52,.26,8.82,.425,57,.43,9.07,.472,76,.18,9.61,.488,75,.18,9.79,.52,76,.17,9.97,.528,75,.18,10.13,.575,76,.17,10.3,.559,71,.17,10.45,.512,74,.17,10.61,.551,72,.19,10.77,.559,45,.2,10.94,.512,69,.17,10.94,.528,52,.32,11.12,.504,57,.13,11.31,.504,60,.17,11.47,.504,64,.16,11.64,.52,69,.19,11.8,.543,40,.12,11.95,.535,71,.16,11.97,.606,52,.17,12.15,.528,56,.09,12.32,.48,64,.19,12.5,.52,68,.17,12.66,.535,71,.21,12.83,.535,72,.27,13,.591,45,.22,13.01,.48,52,.23,13.22,.488,57,.23,13.4,.52,64,.14,13.59,.512,76,.17,13.77,.591,75,.18,13.93,.575,76,.18,14.11,.567,75,.16,14.27,.583,76,.2,14.42,.535,71,.17,14.59,.528,74,.16,14.77,.551,72,.17,14.92,.543,69,.18,15.08,.528,45,.18,15.1,.504,52,.3,15.28,.512,57,.13,15.46,.512,60,.17,15.63,.512,64,.15,15.8,.504,69,.18,15.97,.535,40,.13,16.14,.543,71,.17,16.14,.583,52,.19,16.32,.52,56,.09,16.51,.48,64,.21,16.68,.504,72,.17,16.86,.575,71,.18,17.04,.488,69,.3,17.22,.504,45,.23,17.24,.488,52,.24,17.44,.496,57,.17,17.65,.512,71,.21,17.81,.551,72,.19,17.98,.598,74,.2,18.16,.598,76,.24,18.34,.622,48,.21,18.36,.606,55,.31,18.55,.528,60,.11,18.72,.528,67,.2,18.91,.551,77,.19,19.07,.606,76,.23,19.25,.528,43,.14,19.41,.543,74,.19,19.42,.606,55,.2,19.6,.52,59,.1,19.77,.488,65,.19,19.96,.528,76,.21,20.15,.551,74,.24,20.32,.543,45,.2,20.49,.528,72,.17,20.5,.559,52,.35,20.68,.52,57,.14,20.87,.512,64,.2,21.05,.48,74,.21,21.23,.559,72,.19,21.41,.535,71,.18,21.58,.535,40,.13,21.59,.559,52,.08,21.79,.512,64,.05,21.99,.52,64,.18,22.17,.512,76,.17,22.36,.591,64,.2,22.52,.496,76,.11,22.74,.465,76,.26,22.95,.512,88,.15,23.17,.543,75,.22,23.38,.488,76,.16,23.58,.512,75,.18,23.77,.504,76,.18,23.94,.512,75,.18,24.1,.543,76,.18,24.29,.543,75,.16,24.45,.528,76,.17,24.61,.543,75,.15,24.77,.567,76,.19,24.93,.528,75,.18,25.09,.528,76,.18,25.27,.543,71,.18,25.44,.504,74,.17,25.61,.528,72,.2,25.78,.528,45,.2,25.93,.504,69,.2,25.94,.528,52,.3,26.13,.48,57,.13,26.31,.52,60,.16,26.47,.52,64,.16,26.64,.504,69,.17,26.8,.551,40,.11,26.96,.551,71,.16,26.96,.598,52,.2,27.14,.528,56,.08,27.32,.488,64,.18,27.48,.528,68,.18,27.64,.543,71,.21,27.81,.543,45,.21,27.98,.496,72,.28,27.99,.591,52,.21,28.19,.457,57,.19,28.38,.496,64,.15,28.56,.504,76,.17,28.73,.559,75,.18,28.91,.559,76,.19,29.08,.551,75,.18,29.24,.575,76,.2,29.41,.551,71,.17,29.58,.528,74,.19,29.74,.551,72,.19,29.91,.543,45,.18,30.08,.543,69,.18,30.08,.535,52,.3,30.25,.52,57,.11,30.43,.512,60,.19,30.59,.512,64,.16,30.77,.48,69,.2,30.94,.512,40,.14,31.09,.559,71,.17,31.1,.575,52,.21,31.29,.52,56,.09,31.48,.48,64,.2,31.65,.512,72,.19,31.82,.575,71,.19,32,.512,69,.31,32.19,.48,45,.26,32.2,.488,52,.22,32.44,.417,57,.19,32.63,.48,71,.22,32.8,.543,72,.2,32.97,.583,74,.19,33.16,.559,48,.24,33.33,.559,76,.23,33.33,.63,55,.3,33.53,.512,60,.11,33.71,.52,67,.22,33.87,.575,77,.21,34.05,.614,76,.23,34.22,.559,43,.14,34.38,.535,74,.19,34.39,.622,55,.23,34.56,.512,59,.09,34.76,.52,65,.18,34.93,.528,76,.2,35.1,.559,74,.22,35.26,.559,45,.2,35.43,.543,72,.19,35.43,.575,52,.36,35.63,.512,57,.13,35.83,.528,64,.21,36.01,.496,74,.21,36.18,.567,72,.19,36.36,.528,40,.13,36.52,.567,71,.18,36.53,.559,52,.07,36.71,.528,64,.07,36.91,.535,64,.18,37.08,.535,76,.16,37.27,.559,64,.19,37.43,.504,76,.1,37.64,.504,76,.27,37.83,.504,88,.15,38.05,.559,75,.23,38.24,.52,76,.15,38.45,.551,75,.18,38.65,.512,76,.17,38.82,.551,75,.18,38.98,.567,76,.18,39.16,.551,75,.15,39.32,.543,76,.19,39.49,.575,75,.16,39.66,.575,76,.21,39.81,.504,75,.18,39.99,.567,76,.21,40.16,.551,71,.17,40.34,.535,74,.17,40.51,.551,72,.19,40.67,.543,45,.21,40.84,.535,69,.2,40.84,.528,52,.3,41.03,.488,57,.12,41.2,.488,60,.18,41.35,.488,64,.17,41.53,.535,69,.19,41.69,.543,40,.16,41.85,.551,71,.17,41.86,.591,52,.22,42.05,.496,56,.11,42.24,.425,64,.19,42.4,.496,68,.17,42.57,.528,71,.22,42.74,.528,45,.23,42.92,.528,72,.23,42.93,.583,52,.23,43.12,.449,57,.22,43.29,.496,64,.14,43.47,.504,76,.19,43.64,.575,75,.16,43.82,.559,76,.18,43.99,.535,75,.16,44.16,.551,76,.17,44.33,.559,71,.16,44.5,.528,74,.19,44.67,.551,72,.2,44.84,.535,45,.21,45.01,.528,69,.17,45.01,.528,52,.28,45.19,.465,57,.11,45.36,.496,60,.17,45.52,.496,64,.17,45.69,.504,69,.2,45.86,.535,40,.12,46.02,.543,71,.18,46.04,.567,52,.2,46.21,.496,56,.09,46.39,.465,64,.19,46.56,.457,72,.2,46.73,.551,71,.19,46.92,.488,45,.26,47.11,.504,69,.44,47.11,.496,52,.24,47.33,.449,57,.15,47.57,.496,64,.1,48.03,.535,58,.09,48.03,.52,60,.09,48.03,.512,72,.09,48.04,.543,65,.08,48.28,.559,57,.08,48.28,.543,60,.08,48.28,.535,72,.08,48.28,.591,60,.1,48.49,.535,58,.1,48.5,.567,72,.13,48.5,.551,55,.1,48.51,.512,64,.07,48.51,.575,67,.08,48.52,.528,65,.45,48.69,.598,69,.33,48.78,.591,53,.25,48.81,.622,72,.38,48.82,.638,57,.18,49.03,.575,60,.2,49.22,.559,57,.17,49.41,.543,60,.26,49.6,.535,77,.18,49.61,.622,57,.11,49.8,.551,76,.04,49.88,.559,53,.28,49.98,.551,76,.35,49.99,.654,58,.2,50.19,.543,74,.4,50.38,.583,62,.19,50.4,.559,58,.2,50.58,.575,82,.17,50.78,.614,62,.23,50.8,.559,58,.11,50.99,.559,81,.04,51.08,.559,53,.23,51.17,.551,81,.2,51.18,.693,64,.22,51.37,.535,79,.13,51.39,.575,58,.17,51.56,.551,55,.21,51.57,.512,53,.21,51.57,.472,77,.22,51.57,.567,64,.19,51.77,.528,76,.22,51.79,.543,58,.27,51.97,.512,74,.18,51.97,.583,53,.21,51.97,.409,55,.21,51.97,.488,64,.14,52.18,.52,72,.23,52.18,.575,53,.25,52.36,.535,70,.4,52.38,.606,57,.19,52.58,.528,60,.19,52.79,.535,69,.18,52.79,.543,57,.15,52.98,.488,70,.07,53.05,.559,69,.09,53.14,.504,60,.21,53.16,.504,67,.1,53.25,.575,57,.18,53.34,.504,69,.11,53.35,.488,70,.08,53.45,.583,53,.3,53.55,.543,72,.74,53.58,.614,57,.18,53.77,.528,60,.21,53.94,.551,57,.2,54.14,.559,60,.23,54.33,.551,74,.24,54.33,.622,57,.14,54.53,.528,75,.14,54.53,.654,52,.29,54.73,.512,76,.45,54.73,.646,57,.19,54.93,.543,60,.21,55.13,.559,57,.14,55.31,.551,76,.18,55.32,.606,77,.18,55.51,.669,50,.16,55.51,.52,62,.23,55.51,.614,53,.05,55.71,.496,69,.19,55.71,.559,55,.26,55.91,.622,72,.67,55.93,.677,64,.2,56.13,.543,55,.29,56.33,.591,65,.16,56.54,.606,55,.27,56.73,.504,74,.21,56.73,.638,65,.07,56.94,.528,71,.08,57.01,.551,60,.07,57.14,.661,64,.06,57.14,.614,72,.08,57.15,.622,79,.07,57.27,.614,67,.08,57.37,.583,79,.07,57.48,.614,69,.07,57.59,.535,79,.06,57.7,.551,67,.07,57.78,.567,65,.07,57.79,.535,71,.08,57.81,.551,79,.08,57.93,.543,67,.08,58.01,.559,64,.08,58.02,.567,72,.07,58.03,.606,79,.1,58.14,.535,67,.08,58.23,.614,62,.08,58.24,.512,74,.08,58.24,.614,65,.06,58.25,.48,79,.08,58.36,.496,67,.09,58.46,.717,64,.1,58.47,.598,60,.15,58.47,.614,76,.09,58.48,.622,79,.1,58.6,.551,84,.13,58.7,.654,83,.12,58.82,.535,57,.35,58.92,.646,53,.33,58.92,.591,81,.11,58.93,.567,79,.1,59.05,.559,77,.07,59.15,.551,76,.11,59.27,.551,59,.17,59.38,.559,74,.13,59.38,.559,55,.17,59.38,.543,79,.14,59.51,.575,77,.16,59.6,.543,74,.1,59.74,.559,60,.09,59.86,.638,64,.09,59.86,.543,72,.1,59.87,.685,79,.08,60,.63,67,.07,60.12,.535,79,.08,60.23,.646,69,.08,60.34,.504,79,.09,60.47,.622,65,.08,60.56,.575,67,.07,60.57,.551,71,.09,60.57,.543,79,.08,60.7,.512,64,.08,60.8,.575,67,.08,60.8,.583,72,.09,60.81,.63,79,.12,60.93,.575,65,.07,61.03,.543,67,.07,61.03,.583,62,.07,61.04,.52,74,.09,61.05,.638,79,.08,61.17,.504,64,.12,61.27,.614,60,.16,61.27,.685,76,.11,61.28,.622,79,.12,61.41,.575,84,.13,61.51,.646,83,.13,61.64,.528,53,.38,61.73,.606,57,.39,61.73,.638,81,.12,61.75,.598,79,.1,61.87,.559,77,.08,61.97,.551,76,.12,62.08,.551,55,.51,62.21,.543,59,.47,62.21,.559,74,.13,62.21,.575,79,.14,62.33,.583,77,.16,62.44,.535,74,.13,62.59,.559,59,2.41,62.72,.409,56,2.35,62.73,.543,76,.1,62.73,.535,77,.16,62.86,.512,76,.12,63.01,.496,75,.15,63.14,.543,76,.13,63.3,.496,71,.18,63.45,.48,76,.15,63.64,.37,75,.17,63.83,.496,76,.21,64.03,.441,71,.23,64.24,.433,76,.24,64.48,.362,75,.3,64.74,.402,76,.72,65.09,.362,71,.26,66.38,.496,76,.32,66.64,.433,75,.41,66.97,.378,76,.74,67.41,.291,71,.28,68.76,.488,76,.21,69.03,.457,75,.17,69.24,.512,76,.16,69.43,.441,75,.14,69.61,.504,76,.16,69.76,.551,75,.15,69.91,.559,76,.16,70.07,.551,75,.16,70.23,.559,76,.16,70.39,.543,75,.18,70.55,.567,76,.2,70.72,.559,71,.15,70.91,.504,74,.16,71.07,.551,72,.18,71.23,.543,45,.18,71.38,.504,69,.17,71.39,.543,52,.24,71.56,.472,57,.09,71.72,.488,60,.16,71.88,.504,64,.15,72.03,.528,69,.19,72.19,.535,40,.11,72.33,.559,71,.16,72.34,.559,52,.19,72.51,.488,56,.07,72.69,.441,64,.19,72.86,.512,68,.17,73.02,.52,71,.18,73.2,.496,45,.22,73.34,.449,72,.26,73.38,.559,52,.2,73.57,.417,57,.16,73.75,.472,64,.14,73.92,.528,76,.17,74.09,.575,75,.15,74.26,.591,76,.16,74.42,.575,75,.18,74.57,.598,76,.16,74.73,.63,71,.14,74.9,.543,74,.17,75.05,.559,72,.18,75.2,.583,45,.19,75.34,.535,69,.14,75.36,.559,52,.24,75.54,.488,57,.1,75.7,.504,60,.16,75.84,.504,64,.12,76.01,.535,69,.18,76.17,.591,40,.11,76.33,.567,71,.16,76.33,.622,52,.19,76.5,.504,56,.09,76.67,.465,64,.18,76.83,.535,72,.16,77,.606,71,.18,77.17,.496,69,.29,77.35,.496,45,.24,77.37,.496,52,.2,77.56,.465,57,.16,77.73,.488,71,.19,77.9,.543,72,.18,78.06,.614,74,.18,78.23,.583,48,.22,78.38,.535,76,.21,78.4,.614,55,.35,78.58,.496,60,.14,78.75,.504,67,.18,78.91,.567,77,.19,79.08,.622,76,.21,79.25,.551,43,.13,79.4,.559,74,.17,79.41,.654,55,.21,79.59,.488,59,.08,79.77,.496,65,.18,79.92,.528,76,.19,80.09,.598,74,.22,80.26,.559,45,.18,80.42,.567,72,.16,80.43,.591,52,.3,80.61,.512,57,.1,80.79,.52,64,.22,80.95,.528,74,.2,81.13,.622,72,.19,81.3,.559,40,.11,81.45,.638,71,.15,81.47,.559,52,.07,81.65,.512,64,.05,81.84,.48,64,.17,82.02,.48,76,.14,82.2,.551,64,.21,82.34,.512,76,.08,82.56,.425,76,.23,82.74,.472,88,.14,82.96,.559,75,.19,83.16,.543,76,.13,83.35,.528,75,.19,83.53,.559,76,.18,83.71,.535,75,.16,83.88,.543,76,.16,84.05,.535,75,.15,84.21,.528,76,.16,84.37,.551,75,.15,84.53,.543,76,.17,84.69,.52,75,.18,84.85,.528,76,.18,85.04,.543,71,.15,85.22,.496,74,.17,85.38,.52,72,.17,85.54,.559,45,.2,85.69,.528,69,.18,85.7,.551,52,.24,85.88,.488,57,.1,86.05,.496,60,.2,86.19,.52,64,.14,86.36,.543,69,.19,86.52,.575,40,.16,86.65,.591,71,.16,86.7,.638,52,.18,86.88,.52,56,.09,87.03,.543,64,.2,87.21,.528,68,.19,87.36,.575,71,.15,87.55,.535,45,.21,87.71,.52,72,.26,87.71,.622,52,.2,87.89,.504,57,.17,88.06,.528,64,.13,88.24,.543,76,.17,88.4,.638,75,.15,88.56,.583,76,.18,88.73,.583,75,.16,88.9,.575,76,.18,89.06,.591,71,.17,89.22,.543,74,.16,89.39,.559,72,.18,89.56,.551,45,.15,89.73,.543,69,.16,89.73,.543,52,.26,89.9,.488,57,.09,90.07,.52,60,.16,90.23,.512,64,.14,90.4,.52,69,.16,90.56,.559,40,.11,90.71,.575,71,.17,90.72,.598,52,.2,90.89,.504,56,.09,91.07,.488,64,.17,91.23,.528,72,.22,91.41,.614,71,.24,91.58,.535,45,.07,91.77,.575,69,.36,91.77,.559,45,.07,91.96,.52,45,.08,92.15,.528,45,.09,92.33,.535,45,.09,92.53,.52,45,.09,92.7,.512,45,.11,92.9,.543,70,.46,92.91,.591,73,.47,92.91,.701,64,.43,92.91,.559,67,.4,92.91,.567,45,.09,93.1,.535,45,.09,93.3,.535,45,.1,93.49,.543,45,.09,93.67,.543,45,.08,93.85,.512,45,.09,94.05,.496,74,.41,94.06,.598,65,.36,94.06,.512,69,.32,94.06,.48,45,.09,94.26,.449,45,.08,94.45,.504,45,.08,94.64,.52,45,.08,94.82,.535,73,.09,94.83,.622,76,.11,94.83,.614,45,.09,95.01,.528,77,.1,95.01,.717,74,.11,95.02,.63,74,.47,95.21,.693,68,.45,95.21,.638,77,.45,95.21,.591,45,.09,95.22,.575,45,.09,95.41,.504,45,.09,95.6,.52,45,.09,95.79,.504,77,.21,95.98,.693,68,.2,95.98,.598,74,.25,95.98,.575,45,.08,95.99,.488,45,.08,96.19,.512,45,.08,96.41,.543,69,.8,96.41,.559,76,.73,96.41,.575,72,.76,96.41,.575,45,.08,96.61,.528,45,.09,96.78,.512,45,.07,96.97,.52,45,.07,97.16,.52,45,.08,97.34,.528,74,.31,97.56,.717,45,.09,97.56,.598,65,.38,97.56,.654,38,.09,97.57,.638,38,.08,97.77,.488,45,.07,97.78,.496,38,.08,97.96,.504,45,.08,97.96,.512,45,.07,98.16,.512,38,.07,98.16,.512,64,.1,98.34,.575,45,.07,98.34,.551,72,.08,98.34,.724,38,.08,98.35,.543,38,.08,98.52,.512,45,.07,98.53,.543,62,.08,98.53,.661,71,.07,98.53,.685,45,.1,98.72,.575,69,.57,98.72,.701,39,.09,98.72,.638,60,.57,98.72,.654,66,.59,98.73,.646,39,.08,98.93,.606,45,.1,98.93,.496,45,.1,99.11,.512,39,.08,99.13,.567,39,.07,99.3,.575,45,.08,99.3,.512,39,.07,99.51,.622,45,.08,99.51,.512,69,.22,99.51,.661,60,.19,99.52,.685,45,.08,99.71,.535,39,.07,99.71,.669,60,.16,99.91,.701,45,.09,99.91,.622,69,.19,99.91,.724,40,.08,99.92,.654,45,.08,100.11,.504,40,.07,100.12,.559,45,.07,100.32,.551,64,.17,100.32,.63,40,.07,100.33,.575,72,.14,100.33,.732,40,.08,100.52,.567,45,.07,100.52,.535,62,.19,100.71,.654,44,.06,100.72,.693,71,.16,100.72,.74,40,.07,100.73,.575,40,.09,100.9,.543,44,.05,100.92,.504,60,.84,101.11,.701,69,.89,101.11,.724,45,.09,101.12,.677,33,.1,101.13,.661,45,.08,101.32,.559,45,.08,101.52,.52,45,.07,101.72,.512,45,.08,101.92,.551,45,.07,102.12,.52,64,.6,102.33,.591,67,.58,102.34,.575,73,.63,102.34,.677,70,.61,102.34,.575,45,.09,102.34,.567,45,.08,102.55,.504,45,.09,102.74,.52,45,.08,102.94,.528,45,.09,103.14,.535,45,.08,103.33,.512,45,.09,103.53,.52,65,.33,103.53,.575,69,.29,103.53,.535,74,.38,103.53,.669,45,.09,103.74,.528,45,.08,103.93,.512,45,.08,104.12,.528,45,.08,104.31,.543,73,.1,104.32,.638,76,.13,104.32,.638,45,.09,104.51,.543,77,.1,104.52,.685,74,.09,104.52,.693,77,.55,104.7,.559,45,.1,104.71,.567,74,.55,104.71,.638,45,.09,104.92,.551,45,.09,105.1,.528,45,.08,105.3,.496,74,.32,105.52,.63,77,.3,105.52,.63,45,.08,105.52,.551,45,.08,105.73,.52,46,.1,106.01,.575,74,.74,106.01,.606,77,.71,106.01,.614,46,.07,106.25,.512,46,.07,106.45,.575,46,.08,106.65,.575,46,.07,106.85,.543,46,.07,107.04,.512,46,.1,107.25,.598,67,.32,107.27,.559,75,.24,107.27,.677,46,.08,107.47,.52,46,.07,107.66,.551,46,.06,107.86,.512,46,.08,108.05,.575,74,.13,108.06,.638,65,.08,108.06,.52,46,.07,108.24,.559,63,.08,108.26,.591,72,.08,108.27,.575,46,.09,108.45,.583,70,.41,108.45,.669,65,.44,108.45,.606,62,.41,108.46,.638,46,.07,108.66,.504,46,.07,108.84,.504,46,.08,109.04,.535,62,.21,109.22,.614,69,.23,109.22,.583,46,.08,109.23,.512,65,.2,109.23,.559,46,.07,109.43,.512,68,.52,109.63,.677,62,.48,109.63,.606,65,.51,109.64,.551,47,.11,109.64,.614,47,.09,109.85,.488,47,.09,110.05,.465,47,.08,110.26,.457,68,.19,110.47,.591,47,.09,110.47,.52,62,.21,110.47,.559,65,.18,110.48,.512,47,.08,110.68,.465,69,.63,110.94,.583,48,.55,110.94,.543,60,.56,110.94,.567,64,.58,110.95,.496,71,.56,112.29,.591,64,.59,112.3,.535,52,.61,112.3,.441,56,.53,112.3,.48,57,.13,113.59,.622,33,.08,113.6,.677,60,.14,113.75,.528,64,.05,113.9,.496,69,.09,114.03,.559,72,.13,114.15,.583,76,.14,114.28,.575,60,.14,114.39,.543,57,.15,114.4,.535,64,.14,114.4,.512,74,.14,114.4,.575,72,.09,114.53,.575,71,.09,114.64,.551,60,.53,114.77,.551,64,.53,114.77,.543,69,.1,114.77,.52,57,.52,114.78,.543,72,.11,114.9,.551,76,.06,115.03,.559,81,.08,115.16,.63,84,.1,115.27,.622,88,.14,115.39,.638,86,.14,115.51,.559,60,.14,115.52,.559,64,.14,115.52,.543,57,.14,115.53,.551,84,.1,115.63,.598,83,.09,115.73,.567,81,.1,115.85,.591,64,.54,115.87,.575,57,.53,115.88,.591,60,.54,115.88,.567,84,.1,115.98,.598,88,.07,116.1,.606,93,.07,116.23,.622,96,.13,116.35,.638,100,.2,116.48,.693,98,.19,116.61,.63,57,.14,116.63,.583,64,.14,116.63,.551,60,.13,116.64,.575,96,.14,116.74,.685,95,.17,116.88,.638,94,.16,117.03,.677,60,.2,117.04,.591,64,.21,117.04,.559,57,.21,117.04,.614,93,.14,117.2,.559,92,.15,117.35,.646,91,.15,117.5,.559,90,.18,117.65,.583,89,.18,117.81,.543,88,.17,117.98,.528,87,.17,118.16,.559,86,.18,118.34,.528,85,.2,118.52,.543,84,.19,118.72,.551,83,.24,118.91,.496,82,.22,119.14,.496,81,.23,119.37,.512,80,.21,119.6,.512,79,.28,119.82,.496,78,.29,120.08,.496,77,.26,120.38,.488,76,.25,120.65,.441,75,.25,120.93,.472,76,.21,121.2,.48,71,.2,121.41,.488,74,.17,121.61,.52,72,.22,121.79,.52,45,.22,121.96,.488,69,.2,121.96,.496,52,.23,122.16,.441,57,.1,122.33,.472,60,.14,122.48,.496,64,.14,122.65,.504,69,.18,122.81,.551,40,.12,122.96,.551,71,.14,122.97,.575,52,.16,123.14,.504,56,.07,123.31,.472,64,.16,123.46,.504,68,.18,123.61,.551,71,.18,123.78,.528,45,.2,123.94,.512,72,.26,123.94,.575,52,.22,124.13,.441,57,.15,124.31,.488,64,.12,124.49,.488,76,.16,124.66,.591,75,.15,124.84,.535,76,.16,125,.543,75,.17,125.15,.575,76,.18,125.32,.559,71,.13,125.49,.504,74,.15,125.64,.528,72,.18,125.8,.551,69,.16,125.96,.543,45,.17,125.98,.512,52,.26,126.16,.48,57,.09,126.32,.496,60,.16,126.47,.496,64,.15,126.64,.512,69,.16,126.8,.543,40,.12,126.95,.551,71,.16,126.96,.575,52,.19,127.14,.504,56,.06,127.31,.472,64,.18,127.45,.52,72,.18,127.62,.591,71,.22,127.8,.496,45,.21,127.96,.496,69,.24,127.98,.52,52,.2,128.17,.457,57,.17,128.34,.48,71,.2,128.51,.543,72,.17,128.67,.591,74,.19,128.83,.583,76,.22,129,.622,48,.2,129.01,.591,55,.3,129.2,.48,60,.11,129.38,.52,67,.18,129.55,.559,77,.18,129.71,.606,76,.23,129.88,.528,43,.13,130.03,.528,74,.16,130.04,.583,55,.21,130.21,.488,59,.08,130.38,.488,65,.19,130.55,.512,76,.21,130.72,.543,74,.2,130.9,.535,45,.17,131.05,.52,72,.15,131.07,.551,52,.28,131.24,.496,57,.11,131.42,.528,64,.2,131.58,.52,74,.2,131.76,.598,72,.17,131.94,.543,40,.11,132.09,.575,71,.17,132.1,.575,52,.06,132.29,.528,64,.07,132.48,.52,64,.16,132.66,.496,76,.13,132.83,.559,64,.17,133.01,.52,76,.1,133.18,.528,76,.26,133.38,.512,88,.15,133.59,.606,75,.2,133.79,.559,76,.14,133.97,.543,75,.17,134.15,.559,76,.17,134.31,.551,75,.16,134.48,.52,76,.16,134.63,.52,75,.16,134.79,.567,76,.14,134.97,.528,75,.16,135.13,.512,76,.17,135.29,.512,75,.17,135.45,.52,76,.16,135.63,.504,71,.16,135.78,.496,74,.17,135.95,.535,72,.2,136.11,.504,45,.2,136.28,.504,69,.17,136.29,.504,52,.29,136.47,.496,57,.1,136.64,.512,60,.18,136.8,.512,64,.19,136.97,.528,69,.18,137.14,.551,71,.15,137.3,.591,40,.11,137.31,.567,52,.21,137.48,.528,56,.08,137.65,.504,64,.21,137.81,.551,68,.18,137.97,.575,71,.2,138.14,.535,45,.19,138.29,.504,72,.29,138.3,.622,52,.22,138.47,.512,57,.16,138.65,.535,64,.14,138.83,.512,76,.17,138.98,.575,75,.15,139.15,.575,76,.17,139.32,.551,75,.17,139.46,.575,76,.18,139.64,.559,71,.17,139.8,.512,74,.18,139.96,.543,72,.2,140.14,.528,45,.2,140.29,.512,69,.16,140.31,.528,52,.33,140.49,.512,57,.1,140.69,.512,60,.16,140.86,.504,64,.19,141.04,.504,69,.19,141.21,.52,40,.13,141.39,.591,71,.2,141.39,.583,52,.24,141.58,.528,56,.19,141.8,.512,62,.7,142.03,.559,72,.43,142.31,.598,71,.55,142.67,.535,60,2.89,143.19,.559,69,2.89,143.19,.551,45,2.89,143.2,.441,33,2.85,143.2,.496],sustainPedal:[1.09,2.21,2.42,3.22,3.42,4.31,4.53,6.32,6.51,7.27,7.48,8.61,8.8,10.89,11.08,11.86,12.06,12.97,13.17,15.05,15.24,16.04,16.22,17.27,17.43,18.36,18.54,19.36,19.53,20.49,20.66,21.46,21.64,25.86,26.03,26.81,26.99,27.95,28.13,30.07,30.22,30.95,31.1,32.23,32.4,33.3,33.46,34.3,34.47,35.43,35.57,36.45,36.59,40.81,40.98,41.77,41.94,42.91,43.08,44.95,45.12,45.93,46.09,47.09,47.31,48.73,48.93,49.93,50.1,51.14,51.32,52.35,52.51,53.55,53.7,54.58,54.79,55.44,55.59,55.85,56.02,57.13,58.55,58.78,59.47,59.91,61.38,61.63,68.96,71.29,71.48,72.19,72.41,73.25,73.47,75.2,75.44,76.19,76.4,77.38,77.61,78.35,78.52,79.25,79.47,80.39,80.6,81.31,81.53,85.62,85.82,86.5,86.73,87.66,87.87,89.61,89.84,90.57,90.79,91.63,91.82,92.92,93.04,94.06,94.22,95.21,95.39,96.41,96.58,97.53,97.71,98.7,98.87,99.83,99.99,100.65,100.76,101.03,101.22,103.54,103.67,104.71,104.84,105.96,106.15,107.24,107.41,108.46,108.6,109.59,109.78,110.94,111.29,111.58,112.58,113.24,113.61,121.89,122.1,122.83,123.03,123.9,124.07,125.88,126.09,126.85,127.04,127.96,128.14,128.98,129.17,129.89,130.07,131,131.17,131.95,132.14,136.2,136.41,137.13,137.34,138.17,138.39,140.24,140.45,141.33,141.48,143.23,143.67,145.98]};
const ret = { notes: [], duration: 150 };

for (let i=0, ip=0, n=data.notes, p=data.sustainPedal, sustain=false; i<n.length; i+=4) {
if (n[i+2] > p[ip]) ip++, sustain=!sustain;
ret.notes.push({
midi: n[i+0],
duration: n[i+1],
time: n[i+2],
dt: i>0?n[i+2]-n[i-2]:n[i+2],
velocity: n[i+3],
sustain,
sustainMaxDuration: p[ip]-n[i+2],
});
}

return ret;
}
```