<html lang="en">
<head>
<title>2D audio vizualization: frequencies</title>
</head>
<body>
<h2>2D audio vizualization: frequencies</h2>
<div class="main">
<audio src="https://mainline.i3s.unice.fr/mooc/guitarRiff1.mp3" id="player" controls loop crossorigin="anonymous"></audio>
<source src="https://mainline.i3s.unice.fr/mooc/elephants-dream-medium.mp4" >
</video>
<canvas id="myCanvas" width=300 height=100></canvas>
</div>
</body>
</html>
div audio {
display: block;
margin-bottom:10px;
margin-left:10px;
}
#myCanvas {
border:1px solid;
}
.main {
margin: 32px;
border:1px solid;
border-radius:15px;
background-color:lightGrey;
padding:10px;
width:320px;
box-shadow: 10px 10px 5px grey;
text-align:center;
font-family: "Open Sans";
font-size: 12px;
}
div.controls:hover {
color:blue;
font-weight:bold;
}
div.controls label {
display: inline-block;
text-align: center;
width: 50px;
}
div.controls label, div.controls input, output {
vertical-align: middle;
padding: 0;
margin: 0;
font-family: "Open Sans",Verdana,Geneva,sans-serif,sans-serif;
font-size: 12px;
}
//buil an equalizer with multiple biquad filters
var audioCtx = window.AudioContext || window.webkitAudioContext;
var canvas;
var audioContext, canvasContext;
var analyser;
var width, height;
var dataArray, bufferLength;
window.onload = function() {
audioContext= new audioCtx();
canvas = document.querySelector("#myCanvas");
width = canvas.width;
height = canvas.height;
canvasContext = canvas.getContext('2d');
buildAudioGraph();
requestAnimationFrame(visualize2);
};
function buildAudioGraph() {
var mediaElement = document.getElementById('player');
mediaElement.onplay = (e)=>{audioContext.resume();}
var sourceNode = audioContext.createMediaElementSource(mediaElement);
// fix for autoplay policy
mediaElement.addEventListener('play',() => audioContext.resume());
// Create an analyser node
analyser = audioContext.createAnalyser();
// Try changing for lower values: 512, 256, 128, 64...
analyser.fftSize = 256;
bufferLength = analyser.frequencyBinCount;
dataArray = new Uint8Array(bufferLength);
sourceNode.connect(analyser);
analyser.connect(audioContext.destination);
}
function visualize2() {
canvasContext.save();
canvasContext.fillStyle = "rgba(0, 0, 0, 0.05)";
canvasContext.fillRect (0, 0, width, height);
analyser.getByteFrequencyData(dataArray);
var nbFreq = dataArray.length;
var SPACER_WIDTH = 5;
var BAR_WIDTH = 2;
var OFFSET = 100;
var CUTOFF = 23;
var HALF_HEIGHT = height/2;
var numBars = 1.7*Math.round(width / SPACER_WIDTH);
var magnitude;
canvasContext.lineCap = 'round';
for (var i = 0; i < numBars; ++i) {
magnitude = 0.3*dataArray[Math.round((i * nbFreq) / numBars)];
canvasContext.fillStyle = "hsl( " + Math.round((i*360)/numBars) + ", 100%, 50%)";
canvasContext.fillRect(i * SPACER_WIDTH, HALF_HEIGHT, BAR_WIDTH, -magnitude);
canvasContext.fillRect(i * SPACER_WIDTH, HALF_HEIGHT, BAR_WIDTH, magnitude);
}
// Draw animated white lines top
canvasContext.strokeStyle = "white";
canvasContext.beginPath();
for (i = 0; i < numBars; ++i) {
magnitude = 0.3*dataArray[Math.round((i * nbFreq) / numBars)];
if(i > 0) {
//console.log("line lineTo " + i*SPACER_WIDTH + ", " + -magnitude);
canvasContext.lineTo(i*SPACER_WIDTH, HALF_HEIGHT-magnitude);
} else {
//console.log("line moveto " + i*SPACER_WIDTH + ", " + -magnitude);
canvasContext.moveTo(i*SPACER_WIDTH, HALF_HEIGHT-magnitude);
}
}
for (i = 0; i < numBars; ++i) {
magnitude = 0.3*dataArray[Math.round((i * nbFreq) / numBars)];
if(i > 0) {
//console.log("line lineTo " + i*SPACER_WIDTH + ", " + -magnitude);
canvasContext.lineTo(i*SPACER_WIDTH, HALF_HEIGHT+magnitude);
} else {
//console.log("line moveto " + i*SPACER_WIDTH + ", " + -magnitude);
canvasContext.moveTo(i*SPACER_WIDTH, HALF_HEIGHT+magnitude);
}
}
canvasContext.stroke();
canvasContext.restore();
requestAnimationFrame(visualize2);
}
Output
You can jump to the latest bin by adding /latest
to your URL
Keyboard Shortcuts
Shortcut | Action |
---|---|
ctrl + [num] | Toggle nth panel |
ctrl + 0 | Close focused panel |
ctrl + enter | Re-render output. If console visible: run JS in console |
Ctrl + l | Clear the console |
ctrl + / | Toggle comment on selected lines |
ctrl + ] | Indents selected lines |
ctrl + [ | Unindents selected lines |
tab | Code complete & Emmet expand |
ctrl + shift + L | Beautify code in active panel |
ctrl + s | Save & lock current Bin from further changes |
ctrl + shift + s | Open the share options |
ctrl + y | Archive Bin |
Complete list of JS Bin shortcuts |
JS Bin URLs
URL | Action |
---|---|
/ | Show the full rendered output. This content will update in real time as it's updated from the /edit url. |
/edit | Edit the current bin |
/watch | Follow a Code Casting session |
/embed | Create an embeddable version of the bin |
/latest | Load the very latest bin (/latest goes in place of the revision) |
/[username]/last | View the last edited bin for this user |
/[username]/last/edit | Edit the last edited bin for this user |
/[username]/last/watch | Follow the Code Casting session for the latest bin for this user |
/quiet | Remove analytics and edit button from rendered output |
.js | Load only the JavaScript for a bin |
.css | Load only the CSS for a bin |
Except for username prefixed urls, the url may start with http://jsbin.com/abc and the url fragments can be added to the url to view it differently. |