Ocean Ambience - Dank's First Submission

Hi

This is my first submission.

The composition develops slowly over time, introducing new elements gradually to create a meditative, flowing piece that evokes peaceful, drifting movement of ocean currents.

Key Logging Features Added:

  1. Initialization Log: Shows when the composition starts, displays BPM and timestamp

  2. Runtime Tracking: A dedicated loop that logs every minute of runtime

3.Progression Tracking:

  • Named positions in the chord progression
  • Named bass notes with roman numeral notation
  • Current position tracking for both jellyfish pulse and bass current
  1. Counter Variables: Track occurrences of various elements:
  • Bubble count
  • Tendril count
  • Shimmer cycles
  • Droplet events
  1. Detailed Event Logging*:
  • Timestamps on all log messages ([HH:MM:SS])
  • Notes being played
  • Pan values (rounded for readability)
  • Sleep durations
  • Which samples are triggered in the droplets section
  1. Selective Logging: Some very frequent events (like bubbles) only log every 20th occurrence to avoid log clutter, but I might adjust this
use_debug false
use_bpm 70

# Initialization log
puts "*** JELLYFISH JAM ***"
puts "BPM: 70"
puts "Time: #{Time.now.strftime('%H:%M:%S')}"
puts "----------------------------------"

# Track variables for logging
deep_current_position = 0
jellyfish_pulse_position = 0
bubbles_count = 0
tendrils_count = 0
droplets_count = 0
shimmer_count = 0

# Ambient background
live_loop :ocean_ambience do
  puts "[#{Time.now.strftime('%H:%M:%S')}] Ocean ambience playing..."
  sample :ambi_lunar_land, rate: 0.5, amp: 0.4
  sleep 16
end

# Bubbling sounds
live_loop :bubbles, delay: 4 do
  use_synth :beep
  use_synth_defaults attack: 0.01, release: 0.2, amp: 0.2
  
  with_fx :reverb, room: 0.8, mix: 0.6 do
    with_fx :echo, mix: 0.3, phase: 0.5 do
      note = scale(:e3, :minor_pentatonic).choose
      pan_value = rrand(-0.8, 0.8)
      sleep_time = [0.25, 0.5, 0.75].choose
      
      bubbles_count += 1
      if bubbles_count % 20 == 0
        puts "[#{Time.now.strftime('%H:%M:%S')}] Bubbles: #{bubbles_count} bubbles played"
      end
      
      puts "[#{Time.now.strftime('%H:%M:%S')}] Bubble: playing note #{note}, pan: #{pan_value.round(2)}" if one_in(10)
      play note, pan: pan_value
      sleep sleep_time
    end
  end
end

# Pulsating rhythm
live_loop :jellyfish_pulse do
  use_synth :dtri
  
  with_fx :slicer, phase: 0.5, wave: 1, mix: 0.3 do
    with_fx :reverb, room: 0.9, mix: 0.5 do
      # Define progression with named positions
      progression = [
        { position: "Position 1", chord_name: "Em9", chord: chord(:e3, :m9) },
        { position: "Position 2", chord_name: "Cmaj9", chord: chord(:c3, :maj9) },
        { position: "Position 3", chord_name: "Am9", chord: chord(:a2, :m9) },
        { position: "Position 4", chord_name: "Dmaj9", chord: chord(:d3, :maj9) }
      ]
      
      # Get current position in progression
      current = progression[jellyfish_pulse_position]
      puts "[#{Time.now.strftime('%H:%M:%S')}] Jellyfish pulse: #{current[:position]} - #{current[:chord_name]}"
      
      play_chord current[:chord], attack: 0.1, release: 4, amp: 0.5
      sleep 4
      
      # Update position for next iteration
      jellyfish_pulse_position = (jellyfish_pulse_position + 1) % progression.length
    end
  end
end

# Flowing tendrils
live_loop :tendrils, delay: 8 do
  use_synth :blade
  use_synth_defaults attack: 2, release: 6, amp: 0.3
  
  notes = (scale :e4, :minor_pentatonic, num_octaves: 2)
  current_note = notes.choose
  pan_value = rrand(-0.5, 0.5)
  sleep_duration = [4, 6, 8].choose
  
  tendrils_count += 1
  puts "[#{Time.now.strftime('%H:%M:%S')}] Tendril #{tendrils_count}: note #{current_note}, pan #{pan_value.round(2)}, duration #{sleep_duration}s"
  
  with_fx :hpf, cutoff: 60 do
    with_fx :reverb, room: 0.9, mix: 0.7 do
      play current_note, pan: pan_value
      sleep sleep_duration
    end
  end
end

# Gentle bass current
live_loop :deep_current, delay: 16 do
  use_synth :fm
  use_synth_defaults attack: 0.5, release: 7, amp: 0.6
  
  # Bass progression with labels
  bass_notes = [
    { note: :e2, label: "E2 (I)" },
    { note: :c2, label: "C2 (VI)" },
    { note: :a1, label: "A1 (IV)" },
    { note: :d2, label: "D2 (VII)" }
  ]
  
  current_bass = bass_notes[deep_current_position]
  puts "[#{Time.now.strftime('%H:%M:%S')}] Deep current: playing #{current_bass[:label]}"
  
  with_fx :lpf, cutoff: 80 do
    play current_bass[:note], release: 7
    sleep 8
  end
  
  # Update position for next iteration
  deep_current_position = (deep_current_position + 1) % bass_notes.length
end

# Occasional shimmer
live_loop :shimmer, delay: 24 do
  use_synth :pretty_bell
  
  shimmer_count += 1
  puts "[#{Time.now.strftime('%H:%M:%S')}] Shimmer cycle #{shimmer_count} starting"
  
  with_fx :reverb, room: 0.9, mix: 0.8 do
    with_fx :gverb, mix: 0.6 do
      puts "[#{Time.now.strftime('%H:%M:%S')}] Shimmer: waiting 16 beats before pattern"
      sleep 16
      
      puts "[#{Time.now.strftime('%H:%M:%S')}] Shimmer: playing pattern"
      play_pattern_timed scale(:e5, :minor_pentatonic, num_octaves: 1),
        [0.25, 0.5, 0.25], amp: 0.2, pan: rrand(-0.7, 0.7)
      
      puts "[#{Time.now.strftime('%H:%M:%S')}] Shimmer: pattern complete, waiting 16 beats"
      sleep 16
    end
  end
end

# Gentle, intermittent percussion like water droplets
live_loop :droplets, delay: 32 do
  cymbal_played = false
  blip_played = false
  blip2_played = false
  
  if one_in(4)
    sample :drum_cymbal_soft, rate: 1.5, amp: 0.1
    cymbal_played = true
  end
  
  if one_in(3)
    sample :elec_blip, rate: 1.2, amp: 0.1
    blip_played = true
  end
  
  if one_in(5)
    sample :elec_blip2, rate: 1.5, amp: 0.1
    blip2_played = true
  end
  
  droplets_count += 1
  if cymbal_played || blip_played || blip2_played || droplets_count % 20 == 0
    puts "[#{Time.now.strftime('%H:%M:%S')}] Droplets: " +
      "#{cymbal_played ? 'cymbal ' : ''}" +
      "#{blip_played ? 'blip ' : ''}" +
      "#{blip2_played ? 'blip2 ' : ''}" +
      "(cycle #{droplets_count})"
  end
  
  sleep 0.5
end

# Overall runtime tracking
live_loop :time_tracker, delay: 60 do
  elapsed_minutes = 1
  puts "*** JELLYFISH JAM RUNTIME: #{elapsed_minutes} MINUTE(S) ***"
  puts "Time: #{Time.now.strftime('%H:%M:%S')}"
  puts "----------------------------------"
  sleep 60
  elapsed_minutes += 1
end

Open to feedback. This is my first submission :folded_hands:

3 Likes

Very nice!
Some intriguing programming approaches here. Clearly you’re not a newbie programmer.
Tell us a bit about yourself? How did you find sonic pi, how did you make music before, what programming have you done?
Welcome!

I enjoy experimenting with generative music techniques, using randomness and gradual variation to keep things interesting.

The piece is built on layered live loops, each contributing to an evolving soundscape.

I don’t have a formal background in music or coding, but I’ve always been interested in sound design. Programming-wise, I’ve played around with different languages over the years enough to be comfortable thinking in loops, conditions, and structure