User:Lakelimbo/test
<audio id="audio" src="https://static.miraheze.org/rotompediawiki/3/36/Springyard.wav" controls></audio>
<canvas id="oscilloscope"></canvas> <canvas id="spectrogram"></canvas>
<script type="text/javascript"> // Create context and nodes const audioElement = document.getElementById("audio"); const audioContext = new AudioContext(); audio.crossOrigin = "anonymous"; const track = audioContext.createMediaElementSource(audioElement); const masterGain = audioContext.createGain(); const analyser = audioContext.createAnalyser();
// Build Audio Chain track .connect(masterGain) .connect(analyser) .connect(audioContext.destination);
/*
* The Web Audio API provides the AnalyserNode for this purpose. * In addition to providing the raw waveform (aka time domain) data, * it provides methods for accessing the audio spectrum (aka frequency domain) data. * * At this point, the waveform array will contain values from -1 to 1 corresponding to the audio waveform playing * through the masterGain node. This is just a snapshot of whatever’s currently playing. * */
const waveform = new Float32Array(analyser.frequencyBinCount); analyser.getFloatTimeDomainData(waveform);
function updateWaveform() { requestAnimationFrame(updateWaveform); analyser.getFloatTimeDomainData(waveform); }
updateWaveform();
// Setup canvas const oscCanvas = document.getElementById("oscilloscope"); oscCanvas.width = waveform.length; oscCanvas.height = 200; const canvasContext = oscCanvas.getContext("2d");
function drawOscilloscope() { requestAnimationFrame(drawOscilloscope);
canvasContext.clearRect(0, 0, oscCanvas.width, oscCanvas.height); canvasContext.beginPath(); canvasContext.strokeStyle = "red"; canvasContext.lineWidth = 5;
for (let i = 0; i < waveform.length; i++) { const x = i; const y = (0.5 + waveform[i] / 2) * oscCanvas.height; if (i === 0) { canvasContext.moveTo(x, y); } else { canvasContext.lineTo(x, y); } } canvasContext.stroke(); }
drawOscilloscope();
// Spectrogram /*
- In this case we’ll request the data as a Uint8Array because values in the range 0-255
- are exactly what we need when performing Canvas pixel manipulation.
- */
const spectrum = new Uint8Array(analyser.frequencyBinCount);
function updateSpectrum() { requestAnimationFrame(updateSpectrum); analyser.getByteFrequencyData(spectrum); }
updateSpectrum();
// Setup Canvas const spectroCanvas = document.getElementById("spectrogram"); spectroCanvas.width = spectrum.length; spectroCanvas.height = 200; const spectroContext = spectroCanvas.getContext("2d"); let spectroOffset = 0;
function drawSpectrogram() { requestAnimationFrame(drawSpectrogram);
const slice = spectroContext.getImageData( 0, spectroOffset, spectroCanvas.width, 1 );
for (let i = 0; i < spectrum.length; i++) { slice.data[4 * i + 0] = spectrum[i]; // R slice.data[4 * i + 1] = spectrum[i]; // G slice.data[4 * i + 2] = spectrum[i]; // B slice.data[4 * i + 3] = 255; // A }
spectroContext.putImageData(slice, 0, spectroOffset); spectroOffset += 1; spectroOffset %= spectroCanvas.height; }
drawSpectrogram();