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