Volume lines
This commit is contained in:
parent
550712d2e0
commit
ee60abc62b
88
src/index.js
88
src/index.js
|
@ -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 newBars = [];
|
const point = line.spectrum[i];
|
||||||
for (const bar of bars) {
|
sketch.curveVertex(i * spectrumPointWidth, lineBaseHeight - point);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
sketch.curveVertex(window.innerWidth, lineBaseHeight);
|
||||||
|
sketch.curveVertex(window.innerWidth, lineBaseHeight);
|
||||||
|
sketch.endShape();
|
||||||
}
|
}
|
||||||
|
|
||||||
bars = newBars;
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue