Skip to content

Instantly share code, notes, and snippets.

@jkohlin
Created June 28, 2017 10:58
Show Gist options
  • Save jkohlin/b574145ca23d272a683f34e3c211154b to your computer and use it in GitHub Desktop.
Save jkohlin/b574145ca23d272a683f34e3c211154b to your computer and use it in GitHub Desktop.
Frequency and amplitude visualiser using web audio API
<!doctype html>
<html lang=en>
<head>
<meta charset=utf-8>
<title>Web audio API</title>
<style>
</style>
</head>
<body>
<button id="play-btn" style="display:none;">play/pause</button>
<script src="script.js" charset="utf-8"></script>
</body>
</html>
//set up canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
var cw = canvas.width = 1024;
var ch = canvas.height =255;
var waveForm = document.createElement("canvas");
waveForm.width = 1024;
waveForm.height =255;
var ctxw = waveForm.getContext("2d");
document.body.appendChild(canvas);
document.body.appendChild(waveForm);
// set up HTML5 audio player
var audio = new Audio();
audio.src = "https://kohlin.net/dg/webaudio/mau5.mp3";
audio.load();
// Set up web audio object
var duration=0;
window.AudioContext = window.AudioContext||window.webkitAudioContext; // old safari trick
var audioContext = new AudioContext();
var analyser = audioContext.createAnalyser();
analyser.connect(audioContext.destination);
var source = audioContext.createMediaElementSource(audio);
// async, wait for audio to load before connecting to audioContext
audio.addEventListener("canplaythrough", function(){
source.connect(analyser);
document.getElementById("play-btn").style.display = "block";
duration = audio.duration;
draw();
});
function getDataFromAudio(){
//analyser.fftSize = 2048;
var freqByteData = new Uint8Array(analyser.fftSize/2);
var timeByteData = new Uint8Array(analyser.fftSize/2);
analyser.getByteFrequencyData(freqByteData);
analyser.getByteTimeDomainData(timeByteData);
return {f:freqByteData, t:timeByteData}; // array of all 1024 levels
}
//play button
document.getElementById("play-btn").addEventListener("click", function(){
//audio.currentTime=420;
audio.paused ? (audio.play(), draw()): audio.pause();
})
var currentTime ;
function draw(t) {
currentTime = audio.currentTime;
ctx.clearRect(0,0,1024,255)
var ID = requestAnimationFrame(draw);
if (audio.paused) {
cancelAnimationFrame(ID)
}
var data = getDataFromAudio(); // {f:array, t:array}
var waveSum = 0;
//draw live waveform and oscilloscope
for (let i = 0; i<data.f.length; i++) {
ctx.fillStyle="black";
ctx.fillRect(i, ch, 1, -data.f[i]);
waveSum += data.f[i]; //add current bar value (max 255)
}
for (let i = 0; i<data.t.length; i++) {
ctx.fillStyle="red";
ctx.fillRect(i*2, data.t[i], 1, 1);
}
if (Math.round(currentTime)%4 == 0) {
ctxw.fillRect(currentTime/duration*1024, ch, 1,-waveSum/data.f.length);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment