Instantly share code, notes, and snippets.

Embed
What would you like to do?
Gists for Winds Waveform Blog Post
<svg
viewBox="0 0 100 100"
class="waveform-container"
preserveAspectRatio="none"
>
<rect
class="waveform-bg"
x="0"
y="0"
height="100"
width="100"
/>
<rect
class="waveform-progress"
x="0"
y="0"
height="100"
width=”0
/>
</svg>
indexes values in the bucket max
0 - 4 [ '-0.72', '0.95', '-0.92', '0.47', '-0.02' ] 0.95
5 - 9 [ '-0.76', '0.33', '-0.55', '-0.11', '0.00' ] 0.33
10 - 14 [ '-0.71', '-0.03', '-0.19', '-0.84', '0.13' ] 0.13
15 - 19 [ '-0.72', '0.70', '-0.96', '0.19', '-0.44' ] 0.70
20 - 24 [ '-0.27', '-0.25', '0.23', '-0.23', '-0.50' ] 0.23
...
const NUMBER_OF_BUCKETS = 100; // number of "bars" the waveform should have
let bucketDataSize = Math.floor(decodedAudioData.length / NUMBER_OF_BUCKETS,);
let buckets = [];
for (var i = 0; i < NUMBER_OF_BUCKETS; i++) {
let startingPoint = i * bucketDataSize;
let endingPoint = i * bucketDataSize + bucketDataSize;
let max = 0;
for (var j = startingPoint; j < endingPoint; j++) {
if (decodedAudioData[j] > max) {
max = decodedAudioData[j];
}
}
let size = Math.abs(max);
buckets.push(size / 2);
}
.waveform-bg {
clip-path: url(#waveform-mask);
fill: lightgray;
}
.waveform-progress {
clip-path: url(#waveform-mask);
fill: #44bc75; /* green! */
}
document.getElementById("waveform-mask").innerHTML = buckets.map((bucket, i) => {
let bucketSVGWidth = 100.0 / buckets.length;
let bucketSVGHeight = bucket * 100.0;
return `<rect
x=${bucketSVGWidth * i + SPACE_BETWEEN_BARS / 2.0}
y=${ (100 - bucketSVGHeight) / 2.0}
width=${bucketSVGWidth - SPACE_BETWEEN_BARS}
height=${bucketSVGHeight} />`;
}).join("");
});
0.28 0.20 0.20 0.21 0.26 0.18 0.18 0.18 0.18 0.17 0.18 0.19 0.18 0.18 0.18 0.18 0.24 0.23 0.25 0.23 0.28 0.19 0.29 0.27 0.20 0.22 0.22 0.21 0.18 0.22 0.25 0.24 0.17 0.20 0.34 0.26 0.27 0.23 0.19 0.14 0.26 0.22 0.22 0.24 0.25 0.24 0.21 0.18 0.25 0.25 0.21 0.28 0.23 0.34 0.23 0.17 0.23 0.24 0.23 0.27 0.22 0.24 0.25 0.24 0.23 0.14 0.33 0.28 0.17 0.23 0.27 0.30 0.24 0.23 0.17 0.20 0.27 0.22 0.22 0.21 0.25 0.21 0.24 0.24 0.26 0.21 0.21 0.16 0.23 0.22 0.28 0.22 0.28 0.24 0.29 0.25 0.21 0.27 0.20 0.20
Float32Array(143669376)
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.000030517578125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …]
let audioCtx = new(window.AudioContext || window.webkitAudioContext)();
axios({url: "/car-talk.mp3", responseType: "arraybuffer"})
.then(response => {
var audioData = response.data;
audioCtx.decodeAudioData(audioData, buffer => {
decodedAudioData = buffer.getChannelData(0);
console.log(decodedAudioData);
});
});
<!-- this SVG is the "clipping mask" - the waveform bars -->
<svg height="0" width="0">
<defs>
<clipPath id="waveform-mask"></clipPath>
</defs>
</svg>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment