Public
Edited
Oct 1, 2023
Insert cell
Insert cell
mutable state
Insert cell
state.energy
Insert cell
state.raw
Insert cell
update = (state) => {
const { FFT } = state;
const {
scaling,
frequency: [fMin, fMax]
} = settings;
const samples = 2 ** settings.samples;
p5.getAudioContext().resume();
FFT.analyze();
state.energy = FFT.getEnergy(fMin, fMax);
const step = Math.max(1, (fMax - fMin) / samples);
for (let i = 0; i < samples; ++i) {
let f = fMin + step * i;
state.raw[i] = FFT.getEnergy(f, f + step) ** scaling;
}
state.data = normalize(state.raw);
}
Insert cell
draw = (state) => {
const samples = 2 ** settings.samples;
p8g.colorMode(p8g.HSB);
p8g.rectMode(p8g.CENTER);
p8g.background(0, 0, 0);
p8g.fill(0, 0, 0);
p8g.rect(0, 0, width * 2, width);
p8g.stroke(0);
const step = Math.max(1, width / samples);
for (let i = 0; i < samples; ++i) {
let x = p5.map(i, 0, samples, 0, width);
let y = p5.map(state.data[i], 0, 1, 0, width / 2);
let h = p5.map(i, 0, samples, 0, 360);
p8g.fill(h, 100, 100);
p8g.rect(x, width / 4, step, y);
}
}
Insert cell
Insert cell
viewof settings = Inputs.form({
lowPass: Inputs.toggle({ label: "Low Bass Filter" }),
smoothing: Inputs.range([0, 1], {
step: 0.01,
label: "Smoothing",
value: 0.7
}),
bins: Inputs.range([Math.log2(8), Math.log2(4096)], {
step: 1,
label: "Bins (2^x)",
value: Math.log2(2048)
}),
samples: Inputs.range([Math.log2(8), Math.log2(8192)], {
step: 1,
label: "Samples (2^x)",
value: Math.log2(256)
}),
frequency: interval([10, 18000], {
step: 10,
value: [10, 12500],
label: "Frequency (hz)"
}),
scaling: Inputs.range([1, 5], {
step: 0.1,
label: "Scaling",
value: 2
})
})
Insert cell
settings
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function setupData(settings, state) {
for (const a of ["raw", "data"]) {
state[a] = [];
// state[a].length = 2 ** settings.samples;
// state[a].fill(0);
}
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
p5 = require("p5").then(async (p5) => {
globalThis.p5 = p5;
await import("p5/lib/addons/p5.sound.min.js");
// start a fake sketch to resolve p5 helper functions
return new Promise((resolve) => {
p5._instance = new p5((p) => {
//p.noLoop();
p.setup = () => {
p5.duplicates = [];
const duplicates = [];
for (const key in p) {
if (p5[key] !== undefined) p5.duplicates.push(key);
else p5[key] = p[key];
}
resolve(p5);
};
p.draw = () => {};
}, html`<div>`);
});
})
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more