161 lines
5.1 KiB
PHP
161 lines
5.1 KiB
PHP
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
|
<title>Document</title>
|
|
<script src="/src/page/layout/resources/js/amp-script.js" defer></script>
|
|
<style>
|
|
body {
|
|
background-color: #DBDBDB;
|
|
}
|
|
|
|
canvas {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100vw;
|
|
height: 100vh;
|
|
z-index: -1;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.grid {
|
|
display: grid;
|
|
grid-template-columns: auto min-content;
|
|
justify-content: center;
|
|
justify-items: end;
|
|
align-items: center;
|
|
gap: 5px 10px;
|
|
}
|
|
|
|
input {
|
|
margin: 0;
|
|
}
|
|
</style>
|
|
<script>
|
|
const volume = document.getElementById('volume')
|
|
const bass = document.getElementById('bass')
|
|
const mid = document.getElementById('mid')
|
|
const treble = document.getElementById('treble')
|
|
const visualizer = document.getElementById('visualizer')
|
|
|
|
const context = new AudioContext()
|
|
const analyserNode = new AnalyserNode(context, { fftSize: 256 })
|
|
const gainNode = new GainNode(context, { gain: volume.value})
|
|
const bassEQ = new BiquadFilterNode(context, {
|
|
type: 'lowshelf',
|
|
frequency: 500,
|
|
gain: bass.value
|
|
})
|
|
const midEQ = new BiquadFilterNode(context, {
|
|
type: 'peaking',
|
|
Q: Math.SQRT1_2,
|
|
frequency: 1500,
|
|
gain: mid.value
|
|
})
|
|
const trebleEQ = new BiquadFilterNode(context, {
|
|
type: 'highshelf',
|
|
frequency: 3000,
|
|
gain: treble.value
|
|
})
|
|
|
|
setupEventListeners()
|
|
setupContext()
|
|
resize()
|
|
drawVisualizer()
|
|
|
|
function setupEventListeners() {
|
|
window.addEventListener('resize', resize)
|
|
|
|
volume.addEventListener('input', e => {
|
|
const value = parseFloat(e.target.value)
|
|
gainNode.gain.setTargetAtTime(value, context.currentTime, .01)
|
|
})
|
|
|
|
bass.addEventListener('input', e => {
|
|
const value = parseInt(e.target.value)
|
|
bassEQ.gain.setTargetAtTime(value, context.currentTime, .01)
|
|
})
|
|
|
|
mid.addEventListener('input', e => {
|
|
const value = parseInt(e.target.value)
|
|
midEQ.gain.setTargetAtTime(value, context.currentTime, .01)
|
|
})
|
|
|
|
treble.addEventListener('input', e => {
|
|
const value = parseInt(e.target.value)
|
|
trebleEQ.gain.setTargetAtTime(value, context.currentTime, .01)
|
|
})
|
|
}
|
|
|
|
async function setupContext() {
|
|
const guitar = await getGuitar()
|
|
if (context.state === 'suspended') {
|
|
await context.resume()
|
|
}
|
|
const source = context.createMediaStreamSource(guitar)
|
|
source
|
|
.connect(bassEQ)
|
|
.connect(midEQ)
|
|
.connect(trebleEQ)
|
|
.connect(gainNode)
|
|
.connect(analyserNode)
|
|
.connect(context.destination)
|
|
}
|
|
|
|
function getGuitar() {
|
|
return navigator.mediaDevices.getUserMedia({
|
|
audio: {
|
|
echoCancellation: false,
|
|
autoGainControl: false,
|
|
noiseSuppression: false,
|
|
latency: 0
|
|
}
|
|
})
|
|
}
|
|
|
|
function drawVisualizer() {
|
|
requestAnimationFrame(drawVisualizer)
|
|
|
|
const bufferLength = analyserNode.frequencyBinCount
|
|
const dataArray = new Uint8Array(bufferLength)
|
|
analyserNode.getByteFrequencyData(dataArray)
|
|
const width = visualizer.width
|
|
const height = visualizer.height
|
|
const barWidth = width / bufferLength
|
|
|
|
const canvasContext = visualizer.getContext('2d')
|
|
canvasContext.clearRect(0, 0, width, height)
|
|
|
|
dataArray.forEach((item, index) => {
|
|
const y = item / 255 * height / 2
|
|
const x = barWidth * index
|
|
|
|
canvasContext.fillStyle = `hsl(${y / height * 400}, 100%, 50%)`
|
|
canvasContext.fillRect(x, height - y, barWidth, y)
|
|
})
|
|
}
|
|
|
|
function resize() {
|
|
visualizer.width = visualizer.clientWidth * window.devicePixelRatio
|
|
visualizer.height = visualizer.clientHeight * window.devicePixelRatio
|
|
}
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<canvas id="visualizer"></canvas>
|
|
<div class="grid">
|
|
<label for="volume">Volume</label>
|
|
<input type="range" min="0" max="1" value=".5" step=".01" id="volume">
|
|
<label for="bass">Bass</label>
|
|
<input type="range" min="-10" max="10" value="0" id="bass">
|
|
<label for="mid">Mid</label>
|
|
<input type="range" min="-10" max="10" value="0" id="mid">
|
|
<label for="treble">Treble</label>
|
|
<input type="range" min="-10" max="10" value="0" id="treble">
|
|
</div>
|
|
</body>
|
|
</html>
|