AudioContext and SVG polylines.
More in my Audio Visualization Collection
AudioContext integration from Ali Görkem's Pen Audio Visualizer #3.
A Pen by Jake Albaugh on CodePen.
| <input id=audiofile type=file> | |
| <svg id=svg></svg> | 
| // AudioContext and analyser integration from Ali Görkem's | |
| // Pen "Audio Visualizer #3" | |
| // http://codepen.io/agorkem/pen/PwyNOg/ | |
| // thanks dewd! | |
| window.onload = function() { | |
| var audio, | |
| analyser, | |
| audioContext, | |
| sourceNode, | |
| stream; | |
| var svg = document.getElementById('svg'), | |
| svgNS = svg.namespaceURI, | |
| g = document.createElementNS(svgNS, "g"); | |
| var width = window.innerWidth, | |
| height = window.innerHeight, | |
| maxHeight = Math.max(height * 0.3, 300), | |
| fftSize = 512, // 512 | |
| tilt = 40, | |
| choke = 110, | |
| c = 0; | |
| var audioInput = document.getElementById('audiofile'); | |
| // choose file | |
| audioInput.addEventListener('change', function(event) { | |
| stream = URL.createObjectURL(event.target.files[0]); | |
| audio = new Audio(); | |
| audio.src = stream; | |
| setup(); | |
| }); | |
| function setup() { | |
| audio.addEventListener('canplay', function () { | |
| document.body.className+='loaded'; | |
| audioContext = new AudioContext(); | |
| analyser = (analyser || audioContext.createAnalyser()); | |
| analyser.minDecibels = -90; | |
| analyser.maxDecibels = -10; | |
| analyser.smoothingTimeConstant = 1;//0.75; | |
| analyser.fftSize = fftSize; | |
| sourceNode = audioContext.createMediaElementSource(audio); | |
| sourceNode.connect(analyser); | |
| sourceNode.connect(audioContext.destination); | |
| audio.play(); | |
| update(); | |
| }); | |
| } | |
| function shape(g, freqValue, freqSequence, freqCount, colorSequence) { | |
| var freqRatio = freqSequence/freqCount, | |
| x = (width - (tilt * 2)) * freqRatio + tilt, | |
| y = height / 2; | |
| var polyline = document.createElementNS(svgNS, "polyline"), | |
| // using power to increase highs and decrease lows | |
| freqRatio = freqValue / 255, | |
| throttledRatio = (freqValue - choke) / (255 - choke), | |
| strokeWidth = width / freqCount * 0.6 * throttledRatio, | |
| throttledY = Math.max(throttledRatio, 0) * maxHeight, | |
| // color | |
| color = "hsl(" + | |
| ((freqSequence / 2) + Math.floor(colorSequence)) + ", " + | |
| 100 + "%," + | |
| freqRatio * 80 + "%" + | |
| ")"; | |
| var loc_x = x - strokeWidth / 2, | |
| loc_y1 = y - throttledY / 2, | |
| loc_y2 = y + throttledY / 2, | |
| x_offset = tilt * throttledRatio; | |
| if (throttledRatio > 0) { | |
| var point_1 = (loc_x - x_offset) + "," + loc_y1, | |
| point_2 = (loc_x + x_offset) + "," + loc_y2; | |
| var points = [ point_1, point_2 ]; | |
| } else { | |
| var points = [loc_x + "," + (y-1),loc_x + "," + (y+1)] | |
| } | |
| polyline.setAttribute("stroke-width", strokeWidth); | |
| polyline.setAttribute("stroke", color); | |
| polyline.setAttribute("points", points.join(" ")); | |
| g.appendChild(polyline); | |
| } | |
| svg.setAttribute("width", width+"px"); | |
| svg.setAttribute("height", height+"px"); | |
| svg.setAttribute("viewBox", "0 0 " + width + " " + height); | |
| svg.appendChild(g); | |
| function update() { | |
| g.remove(); | |
| g = document.createElementNS(svgNS, "g"); | |
| var freqArray = new Uint8Array(analyser.frequencyBinCount); | |
| analyser.getByteTimeDomainData(freqArray); | |
| for (var i = 0; i < freqArray.length; i++) { | |
| var v = freqArray[i]; | |
| shape(g, v, i+1, freqArray.length, c); | |
| } | |
| svg.appendChild(g); | |
| c += 0.5; | |
| requestAnimationFrame(update); | |
| } | |
| }; | 
| body { | |
| margin: 0; | |
| background-color: #000000; | |
| font-family: 'Helvetica', sans-serif; | |
| color: #FFFFFF; | |
| } | |
| input { | |
| position: absolute; | |
| top: 50%; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| z-index: 2; | |
| } | |
| body.loaded input { | |
| display: none; | |
| } | |
| #svg { | |
| display: block; | |
| position: absolute; | |
| top: 50%; left: 50%; | |
| transform: translate3d(-50%, -50%, 0); | |
| polyline { | |
| stroke-linecap: round; | |
| } | |
| } | 
AudioContext and SVG polylines.
More in my Audio Visualization Collection
AudioContext integration from Ali Görkem's Pen Audio Visualizer #3.
A Pen by Jake Albaugh on CodePen.