Volume lines

This commit is contained in:
Benjamin Bädorf 2019-06-08 21:14:20 +02:00
parent 550712d2e0
commit ee60abc62b

View file

@ -3,6 +3,8 @@ import './index.scss';
const FFT_SIZE = 256; const FFT_SIZE = 256;
const VOLUME_THRESHOLD = 20; const VOLUME_THRESHOLD = 20;
const LINE_MARGIN = 20;
const MAX_LINES = 60;
function getRMS(spectrum) { function getRMS(spectrum) {
let rms = 0; let rms = 0;
@ -40,20 +42,14 @@ async function main() {
analyser.smoothingTimeConstant = 0.2; analyser.smoothingTimeConstant = 0.2;
analyser.fftSize = FFT_SIZE; analyser.fftSize = FFT_SIZE;
let fresh = false; let lines = [];
let spectrum = []; let maxPitch = 0;
let pitch = 0; let minPitch = 0;
let minPitch = 90;
let maxPitch = 90;
let volume = 0;
let volumeThreshold = 0;
let bars = [];
const audioProcessor = audioCtx.createScriptProcessor(FFT_SIZE * 2, 1, 1); const audioProcessor = audioCtx.createScriptProcessor(FFT_SIZE * 2, 1, 1);
audioProcessor.onaudioprocess = () => { audioProcessor.onaudioprocess = () => {
fresh = true;
// bitcount returns array which is half the FFT_SIZE // bitcount returns array which is half the FFT_SIZE
spectrum = new Uint8Array(analyser.frequencyBinCount); const spectrum = new Uint8Array(analyser.frequencyBinCount);
// getByteFrequencyData returns amplitude for each bin // getByteFrequencyData returns amplitude for each bin
analyser.getByteFrequencyData(spectrum); analyser.getByteFrequencyData(spectrum);
@ -62,24 +58,34 @@ async function main() {
spectrum.reverse(); spectrum.reverse();
const currentVolume = getRMS(spectrum);
// get peak - a hack when our volumes are low const volume = getRMS(spectrum);
if (currentVolume > volumeThreshold) { const pitch = getPitch(spectrum, volume);
volumeThreshold = currentVolume; lines.unshift({
} spectrum,
volume = currentVolume; volume,
pitch = getPitch(spectrum, volume, volumeThreshold); pitch,
});
if (pitch > maxPitch) { if (pitch > maxPitch) {
maxPitch = pitch maxPitch = pitch;
} else if (pitch < minPitch) { }
if (pitch < minPitch) {
minPitch = pitch; minPitch = pitch;
} }
if (lines.length > MAX_LINES) {
lines.pop();
}
} }
const input = audioCtx.createMediaStreamSource(microphone); const input = audioCtx.createMediaStreamSource(microphone);
input.connect(analyser); input.connect(analyser);
analyser.connect(audioProcessor); analyser.connect(audioProcessor);
// audioProcessor.connect(audioCtx.destination); // audioProcessor.connect(audioCtx.destination);
const baseHeight = window.innerHeight * 0.8;
const spectrumPointWidth = window.innerWidth / analyser.frequencyBinCount;
const instance = new p5(( sketch ) => { const instance = new p5(( sketch ) => {
sketch.setup = () => { sketch.setup = () => {
@ -87,35 +93,35 @@ async function main() {
sketch.colorMode(sketch.HSL, 255); sketch.colorMode(sketch.HSL, 255);
}; };
let shouldDraw = 0;
sketch.draw = () => { sketch.draw = () => {
if (!fresh) { shouldDraw += 1;
if (shouldDraw > 0) {
if (shouldDraw > 3) {
shouldDraw = -1;
}
return; return;
} }
fresh = false;
sketch.background(sketch.color(0, 0, 0)); sketch.background(sketch.color(0, 0, 0));
for (let l = 0; l < lines.length; l++) {
if (volume > VOLUME_THRESHOLD) { const lineBaseHeight = baseHeight - (l * LINE_MARGIN);
bars.push({ const line = lines[l];
x: getRandomX(), sketch.fill(`rgba(255, 255, 255, 0.2)`);
volume, sketch.stroke(((line.pitch - minPitch) / (maxPitch - minPitch)) * 255);
pitch, sketch.strokeWeight(1);
age: 1, sketch.beginShape();
}); sketch.curveVertex(0, lineBaseHeight);
sketch.curveVertex(0, lineBaseHeight);
for (let i = 1; i < line.spectrum.length - 1; i++) {
const point = line.spectrum[i];
sketch.curveVertex(i * spectrumPointWidth, lineBaseHeight - point);
} }
sketch.curveVertex(window.innerWidth, lineBaseHeight);
const newBars = []; sketch.curveVertex(window.innerWidth, lineBaseHeight);
for (const bar of bars) { sketch.endShape();
const normalizedPitchColor = ((bar.pitch - minPitch) / (maxPitch - minPitch)) * 220;
sketch.fill(sketch.color(normalizedPitchColor, bar.volume, (bar.volume / volumeThreshold) * 255));
sketch.rect(bar.x, 0, bar.age * bar.volume * 2, window.innerHeight);
bar.age /= 2;
if (bar.age > 0.1) {
newBars.push(bar);
} }
}
bars = newBars;
}; };
}); });