Created
June 28, 2017 10:58
-
-
Save jkohlin/b574145ca23d272a683f34e3c211154b to your computer and use it in GitHub Desktop.
Frequency and amplitude visualiser using web audio API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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