{
if (renderBtn === 0) return;
const notes = 16;
const noteOffsets = [0.5];
const tempoChanges = [0.01];
const wrongNoteIndices = [3];
const noteDeviations = d3.range(-0.05, 0.06, 0.02);
const imageWidth = 1000;
const imageHeight = 100;
const maxTimeDrawn = notes * d3.max(noteOffsets) + 5;
const zip = new jszip.default();
const count =
noteOffsets.length *
tempoChanges.length *
wrongNoteIndices.length *
noteDeviations.length;
console.log(`rendering ${count} samples`);
let current = 1;
for (const noteOffset of noteOffsets) {
for (const tempoChange of tempoChanges) {
for (const wrongNoteIndex of wrongNoteIndices) {
for (const noteDeviation of noteDeviations) {
if (current % 50 === 0 || current === count)
console.log(`rendering ${current} / ${count}`);
current++;
const name = `n-${notes}_no-${noteOffset.toFixed(
3
)}_tc-${tempoChange.toFixed(
3
)}_wni-${wrongNoteIndex}_nd-${noteDeviation.toFixed(3)}`;
// pattern
const pattern = generatePattern(
notes,
noteOffset,
tempoChange,
wrongNoteIndex,
noteDeviation
);
// render audio
const data = simulate(instrument, pattern);
const buffer = new AudioBuffer({ sampleRate, length: data.length });
buffer.copyToChannel(data, 0);
const blob = new Blob([audioBufferToWav.default(buffer)], {
type: "audio/wav"
});
zip.file(`${name}.wav`, blob);
// render tick image
// use fixed seconds/pixel
const canvas = document.createElement("canvas");
canvas.width = imageWidth;
canvas.height = imageHeight;
const context = canvas.getContext("2d");
context.fillStyle = "white";
context.fillRect(0, 0, imageWidth, imageHeight);
context.fillStyle = "black";
const scaleX = d3
.scaleLinear()
.domain([0, maxTimeDrawn])
.range([10, imageWidth - 10]);
for (const note of pattern) {
context.fillRect(scaleX(note), 0, 2, imageHeight);
}
const imgBlob = await new Promise((resolve) =>
canvas.toBlob(resolve)
);
zip.file(`${name}_ticks.png`, imgBlob);
// render waveform
context.fillStyle = "white";
context.fillRect(0, 0, imageWidth, imageHeight);
context.strokeStyle = "black";
const max = d3.max(data.map((d) => Math.abs(d)));
const scaleY = d3
.scaleLinear()
.domain([max, -max])
.range([0, imageHeight]);
const line = d3
.line()
.x((d, i) => scaleX(i / sampleRate))
.y((d) => scaleY(d))
.context(context);
context.beginPath();
line(data);
context.stroke();
const imgBlob2 = await new Promise((resolve) =>
canvas.toBlob(resolve)
);
zip.file(`${name}_wave.png`, imgBlob2);
}
}
}
}
// download
zip.generateAsync({ type: "blob" }).then((content) => {
// see FileSaver.js
fileSaver.default(content, "example.zip");
});
}