```

```

### Smoke on the water (loud!)

A small remake of the classic riff by . I wanted to create a distortion effect and it turns out that FM synthesis is quite usable for creating that effect when fiddling with the modulation frequency. Here, it has to be really close to, but not exactly a quarter of the carrier frequency to yield a somewhat convincing result. Other values just sound meh.

```const sin = Math.sin;
const TAU = 2*Math.PI;

ditty.bpm = 120;

// synths

const kick = synth.def( (phase, env, tick, options) => sin(phase*TAU*(tick<0.5?0.5-tick:0)) * env.value);

const strat = synth.def( class {
constructor (options) {
this.t = 0
this.iom = options.iom || 13.37;
this.mul = options.multiplier || 0.251;
}
// carrier frequency
const fc = midi_to_hz(note);
// modulator frequency
const fm = fc * this.mul;
return sin(
TAU*this.t*fc + this.iom*sin(TAU*this.t*fm)
) * env.value;
}
process(note, env, tick, options) {
// forward time
this.t += ditty.dt;

// overdrive the oscillators
const gain = 5;

// create power-chord, i.e. perfect fifth
let osc = this.add_fm(note, env) * gain;
osc +=  this.add_fm(note+7, env) * gain;

// clip
osc = osc < -1 ? -1 : osc > 1 ? 1 : osc;

return [osc, osc]; // left, right
}
});

// filters

// from https://dittytoy.net/syntax#filters
const lowpass = filter.def(class {
constructor(options) {
this.hist0 = [0, 0];
this.hist1 = [0, 0];
this.t = 0;
}

process(input, options) {
const alpha = clamp(options.cutoff, 0.01, 1);
if (input) {
for (let i = 0; i < 2; i++) {
this.hist0[i] += alpha * (input[i] - this.hist0[i]);
this.hist1[i] += alpha * (this.hist0[i] - this.hist1[i]);
}
return this.hist1;
}
}
});

// notes

const riff = [
[d4, 1], [f4, 1], [g4, 1.5],
[d4, 1], [f4, 1], [gs4, 0.5], [g4, 2],
[d4, 1], [f4, 1], [g4, 1.5],
[f4, 1], [d4, 0.5], [d4, 3],
];
let i = 0;

// loops

loop( () => {
kick.play(g4, { attack: 0.01, release: 0.05, duration: 0.2, amp: 1.2 });
sleep(1);
}, { name: 'Kick' });

loop( () => {
let [note, duration] = riff[i++];
if (i>=riff.length) i = 0;

const ds = 0.25 * duration;
const dt = second_to_tick(ds);
strat.play(note, { attack: 0.01, decay: ds, duration: dt, amp: 0.7 });
sleep(duration); // sleep in ticks

}, { name: 'Riff' }).connect( lowpass.create( { cutoff: () => input.cutoff } ));

// inputs

input.cutoff = 0.464;
```