Skip to content

Instantly share code, notes, and snippets.

@loganzartman
Last active August 29, 2015 14:02
Show Gist options
  • Save loganzartman/24b7bab4b31f63e698c8 to your computer and use it in GitHub Desktop.
Save loganzartman/24b7bab4b31f63e698c8 to your computer and use it in GitHub Desktop.
rain is better now
/*!
*
* wavepot windchimes
* nondefault.net
*
*/
var transpose = 0;
var ct = 0;
var chimes = []; //stores chimes that are being played
//a single chime note
chimes.push({
"start": 0,
"len": 1,
"freq1": 200,
"freq2": 400
});
//DSP function outputs sound wave height at time t
function dsp(t) {
//occasionally add a new chime
if (t-ct>1) {
ct = t-Math.random()*0.6;
chimes.push(makeRandomChime(t));
}
var dspOut = 0; //sum of all chime sounds being played right now
var cl = chimes.length; //number of chimes
for (var i=cl-1; i>=0; i--) {
if (chimes[i]!==null) {
dspOut += chime(chimes[i], t); //add this chime sound
if (t > chimes[i].start + chimes[i].len) { //remove this chime sound from the array if it's done playing
chimes[i] = null;
}
}
}
return dspOut*0.15 //chimes at 15% volume
+brownNoise()*(0.04*Math.abs(Math.sin(t*0.24)+Math.sin(t*0.6)+Math.sin(t*0.014))+0.02) //wind or waves or something
+rain()*0.6; //rain
}
//add a chime
function makeRandomChime(t) {
var freq = note(~~(Math.random()*7)*2+24);
return {
"start": t,
"len": Math.random()*2+2,
"freq1": freq,
"freq2": freq*(1/5)
};
}
function chime(props, t) {
var wave1 = sin(props.freq1, t); //note #1
var wave2 = sin(props.freq2, t); //note #2
var wave3 = sin(props.freq1*0.01, t); //a sort of ringing effect
//mix the three sounds
return decayf(wave1, props.start, props.len, t)*
decayf(wave2, props.start, props.len, t)*
(1+decayf(wave3, props.start, props.len, t)*0.2);
}
//sin
function sin(x, t){
return Math.sin(2 * Math.PI * t * x);
}
//brownian noise generator
var brownNoise = Brownian();
function Brownian() {
var lnoise = 0.5;
return function() {
var n = Math.random()*2-1;
var v = (lnoise + (0.02 * n)) / 1.02;
lnoise = v;
return v*3.5;
}
}
//rain generator
var np = 0.5;
var rainlp = FastLP(10);
var rainNoise = Brownian(), rainNoise2 = Brownian();
function rain() {
var n = rainNoise()*rainNoise2();
var val = Math.abs(n-np)<0.04?n:0;
np = n;
return rainlp(val);
}
//decay function. Return value wave decayed from start s for length l seconds, at time t.
function decayf(wave,s,l,t) {
return Math.max(0,1-(t-(s))/l)*wave - Math.max(0,1-(t-s)/0.01)*wave;
}
// gets note `n` frequency of `octave`
function note(n, octave){
n += transpose;
return Math.pow(2, (n - 33 + (12 * (octave || 0))) / 12) * 440;
}
function FastHP(n){
var value = 0;
return function(x){
return value += x - value * n;
};
}
function FastLP(n){
var value = 0;
return function(x){
return value += (x - value) / n;
};
}
@panzi
Copy link

panzi commented Jun 19, 2014

Very nice. How do you decrease the number of chimes, though? And make the rain a little quieter?

@loganzartman
Copy link
Author

If you're still wondering, the time between chimes is determined by line 24. The 1 (second between chimes) can be increased. The sounds are mixed on lines 41-43. You could multiply the rain noise, on line 43, by a lower number to decrease its volume,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment