Phase Music Exploration

Hey there! I run a Facebook group called Electronic Music Philosophy where, among other discussions, I set challenges for the group to complete and release as an album every 6 weeks. I’ve been trying to use Sonic Pi for my contributions as much as possible to familiarize myself with the program, and hone my skill.

Our most recent challenge was an exploration of phase music (Reich style), and I felt that the source of my track was strong enough to share.

Source: https://gist.github.com/Skoddiethecat/6d3581beee3be35b388c634aceb5c439
Output: https://electronicmusicphilosophy.bandcamp.com/track/transitional-entropy

As an interesting easter egg, the code includes a commented line from an earlier revision where my primary melody was playing duophonic chords. I ended up deciding that this overwhelmed the track, but it seemed fun to keep it included for anybody playing with the source.

Here is a brief synopsis of my compositional process for this track:

I initially began with a random phrase in 5-ET, and had three melodies phasing with a randomly changing, but in-sync tempo to create rhythmic variation. After about a week of this, I decided it sounded terrible and threw it out.

I went back to the drawing bored and started thinking about Reich’s Piano Phase. The melody of Piano Phase is interesting on its own, and even sounds good played a single time without repetition. With this in mind, I started looking at melodies with a prime number of notes in 5-ET, but this was still too cacophanous for me. I considered switching to an approximated Pelog in 12-ET, but I do this SO MUCH. Searching for something else, I got to thinking about Gamelan Jegog, and specifically how it doesn’t sound like Gamelong Gong Keybar. I looked up the tuning and discovered that it uses a 4 note scale that is pretty darn close to a dominant 7th chord in 12-ET. After a little bit of messing around, I had my melody.

At about the same time that I reached this stage, a friend posted about Euclidean rhythms. The idea seemed pretty interesting, so I started looking at how to accomplish it in Sonic Pi. I didn’t have to look far, Spread generates them directly into a Ring. A few lines of code (and the discovery of Ruby’s weird one-liner conditionals) later, and I had a melody that would phase while working through random euclidean rhythms in sync. Furthermore, my melody had 13 notes, but the rhythm has a maximum of 12 pulses, which causes the first note to shift forward no matter what.

Once I had this established, I added a faster version of the melody with no euclidean rhythm two octaves up, and another two octaves down at a slower speed. I was generally happy with the sound at this point, so I refactored the code to functionize each instrument, then created higher level functions to call and phase the instruments, as well as apply effects. Finally, I wrote the main code to ‘arrange’ the piece by calling the high-level functions and specifying how many times they should repeat, as well as any arguments that I wanted to vary throughout the piece. After listening to this a few times I felt that it was too sparse, so I went back and added legato strings to reinforce the harmony, following the same patterns I had used for the other parts.

The piece has five major sections with changes indicated by a chime:
• The first section plays the bass 4 times, then brings in the melody and higher melody. After 8 more cycles of the bass, the strings come in to round out the sound. This section lasts for just under 10 minutes.
• The second section is the same as the first, except the euclidean rhythm for the melody begins to rotate as well as phase, creating more complex rhythms. This section lasts for just under 10 minutes as well.
• The third section redefines many of the variables, simplifying the melody, doubling the tempo of the bass, changing the number of euclidean pulses to 5 (from 12), and using a different random seed to vary the sequence of rhythms.
• The fourth section uses a loop to slow everything down, by adding a constant value to the timing variables each phrase
• The fifth section changes the melody to a rising pattern while continuing to slow, and this finishes out the track.

I had a LOT of fun making this piece, and I hope it’s even half as enjoyable to listen to.

3 Likes

Howdy…

I’m afraid a lot of the technical terms you use just go right over my head… I’m neither a musician
nor a programmer, you see… I’m just someone who twiddles with SP.

However, would I be right in thinking that this is of a similar style? I came across some of the code
in 2016, and twiddled till I got something I liked. It actually made it into a couple of my Soundcloud
tracks.

Even if it’s not related, I’d be interested in the technical term (if any) for it.

Eli…

# ___________________
# Hopscotch... Just Eli...
# Setup some basics
# ___________________


use_bpm 90
use_synth :tri
use_debug false

tracking = [0, 0, 0, 0, 0, 0]
volumes = [0, 0, 0, 0, 0, 0]

define :pat do |a|
  with_fx :reverb do
    a[:count].times do |i|
      # volume varies randomly around the specified level
      variance = rrand(0, 0.1)
      play a[:notes][i], amp: volumes[a[:loop]]*(a[:amps][i] + variance),
        release: a[:rel] || a[:time]
      sleep a[:time]
    end
  end
end

live_loop :zero do
  if tracking[0] > 0 then
    pat loop: 0, count: 12,
      notes: (ring :c4, :eb4), amps: (ring 0.3, 0.2, 0.2),
      time: 1/3.0, rel: 0.45
  else
    sleep 1
  end
end

live_loop :one, auto_cue:false do
  sync :zero
  if tracking[1] > 0 then
    pat loop: 1, count: 12,
      notes: (ring :g4, :bb5), amps: (ring 0.2, 0.1, 0.1),
      time: 1/3.0, rel: 0.4
  else
    sleep 1
  end
end

live_loop :two, auto_cue:false do
  sync :zero
  if tracking[2] > 0 then
    pat loop: 2, count: 8,
      notes: (ring :c4, :bb3, :ab3), amps: (ring 0.35, 0.3, 0.3),
      time: 8 if volumes[2] != 0 # don't start playing until we fade in, keeps in sync better
  else
    sleep 1
  end
end

live_loop :three, auto_cue:false do
  sync :zero
  if tracking[3] > 0 then
    pat loop: 3, count: 8,
      notes: (ring :eb4), amps: (ring 0.4, 0.3, 0.3),
      time: 8, rel: 7 if volumes[3] != 0
  else
    sleep 1
  end
  
end

live_loop :four, auto_cue:false do
  sync :zero
  if tracking[4] > 0 then
    pat loop: 4, count: 24,
      notes: (ring :bb5, :eb5, :g6, :eb5, :g6, :eb5), amps: (ring 0.2, 0.1, 0.1),
      time: 1/6.0 if volumes[4] != 0
  else
    sleep 1
  end
end

live_loop :five, auto_cue: false do
  if tracking[5] > 0 then
    6.times do |loop|
    end
    puts volumes
    sleep 1
    # add some ambience occasionally, almost in key but slightly dissonant
    sample :ambi_glass_hum, amp: 0.6, rate: 0.5 if one_in(24)
  else
    sleep 1
  end
end

define :fade_in do |loop|
  tracking[loop] = 1
  8.times do
    volumes[loop] += 1
    puts tracking
    puts volumes
    sleep 1
  end
  sleep 1
end

define :fade_out do |loop|
  8.times do
    volumes[loop] -= 1
    puts tracking
    puts volumes
    sleep 1
  end
  tracking[loop] = 0
  sleep 1
end

define :fade_in_all do
  fade_in 0
  fade_in 1
  fade_in 2
  fade_in 3
  fade_in 4
  fade_in 5
end

define :fade_out_all do
  fade_out 5
  fade_out 4
  fade_out 3
  fade_out 2
  fade_out 1
  fade_out 0
end


fade_in_all
sleep 20
fade_out_all



Eli...
2 Likes

Hi @Skoddie, hi @Eli,

I am very interested in Minimal Music and I do like Reich very much. I did listen to your composition, @Skoddie, and I liked it a lot. It did remind me more of Terry Riley then Reich, although I am not at all an expert.

I do especially like the concept of starting with a very simple idea and ‘overlay it with itself’ (so to say) and thus gradually creating very complex structures. There are two aspects I am particularly enthusiastic about: 1. that a compositional abstraction/idea does not have to relate in any way to the audible outcome - which is to say: the emotional experience of listening is not or has not to be related to the inherent rationality (but that is obviously true for a lot of music) and 2. (this has a bit more to do with the way/style of composition): I tend to hear notes that are not played (or at least: I assume they are not). This also aplies to a lot of other music but I guess that gradually variated repetition does lay a fruitful base for this kind of imagination.

Anyhow: nice work and an interesting field you are pursuing with your group. I downloaded the whole album (thanks for that in advance) and will listen to it during the next days.

I also do like you little piece, @Eli. This one reminds me of Michael Nyman (who interestingly worked as a musicologist quite some time and has published a nice book: Experimental Music: Cage and beyond).

Finally I also did some work related to minimal principles. For this tiny composition (if I may call it like that) the basic idea was to use a C and D major chord (which - together played give something like a lydian tonality) and expore - like you @Skoddie - the wonderful spread command:

Code: https://gist.github.com/mbutz/ed8105fa24c0ccd1eee9c078ea9a65de

I also made use of the freshly integrated midi capabilites and send the notes to Amsynth to have a more or less realistic guitar sound (actually I can’t tell any difference and could imagine that this piece is being played by some capable guitarist). It is nothing complicated but it did fulfill my expectations about a simple idea somehow intertwined with itself.

There is another redition (live) with the inbuild piano synth, which somehow does sound more artificial:

1 Like

@Eli I did quite enjoy your piece! While I think it would count as Minimal Music, it doesn’t not have any elements of phase music in it.

A great example of Phase Music is actually included in the built-in documentation, which I’ve copied below:

# Steve Reich's Piano Phase
# See: https://en.wikipedia.org/wiki/Piano_Phase

# use_synth :piano
notes = (ring :E4, :Fs4, :B4, :Cs5, :D5, :Fs4, :E4, :Cs5, :B4, :Fs4, :D5, :Cs5)

live_loop :slow do
  play notes.tick, release: 0.1
  sleep 0.3
end

live_loop :faster do
  play notes.tick, release: 0.1
  sleep 0.295
end

Your piece is definitely related by tradition though, without being precisely the same thing.

@Martin Thank you for your insight, and I’m glad you enjoyed my piece. I hope the album proves as rewarding :slight_smile:

I really like your piece exploring Spread. The rotations really give a similar impression to Clapping Music, but with more modulation

Hi Martin,

Slightly off-topic, but no apology, I’m currently re-watching a tv series called Longmire:

‘Longmire is an American modern Western crime drama television series that premiered on June 3, 2012’

Its set in (fictional) Wyoming, and they use very similar, sparse guitar/piano based music whilst panning
across the glorious scenery… it really gives a sense of the space and… ‘harshness’ of the country.

The storylines engaging too, but lets keep it to the music, eh? :slight_smile:

Eli…

Slightly off-topic answer: Thanks for the hint. Hope that it’ll be on German Netflix someday… then I’ll definitely have a look at it.

@Martin Upon further listening, while the Qsynth piece sounds more acoustic, I actually am finding the version with the built-in piano more interesting. The unnatural quality of the timbre really underscores the music well.

Yes, I am thinking the same. Thanks for listening again.

# ReichMitFiboNakki_V3
# See Fibonacci Sequence on Google
# Steve Reich's Piano Phase
# See: https://en.wikipedia.org/wiki/Piano_Phase

fibo = 1.618034

fibodiv = 1/fibo

fibobpm = 55/fibodiv

use_bpm fibobpm

x = fibo

y = x-0.01


live_loop :bietje do
  sleep x
end

sleep 2

with_fx :reverb do
  
  live_loop :arp1 do
    8.times do
      use_synth :fm
      play :b3, release: 0.35, cutoff: rrand(90, 120), mix: rrand(0.3,0.9), amp: rrand(0.3,0.9)
      use_synth :blade
      play :fs4, release: 0.35, cutoff: rrand(90, 120), mix: rrand(0.3,0.9), amp: rrand(0.3,0.9)
      
      sleep x
    end
    use_synth :dark_ambience
    play :fs4, attack: rrand(4,6), release: rrand(5.15,7.15), cutoff: rrand(60, 120), amp: rrand(1.2,3.1)
    sleep x*5
  end
  
  live_loop :arp2 do
    8.times do
      use_synth :fm
      play :b3, release: 0.35, cutoff: rrand(90, 120), mix: rrand(0.3,0.9), amp: rrand(0.3,0.9)
      use_synth :blade
      play :fs4, release: 0.35, cutoff: rrand(90, 120), mix: rrand(0.3,0.9), amp: rrand(0.3,0.9)
      
      sleep y
    end
    use_synth :dark_ambience
    play :fs4, attack: rrand(4,6), release: rrand(5.15,7.15), cutoff: rrand(60, 120), amp: rrand(1.2,3.1)
    sleep y*5
  end
  
end

sleep 13

with_fx :ixi_techno do
  
  live_loop :keys1 do
    with_fx :reverb, mix: rrand(0.2, 0.6) do
      use_synth :hollow
      play chord(:c, :minor), amp: rrand(0.2,2.4), attack: rrand(fibodiv,fibo*5), release: fibo*3, rate: rrand(x,x*3)
      sleep x*21
    end
  end
  
  live_loop :keys2 do
    with_fx :reverb, mix: rrand(0.2, 0.6) do
      use_synth :hollow
      play chord(:c, :minor), amp: rrand(0.2,2.4), attack: rrand(fibodiv,fibo*5), release: fibo*3, rate: rrand(y,y*3)
      sleep y*21
    end
  end
  
end

with_fx :reverb do
  
  s = :bd_tek
  
  #sample :bd_klub
  
  
  live_loop :kick1 do
    sample s, rate: rrand(0.6,1.6), cutoff: rrand(90, 120), amp: rrand(0.6,2.9), release: fibo
    sleep x*5
  end
  
  live_loop :kick2 do
    sample s, rate: rrand(0.6,1.6), cutoff: rrand(90, 120), amp: rrand(0.6,2.9), release: fibo
    sleep y*5
  end
  
end

with_fx :bitcrusher do
  
  s = :elec_hollow_kick
  
  #sample :elec_hollow_kick
  
  
  live_loop :kickzz1 do
    sample s, rate: rrand(0.6,2.6), cutoff: rrand(90, 120), amp: rrand(0.6,2.9), release: 2.45
    sleep 5*x
  end
  
  live_loop :kickzz2 do
    sample s, rate: rrand(0.6,2.6), cutoff: rrand(90, 120), amp: rrand(0.6,2.9), release: 2.45
    sleep 5*y
  end
  
end


sleep 13


live_loop :NoiseHats1, sync: :bietje do
  
  
  with_fx :slicer, mix: 1, phase: 0.25, pulse_width: 0.2, reps: 8 do
    with_fx :hpf, cutoff: 130-dice, reps: 8 do
      with_synth :chipbass do
        play 28+dice, decay: rrand(0.5,1.8), amp: rrand(0.5,1.5)
      end
    end
  end
  sleep x*8
end


live_loop :NoiseHats2, sync: :bietje do
  
  
  with_fx :slicer, mix: 1, phase: 0.25, pulse_width: 0.2, reps: 8 do
    with_fx :hpf, cutoff: 130-dice, reps: 8 do
      with_synth :chipbass do
        play 28+dice, decay: rrand(0.5,1.8), amp: rrand(0.5,1.5)
      end
    end
  end
  sleep y*8
end

sleep 8

with_fx :reverb do
  
  5.times do
    
    with_synth :dark_ambience do
      with_fx :ixi_techno, phase_offset: fibodiv, phase: 21 do
        play :b3, amp: fibo, attack: 13, release: 8, pan: -0.21
        play :fs4, amp: fibodiv, attack: 13, release: 8, pan: 0.21
        
      end
    end
    
    
    sleep 13
    
    with_synth :chipnoise do
      with_fx :hpf, phase_offset: fibodiv, phase: 34 do
        play :b3, amp: fibodiv, attack: 13, release: 21, pan: -0.34
        play :fs4, amp: fibodiv, attack: 13, release: 21, pan: 0.34
        
      end
    end
    
    sleep 21
    
    with_synth :hollow do
      with_fx :reverb, phase_offset: fibodiv, phase: 89 do
        play :b3, amp: fibodiv, attack: 34, release: 55, pan: -0.89
        play :fs4, amp: fibodiv, attack: 34, release: 55, pan: 0.89
        
      end
    end
    
    sleep 34
    
    with_synth :dark_ambience do
      with_fx :ixi_techno, phase_offset: fibodiv, phase: 89 do
        play :b3, amp: fibodiv, attack: 55, release: 89, pan: -0.999999
        play :fs4, amp: fibodiv, attack: 55, release: 89, pan: 0.999999
        
      end
    end
    
    sleep 55
    
  end
  
end