erynwells.me/content/blog/2022/08/audio-scope-with-p5js/sketch.js

89 lines
2.8 KiB
JavaScript

const oscilloscopeFinal = p => {
let analyzerNode = null;
let samples = null;
let audioElement = (() => {
return document.querySelector('audio#amen');
})();
let audioContext = (() => {
const audioContext = new AudioContext();
const track =
audioContext.createMediaElementSource(audioElement);
analyzerNode = audioContext.createAnalyser();
track.connect(analyzerNode)
.connect(audioContext.destination);
return audioContext;
})();
p.setup = () => {
const sketchContainer = document.querySelector('#oscilloscopeFinal');
const canvasWidth = parseFloat(getComputedStyle(sketchContainer).width);
let canvas = p.createCanvas(canvasWidth, 250);
canvas.canvas.removeAttribute('style');
sketchContainer.appendChild(canvas.canvas);
p.pixelDensity(p.displayDensity());
samples = new Float32Array(p.width);
const playPauseButton = p.createButton('Play');
playPauseButton.position(10, 10);
const playPauseButtonElement = playPauseButton.elt;
playPauseButtonElement.dataset.playing = 'false';
playPauseButtonElement.addEventListener('click', function() {
if (audioContext.state === 'suspended') {
audioContext.resume();
}
if (this.dataset.playing === 'false') {
audioElement.play();
this.dataset.playing = 'true';
this.innerHTML = '<span>Pause</span>';
} else if (this.dataset.playing === 'true') {
audioElement.pause();
this.dataset.playing = 'false';
this.innerHTML = '<span>Play</span>';
}
});
audioElement.addEventListener('ended', function() {
playPauseButtonElement.dataset.playing = 'false';
playPauseButtonElement.innerHTML = '<span>Play</span>';
}, false);
};
p.draw = () => {
const amplitude = p.height / 2;
const axis = p.height / 2;
const blue = p.color(24, 62, 140);
const purple = p.color(255, 0, 255);
p.background(255);
if (analyzerNode) {
analyzerNode.getFloatTimeDomainData(samples);
}
for (let i = 0; i < samples.length; i++) {
const sampleValue = samples[i];
const absSampleValue = Math.abs(sampleValue);
const weight = p.lerp(2, 12, 1.5 * absSampleValue);
p.strokeWeight(sampleValue === 0 ? 1 : weight);
p.stroke(p.lerpColor(blue, purple, absSampleValue));
p.point(i, axis + amplitude * sampleValue);
}
};
p.mouseClicked = () => {
p.clear();
};
};
new p5(oscilloscopeFinal, 'oscilloscopeFinal');