// Pioggia senza registrazioni: rumore filtrato più gocce sparse.
const ctx = new AudioContext();
function rumore(secondi = 2) {
const buf = ctx.createBuffer(1, ctx.sampleRate * secondi, ctx.sampleRate);
const d = buf.getChannelData(0);
for (let i = 0; i < d.length; i++) d[i] = Math.random() * 2 - 1;
return buf;
}
function pioggia(intensita = 0.5) {
// il fondo: rumore bianco a cui si toglie tutto ciò che non somiglia all'acqua
const fondo = ctx.createBufferSource();
fondo.buffer = rumore(4);
fondo.loop = true;
const passaAlto = ctx.createBiquadFilter();
passaAlto.type = "highpass";
passaAlto.frequency.value = 400 + intensita * 600;
const passaBasso = ctx.createBiquadFilter();
passaBasso.type = "lowpass";
passaBasso.frequency.value = 2000 + intensita * 6000;
const vol = ctx.createGain();
vol.gain.value = 0.04 + intensita * 0.1;
fondo.connect(passaAlto).connect(passaBasso).connect(vol).connect(ctx.destination);
fondo.start();
// le gocce singole: senza queste è vento, non pioggia
(function goccia() {
const t = ctx.currentTime;
const osc = ctx.createOscillator();
const g = ctx.createGain();
osc.type = "sine";
osc.frequency.setValueAtTime(900 + Math.random() * 2600, t);
osc.frequency.exponentialRampToValueAtTime(300, t + 0.05);
g.gain.setValueAtTime(0.0001, t);
g.gain.exponentialRampToValueAtTime(0.03 + Math.random() * 0.04, t + 0.003);
g.gain.exponentialRampToValueAtTime(0.0001, t + 0.09);
osc.connect(g).connect(ctx.destination);
osc.start(t); osc.stop(t + 0.1);
setTimeout(goccia, 40 + Math.random() * (500 - intensita * 420));
})();
return { fondo, vol };
}
// pioggia(0.2) è una pioggerella. pioggia(0.9) è un temporale.Pioggia sintetica
Pioggia costruita dal nulla con rumore filtrato: nessun campione, solo matematica. Dalla collezione di apertura.
Prompt
Scrivi con la Web Audio API un generatore di pioggia che non usi nessun file audio: solo rumore bianco filtrato, più gocce singole distribuite nel tempo. Deve poter diventare più fitta o più rada.