Scheduling musical motif at given bar

Hi everyone,

I am a computer science and music student. I have been invited to play a piece with live coding for an event at my university, and I am trying to figure out how to play the music I have in my head, using Sonic Pi.

Specifically, I was thinking about scheduling motives. I personally structure music as motives that may come into place once or several times across the piece, in specific bars or sections. Something like this:
motif1 = […]
motif2 = […]
play motif1 at bar 0
play motif2 at bar 15

Which is the best way to do this in Sonic Pi? Is it possible to schedule blocks of music to play in a future bar? Are bars, time signatures and beats incorporated into the language, or would I have to implement that?

Thank you and best regards,
Alvaro

Hi,

perhaps a natural way of coding motives as you describe them is using functions. This is described in section 5.5 of the built-in tutorial.

Also, to answer your question about bars time signatures and beats - these are things that are specific to Western music and do not have any direct manifestation in Sonic Pi which attempts to be much broader in its musical opportunities. Sonic Pi just talks about tempo and time - out of which you can build your own versions of these constructs. Of course, you can also deviate and do something non-traditional should you choose. See the Steve Reich example for something that illustrates this.

1 Like

I don’t know Sonic Pi in depth, but i would guess you have to implement it for yourself. My first idea to do so is: use semaphoring. In SonicPi you can use cue: and sync: explained in the tutorial (Thread Synchronisation). You may create a technical loop which cue’s every bar (i.e. every 4 beats) and create a Thread araound a motif which sync to the bar you like to play along, here an example, working with live_loops:

live_loop :give_bar_signal, auto_cue: false do 
  cue ("bar" + tick.to_s).to_sym
  sleep 4
end
 
 
live_loop :motifInBar3 do
  sync :bar3
  play 60 # not really a motif
  sleep 4
end

i can’t say, that this is the best, hope it helps.

@herbert - good call and nice explanation, thanks :slight_smile:

Also, I should point out that the call to sleep in your :motifInBar3 live loop is actually superfluous in this case, as the sync actually ‘sleeps’ until the next matching cue is observed.

Hiya all,

I’m suprised nobody has yet mentioned the ‘at’ command,
which seems to fit the bill completely…

I know there are better examples around than this, just can’t
find one off-hand.

Eli…

use_bpm 120
live_loop :beat4 do
  sleep 4
end


define :hat do
  at [0, 2, 3],
  [{:amp=>0.3}, {:amp=> 1}, {:amp=>0.5}] do |p|
    sample :drum_cymbal_pedal, p
  end
end

define :drum do
  at [1, rrand_i(2, 3)],
  [{:amp=>1}] do |p|
    sample [:drum_bass_hard, :drum_bass_soft].choose, p
  end
end



live_loop :do_hat do
  sync :beat4
  hat
  sleep 1
end

live_loop :do_drum do
  sync :beat4
  drum
  sleep 1
end
2 Likes

Good call - you can totally use at to schedule any arbitrary piece of code/function call to be executed in the future :slight_smile: Another related fn is time_warp which has a similar affect (although is subtly different in semantics in important ways).

Wow, thank you so much for all the answers and for the fast response! Your tips will definitely help me.