(function () { const graph = document.getElementById('graph') const bars = document.getElementById('bars') const file = document.getElementById('track') const gctx = graph.getContext('2d') const bctx = bars.getContext('2d') let context let analyser let dataArray let bufferLength let source let started = false const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0) const vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0) - 5 graph.width = vw - 100 graph.height = vh bars.height = vh bars.width = 100 function analyse () { window.requestAnimationFrame(analyse) analyser.getFloatFrequencyData(dataArray) gctx.drawImage(graph, -2, 0) bctx.clearRect(0, 0, bars.width, bars.height) const dheight = (1 / dataArray.length) * graph.height for (let i = 0; i < dataArray.length; i++) { const p = i / dataArray.length const h = graph.height - p * graph.height const c = Math.max((dataArray[i] - analyser.minDecibels) / 95, 0) const s = 'hsl(0, 100%, ' + Math.floor(c * 100 - 10) + '%)' gctx.fillStyle = s gctx.fillRect(graph.width - 2, h, 2, dheight) // const freq = i * context.sampleRate / analyser.fftSize const bar = (dataArray[i] + 100) bctx.fillStyle = s bctx.fillRect(0, h, bar, dheight) } } async function start (arrayBuffer) { if (!context) context = new window.AudioContext() const audioBuffer = await context.decodeAudioData(arrayBuffer) analyser = context.createAnalyser() analyser.buffer = audioBuffer analyser.connect(context.destination) if (source) source.stop() source = context.createBufferSource() source.buffer = audioBuffer source.connect(analyser) source.start() bufferLength = analyser.frequencyBinCount dataArray = new Float32Array(bufferLength) if (started) return started = true analyse() } file.addEventListener('change', function (e) { const fp = file.files[0] if (!fp) return window.alert('Invalid file.') const fr = new window.FileReader() fr.addEventListener('loadend', function (e) { if (fr.readyState !== 2) return window.alert('File reading failed.') start(fr.result) }) fr.readAsArrayBuffer(fp) }) })()