HANNAH ZENG

How to Simulate Digital Bubbles

Click to hear result.

| Objective

The goal is to implement a physical simulation of the sound of bubbles using WebAudio (based on Javascript). That is, the sound should be synthesized digitally.

| Decomposing bubbles

The sound of one bubble is the high-pitch bursting sound produced by the destruction of a water bubble. A series of such sound compose the sound of a bubbling water.

To achieve the high-pitch bursting, we need (1) a Resonant High Pass Filter (RHPF) that narrowly attenuates a characteristic high frequency, which can be capture by the Q-factor. In a resonant high-pass filter, the Q factor determines how effectively the filter attenuates frequencies below the cutoff frequency and allows frequencies above the cutoff frequency to pass through with minimal attenuation. A higher Q factor indicates a narrower bandwidth and a sharper roll-off of frequencies below the cutoff. In addition, we will use (2) FM synthesis to modulate the frequency of this RHPF. This way, the resonant pitch will vary over time to create the dynamic of bubbles at different sizes burst one after the other.

And to mimic the ephemeral life cycle of a bubble, we need an envelope with a small attack (quick generation), small sustain (short life span), and small release (fast dissappearance)

Lastly, we will need to repeatly simulate the one bubble sound over and over again to create a streaming bubbling sound.


A break down of the bubbling sound.

| Planning the signal flow

Below is a diagram that depicts the ideal signal flow for simulating bubbles.


Signal Diagram.

| Implementing with WebAudio

First, I created two distinct filtered brown noise using two LFOs. The second lower frequency signal will be used for the FM later.

Then, I created the RHPF with a high Q-factor and a high cutoff frequency, so that the bubbles have clear, brisk sounds.

The modulation index for the FM is also set up.

                
    ////// setting up the bubble sound //////
    
    var noise_1 = BrownNoise();
    var noise_2 = BrownNoise();
    
    var LPF_high = audioCtx.createBiquadFilter();
    LPF_high.type = "lowpass";
    LPF_high.frequency.value = 400;

    var LPF_low = audioCtx.createBiquadFilter();
    LPF_low.type = "lowpass";
    LPF_low.frequency.value = 14;
    
    var RHPF = audioCtx.createBiquadFilter();
    RHPF.type = "highpass";
    RHPF.Q.value = 33.3; //0.03 in supercollider
    RHPF.frequency.value = 500; //+500 in supercollider
    
    var global_gain = audioCtx.createGain();
    global_gain.gain.value = 0.1;
    
    var modulationIndex = audioCtx.createGain();
    modulationIndex.gain.value = 1000;
        

Lastly, I connected the nodes together according to the diagram.

                
    noise_1.connect(LPF_high)
            .connect(RHPF)
            .connect(global_gain)
            .connect(audioCtx.destination);
    noise_2.connect(LPF_low)
            .connect(modulationIndex)
            .connect(RHPF.frequency);
        

The nodes in WebAudio are organized as below.


Signal Flow in Web Audio.

In summary, this physical simulation uses RHPF on a higher-frequency filtered brown noise to simulate the burst of bubbles, with the frequency of the RHPF modulated by a lower-frequency filtered brown noise to achieve a dynamic bubbling effect. The source code can be viewed by inspecting this page.