initial commit

This commit is contained in:
Evert Prants 2020-09-26 14:53:16 +03:00
commit 4a197c2d25
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
2 changed files with 115 additions and 0 deletions

37
index.html Normal file
View File

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Audio Spectrum Visualizer</title>
<style media="screen">
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
display: block;
overflow: hidden;
}
body {
background-color: #000;
}
.input {
position: absolute;
}
.canvases {
display: flex;
flex-direction: row;
}
</style>
</head>
<body>
<div class="input">
<input type="file" name="track" accept="audio/*" id="track"/>
</div>
<div class="canvases">
<canvas width="300" height="300" id="graph"></canvas>
<canvas id="bars" width="300" height="300"></canvas>
</div>
<script src="./index.js" charset="utf-8"></script>
</body>
</html>

78
index.js Normal file
View File

@ -0,0 +1,78 @@
(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)
})
})()