JSFiddle - React, Tailwind, and code Playground
JavaScript
var sampleRate = 8000;
function encodeAudio8bit(data) {
var n = data.length;
var integer = 0,
i;
var header = 'RIFF<##>WAVEfmt \x10\x00\x00\x00\x01\x00\x01\x00<##><##>\x01\x00\x08\x00data<##>';
function insertLong(value) {
var bytes = "";
for (i = 0; i < 4; ++i) {
bytes += String.fromCharCode(value % 256);
value = Math.floor(value / 256);
}
header = header.replace('<##>', bytes);
}
insertLong(36 + n);
insertLong(sampleRate);
insertLong(sampleRate);
insertLong(n);
for (var i = 0; i < n; ++i) {
header += String.fromCharCode(Math.round(Math.min(1, Math.max(-1, data[i])) * 127 + 127));
}
return 'data:audio/wav;base64,' + btoa(header);
}
function plotAudio(data, width, height) {
width = width || 1280;
height = height || 200;
var $canvas = $('<canvas>').attr({
width: width,
height: height
}).css({
cursor: 'pointer'
}),
ctx = $canvas[0].getContext('2d'),
dw = width / data.length,
x = 0,
h2 = height / 2;
ctx.strokeStyle = '#000';
ctx.beginPath();
ctx.moveTo(x, h2);
for (var i = 0; i < data.length; ++i) {
ctx.lineTo(x, h2 * (1 - data[i]));
x += dw;
}
ctx.stroke();
var dataUri = encodeAudio8bit(data);
var $audioPlayer = $('<audio>').attr({
src: dataUri,
controls: true
});
$('body').append($audioPlayer).append($canvas);
}
function addFractalMusic() {
var arr = []
for (var t = 0; t < 655360; t++) {
arr[t] = ((t * 40 >> 430 | t * 40 >> 4) * 430);
arr[t] = (arr[t] & 0xff) / 256.0;
}
plotAudio(arr, 300, 100);
}
addFractalMusic();