gameaudio

bubble


declare name "bubble";
declare description "Production of a water drop bubble sound.";
declare license "MIT";
declare copyright "(c) 2017: Yann Orlarey, GRAME";

import("stdfaust.lib");

//---------------------------bubble--------------------------
// bubble(f0, trig) : produces a water drop bubble sound
//
// #### Usage
//
// 
// bubble(f0, trig) : _
// 
//
// Where:
//
// *  f0 : base frequency of bubble sound
// * trig: trigs the bubble sound on the rising front
//
// #### Example
//
// 
// button("drop") : bubble(600) : _
// 
//
// #### Reference:
//
// <http://www.cs.ubc.ca/~kvdoel/publications/tap05.pdf>
//------------------------------------------------------------

bubble(f0,trig) = os.osc(f) * (exp(-damp*time) : si.smooth(0.99))
    with {
        damp = 0.043*f0 + 0.0014*f0^(3/2);
        f = f0*(1+sigma*time);
        sigma = eta * damp;
        eta = 0.075;
        time = 0 : (select2(trig>trig'):+(1)) ~ _ : ba.samp2sec;
    };

process = button("drop") : bubble(hslider("v:bubble/freq", 600, 150, 2000, 1)) <: dm.freeverb_demo;

door


//----------------------------door--------------------------
// door(force) : produces a creaking door sound,
//                          based on examples
//                          from the book "Designing Sound"
//                                by Andy Farnell
//
// #### Usage
//
// 
// door(force) : _
// 
//
// Where:
//
// * force: a float value between 0 and 1
//              (0.3 to 0.93 for best results)
//
// #### Examples
//
// 
// door(hslider("force", 0, 0, 0.93, 0.001)) <: _, _;
// 
//
//------------------------------------------------------------

import("stdfaust.lib");

stickslip(force) = metro : timer : *(1000) : min(100) : /(100) :
                   sqrt <: (+(0.1) : sqrt), (vline) : (*)
    with {
        swap(a, b) = (b, a);
        metro = force : ba.line(ba.sec2samp(0.1)) : (step1 ~ _);
        step1(t, s) = s <: (>(0.3)), (swap(1) : (-) <:
                   ((*(60) : +(3)), (*(6) : *(no.noise : abs : ba.sAndH(t)))) : (+)) : _, (/(1000) : ba.sec2samp : ba.pulse) : (*);
        timer(s) = 1 : ba.pulse_countup(((s : mem) == 0)) : /(ma.SR) : ba.sAndH(s);
        vline(s) = s <: _, mem : (!=) : en.ar(0, s / 1000) <: (*);
    };

wood1 = _ <: ((fs, qs, si.bus(6)) : ro.interleave(6, 3) : par(i, 6, flt)), *(0.2) :> _
    with {
        fs = (62.5, 125, 250, 395, 560, 790);
        qs = (1, 1, 2, 2, 3, 3);
        flt(f, q) = fi.resonbp(f, q, 1);
    };

wood2 = _ <: (ds, si.bus(8)) : ro.interleave(8, 2) : par(i, 8, res) :> fi.highpass(1, 125)
    with {
        res(b) = dfbe(b, 0.05);
        ds = (4.52, 5.06, 6.27, 8, 5.48, 7.14, 10.12, 16);
        dfbe(i, g) = ((+) : de.delay(ba.sec2samp(0.1), ba.sec2samp(i / 1000))) ~ (*(g));
    };

door(force) = stickslip(force) : wood1 : wood2 : *(0.2);

process = door(force) <: (_, _)
    with {
        force = button("door") : ba.impulsify : en.ar(2, 1.5) : *(0.61) : +(0.28);
    };

fire


import("stdfaust.lib");

//----------------------------fire---------------------------
// fire(is_wet) : produces burning fire sound
//
// #### Usage
//
// 
// fire(is_wet) : _
// 
//
// Where:
//
// * is_wet: a binary flag/signal adding wet wood
//             popping sound
//
// #### Example
//
// 
// checkbox("wet") : fire : _
// 
//
//------------------------------------------------------------

sq(x) = x * x;
stretch(ms) = ba.countdown(ma.SR * ms / 1000): >(0);

crackle(dens, rel) = ((no.noise : fi.lowpass(3, 10000)) * 0.77 * os.osc(50 / dens) * 
                      en.arfe(0.001, release, 0, trigger: >(0)
                      : stretch(sus)))
                      : fi.highpass(3, 1000)
    with {
        trigger = no.sparse_noise(dens): abs;
        sus = 2 + (trigger: ba.latch(trigger) * 8);
        release = rel + (0.3 * (no.noise : abs : ba.latch(trigger)));
    };

fire(is_wet) = (is_wet * wet) + (base <: (_, fi.lowpass(3, 1000), fi.highpass(3, 10000)) :> _)
    with {
        hiss = (no.noise : fi.lowpass(3, 500)) / 5;
        hiss2 = 0.8 * (no.noise : fi.highpass(3, 3000) / 8) * sq(no.lfnoise(1000));
        wet = (3 * crackle(0.1, 0.05)) + (2 * crackle(0.2, 0.3));
        base = hiss + hiss2 + (0.2 * crackle(5, 0.1));
    };

process = checkbox("wet"): fire;

insects


import("stdfaust.lib");

//---------------------------cricket-------------------------
// cricket(f1, f2, trig) : produces a cricket chirp,
//                         the cricket sound based on examples
//                         from the book "Designing Sound"
//                               by Andy Farnell
//
// #### Usage
//
// 
// cricket(f1, f2, trig) : _
// 
//
// Where:
//
// *  f1 : frequency of the first harmonic of the chirp
// *  f2 : frequency of the second harmonic of the chirp
// * trig: the trigger impulse
//
// #### Examples
//
// 
// ba.pulse(20000) : cricket(5134, 12342) : _
// 
// or
// 
// button("chirp") : ba.impulsify : cricket(5134, 12342, trig1) : _
// 
//
//------------------------------------------------------------

//--------------------------critters------------------------
// critters(freqs) : produces background 'critters' sound,
//                            based on examples
//                            from the book "Designing Sound"
//                                  by Andy Farnell
//
// #### Usage
//
// 
// critters(freqs) : _
// 
//
// Where:
//
// * freqs: a list with 4 frequencies
//
// #### Examples
//
// 
// critters((2012, 4, 20, 2)) : _
// 
//
//------------------------------------------------------------

//----------------------------frog--------------------------
// frog(l, f, trig) : produces a frog croaking sound,
//                             based on examples
//                             from the book "Designing Sound"
//                                   by Andy Farnell
//
// #### Usage
//
// 
// frog(l, f, trig) : _
// 
//
// Where:
//
// *  l  : length of the croak in [ms]
// *  f  : the frequency of resonance (don't go below ~300Hz)
// * trig: the trigger impulse
//
// #### Examples
//
// 
// button("croak") : ba.impulsify : frog(250, 900) : _
// 
//
//------------------------------------------------------------


wrap(s) = s - int(s);
normsin(s) = sin(2 * ma.PI * s);
normcos(s) = cos(2 * ma.PI * s);
phasor(f) = os.phasor(1, f);
stretch(ms) = ba.countdown(ma.SR * ms / 1000) : >(0);
pulsetrain(ms, n, trig) =  (trig: stretch(ms * n)) * ba.pulse(ma.SR * ms / 1000);

cricket(f1, f2, trig) = s1 : *(44) <: ((aa.clip(0, 1.0): wrap), (aa.clip(1.0, 4.0) : wrap)) :> (+):
               normsin : aa.clip(0.0, 1.0) : *(s2) : *(0.3): *(e)
               with {
                   f = 0.8;
                   sig = phasor(f);
                   phase = sig : ba.sAndH(trig);
                   s1 = wrap(sig + (1 - phase));
                   s2 = os.osc(f1) + os.osc(f2) : *(no.lfnoise(500));
                   e = trig : stretch(1000 / f);
               };

water = no.noise : abs : ba.sAndH(no.sparse_noise(250) : abs : >(0)) :
        *(1200) : +(400) : os.osc : fi.resonhp(850, 15, 1) : *(0.008);

hum = no.noise : fi.resonlp(800, 1, 0.08);

critters(freqs) = freqs : prod(i, ba.count(freqs), phasor: normcos):>
           fi.resonhp(20, 1, 1) : *(os.osc(0.01)): *(0.025);

frog(l, f, trig) = out
    with {
        sq(x) = x * x;
        src = en.asr(0.0, 1.0, l / 1000, trig);
        ch1 = 1.0 / (src : max(0.5): *(-1.0): +(ch2): *(3): sq: *(2): -(1) : wrap *(122): sq: +(1));
        ch2 = src : min(0.5);
        ch3 = (1 - src) <: ((max(0.9) : *(-1)), min(0.5)) :> *(3) <: ((*(40): +(f)), (*(90): +(2 * f)), (*(240): +(3 * f)));
        out = ch3 : vcf(ch1, 5), vcf(ch1, 4), vcf(ch1, 3) : (*(0.45), _, *(0.45)) :> fi.resonhp(10, 1, 1): *(0.5);
        vcf(s, res, f) = s : fi.resonbp(f, res, 1): fi.resonlp(1400, 1, 1);
    };

process = insects, background : ro.interleave(2, 2) : par(i, 2, sum(j, 2, _))
    with {
        N = ba.count(channels);
        trig_data = ((0.1, 500, 5),  (0.15, 300, 3),
                     (0.05, 250, 6), (0.0921, 320, 4),
                     (0.093, 250, 3), (0.09, 300, 2), (0.087, 150, 5));
        channels = (cricket(5134, 12342),
                    cricket(3134, 8342),
                    cricket(8134, 15342),
                    cricket(6134, 1842),
                    frog(250, 900),
                    frog(400, 600),
                    frog(200, 800));
        spat(rng1, rng2, trig) = sp.spat(2, r, d)
            with {
                r = rng1 : abs : ba.sAndH(trig);
                d = rng2 : abs : ba.sAndH(trig);
            };
        trig(f, ms, n) = no.sparse_noise(f) : abs : >(0) <:  (_, pulsetrain(ms, n));
        trigsm = trig_data : par(i, N, trig): ro.interleave(2, N);
        btrigs = trigsm : (si.bus(N), si.block(N));
        trigs =  trigsm : (si.block(N), si.bus(N));
        spats = (no.multinoise(2 * N), btrigs, (trigs : channels)) : ro.interleave(N, 4): par(i, N, spat);
        insects = spats : ro.interleave(2, N) : par(i, 2, sum(j, N, _));
        background = water + hum +
                     critters((2012, 4, 20, 2)) +
                     critters((2134, 4.279, 20.4, 15.5)) : *(0.4) <: (_, _);
    };

rain


//----------------------rain--------------------------
// A very simple rain simulator
//
// #### Usage
//
// 
//  rain(d,l) : _,_
// 
//
// Where:
//
// * d: is the density of the rain: between 0 and 1
// * l: is the level (volume) of the rain: between 0 and 1
//
//----------------------------------------------------------

import("stdfaust.lib");

rain(density,level) = no.multinoise(2) : par(i, 2, drop) : par(i, 2, *(level))
    with {
        drop = _ <: @(1), (abs < density) : *;
    };

process  =  rain(
                hslider("v:rain/density", 300, 0, 1000, 1) / 1000,
                hslider("v:rain/volume", 0.5, 0, 1, 0.01)
            );

wind


//----------------------wind--------------------------
// A very simple wind simulator, based on a filtered white noise
//
// #### Usage
//
// 
//  wind(f) : _
// 
//
// Where:
//
// * f: is the force of the wind: between 0 and 1
//
//----------------------------------------------------------

import("stdfaust.lib");

wind(force) = no.multinoise(2) : par(i, 2, ve.moog_vcf_2bn(force,freq)) : par(i, 2, *(force))
    with {
        freq = (force*87)+1 : ba.pianokey2hz;
    };

process = wind(hslider("v:wind/force",0.66,0,1,0.01) : si.smooth(0.997));