Tropical Island: music out of noise

For a while now, I’ve had an idea to try and make some music using only white noise (and filters/effects). This week we had a (online) music night at work so I decided to give it a go. I borrowed some ideas (like Sam’s Ocean example in Sonic Pi), played around a bit, and came up with this: https://vimeo.com/443175085 (the code is below).

I decided to name it Tropical Island after one of the comments (“I feel I’ve been on a choppy journey through space and ended up on a tropical island”). There are quite a few mistakes, and the audio gets a bit crackly at one point, but I was running late so didn’t have time to redo it.

Please do comment if you have any ideas for other sounds that might sound good and can be made from white noise.

Hope you enjoy it.

Here’s the code:

# I set myself a challenge to code a piece using only white noise.
# White noise contains equal amounts of energy at every (audible) frequency.

# It sounds like this:
#synth :noise

# Not very musical.

# But... it contains every frequency, so every possible sound or piece of music
# is hidden in there somewhere... you just have to filter out the parts you don't want.

# I will use no source of sound other than "synth :noise", passing it through different
# filters and effects to try to create something that sounds a bit less like noise...

# To run this, progressively comment out the "stop"s in each live_loop, hitting run each time...

use_bpm 96

with_fx :reverb, room: 0.8 do
  live_loop :waves do
    stop
    s = synth :noise, cutoff: rrand(50, 110), amp: rrand(0.03, 0.1), attack: rrand(1, 4), sustain: rrand(0, 2), release: rrand(1, 5), slide: rrand(1, 5)
    control s, cutoff: rrand(50, 110)
    sleep rrand(2,4)
  end
end

live_loop :tick, delay: 0.01 do
  sleep 4
end

live_loop :bd, sync: :tick do
  stop
  with_fx :reverb, room: 0.4, amp: 0.3 do
    with_fx :rlpf, cutoff: 35 do
      2.times do
        synth :noise, release: 0.1, amp: 0.5, amp: 150
        sleep 1
        synth :noise, release: 0.1, amp: 0.5, amp: 50
        sleep 1
        synth :noise, release: 0.1, amp: 0.5, amp: 100
        sleep 1.5
        synth :noise, release: 0.1, amp: 0.5, amp: 100
        sleep 0.5
      end
    end
  end
end

live_loop :hats, sync: :tick do
  stop
  with_fx :reverb, room: 0.3, amp: 0.3 do
    with_fx :hpf, cutoff: 90 do
      16.times do
        synth :noise, release: 0.05, amp: 0.5, on: spread(9, 16).tick
        sleep 0.25
      end
    end
  end
end

live_loop :hi, sync: :tick do
  stop
  with_fx :reverb, room: 0.6, amp: 0.3 do
    with_fx :hpf, cutoff: 110 do
      16.times do
        synth :noise, release: 0.02, amp: 0.5, on: spread(11, 16).tick
        sleep 0.25
      end
    end
  end
end

live_loop :mid, sync: :tick do
  stop
  with_fx :reverb, room: 0.3, amp: 0.3 do
    with_fx :bpf, centre: 60, res: 0.9 do
      8.times do
        synth :noise, release: 0.1, amp: 30, on: spread(3, 8).tick
        sleep 0.5
      end
    end
  end
end

live_loop :rhythm, sync: :tick do
  stop
  c = [(chord :c3, :maj),
       (chord :a3, :min),
       (chord :f3, :maj),
       (chord :g3, :maj)].tick
  p = (ring 1, 0.5, 0.25).stretch(4).look
  with_fx :reverb, room: 0.8, amp: 0.5 do
    with_fx :slicer, phase: p, smooth: 0.01 do
      with_fx :octaver, mix: 0.2 do
        c.each do |n|
          with_fx :rbpf, centre: n, res: 0.992 do
            synth :noise, sustain: 2, release: 2, amp: 25
          end
        end
      end
    end
  end
  sleep 4
end

live_loop :melody, sync: :tick do
  stop
  use_random_seed [2000, 88000, 7000, 9000].tick(:x)
  16.times do
    n = scale(:c, :major_pentatonic).choose
    with_fx :octaver, mix: 0.2 do
      with_fx :rbpf, centre: n, res: 0.995 do
        synth :noise, release: 0.5, amp: 12, on: bools(1,1,1,0).choose
        sleep 0.5
      end
    end
  end
end

live_loop :melody2, sync: :tick do
  stop
  use_random_seed [260000, 810000, 920000, 47000].tick(:x)
  16.times do
    n = scale(:c6, :major_pentatonic).choose
    with_fx :octaver, mix: 0.2 do
      with_fx :rbpf, centre: n, res: 0.995 do
        synth :noise, release: 0.25, amp: 3 if one_in(2)
        sleep 0.25
      end
    end
  end
end
5 Likes

I do… But depends whether you would permit adding various other FX besides straight filters, to manipulate the noise into becoming musical :joy:
(Great tune by the way :slightly_smiling_face:)

1 Like

Well, to be fair I wasn’t too strict on the filters myself. I used a fair amount of reverb, an octaver in a couple of places (although I guess you could get something similar by repeating the noise through different band pass filters), and I’m not sure the resonant filters are purely filtering either.

That is Fab ! ( for lack of a better term )
The flexibility of Sonic - Pi is actually astounding : )

1 Like

Hmmm… I’ve been wanting my own Steel Band for a while now.

I can hear a faint echo of them in your code… this could be
interesting.

Eli…

1 Like

Nice tune, reminds me something of Jean-Michel Jarre. Sure it’s also a good idea to start only from noise, I will try something me too.

1 Like

I’ve been working on my own version - but I’m not quite finished yet :joy:
It’s fun though - should have something I’m happy with in the next day or two :slight_smile:

1 Like

Looking forward to seeing what you come up with :smiley:

Hi @emlyn, some time ago I also used the trick to filter noise with the bandpass filter, which yields some nice results (gradually increasing the resonance value and also changing the envelope settings):

Though admittedly the track is only made partly out of noise…

2 Likes

Nice, that sounds great! I might borrow some ideas from here if I make a version 2 :smiley:

1 Like

You are very welcome to do so. I like the idea of filtering noise. I also like that you used noise for all of your sound sources!

1 Like

Alright, a bit more than ‘a day or two’! - but here’s my noise tune. I could spend another day or so tweaking it, but felt I just wanted to get it out :joy:
Note: it starts out slightly resource demanding, so hopefully it won’t grind to a halt for you :crossed_fingers:
The code is a bit messy, and could probably be simplified a bit, but it does the job :wink:
I haven’t done any mastering on it either - so possibly some small improvements could be made in that regard - but it’s still fairly reasonable :slight_smile:

# chill made with noise and some simple fx only

use_bpm 100

live_loop :met do
 sleep 2
end

live_loop :mel1, sync: :met do
 ns = (ring :a2).repeat(32) + (ring :a2, :b2, :d2, :a2, :d2, :c2).repeat(4)
 ds = (ring 4).repeat(32) + (ring 4, 4, 8).repeat(8)
 with_fx :level, amp: (ring 0, 0.5).ramp.tick(:a) do |lv|
   control lv, amp_slide: 32, amp: (ring 0.5, 1).ramp.look(:a)
   with_fx :reverb, room: 1, mix: 0.4 do
     with_fx :rlpf, centre: 100, res: 0.8, mix: 1, amp: 2 do |rb0|
       with_fx :wobble, filter: 1, phase: 32, mix: 0.75, cutoff_min: 60, cutoff_max: 70, invert_wave: 1, amp: 1 do |rh|
         with_fx :tanh, krunch: 5, mix: 1, amp: 3 do |th|
           2.times do |i|
             ds.length.times do
               stop if i == 1 && look % ns.length == 32
               tick
               cue :four if i == 0 && look % ns.length == 44
               with_fx :rbpf, centre: ns.look + 24, res: 0.9 do |rb1|
                 with_fx :rlpf, cutoff: ns.look + 1, res: 0.7 do |rb2|
                   synth :noise, amp: 1,  sustain: ds.look, release: 0, cutoff: ns.look, res: 0.995
                 end
                 s = synth :noise, amp: 0.1,  sustain: ds.look, release: 0, cutoff: ns.look + 12, res: 0.995
                 control s, slide: ds.look, cutoff: ns.look + 12.1
               end
               sleep ds.look
             end
           end
         end
       end
     end
   end
 end
end

live_loop :beat1, sync: :met do
 hs = (bools 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0)
 with_fx :level, amp: (ring 0, 1).ramp.tick(:a) do |lv|
   control lv, amp_slide: 64, amp: 1
   with_fx :rbpf, centre: 45, mix: 0.7, amp: 2 do
     with_fx :rlpf, cutoff: 40, amp: 1, res: 0.85, reps: (16 * 4) do
       hs.length.times do
         with_fx :rbpf, centre: 70, amp: 5, res: 0.85 do |rb|
           tick
           synth :noise, amp: 5, sustain: 0.125, release: 0, res: 0.998, cutoff: 60 if hs.look
           control rb, slide: 0.0625, centre: 20
           sleep 0.25
         end
       end
     end
   end
 end
 stop
end


live_loop :beat2, sync: :met, delay: 128 do
 hs = (bools 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
 
 with_fx :gverb, ref_level: 0, tail_level: 0.8, release: 8, room: 100, spread: 0.2, mix: 0.75 do
   with_fx :rhpf, cutoff: 125, res: 0.9, amp: 0.8 do
     with_fx :rhpf, cutoff: 122, reps: 32 do
       hs.length.times do
         
         with_fx :rbpf, centre: 117, amp: 0.75, res: 0.975 do |rb|
           tick
           synth :noise, amp: rrand(2, 2.5), sustain: 0, release: rrand(0.25, 0.5), res: 0.1, cutoff: 120 if hs.look
           sleep 0.25
         end
       end
     end
   end
 end
 stop
end

live_loop :mel3, sync: :mel1 do |i|
 sleep 64
 stop if i == 1
 ns = (ring :e3) + (ring :e3, :cs3, :b2, :a2, :e3, :a2, :d3).repeat(4)
 ds = (ring 64) + (knit 4, 6, 8, 1).repeat(4)
 with_fx :reverb, room: 1 do
   with_fx :hpf, cutoff: 90, amp: 4 do
     with_fx :lpf, cutoff: 80, amp: 1, mix: 0.9 do
       with_fx :tanh, mix: 0.1 do
         ns.length.times do
           tick
           with_fx :bpf, centre: ns.look + 12, amp: 1, res: 0.95 do
             with_fx :rbpf, centre: ns.look + 12.1, amp: 1, res: 0.975 do
               synth :noise, amp: 1, attack: 0.5, release: ds.look, cutoff: ns.look + 12, res: 0.997
               
               sleep ds.look
             end
           end
         end
       end
     end
   end
 end
 i += 1
end

live_loop :mel4, sync: :met do
 sync :four
 ns = ((ring :a4, :cs5, :b4, :fs4, :cs5, :b4).repeat(2) +
       (ring :gs4, :b4, :a4, :cs5, :d5, :e5) +
 (ring :gs4, :b4, :a4, :cs5, :d5, :e5).shuffle).repeat(2) +
   ((ring :a4, :cs5, :b4, :fs4, :cs5, :b4).shuffle.repeat(2) +
    (ring :gs4, :b4, :a4, :cs5, :d5, :e5).shuffle +
    (ring :gs4, :b4, :a4, :cs5, :d5, :e5).shuffle).repeat(2)
 ds = (ring 0.75, 0.75, 0.75, 0.75, 0.5, 0.5)
 with_fx :reverb, room: 1, mix: 0.4 do
   with_fx :rbpf, centre: 110, res: 0.8, amp: 1.8 do
     with_fx :lpf, cutoff: 80, amp: 1, mix: 0.9, reps: 2 do
       ns.length.times do |i|
         tick
         unless ns.look == :r
           if i < (ns.length / 2.0)
             with_fx :bpf, centre: ns.look + 12, amp: 1, res: 0.95 do
               with_fx :rbpf, centre: ns.look + 12.1, amp: 1, res: 0.975 do
                 synth :noise, amp: 1, attack: 0, sustain: ds.look, release: 0, cutoff: ns.look + 12, res: 0.997
                 
                 
               end
             end
           else
             with_fx :bpf, centre: ns.look, amp: 2, res: 0.95 do
               with_fx :rbpf, centre: ns.look + 0.1, amp: 1, res: 0.975 do
                 synth :noise, amp: 1, attack: 0, sustain: ds.look, release: 0, cutoff: ns.look, res: 0.997
                 
                 
               end
             end
           end
         end
         sleep ds.look
       end
     end
   end
 end
 stop
end

live_loop :mel5, sync: :met, delay: 258 do
 ns = (ring :b4)
 ns2 = (ring :a4)
 ds = (ring 16)
 with_fx :lpf, cutoff: 60, amp: 1.3 do
   with_fx :distortion, distort: 0.2, amp: 0.5, reps: 6 do
     ns.length.times do
       tick
       s = synth :noise, amp: 0.5, sustain: ds.look, release: 0, cutoff: ns.look, res: 0.997
       sleep 7
       control s, slide: 1, cutoff: ns2.look
       sleep ds.look - 7
     end
   end
 end
 stop
end
5 Likes

That sounds amazing! I don’t know why I didn’t think to pass the noise through more than one band pass filter - it makes so much difference to the clarity of the note. I’ll definitely do that if I make an improved version :smiley:

1 Like

Ha! That’s very kind, glad you like it :smile: