Get all sample names

all_sample_names  

Return a list of all the sample names available

Introduced in v2.0


Ensure arg is valid

assert  arg (anything)

Raises an exception if the argument is either nil or false.

Introduced in v2.8

Examples

# Example 1


assert true  
assert 1     
assert "foo"
assert false 



# Simple assertions
# As true is neither nil or false, this assertion passes
# Similarly, 1 passes
# As do string
# This will raise an exception



# Example 2


assert false, "oops"



# Communicating error messages
# This will raise an exception containing the message "oops"



# Example 3


assert (1 + 1) == 2
assert [:a, :b, :c].size == 3



# More interesting assertions
# Ensure that arithmetic is sane!
# ensure lists can be correctly counted




Ensure args are equal

assert_equal  arg1 (anything), arg2 (anything)

Raises an exception if both arguments aren’t equal.

Introduced in v2.8

Examples

# Example 1


assert_equal 1, 1


# Simple assertions
 



# Example 2


assert_equal 1 + 1, 2
assert_equal [:a, :b, :c].size,  3



# More interesting assertions
# Ensure that arithmetic is sane!
# ensure lists can be correctly counted



# Example 3


assert_equal 3, 5, "something is seriously wrong!"


# Add messages to the exceptions
 




Asynchronous Time. Run a block at the given time(s)

at  times (list), params (list)

Given a list of times, run the block once after waiting each given time. If passed an optional params list, will pass each param individually to each block call. If size of params list is smaller than the times list, the param values will act as rings (rotate through). If the block is given 1 arg, the times are fed through. If the block is given 2 args, both the times and the params are fed through. A third block arg will receive the index of the time.

Note, all code within the block is executed in its own thread. Therefore despite inheriting all thread locals such as the random stream and ticks, modifications will be isolated to the block and will not affect external code.

Introduced in v2.1

Examples

# Example 1

at 4 do
    sample :ambi_choir   
  end


 
# play sample after waiting for 4 beats
 



# Example 2

at [1, 2, 4] do 
    play 75          
  end                



# plays a note after waiting 1 beat,
# then after 1 more beat,
# then after 2 more beats (4 beats total)



# Example 3

at [1, 2, 3], [75, 76, 77] do |n| 
    play n
  end


# plays 3 different notes
 
 



# Example 4

at [1, 2, 3],
      [{:amp=>0.5}, {:amp=> 0.8}] do |p|
    sample :drum_cymbal_open, p         
  end


 
# alternate soft and loud
# cymbal hits three times
 



# Example 5

at [0, 1, 2] do |t|
    puts t
  end


# when no params are given to at, the times are fed through to the block
#=> prints 0, 1, then 2
 



# Example 6

at [0, 1, 2], [:a, :b] do |t, b| 
    puts [t, b]
  end


#If you specify the block with 2 args, it will pass through both the time and the param
#=> prints out [0, :a], [1, :b], then [2, :a]
 



# Example 7

at [0, 0.5, 2] do |t, idx| 
    puts [t, idx]
  end


#If you specify the block with 2 args, and no param list to at, it will pass through both the time and the index
#=> prints out [0, 0], [0.5, 1], then [2, 2]
 



# Example 8

at [0, 0.5, 2], [:a, :b] do |t, b, idx| 
    puts [t, b, idx]
  end


#If you specify the block with 3 args, it will pass through the time, the param and the index
#=> prints out [0, :a, 0], [0.5, :b, 1], then [2, :a, 2]
 



# Example 9


puts "main: ", rand 
rand_back
at 1 do        
               
  puts "at:", rand
  puts "at:", rand
end

sleep 2
puts "main: ", rand



# at does not consume & interfere with the outer random stream
# 0.75006103515625
 
# the random stream inside the at block is separate and
# isolated from the outer stream.
# 0.9287109375
# 0.1043701171875
 
 
 
# value is still 0.75006103515625



# Example 10


at [1, 2] do
           
  puts rand
  puts rand
end
           
           
           



# Each block run within at has its own isolated random stream:
 
# first time round (after 1 beat) prints:
# 0.9287109375
# 0.1043701171875
 
# second time round (after 2 beats) prints:
# 0.1043701171875
# 0.764617919921875




Get current beat

beat   ()

Returns the beat value for the current thread/live_loop. Beats are advanced only by calls to sleep and sync. Beats are distinct from virtual time (the value obtained by calling vt) in that it has no notion of rate. It is just essentially a counter for sleeps. After a sync, the beat is overridden with the beat value from the thread which called cue.

Introduced in v2.10

Example

# Example 1

use_bpm 120 
  puts beat   
  sleep 1
  puts beat   
  use_bpm 2000
  sleep 2
  puts beat   



# The current BPM makes no difference
#=> 0
 
#=> 1
 
 
#=> 3




Return block duration

block_duration   ()

Given a block, runs it and returns the amount of time that has passed. This time is in seconds and is not scaled to the current BPM. Any threads spawned in the block are not accounted for.

Introduced in v2.9

Examples

# Example 1

dur = block_duration do
  play 50
  sleep 1
  play 62
  sleep 2
end

puts dur



 
 
 
 
 
 
 
#=> Returns 3 as 3 seconds have passed within the block



# Example 2

use_bpm 120
dur = block_duration do
  play 50
  sleep 1
  play 62
  sleep 2
end

puts dur
        



 
 
 
 
 
 
 
 
#=> Returns 1.5 as 1.5 seconds have passed within the block
#   (due to the BPM being 120)




Determine if block contains sleep time

block_slept?   ()

Given a block, runs it and returns whether or not the block contained sleeps or syncs

Introduced in v2.9

Examples

# Example 1

slept = block_slept? do
  play 50
  sleep 1
  play 62
  sleep 2
end

puts slept



 
 
 
 
 
 
 
#=> Returns true as there were sleeps in the block



# Example 2

in_thread do
  sleep 1
  cue :foo 
end

slept = block_slept? do
  sync :foo 
  play 62
end

puts slept



 
 
# trigger a cue on a different thread
 
 
 
# wait for the cue before playing the note
 
 
 
#=> Returns true as the block contained a sync.



# Example 3

slept = block_slept? do
  play 50
  play 62
end

puts slept



 
 
 
 
 
#=> Returns false as there were no sleeps in the block




Create a ring of boolean values

bools  list (array)

Create a new ring of booleans values from 1s and 0s, which can be easier to write and manipulate in a live setting.

Introduced in v2.2

Examples

# Example 1

(bools 1, 0)   



#=> (ring true, false)



# Example 2

(bools 1, 0, true, false, nil)



#=> (ring true, false, true, false, false)




Beat time conversion

bt  seconds (number)

Beat time representation. Scales the time to the current BPM. Useful for adding bpm scaling

Introduced in v2.8

Example

# Example 1

use_bpm 120 
  puts bt(1)
  use_bpm 60  
  puts bt(1)
  use_bpm 30  
  puts bt(1)



# Set the BPM to be double the default
# 0.5
# BPM is now default
# 1
# BPM is now half the default
# 2




Random list selection

choose  list (array)

Choose an element at random from a list (array).

Introduced in v2.0

Example

# Example 1

loop do
    play choose([60, 64, 67])
    sleep 1
    play chord(:c, :major).choose
    sleep 1
  end


 
#=> plays one of 60, 64 or 67 at random
 
#=> You can also call .choose on the list
 
 




Create chord

chord  tonic (symbol), name (symbol)

Creates an immutable ring of Midi note numbers when given a tonic note and a chord type. If only passed a chord type, will default the tonic to 0. See examples.

Introduced in v2.0

Options

invert:

Apply the specified num inversions to chord. See the fn chord_invert.

num_octaves:

Create an arpeggio of the chord over n octaves

Examples

# Example 1

puts (chord :e, :minor)



# returns a ring of midi notes - (ring 64, 67, 71)



# Example 2


play (chord :e, :minor)


# Play all the notes together
 



# Example 3


play (chord :e3, :minor, invert: 0)
play (chord :e3, :minor, invert: 1)
play (chord :e3, :minor, invert: 2)



# Chord inversions (see the fn chord_invert)
# Play the basic :e3, :minor chord - (ring 52, 55, 59)
# Play the first inversion of :e3, :minor - (ring 55, 59, 64)
# Play the first inversion of :e3, :minor - (ring 59, 64, 67)



# Example 4


puts (chord :minor)



# You can create a chord without a tonic:
#=> (ring 0, 3, 7)



# Example 5


live_loop :arp do
  play chord(:e, :minor, num_octaves: 2).tick, release: 0.1
  sleep 0.125
end


# chords are great for arpeggiators
 
 
 
 



# Example 6



(chord :C, '1')
(chord :C, '5')
(chord :C, '+5')
(chord :C, 'm+5')
(chord :C, :sus2)
(chord :C, :sus4)
(chord :C, '6')
(chord :C, :m6)
(chord :C, '7sus2')
(chord :C, '7sus4')
(chord :C, '7-5')
(chord :C, 'm7-5')
(chord :C, '7+5')
(chord :C, 'm7+5')
(chord :C, '9')
(chord :C, :m9)
(chord :C, 'm7+9')
(chord :C, :maj9)
(chord :C, '9sus4')
(chord :C, '6*9')
(chord :C, 'm6*9')
(chord :C, '7-9')
(chord :C, 'm7-9')
(chord :C, '7-10')
(chord :C, '9+5')
(chord :C, 'm9+5')
(chord :C, '7+5-9')
(chord :C, 'm7+5-9')
(chord :C, '11')
(chord :C, :m11)
(chord :C, :maj11)
(chord :C, '11+')
(chord :C, 'm11+')
(chord :C, '13')
(chord :C, :m13)
(chord :C, :add2)
(chord :C, :add4)
(chord :C, :add9)
(chord :C, :add11)
(chord :C, :add13)
(chord :C, :madd2)
(chord :C, :madd4)
(chord :C, :madd9)
(chord :C, :madd11)
(chord :C, :madd13)
(chord :C, :major)
(chord :C, :M)
(chord :C, :minor)
(chord :C, :m)
(chord :C, :major7)
(chord :C, :dom7)
(chord :C, '7')
(chord :C, :M7)
(chord :C, :minor7)
(chord :C, :m7)
(chord :C, :augmented)
(chord :C, :a)
(chord :C, :diminished)
(chord :C, :dim)
(chord :C, :i)
(chord :C, :diminished7)
(chord :C, :dim7)
(chord :C, :i7)


# Sonic Pi supports a large range of chords
# Notice that the more exotic ones have to be surrounded by ' quotes
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 




Construct chords of stacked thirds, based on scale degrees

chord_degree  degree (symbol_or_number), tonic (symbol), scale (symbol), number_of_notes (number)

In music we build chords from scales. For example, a C major chord is made by taking the 1st, 3rd and 5th notes of the C major scale (C, E and G). If you do this on a piano you might notice that you play one, skip one, play one, skip one etc. If we use the same spacing and start from the second note in C major (which is a D), we get a D minor chord which is the 2nd, 4th and 6th notes in C major (D, F and A). We can move this pattern all the way up or down the scale to get different types of chords. chord_degree is a helper method that returns a ring of midi note numbers when given a degree (starting point in a scale) which is a symbol :i, :ii, :iii, :iv, :v, :vi, :vii or a number 1-7. The second argument is the tonic note of the scale, the third argument is the scale type and finally the fourth argument is number of notes to stack up in the chord. If we choose 4 notes from degree :i of the C major scale, we take the 1st, 3rd, 5th and 7th notes of the scale to get a C major 7 chord.

Introduced in v2.1

Examples

# Example 1

puts (chord_degree :i, :A3, :major)



# returns a ring of midi notes - (ring 57, 61, 64, 68) - an A major 7 chord



# Example 2

play (chord_degree :i, :A3, :major, 3)


 



# Example 3

play (chord_degree :ii, :A3, :major, 3)



# Chord ii in A major is a B minor chord



# Example 4

play (chord_degree :iii, :A3, :major, 3)



# Chord iii in A major is a C# minor chord



# Example 5

play (chord_degree :iv, :A3, :major, 3)



# Chord iv in A major is a D major chord



# Example 6

play (chord_degree :i, :C4, :major, 4)



# Taking four notes is the default. This gives us 7th chords - here it plays a C major 7



# Example 7

play (chord_degree :i, :C4, :major, 5)



# Taking five notes gives us 9th chords - here it plays a C major 9 chord




Chord inversion

chord_invert  notes (list), shift (number)

Given a set of notes, apply a number of inversions indicated by the shift parameter. Inversions being an increase to notes if shift is positive or decreasing the notes if shift is negative.

An inversion is simply rotating the chord and shifting the wrapped notes up or down an octave. For example, consider the chord :e3, :minor - (ring 52, 55, 59). When we invert it once, we rotate the notes around to (ring 55, 59, 52). However, because note 52 is wrapped round, it’s shifted up an octave (12 semitones) so the actual first inversion of the chord :e3, :minor is (ring 55, 59, 52 + 12) or (ring 55, 59, 64).

Note that it’s also possible to directly invert chords on creation with the invert: opt - (chord :e3, :minor, invert: 2)

Introduced in v2.6

Example

# Example 1

play (chord_invert (chord :A3, "M"), 0)
sleep 1
play (chord_invert (chord :A3, "M"), 1)
sleep 1
play (chord_invert (chord :A3, "M"), 2)



#No inversion     - (ring 57, 61, 64)
 
#First inversion  - (ring 61, 64, 69)
 
#Second inversion - (ring 64, 69, 73)




All chord names

chord_names  

Returns a ring containing all chord names known to Sonic Pi

Introduced in v2.6

Example

# Example 1

puts chord_names



#=>  prints a list of all the chords




Block level commenting

comment  

Does not evaluate any of the code within the block. However, any optional args passed before the block will be evaluated although they will be ignored. See uncomment for switching commenting off without having to remove the comment form.

Introduced in v2.0

Example

# Example 1

comment do
    play 50
    sleep 1
    play 62
  end


# starting a block level comment:
# not played
# no sleep happens
# not played
 




Control running synth

control  node (synth_node)

Control a running synth node by passing new parameters to it. A synth node represents a running synth and can be obtained by assigning the return value of a call to play or sample or by specifying a parameter to the do/end block of an FX. You may modify any of the parameters you can set when triggering the synth, sample or FX. See documentation for opt details. If the synth to control is a chord, then control will change all the notes of that chord group at once to a new target set of notes - see example. Also, you may use the on: opt to conditionally trigger the control - see the docs for the synth and sample fns for more information.

Introduced in v2.0

Examples

# Example 1



my_node = play 50, release: 5, cutoff: 60
sleep 1
control my_node, cutoff: 70
sleep 1
control my_node, cutoff: 90



# Basic control
 
# play note 50 with release of 5 and cutoff of 60. Assign return value to variable my_node
# Sleep for a second
# Now modify cutoff from 60 to 70, sound is still playing
# Sleep for another second
# Now modify cutoff from 70 to 90, sound is still playing



# Example 2



s = synth :prophet, note: :e1, cutoff: 70, cutoff_slide: 8, release: 8
control s, cutoff: 130
                      



# Combining control with slide opts allows you to create nice transitions.
 
# start synth and specify slide time for cutoff opt
# Change the cutoff value with a control.
# Cutoff will now slide over 8 beats from 70 to 130



# Example 3



notes = (scale :e3, :minor_pentatonic, num_octaves: 2).shuffle

s = synth :beep, note: :e3, sustain: 8, note_slide: 0.05
64.times do
  control s, note: notes.tick                           
  sleep 0.125
end


# Use a short slide time and many controls to create a sliding melody
 
# get a random ordering of a scale
 
# Start our synth running with a long sustain and short note slide time
 
# Keep quickly changing the note by ticking through notes repeatedly
 
 



# Example 4



with_fx :bitcrusher, sample_rate: 1000, sample_rate_slide: 8 do |bc|
                                                                    
                                                                    
  sample :loop_garzul, rate: 1
  control bc, sample_rate: 5000                                     
                                                                    
end


# Controlling FX
 
# Start FX but also use the handy || goalposts
# to grab a handle on the running FX. We can call
# our handle anything we want. Here we've called it bc
 
# We can use our handle bc now just like we used s in the
# previous example to modify the FX as it runs.
 



# Example 5


cg = play (chord :e4, :minor), sustain: 2 
sleep 1
control cg, notes: (chord :c3, :major)    
                                          
                                          



# Controlling chords
# start a chord
 
# transition to new chord.
# Each note in the original chord is mapped onto
# the equivalent in the new chord.



# Example 6



cg = play (chord :e4, :minor), sustain: 4, note_slide: 3 
sleep 1
control cg, notes: (chord :c3, :major)                   
                                                         
                                                         



# Sliding between chords
 
# start a chord
 
# slide to new chord.
# Each note in the original chord is mapped onto
# the equivalent in the new chord.



# Example 7


cg = play (chord :e3, :m13), sustain: 4, note_slide: 3 
sleep 1
control cg, notes: (chord :c3, :major)                   
                                                         
                                                         
                                                         
                                                         



# Sliding from a larger to smaller chord
# start a chord with 7 notes
 
# slide to new chord with fewer notes (3)
# Each note in the original chord is mapped onto
# the equivalent in the new chord using ring-like indexing.
# This means that the 4th note in the original chord will
# be mapped onto the 1st note in the second chord and so-on.



# Example 8


cg = play (chord :c3, :major), sustain: 4, note_slide: 3 
sleep 1
control cg, notes: (chord :e3, :m13)                    
                                                         
                                                         
                                                         
                                                         
                                                         



# Sliding from a smaller to larger chord
# start a chord with 3 notes
 
# slide to new chord with more notes (7)
# Each note in the original chord is mapped onto
# the equivalent in the new chord.
# This means that the 4th note in the new chord
# will not sound as there is no 4th note in the
# original chord.




Cue other threads

cue  cue_id (symbol)

Send a heartbeat synchronisation message containing the (virtual) timestamp of the current thread. Useful for syncing up external threads via the sync fn. Any opts which are passed are given to the thread which syncs on the cue_id as a map. The values of the opts must be immutable. Currently only numbers, symbols and booleans are supported.

Introduced in v2.0

Options

your_key:

Your value

another_key:

Another value

key:

All these opts are passed through to the thread which syncs

Examples

# Example 1

in_thread do
    sync :foo
    sample :ambi_lunar_land
  end

  sleep 5

  cue :foo
           



 
# this parks the current thread waiting for a foo cue message to be received.
 
 
 
 
 
# We send a cue message from the main thread.
# This then unblocks the thread above and we then hear the sample



# Example 2

in_thread do  
    loop do     
      cue :tick 
      sleep 0.5 
    end
  end

 
  loop do                   
    sync :tick              
    sample :drum_heavy_kick 
  end


# Start a metronome thread
# Loop forever:
# sending tick heartbeat messages
# and sleeping for 0.5 beats between ticks
 
 
 
# We can now play sounds using the metronome.
# In the main thread, just loop
# waiting for :tick cue messages
# after which play the drum kick sample
 



# Example 3

in_thread do  
    loop do     
      cue [:foo, :bar, :baz].choose
      sleep 0.5 
    end
  end

 

  in_thread do
    loop do             
      sync :foo         
      sample :elec_beep 
    end
  end

  in_thread do
    loop do             
      sync :bar         
      sample :elec_flip 
    end
  end

  in_thread do
    loop do             
      sync :baz         
      sample :elec_blup 
    end
  end


# Start a metronome thread
# Loop forever:
# sending one of three tick heartbeat messages randomly
# and sleeping for 0.5 beats between ticks
 
 
 
# We can now play sounds using the metronome:
 
 
# In the main thread, just loop
# waiting for :foo cue messages
# after which play the elec beep sample
 
 
 
 
# In the main thread, just loop
# waiting for :bar cue messages
# after which play the elec flip sample
 
 
 
 
# In the main thread, just loop
# waiting for :baz cue messages
# after which play the elec blup sample
 
 



# Example 4

in_thread do
    loop do
      cue :tick, foo: 64 
      sleep 0.5
    end
  end

 

  loop do
    values = sync :tick
    play values[:foo]   
  end


 
 
# sending tick heartbeat messages with a value :foo
 
 
 
 
# The value for :foo can now be used in synced threads
 
 
 
# play the note value from :foo
 




Get current arg checking status

current_arg_checks  

Returns the current arg checking setting (true or false).

This can be set via the fns use_arg_checks and with_arg_checks.

Introduced in v2.0

Example

# Example 1

puts current_arg_checks



# Print out the current arg check setting




Duration of current beat

current_beat_duration  

Get the duration of the current beat in seconds. This is the actual length of time which will elapse with sleep 1.

Affected by calls to use_bpm, with_bpm, use_sample_bpm and with_sample_bpm.

Introduced in v2.6

Example

# Example 1

use_bpm 60
  puts current_beat_duration

  use_bpm 120
  puts current_beat_duration



 
#=> 1
 
 
#=> 0.5




Get current tempo

current_bpm  

Returns the current tempo as a bpm value.

This can be set via the fns use_bpm, with_bpm, use_sample_bpm and with_sample_bpm.

Introduced in v2.0

Example

# Example 1

puts current_bpm



# Print out the current bpm




Get current cent shift

current_cent_tuning  

Returns the cent shift value.

This can be set via the fns use_cent_tuning and with_cent_tuning.

Introduced in v2.9

Example

# Example 1

puts current_cent_tuning



# Print out the current cent shift




Get current debug status

current_debug  

Returns the current debug setting (true or false).

This can be set via the fns use_debug and with_debug.

Introduced in v2.0

Example

# Example 1

puts current_debug



# Print out the current debug setting




Get current octave shift

current_octave  

Returns the octave shift value.

This can be set via the fns use_octave and with_octave.

Introduced in v2.9

Example

# Example 1

puts current_octave



# Print out the current octave shift




Get current random seed

current_random_seed  

Returns the current random seed.

This can be set via the fns use_random_seed and with_random_seed. It is incremented every time you use the random number generator via fns such as choose and rand`.

Introduced in v2.10

Examples

# Example 1

puts current_random_seed



# Print out the current random seed



# Example 2


puts rand              
puts rand              
a = current_random_seed
puts rand              
puts rand              
use_random_seed a      
                       
puts rand              
puts rand              



# Resetting the seed back to a known place
#=>  0.75006103515625
#=>  0.733917236328125
# Grab the current seed
#=> 0.464202880859375
#=> 0.24249267578125
# Restore the seed
# we'll now get the same random values:
#=> 0.464202880859375
#=> 0.24249267578125




Get current sample defaults

current_sample_defaults  

Returns the current sample defaults. This is a map of synth arg names to either values or functions.

This can be set via the fns use_sample_defaults, with_sample_defaults, use_merged_sample_defaults and with_merged_sample_defaults.

Introduced in v2.5

Example

# Example 1

use_sample_defaults amp: 0.5, cutoff: 80
sample :loop_amen
puts current_sample_defaults



 
# Plays amen break with amp 0.5 and cutoff 80
#=> Prints {amp: 0.5, cutoff: 80}




Get current sample pack

current_sample_pack  

Returns the current sample pack.

This can be set via the fns use_sample_pack and with_sample_pack.

Introduced in v2.0

Example

# Example 1

puts current_sample_pack



# Print out the current sample pack




Get current sched ahead time

current_sched_ahead_time  

Returns the current schedule ahead time.

This can be set via the fn set_sched_ahead_time!.

Introduced in v2.0

Example

# Example 1

set_sched_ahead_time! 0.5
puts current_sched_ahead_time



 
# Prints 0.5




Get current synth

current_synth  

Returns the current synth name.

This can be set via the fns use_synth and with_synth.

Introduced in v2.0

Example

# Example 1

puts current_synth



# Print out the current synth name




Get current synth defaults

current_synth_defaults  

Returns the current synth defaults. This is a map of synth arg names to either values or functions.

This can be set via the fns use_synth_defaults, with_synth_defaults, use_merged_synth_defaults and with_merged_synth_defaults.

Introduced in v2.0

Example

# Example 1

use_synth_defaults amp: 0.5, cutoff: 80
play 50
puts current_synth_defaults



 
# Plays note 50 with amp 0.5 and cutoff 80
#=> Prints {amp: 0.5, cutoff: 80}




Get current transposition

current_transpose  

Returns the current transpose value.

This can be set via the fns use_transpose and with_transpose.

Introduced in v2.0

Example

# Example 1

puts current_transpose



# Print out the current transpose value




Get current volume

current_volume  

Returns the current volume.

This can be set via the fn set_volume!.

Introduced in v2.0

Examples

# Example 1

puts current_volume



# Print out the current volume



# Example 2

set_volume! 2
puts current_volume



 
#=> 2




Decrement

dec  n (number)

Decrement a number by 1. Equivalent to n - 1

Introduced in v2.1

Examples

# Example 1

dec 1



# returns 0



# Example 2

dec -1



# returns -2




Define a new function

define  name (symbol)

Allows you to group a bunch of code and give it your own name for future re-use. Functions are very useful for structuring your code. They are also the gateway into live coding as you may redefine a function whilst a thread is calling it, and the next time the thread calls your function, it will use the latest definition.

Introduced in v2.0

Example

# Example 1


  define :foo do
    play 50
    sleep 1
  end

 
  foo

 
 
  3.times do
    foo
  end


# Define a new function called foo
 
 
 
 
 
# Call foo on its own
 
 
# You can use foo anywhere you would use normal code.
# For example, in a block:
 
 
 




Define a named value only once

defonce  name (symbol)

Allows you to assign the result of some code to a name, with the property that the code will only execute once - therefore stopping re-definitions. This is useful for defining values that you use in your compositions but you don’t want to reset every time you press run. You may force the block to execute again regardless of whether or not it has executed once already by using the override option (see examples).

Introduced in v2.0

Options

override:

If set to true, re-definitions are allowed and this acts like define

Examples

# Example 1

defonce :foo do 
    sleep 1       
                  
                  
    puts "hello"
    10            
  end

 
  puts foo

 
  puts foo



  defonce :foo do
    puts "you can't redefine me"
    15
  end

  puts foo

 
 
  3.times do
    play foo 
  end


# Define a new function called foo
# Sleep for a beat in the function definition. Note that this amount
# of time in seconds will depend on the current BPM of the live_loop
# or thread calling this function.
# Print hello
# Return a value of 10
 
 
# Call foo on its own
# The run sleeps for a beat and prints "hello" before returning 10
 
# Try it again:
# This time the run doesn't sleep or print anything out. However, 10 is still returned.
 
 
 
# Try redefining foo
 
 
 
 
# We still don't see any printing or sleeping, and the result is still 10
 
# You can use foo anywhere you would use normal code.
# For example, in a block:
 
# play 10
 



# Example 2

defonce :bar do
    50
  end

  play bar

  defonce :bar do
    70
  end

  play bar

  defonce :bar, override: true do 
    80
  end

  play bar



 
 
 
 
# plays 50
 
# This redefinition doesn't work due to the behaviour of defonce
 
 
 
# Still plays 50
 
# Force definition to take place with override option
 
 
 
# plays 80




Convert a degree into a note

degree  degree (symbol_or_number), tonic (symbol), scale (symbol)

For a given scale and tonic it takes a symbol :i, :ii, :iii, :iv,:v, :vi, :vii or a number 1-7 and resolves it to a midi note.

Introduced in v2.1

Example

# Example 1

play degree(:ii, :D3, :major)
play degree(2, :C3, :minor)


 
 




Squash and repeat time

density  d (density)

Runs the block d times with the bpm for the block also multiplied by d. Great for repeating sections a number of times faster yet keeping within a fixed time. If d is less than 1, then time will be stretched accordingly and the block will take longer to complete.

Introduced in v2.3

Examples

# Example 1

use_bpm 60  

  density 2 do      
                    
    sample :bd_hause
    sleep 0.5       
  end


# Set the BPM to 60
 
# BPM for block is now 120
# block is called 2.times
# sample is played twice
# sleep is 0.25s
 



# Example 2

density 2 do |idx|
    puts idx        
    sleep 0.5       
  end


# You may also pass a param to the block similar to n.times
# prints out 0, 1
# sleep is 0.25s
 



# Example 3

density 0.5 do         
                         
                         
    play 80, release: 1  
    sleep 0.5            
  end


# Specifying a density val of < 1 will stretch out time
# A density of 0.5 will double the length of the block's
# execution time.
# plays note 80 with 2s release
# sleep is 1s
 




Random dice throw

dice  num_sides (number)

Throws a dice with the specified num_sides (defaults to 6) and returns the score as a number between 1 and num_sides.

Introduced in v2.0

Examples

# Example 1

dice
      



# will return a number between 1 and 6 inclusively
# (with an even probability distribution).



# Example 2

dice 3



# will return a number between 1 and 3 inclusively




Create a ring of successive doubles

doubles  start (number), num_doubles (int)

Create a ring containing the results of successive doubling of the start value. If num_doubles is negative, will return a ring of halves.

Introduced in v2.10

Examples

# Example 1

(doubles 60, 2) 



#=> (ring 60, 120)



# Example 2

(doubles 1.5, 3)



#=> (ring 1.5, 3, 6)



# Example 3

(doubles 1.5, 5)



#=> (ring 1.5, 3, 6, 12, 24)



# Example 4

(doubles 100, -4)



#=> (ring 100, 50, 25, 12.5)




Factor test

factor?  val (number), factor (number)

Test to see if factor is indeed a factor of val. In other words, can val be divided exactly by factor.

Introduced in v2.1

Examples

# Example 1

factor?(10, 2)



# true - 10 is a multiple of 2 (2 * 5 = 10)



# Example 2

factor?(11, 2)



#false - 11 is not a multiple of 2



# Example 3

factor?(2, 0.5)



#true - 2 is a multiple of 0.5 (0.5 * 4 = 2)




Get all FX names

fx_names  

Return a list of all the FX available

Introduced in v2.10


Create a ring of successive halves

halves  start (number), num_halves (int)

Create a ring containing the results of successive halving of the start value. If num_halves is negative, will return a ring of doubles.

Introduced in v2.10

Examples

# Example 1

(halves 60, 2) 



#=> (ring 60, 30)



# Example 2

(halves 120, 3)



#=> (ring 120, 60, 30)



# Example 3

(halves 120, 5)



#=> (ring 120, 60, 30, 15, 7.5)



# Example 4

(halves 30, -5)



#=> (ring 30, 60, 120, 240, 480)




Hz to MIDI conversion

hz_to_midi  freq (number)

Convert a frequency in hz to a midi note. Note that the result isn’t an integer and there is a potential for some very minor rounding errors.

Introduced in v2.0

Example

# Example 1

hz_to_midi(261.63)



#=> 60.0003




Run code block at the same time

in_thread  

Execute a given block (between doend) in a new thread. Use for playing multiple ‘parts’ at once. Each new thread created inherits all the use/with defaults of the parent thread such as the time, current synth, bpm, default synth args, etc. Despite inheriting defaults from the parent thread, any modifications of the defaults in the new thread will not affect the parent thread. Threads may be named with the name: optional arg. Named threads will print their name in the logging pane when they print their activity. If you attempt to create a new named thread with a name that is already in use by another executing thread, no new thread will be created.

It is possible to delay the initial trigger of the thread on creation with both the delay: and sync: opts. See their respective docstrings. If both delay: and sync: are specified, on initial thread creation first the delay will be honoured and then the sync.

Introduced in v2.0

Options

name:

Make this thread a named thread with name. If a thread with this name already exists, a new thread will not be created.

delay:

Initial delay in beats before the thread starts. Default is 0.

sync:

Initial sync symbol. Will sync with this symbol before the thread starts.

sync_bpm:

Initial sync symbol. Will sync with this symbol before the live_loop starts. Live loop will also inherit the BPM of the thread which cued the symbol.

Examples

# Example 1

loop do     
    play 50   
    sleep 1   
  end

  loop do     
    play 55
    sleep 0.5
  end


# If you write two loops one after another like this,
# then only the first loop will execute as the loop acts
# like a trap not letting the flow of control out
 
 
# This code is never executed.
 
 
 



# Example 2


 
 

 
 
 
 

  in_thread do
   
    loop do
     
      play 50
      sleep 1
    end
  end

 

  loop do     
    play 55
    sleep 0.5
  end


# In order to play two loops at the same time, the first loops need to
# be in a thread (note that it's probably more idiomatic to use live_loop
# when performing):
 
# By wrapping our loop in an in_thread block, we split the
# control flow into two parts. One flows into the loop (a) and
# the other part flows immediately after the in_thread block (b).
# both parts of the control flow execute at exactly the same time.
 
 
# (a)
 
# (a)
 
 
 
 
 
# (b)
 
# This loop is executed thanks to the thread above
 
 
 



# Example 3

use_bpm 120 
  use_synth :dsaw 

  in_thread do    
    play 50       
    use_synth :fm 
    sleep 1       
    play 38       
  end

  play 62         
  sleep 2         
  play 67         



# Set the bpm to be double rate
# Set the current synth to be :dsaw
 
# Create a new thread
# Play note 50 at time 0
# Switch to fm synth (only affects this thread)
# sleep for 0.5 seconds (as we're double rate)
# Play note 38 at time 0.5
 
 
# Play note 62 at time 0 (with dsaw synth)
# sleep 1s
# Play note 67 at time 1s (also with dsaw synth)



# Example 4

in_thread(name: :foo) do
    loop do
      sample :drum_bass_hard
      sleep 1
    end
  end

  in_thread(name: :foo) do
    loop do               
      sample :elec_chime  
      sleep 0.5
    end
  end


# Here we've created a named thread
 
 
 
 
 
 
# This thread isn't created as the name is
# the same as the previous thread which is
# still executing.
 
 
 



# Example 5


  define :foo do 
    play 50      
    sleep 1      
  end

  in_thread(name: :main) do 
    loop do                 
      foo                   
    end
  end

 
 
 
 
 



# Named threads work well with functions for live coding:
# Create a function foo
# which does something simple
# and sleeps for some time
 
 
# Create a named thread
# which loops forever
# calling our function
 
 
 
# We are now free to modify the contents of :foo and re-run the entire buffer.
# We'll hear the effect immediately without having to stop and re-start the code.
# This is because our fn has been redefined, (which our thread will pick up) and
# due to the thread being named, the second re-run will not create a new similarly
# named thread. This is a nice pattern for live coding and is the basis of live_loop.



# Example 6


  in_thread delay: 1 do
    sample :ambi_lunar_land
  end

  play 80                  



#Delaying the start of a thread
 
# this sample is not triggered at time 0 but after 1 beat
 
 
# Note 80 is played at time 0




Increment

inc  n (number)

Increment a number by 1. Equivalent to n + 1

Introduced in v2.1

Examples

# Example 1

inc 1



# returns 2



# Example 2

inc -1



# returns 0




Display inspected information in the output pane

inspect  output (anything)

Displays the information you specify as an inspected string inside the output pane. This can be a number, symbol, or a string itself.

Introduced in v2.8

Examples

# Example 1

print "hello there"



#=> will print the string "hello there" to the output pane with quotes



# Example 2

print 5              



#=> will print the number 5 to the output pane



# Example 3

print :foo           



#=> will print the :foo to the output pane




Kill synth

kill  node (synth_node)

Kill a running synth sound or sample. In order to kill a sound, you need to have stored a reference to it in a variable.

Introduced in v2.0

Examples

# Example 1


foo = play 50, release: 4
sleep 1

kill foo


# store a reference to a running synth in a variable called foo:
 
 
# foo is still playing, but we can kill it early:
 



# Example 2

bar = sample :loop_amen
sleep 0.5
kill bar


 
 
 




Knit a sequence of repeated values

knit  value (anything), count (number)

Knits a series of value, count pairs to create a ring buffer where each value is repeated count times.

Introduced in v2.2

Examples

# Example 1

(knit 1, 5)   



#=> (ring 1, 1, 1, 1, 1)



# Example 2

(knit :e2, 2, :c2, 3)



#=> (ring :e2, :e2, :c2, :c2, :c2)




Create a ring buffer representing a straight line

line  start (number), finish (number)

Create a ring buffer representing a straight line between start and finish of num_slices elements. Num slices defaults to 8. Indexes wrap around positively and negatively. Similar to range.

Introduced in v2.5

Options

steps:

number of slices or segments along the line

inclusive:

boolean value representing whether or not to include finish value in line

Examples

# Example 1

(line 0, 4, steps: 4)   



#=> (ring 0.0, 1.0, 2.0, 3.0)



# Example 2

(line 5, 0, steps: 5)   



#=> (ring 5.0, 4.0, 3.0, 2.0, 1.0)



# Example 3

(line 0, 3, inclusive: true)



#=> (ring 0.0, 1.0, 2.0, 3.0)




A loop for live coding

live_loop  name (symbol)

Run the block in a new thread with the given name, and loop it forever. Also sends a cue with the same name each time the block runs. If the block is given a parameter, this is given the result of the last run of the loop (with initial value either being 0 or an init arg).

It is possible to delay the initial trigger of the live_loop on creation with both the delay: and sync: opts. See their respective docstrings. If both delay: and sync: are specified, on initial live_loop creation first the delay will be honoured and then the sync.

Introduced in v2.1

Options

init:

initial value for optional block arg

auto_cue:

enable or disable automatic cue (default is true)

delay:

Initial delay in beats before the live_loop starts. Default is 0.

sync:

Initial sync symbol. Will sync with this symbol before the live_loop starts.

sync_bpm:

Initial sync symbol. Will sync with this symbol before the live_loop starts. Live loop will also inherit the BPM of the thread which cued the symbol.

seed:

override initial random generator seed before starting loop.

Examples

# Example 1

live_loop :ping do
  sample :elec_ping
  sleep 1
end


 
 
 
 



# Example 2

live_loop :foo do |a| 
  puts a              
  sleep 1
  a += 1              
end


# pass a param (a) to the block (inits to 0)
# prints out all the integers
 
# increment a by 1 (last value is passed back into the loop)
 




Load the contents of a file to the current buffer

load_buffer  path (string)

Given a path to a file, will read the contents and load it into the current buffer. This will replace any previous content.

Introduced in v2.10

Example

# Example 1

load_buffer "~/sonic-pi-tracks/phat-beats.rb"



# will replace content of current buffer with contents of the file




Load a built-in example

load_example  path (string)

Given a keyword representing an example, will load it into the current buffer. This will replace any previous content.

Introduced in v2.10

Example

# Example 1

load_example :rerezzed



# will replace content of current buffer with the rerezzed example




Pre-load sample(s)

load_sample  path (string)

Given a path to a .wav, .wave, .aif, .aiff or .flac file, pre-loads the sample into memory.

You may also specify the same set of source and filter pre-args available to sample itself. load_sample will then load all matching samples. See sample’s docs for more information.

Introduced in v2.0

Examples

# Example 1

load_sample :elec_blip
sample :elec_blip



# :elec_blip is now loaded and ready to play as a sample
# No delay takes place when attempting to trigger it



# Example 2


dir = "/path/to/sample/dir"
load_sample dir
load_sample dir, 1
load_sample dir, :foo
load_sample dir, /[Bb]ar/



# Using source and filter pre-args
 
# loads any samples in "/path/to/sample/dir"
# loads sample with index 1 in "/path/to/sample/dir"
# loads sample with name "foo" in "/path/to/sample/dir"
# loads sample which matches regex /[Bb]ar/ in "/path/to/sample/dir"




Pre-load samples

load_samples  paths (list)

Synonym for load_sample

Introduced in v2.0

Example

# Example 1





# See load_sample for examples




Load external synthdefs

load_synthdefs  path (string)

Load all pre-compiled synth designs in the specified directory. The binary files containing synth designs need to have the extension .scsyndef. This is useful if you wish to use your own SuperCollider synthesiser designs within Sonic Pi.

Important notes

You may not trigger external synthdefs unless you enable the following GUI preference:

Studio -> Synths -> Enable external synths and FX

Also, if you wish your synth to work with Sonic Pi’s automatic stereo sound infrastructure you need to ensure your synth outputs a stereo signal to an audio bus with an index specified by a synth arg named out_bus. For example, the following synth would work nicely:

(
SynthDef(\piTest,
         {|freq = 200, amp = 1, out_bus = 0 |
           Out.ar(out_bus,
                  SinOsc.ar([freq,freq],0,0.5)* Line.kr(1, 0, 5, amp, doneAction: 2))}
).writeDefFile("/Users/sam/Desktop/")
)

Introduced in v2.0

Example

# Example 1

load_synthdefs "~/Desktop/my_noises"



# Load all synthdefs in my_noises folder




Obtain value of a tick

look  

Read and return value of default tick. If a key is specified, read the value of that specific tick. Ticks are in_thread and live_loop local, so the tick read will be the tick of the current thread calling look.

Introduced in v2.6

Options

offset:

Offset to add to index returned. Useful when calling look on lists, rings and vectors to offset the returned value

Examples

# Example 1

puts look
  puts look
  puts look



#=> 0
#=> 0
#=> 0 # look doesn't advance the tick, it just returns the current value



# Example 2

puts look
  tick
  puts look
  tick
  puts look
  puts look
  tick
  puts look



#=> 0 # A look is always 0 before the first tick
# advance the tick
#=> 0 # Note: a look is still 0 after the first tick.
 
#=> 1
#=> 1 # making multiple calls to look doesn't affect tick value
 
#=> 2



# Example 3

tick(:foo)
  tick(:foo)
  puts look(:foo)
  puts look
  puts look(:bar)



 
 
#=> 1 (keyed look :foo has been advanced)
#=> 0 (default look hasn't been advanced)
#=> 0 (other keyed looks haven't been advanced either)



# Example 4


  live_loop :foo do
    tick                                     
    use_synth :beep
    play (scale :e3, :minor_pentatonic).look 
    sleep 0.5
    use_synth :square
    play (ring :e1, :e2, :e3).look, release: 0.25
    sleep 0.25
  end


# You can call look on lists and rings
 
# advance the default tick
 
# look into the default tick to play all notes in sequence
 
 
# use the same look on another ring
 
 




Minecraft Pi - normalise block code

mc_block_id  name (symbol_or_number)

Given a block name or id will return a number representing the id of the block or throw an exception if the name or id isn’t valid

Introduced in v2.5

Examples

# Example 1

puts mc_block_id :air



#=> 0



# Example 2

puts mc_block_id 0 



#=> 0



# Example 3

puts mc_block_id 19



#=> Throws an invalid block id exception



# Example 4

puts mc_block_id :foo



#=> Throws an invalid block name exception




Minecraft Pi - list all block ids

mc_block_ids  

Returns a list of all the valid block ids as numbers. Note not all numbers are valid block ids. For example, 19 is not a valid block id.

Introduced in v2.5

Example

# Example 1

puts mc_block_ids



#=> [0, 1, 2, 3, 4, 5...




Minecraft Pi - normalise block name

mc_block_name  id (number_or_symbol)

Given a block id or a block name will return a symbol representing the block name or throw an exception if the id or name isn’t valid.

Introduced in v2.5

Examples

# Example 1

puts mc_block_name :air



#=> :air



# Example 2

puts mc_block_name 0  



#=> :air



# Example 3

puts mc_block_name 19



#=> Throws an invalid block id exception



# Example 4

puts mc_block_name :foo



#=> Throws an invalid block name exception




Minecraft Pi - list all block names

mc_block_names  

Returns a list of all the valid block names as symbols

Introduced in v2.5

Example

# Example 1

puts mc_block_names



#=> [:air, :stone, :grass, :dirt, :cobblestone...




Minecraft Pi - fixed camera mode

mc_camera_fixed  

Set the camera mode to fixed.

Introduced in v2.5

Example

# Example 1








Minecraft Pi - normal camera mode

mc_camera_normal  

Set the camera mode to normal.

Introduced in v2.5

Example

# Example 1








Minecraft Pi - move camera

mc_camera_set_location  

Move the camera to a new location.

Introduced in v2.5

Example

# Example 1








Minecraft Pi - third person camera mode

mc_camera_third_person  

Set the camera mode to third person

Introduced in v2.5

Example

# Example 1








Minecraft Pi - synonym for mc_message

mc_chat_post  

See mc_message

Introduced in v2.5


Minecraft Pi - restore checkpoint

mc_checkpoint_restore  

Restore the world to the last snapshot taken with mc_checkpoint_save.

Introduced in v2.5

Example

# Example 1








Minecraft Pi - save checkpoint

mc_checkpoint_save  

Take a snapshot of the world and save it. Restore back with mc_checkpoint_restore

Introduced in v2.5

Example

# Example 1








Minecraft Pi - get type of block at coords

mc_get_block  x (number), y (number), z (number)

Returns the type of the block at the coords x, y, z as a symbol.

Introduced in v2.5

Example

# Example 1

puts mc_get_block 40, 50, 60



#=> :air




Minecraft Pi - synonym for mc_ground_height

mc_get_height  

See mc_ground_height

Introduced in v2.5


Minecraft Pi - synonym for mc_location

mc_get_pos  

See mc_location

Introduced in v2.5


Minecraft Pi - get location of current tile/block

mc_get_tile  

Returns the coordinates of the nearest block that the player is next to. This is more course grained than mc_location as it only returns whole number coordinates.

Introduced in v2.5

Example

# Example 1

puts mc_get_tile



#=> [10, 20, 101]




Minecraft Pi - get ground height at x, z coords

mc_ground_height  x (number), z (number)

Returns the height of the ground at the specified x and z coords.

Introduced in v2.5

Example

# Example 1

puts mc_ground_height 40, 50



#=> 43 (height of world at x=40, z=50)




Minecraft Pi - get current location

mc_location  

Returns a list of floats [x, y, z] coords of the current location for Steve. The coordinates are finer grained than raw block coordinates but may be used anywhere you might use block coords.

Introduced in v2.5

Examples

# Example 1

puts mc_location   



#=> [10.1, 20.67, 101.34]



# Example 2

x, y, z = mc_location      



#=> Find the current location and store in x, y and z variables.




Minecraft Pi - post a chat message

mc_message  msg (string)

Post contents of msg on the Minecraft chat display. You may pass multiple arguments and all will be joined to form a single message (with spaces).

Introduced in v2.5

Example

# Example 1

mc_message "Hello from Sonic Pi"



#=> Displays "Hello from Sonic Pi" on Minecraft's chat display




Minecraft Pi - set area of blocks

mc_set_area  block_name (symbol_or_number), x (number), y (number), z (number), x2 (number), y2 (number), z2 (number)

Set an area/box of blocks of type block_name defined by two distinct sets of coordinates.

Introduced in v2.5


Minecraft Pi - set block at specific coord

mc_set_block  x (number), y (number), z (number), block_name (symbol_or_number)

Change the block type of the block at coords x, y, z to block_type. The block type may be specified either as a symbol such as :air or a number. See mc_block_ids and mc_block_types for lists of valid symbols and numbers.

Introduced in v2.5

Example

# Example 1

mc_set_block :glass, 40, 50, 60



#=> set block at coords 40, 50, 60 to type glass




Minecraft Pi - synonym for mc_teleport

mc_set_pos  

See mc_teleport

Introduced in v2.5


Minecraft Pi - set location to coords of specified tile/block

mc_set_tile  x (number), y (number), z (number)

Introduced in v2.5

Example

# Example 1








Minecraft Pi - teleport to world surface at x and z coords

mc_surface_teleport  x (number), z (number)

Teleports you to the specified x and z coordinates with the y automatically set to place you on the surface of the world. For example, if the x and z coords target a mountain, you’ll be placed on top of the mountain, not in the air or under the ground. See mc_ground_height for discovering the height of the ground at a given x, z point.

Introduced in v2.5

Example

# Example 1

mc_surface_teleport 40, 50



#=> Teleport user to coords x = 40, y = height of surface, z = 50




Minecraft Pi - teleport to a new location

mc_teleport  x (number), y (number), z (number)

Magically teleport the player to the location specified by the x, y, z coordinates. Use this for automatically moving the player either small or large distances around the world.

Introduced in v2.5

Example

# Example 1

mc_teleport 40, 50, 60 
                       



# The player will be moved to the position with coords:
# x: 40, y: 50, z: 60




Create a ring buffer of midi note numbers

midi_notes  list (array)

Create a new immutable ring buffer of notes from args. Indexes wrap around positively and negatively. Final ring consists only of MIDI numbers and nil.

Introduced in v2.7

Examples

# Example 1

(midi_notes :d3, :d4, :d5)



#=> (ring 50, 62, 74)



# Example 2

(midi_notes :d3, 62,  nil)



#=> (ring 50, 62, nil)




MIDI to Hz conversion

midi_to_hz  note (symbol_or_number)

Convert a midi note to hz

Introduced in v2.0

Example

# Example 1

midi_to_hz(60)



#=> 261.6256




Define a new function

ndefine  name (symbol)

Does nothing. Use to stop a define from actually defining. Simpler than wrapping whole define in a comment block or commenting each individual line out.

Introduced in v2.1


Describe note

note  note (symbol_or_number)

Takes a midi note, a symbol (e.g. :C) or a string (e.g. "C") and resolves it to a midi note. You can also pass an optional octave: parameter to get the midi note for a given octave. Please note - octave: param overrides any octave specified in a symbol i.e. :c3. If the note is nil, :r or :rest, then nil is returned (nil represents a rest)

Introduced in v2.0

Options

octave:

The octave of the note. Overrides any octave declaration in the note symbol such as :c2. Default is 4

Examples

# Example 1


puts note(60)
puts note(:C)
puts note(:C4)
puts note('C')


# These all return 60 which is the midi number for middle C (octave 4)
 
 
 
 



# Example 2


puts note(60, octave: 2)


puts note(:C, octave: 2)
puts note(:C4, octave: 2)
puts note('C', octave: 2)


# returns 60 - octave param has no effect if we pass in a number
 
 
# These all return 36 which is the midi number for C2 (two octaves below middle C)
 
# note the octave param overrides any octaves specified in a symbol
 




Get note info

note_info  note (symbol_or_number)

Returns an instance of SonicPi::Note. Please note - octave: param overrides any octave specified in a symbol i.e. :c3

Introduced in v2.0

Options

octave:

The octave of the note. Overrides any octave declaration in the note symbol such as :c2. Default is 4

Example

# Example 1

puts note_info(:C, octave: 2)




 
# returns #<SonicPi::Note :C2>




Get a range of notes

note_range  low_note (note), high_note (note)

Produces a ring of all the notes between a low note and a high note. By default this is chromatic (all the notes) but can be filtered with a :pitches argument. This opens the door to arpeggiator style sequences and other useful patterns. If you try to specify only pitches which aren’t in the range it will raise an error - you have been warned!

Introduced in v2.6

Options

pitches:

An array of notes (symbols or ints) to filter on. Octave information is ignored.

Examples

# Example 1

(note_range :c4, :c5)



# => (ring 60,61,62,63,64,65,66,67,68,69,70,71,72)



# Example 2

(note_range :c4, :c5, pitches: (chord :c, :major))



# => (ring 60,64,67,72)



# Example 3

(note_range :c4, :c6, pitches: (chord :c, :major))



# => (ring 60,64,67,72,76,79,84)



# Example 4

(note_range :c4, :c5, pitches: (scale :c, :major))



# => (ring 60,62,64,65,67,69,71,72)



# Example 5

(note_range :c4, :c5, pitches: [:c4, :g2])



# => (ring 60,67,72)



# Example 6

live_loop :arpeggiator do
 
  play (note_range :c4, :c5, pitches: (chord :c, :major)).tick
  sleep 0.125
end


 
# try changing the chord
 
 
 




Create a ring of octaves

octs  start (note), num_octaves (pos_int)

Create a ring of successive octaves starting at start for num_octaves.

Introduced in v2.8

Examples

# Example 1

(octs 60, 2) 



#=> (ring 60, 72)



# Example 2

(octs :e3, 3)



#=> (ring 52, 64, 76)




Optionally evaluate block

on  condition (truthy)

Optionally evaluate the block depending on the truthiness of the supplied condition. The truthiness rules are as follows: all values are seen as true except for: false, nil and 0. Lambdas will be automatically called and the truthiness of their results used.

Introduced in v2.10

Examples

# Example 1

on true do
  play 70    
end


 
#=> will play 70 as true is truthy
 



# Example 2

on 1 do
  play 70    
end


 
#=> will play 70 as 1 is truthy
 



# Example 3

on 0 do
  play 70    
end


 
#=> will *not* play 70 as 0 is not truthy
 



# Example 4

on false do
  play 70    
end


 
#=> will *not* play 70 as false is not truthy
 



# Example 5

on nil do
  play 70    
end


 
#=> will *not* play 70 as nil is not truthy
 



# Example 6

on lambda{true} do
  play 70    
end


 
#=> will play 70 as the lambda returns a truthy value
 



# Example 7

on lambda{false} do
  play 70    
end


 
#=> will *not* play 70 as the lambda does not return a truthy value
 



# Example 8

on lambda{[true, false].choose} do
  play 70    
end


 
#=> will maybe play 70 depending on the choice in the lambda
 




Random true value with specified probability

one_in  num (number)

Returns true or false with a specified probability - it will return true every one in num times where num is the param you specify

Introduced in v2.0

Examples

# Example 1

one_in 2



# will return true with a probability of 1/2, false with probability 1/2



# Example 2

one_in 3



# will return true with a probability of 1/3, false with a probability of 2/3



# Example 3

one_in 100



# will return true with a probability of 1/100, false with a probability of 99/100




Randomly pick from list (with duplicates)

pick  list (array), n (number_or_nil)

Pick n elements from list or ring. Unlike shuffle, after each element has been picked, it is ‘returned’ to the list so it may be picked again. This means there may be duplicates in the result. If n is greater than the size of the ring/list then duplicates are guaranteed to be in the result.

If n isn’t supplied it defaults to the size of the list/ring.

Introduced in v2.10

Options

skip:

Number of rands to skip over with each successive pick

Examples

# Example 1

puts [1, 2, 3, 4, 5].pick(3)



#=> [4, 4, 3]



# Example 2

puts (ring 1, 2, 3, 4, 5).pick(3)



#=> (ring 4, 4, 3)



# Example 3

puts (ring 1, 2).pick(5)



#=> (ring 2, 2, 1, 1, 1)



# Example 4

puts (ring 1, 2, 3).pick



#=> (ring 3, 3, 2)




Relative MIDI pitch to frequency ratio

pitch_to_ratio  pitch (midi_number)

Convert a midi note to a ratio which when applied to a frequency will scale the frequency by the number of semitones. Useful for changing the pitch of a sample by using it as a way of generating the rate.

Introduced in v2.5

Examples

# Example 1

pitch_to_ratio 12



#=> 2.0



# Example 2

pitch_to_ratio 1



#=> 1.05946



# Example 3

pitch_to_ratio -12



#=> 0.5



# Example 4

sample :ambi_choir, rate: pitch_to_ratio(3)



# Plays :ambi_choir 3 semitones above default.



# Example 5


(range 0, 16).each do |n|                 
  sample :ambi_choir, rate: pitch_to_ratio(n)
  sleep 0.5                               
end


# Play a chromatic scale of semitones
# For each note in the range 0->16
# play :ambi_choir at the relative pitch
# and wait between notes
 




Play current synth

play  note (symbol_or_number)

Play note with current synth. Accepts a set of standard options which include control of an amplitude envelope with attack:, decay:, sustain: and release: phases. These phases are triggered in order, so the duration of the sound is attack + decay + sustain + release times. The duration of the sound does not affect any other notes. Code continues executing whilst the sound is playing through its envelope phases.

Accepts optional args for modification of the synth being played. See each synth’s documentation for synth-specific opts. See use_synth and with_synth for changing the current synth.

If note is nil, :r or :rest, play is ignored and treated as a rest. Also, if the on: opt is specified and returns false, or nil then play is similarly ignored and treated as a rest.

Note that the default opts listed are only a guide to the most common opts across all the synths. Not all synths support all the default opts and each synth typically supports many more opts specific to that synth. For example, the :tb303 synth supports 45 unique opts. For a full list of a synth’s opts see its documentation in the Help system.

Introduced in v2.0

Options

amp:

The amplitude of the note

amp_slide:

The duration in beats for amplitude changes to take place

pan:

The stereo position of the sound. -1 is left, 0 is in the middle and 1 is on the right. You may use a value in between -1 and 1 such as 0.25

pan_slide:

The duration in beats for the pan value to change

attack:

Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently.

decay:

Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).

sustain:

Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.

release:

Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently.

attack_level:

Amplitude level reached after attack phase and immediately before decay phase

decay_level:

Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set

sustain_level:

Amplitude level reached after decay phase and immediately before release phase.

env_curve:

Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed

slide:

Default slide time in beats for all slide opts. Individually specified slide opts will override this value

pitch:

Pitch adjustment in semitones. 1 is up a semitone, 12 is up an octave, -12 is down an octave etc. Decimal numbers can be used for fine tuning.

on:

If specified and false/nil/0 will stop the synth from being played. Ensures all opts are evaluated.

Examples

# Example 1

play 50



# Plays note 50 on the current synth



# Example 2

play 50, attack: 1



# Plays note 50 with a fade-in time of 1s



# Example 3

play 62, pan: -1, release: 3



# Play note 62 in the left ear with a fade-out time of 3s.




Play notes simultaneously

play_chord  notes (list)

Play a list of notes at the same time.

Accepts optional args for modification of the synth being played. See each synth’s documentation for synth-specific opts. See use_synth and with_synth for changing the current synth.

Introduced in v2.0

Options

amp:

The amplitude of the note

amp_slide:

The duration in beats for amplitude changes to take place

pan:

The stereo position of the sound. -1 is left, 0 is in the middle and 1 is on the right. You may use a value in between -1 and 1 such as 0.25

pan_slide:

The duration in beats for the pan value to change

attack:

Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently.

decay:

Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).

sustain:

Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.

release:

Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently.

attack_level:

Amplitude level reached after attack phase and immediately before decay phase

decay_level:

Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set

sustain_level:

Amplitude level reached after decay phase and immediately before release phase.

env_curve:

Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed

slide:

Default slide time in beats for all slide opts. Individually specified slide opts will override this value

pitch:

Pitch adjustment in semitones. 1 is up a semitone, 12 is up an octave, -12 is down an octave etc. Decimal numbers can be used for fine tuning.

on:

If specified and false/nil/0 will stop the synth from being played. Ensures all opts are evaluated.

Examples

# Example 1

play_chord [40, 45, 47]



play 40
play 45
play 47


 
 
# same as:
 
 
 
 



# Example 2

play_chord [40, 45, 47], amp: 0.5



play 40, amp: 0.5
play 45, amp: 0.5
play 47, amp: 0.5


 
 
# same as:
 
 
 
 



# Example 3

play_chord chord(:e3, :minor)


 




Play pattern of notes

play_pattern  notes (list)

Play list of notes with the current synth one after another with a sleep of 1

Accepts optional args for modification of the synth being played. See each synth’s documentation for synth-specific opts. See use_synth and with_synth for changing the current synth.

Introduced in v2.0

Examples

# Example 1

play_pattern [40, 41, 42]
                         
                         
                         
                         
                         



# Same as:
#   play 40
#   sleep 1
#   play 41
#   sleep 1
#   play 42



# Example 2

play_pattern [:d3, :c1, :Eb5]



# You can use keyword notes



# Example 3

play_pattern [:d3, :c1, :Eb5], amp: 0.5, cutoff: 90



# Supports the same arguments as play:




Play pattern of notes with specific times

play_pattern_timed  notes (list), times (list_or_number)

Play each note in a list of notes one after another with specified times between them. The notes should be a list of MIDI numbers, symbols such as :E4 or chords such as chord(:A3, :major) - identical to the first parameter of the play function. The times should be a list of times between the notes in beats.

If the list of times is smaller than the number of gaps between notes, the list is repeated again. If the list of times is longer than the number of gaps between notes, then some of the times are ignored. See examples for more detail.

Accepts optional args for modification of the synth being played. See each synth’s documentation for synth-specific opts. See use_synth and with_synth for changing the current synth.

Introduced in v2.0

Options

amp:

The amplitude of the note

amp_slide:

The duration in beats for amplitude changes to take place

pan:

The stereo position of the sound. -1 is left, 0 is in the middle and 1 is on the right. You may use a value in between -1 and 1 such as 0.25

pan_slide:

The duration in beats for the pan value to change

attack:

Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently.

decay:

Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).

sustain:

Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.

release:

Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently.

attack_level:

Amplitude level reached after attack phase and immediately before decay phase

decay_level:

Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set

sustain_level:

Amplitude level reached after decay phase and immediately before release phase.

env_curve:

Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed

slide:

Default slide time in beats for all slide opts. Individually specified slide opts will override this value

pitch:

Pitch adjustment in semitones. 1 is up a semitone, 12 is up an octave, -12 is down an octave etc. Decimal numbers can be used for fine tuning.

on:

If specified and false/nil/0 will stop the synth from being played. Ensures all opts are evaluated.

Examples

# Example 1

play_pattern_timed [40, 42, 44, 46], [1, 2, 3]



play 40
sleep 1
play 42
sleep 2
play 44
sleep 3
play 46


 
 
# same as:
 
 
 
 
 
 
 
 



# Example 2

play_pattern_timed [40, 42, 44, 46, 49], [1, 0.5]



play 40
sleep 1
play 42
sleep 0.5
play 44
sleep 1
play 46
sleep 0.5
play 49


 
 
# same as:
 
 
 
 
 
 
 
 
 
 



# Example 3

play_pattern_timed [40, 42, 44, 46], [0.5]



play 40
sleep 0.5
play 42
sleep 0.5
play 44
sleep 0.5
play 46


 
 
# same as:
 
 
 
 
 
 
 
 



# Example 4

play_pattern_timed [40, 42, 44], [1, 2, 3, 4, 5]



play 40
sleep 1
play 42
sleep 2
play 44


 
 
#same as:
 
 
 
 
 
 




Display a message in the output pane

print  output (anything)

Displays the information you specify as a string inside the output pane. This can be a number, symbol, or a string itself. Useful for debugging. Synonym for puts.

Introduced in v2.0

Examples

# Example 1

print "hello there"  



#=> will print the string "hello there" to the output pane



# Example 2

print 5              



#=> will print the number 5 to the output pane



# Example 3

print foo            



#=> will print the contents of foo to the output pane




Display a message in the output pane

puts  output (anything)

Displays the information you specify as a string inside the output pane. This can be a number, symbol, or a string itself. Useful for debugging. Synonym for print.

Introduced in v2.0

Examples

# Example 1

print "hello there"  



#=> will print the string "hello there" to the output pane



# Example 2

print 5              



#=> will print the number 5 to the output pane



# Example 3

print foo            



#=> will print the contents of foo to the output pane




Quantise a value to resolution

quantise  n (number), step (positive_number)

Round value to the nearest multiple of step resolution.

Introduced in v2.1

Examples

# Example 1

quantise(10, 1)



# 10 is already a multiple of 1, so returns 10



# Example 2

quantise(10, 1.1)



# Returns 9.9 which is 1.1 * 9



# Example 3

quantise(13.3212, 0.1)



# 13.3



# Example 4

quantise(13.3212, 0.2)



# 13.4



# Example 5

quantise(13.3212, 0.3)



# 13.2



# Example 6

quantise(13.3212, 0.5)



# 13.5




Create a ramp vector

ramp  list (array)

Create a new immutable ramp vector from args. Indexes always return first or last value if out of bounds.

Introduced in v2.6

Examples

# Example 1

(ramp 1, 2, 3)[0]



#=> 1



# Example 2

(ramp 1, 2, 3)[1]



#=> 2



# Example 3

(ramp 1, 2, 3)[2]



#=> 3



# Example 4

(ramp 1, 2, 3)[3]



#=> 3



# Example 5

(ramp 1, 2, 3)[1000]



#=> 3



# Example 6

(ramp 1, 2, 3)[-1]



#=> 1



# Example 7

(ramp 1, 2, 3)[-1000]



#=> 1




Generate a random float below a value

rand  max (number_or_range)

Given a max number, produces a float between 0 and the supplied max value. If max is a range, produces a float within the range. With no args returns a random value between 0 and 1.

Introduced in v2.0

Example

# Example 1

print rand(0.5)



#=> will print a number like 0.375030517578125 to the output pane




Roll back random generator

rand_back  amount (number)

Roll the random generator back essentially ‘undoing’ the last call to rand. You may specify an amount to roll back allowing you to skip back n calls to rand.

Introduced in v2.7

Examples

# Example 1



  puts rand

  rand_back
           
           

  puts rand
  puts rand



# Basic rand stream rollback
 
# prints 0.75006103515625
 
# roll random stream back one
# the result of the next call to rand will be
# exactly the same as the previous call
 
# prints 0.75006103515625 again!
# prints 0.733917236328125



# Example 2



  puts rand
  puts rand
  puts rand
  puts rand

  rand_back(3)
              
              
              

  puts rand
  puts rand



# Jumping back multiple places in the rand stream
 
# prints 0.75006103515625
# prints 0.733917236328125
# prints 0.464202880859375
# prints 0.24249267578125
 
# roll random stream back three places
# the result of the next call to rand will be
# exactly the same as the result 3 calls to
# rand ago.
 
# prints  0.733917236328125 again!
# prints  0.464202880859375




Generate a random whole number below a value (exclusive)

rand_i  max (number_or_range)

Given a max number, produces a whole number between 0 and the supplied max value exclusively. If max is a range produces an int within the range. With no args returns either 0 or 1

Introduced in v2.0

Example

# Example 1

print rand_i(5)



#=> will print a either 0, 1, 2, 3, or 4 to the output pane




Reset rand generator to last seed

rand_reset   ()

Resets the random stream to the last specified seed. See use_random_seed for changing the seed.

Introduced in v2.7

Example

# Example 1

puts rand
  puts rand
  puts rand
  puts rand
  rand_reset 
  puts rand



# prints 0.75006103515625
# prints 0.733917236328125
# prints 0.464202880859375
# prints 0.24249267578125
# reset the random stream
# prints 0.75006103515625




Jump forward random generator

rand_skip  amount (number)

Jump the random generator forward essentially skipping the next call to rand. You may specify an amount to jump allowing you to skip n calls to rand.

Introduced in v2.7

Examples

# Example 1



  puts rand

  rand_skip
           

  puts rand



# Basic rand stream skip
 
# prints 0.75006103515625
 
# jump random stream forward one
# typically the next rand is 0.733917236328125
 
# prints 0.464202880859375



# Example 2



  puts rand
  puts rand
  puts rand
  puts rand

  rand_reset 

  puts rand

  rand_skip(2)
              
              
              

  puts rand 0.24249267578125


# Jumping forward multiple places in the rand stream
 
# prints 0.75006103515625
# prints 0.733917236328125
# prints 0.464202880859375
# prints 0.24249267578125
 
# reset the random stream
 
# prints 0.75006103515625
 
# jump random stream forward three places
# the result of the next call to rand will be
# exactly the same as if rand had been called
# three times
 
 




Create a ring buffer with the specified start, finish and step size

range  start (number), finish (number), step_size (number)

Create a new ring buffer from the range arguments (start, finish and step size). Step size defaults to 1. Indexes wrap around positively and negatively

Introduced in v2.2

Options

step:

Size of increment between steps; step size.

inclusive:

If set to true, range is inclusive of finish value

Examples

# Example 1

(range 1, 5)   



#=> (ring 1, 2, 3, 4)



# Example 2

(range 1, 5, inclusive: true)



#=> (ring 1, 2, 3, 4, 5)



# Example 3

(range 1, 5, step: 2)



#=> (ring 1, 3)



# Example 4

(range 1, -5, step: 2)



#=> (ring 1, -1, -3)



# Example 5

(range 1, -5, step: 2)[-1]



#=> -3




Relative frequency ratio to MIDI pitch

ratio_to_pitch  ratio (number)

Convert a frequency ratio to a midi note which when added to a note will transpose the note to match the frequency ratio.

Introduced in v2.7

Examples

# Example 1

ratio_to_pitch 2



#=> 12.0



# Example 2

ratio_to_pitch 0.5



#=> -12.0




Random number in centred distribution

rdist  width (number), centre (number)

Returns a random number within the range with width around centre. If optional arg step: is used, the result is quantised by step.

Introduced in v2.3

Options

step:

Step size of value to quantise to.

Examples

# Example 1

print rdist(1, 0)



#=> will print a number between -1 and 1



# Example 2

print rdist(1)



#=> centre defaults to 0 so this is the same as rdist(1, 0)



# Example 3

loop do
    play :c3, pan: rdist(1)
    sleep 0.125
  end


 
#=> Will play :c3 with random L/R panning
 
 




Reset master mixer

reset_mixer!  

The master mixer is the final mixer that all sound passes through. This fn resets it to its default set - undoing any changes made via set_mixer_control!

Introduced in v2.9

Example

# Example 1

set_mixer_control! lpf: 70
sample :loop_amen         
sleep 3
reset_mixer!              
sample :loop_amen         



# LPF cutoff value of master mixer is now 70
# :loop_amen sample is played with low cutoff
 
# mixer is now reset to default values
# :loop_amen sample is played with normal cutoff




Determine if note or args is a rest

rest?  note_or_args (number_symbol_or_map)

Given a note or an args map, returns true if it represents a rest and false if otherwise

Introduced in v2.1

Examples

# Example 1

puts rest? nil



# true



# Example 2

puts rest? :r



# true



# Example 3

puts rest? :rest



# true



# Example 4

puts rest? 60



# false



# Example 5

puts rest? {}



# false



# Example 6

puts rest? {note: :rest}



# true



# Example 7

puts rest? {note: nil}



# true



# Example 8

puts rest? {note: 50}



# false




Create a ring buffer

ring  list (array)

Create a new immutable ring buffer from args. Indexes wrap around positively and negatively

Introduced in v2.2

Examples

# Example 1

(ring 1, 2, 3)[0]



#=> 1



# Example 2

(ring 1, 2, 3)[1]



#=> 2



# Example 3

(ring 1, 2, 3)[3]



#=> 1



# Example 4

(ring 1, 2, 3)[-1]



#=> 3




Generate a random float between two numbers

rrand  min (number), max (number)

Given two numbers, this produces a float between the supplied min and max values exclusively. Both min and max need to be supplied. For random integers, see rrand_i. If optional arg step: is used, the result is quantised by step.

Introduced in v2.0

Options

step:

Step size of value to quantise to.

Examples

# Example 1

print rrand(0, 10)



#=> will print a number like 8.917730007820797 to the output pane



# Example 2

loop do
    play rrand(60, 72)
    sleep 0.125
  end


 
#=> Will play a random non-integer midi note between C4 (60) and C5 (72) such as 67.3453 or 71.2393
 
 




Generate a random whole number between two points inclusively

rrand_i  min (number), max (number)

Given two numbers, this produces a whole number between the min and max you supplied inclusively. Both min and max need to be supplied. For random floats, see rrand

Introduced in v2.0

Examples

# Example 1

print rrand_i(0, 10)



#=> will print a random number between 0 and 10 (e.g. 4, 0 or 10) to the output pane



# Example 2

loop do
    play rrand_i(60, 72)
    sleep 0.125
  end


 
#=> Will play a random midi note between C4 (60) and C5 (72)
 
 




Real time conversion

rt  seconds (number)

Real time representation. Returns the amount of beats for the value in real-time seconds. Useful for bypassing any bpm scaling

Introduced in v2.0

Example

# Example 1

use_bpm 120 
  play 50
  sleep 1     
  play 62
  sleep rt(1) 
  play 72


# modifies all time to be half
 
# actually sleeps for half of a second
 
# bypasses bpm scaling and sleeps for a second
 




Trigger sample

sample  name_or_path (symbol_or_string)

Play back a recorded sound file (sample). Sonic Pi comes with lots of great samples included (see the section under help) but you can also load and play .wav, .wave, .aif, .aiff or .flac files from anywhere on your computer too. To play a built-in sample use the corresponding keyword such as sample :bd_haus. To play any file on your computer use a full path such as sample "/path/to/sample.wav".

There are many opts for manipulating the playback. For example, the rate: opt affects both the speed and the pitch of the playback. To control the rate of the sample in a pitch-meaningful way take a look at the rpitch: opt.

The sampler synth has three separate envelopes - one for amplitude, one for a low pass filter and another for a high pass filter. These work very similar to the standard synth envelopes except for two major differences. Firstly, the envelope times do not stretch or shrink to match the BPM. Secondly, the sustain time by default stretches to make the envelope fit the length of the sample. This is explained in detail in the tutorial.

Samples are loaded on-the-fly when first requested (and subsequently remembered). If the sample loading process takes longer than the schedule ahead time, the sample trigger will be skipped rather than be played late and out of time. To avoid this you may preload any samples you wish to work with using load_sample or load_samples.

Finally, the sampler supports a powerful filtering system to make it easier to work with large folders of samples. The filter commands must be used before the first standard opt. There are six kinds of filter parameters you may use:

  1. Folder strings - "/foo/bar" - which will add all samples within the folder to the set of candidates.
  2. Sample strings - "/path/to/sample.wav" - which will add the specific sample to the set of candidates.
  3. Other strings - "foobar" - which will filter the candidates based on whether the filename contains the string.
  4. Regular expressions - /b[aA]z.*/ - which will filter the candidates based on whether the regular expression matches the filename.
  5. Keywords - :quux - will filter the candidates based on whether the keyword is a direct match of the filename (without extension).
  6. Numbers - 0 - will select the candidate with that index (wrapping round like a ring if necessary).
  7. Lists of the above - ["/foo/bar", "baz", /0-9.*/] - will recurse down and work through the internal filter parameters as if they were in the top level.

By combining commands which add to the candidates and then filtering those candidates it is possible to work with folders full of samples in very powerful ways. Note that the specific ordering of filter parameters is irrelevant with the exception of the numbers - in which case the last number is the index. All the candidates will be gathered first before the filters are applied.

Introduced in v2.0

Options

rate:

Rate with which to play back the sample. Higher rates mean an increase in pitch and a decrease in duration. Default is 1.

beat_stretch:

Stretch (or shrink) the sample to last for exactly the specified number of beats. Please note - this does not keep the pitch constant and is essentially the same as modifying the rate directly.

pitch_stretch:

Stretch (or shrink) the sample to last for exactly the specified number of beats. This attempts to keep the pitch constant using the pitch: opt. Note, it’s very likely you’ll need to experiment with the window_size:, pitch_dis: and time_dis: opts depending on the sample and the amount you’d like to stretch/shrink from original size.

attack:

Time to reach full volume. Default is 0.

sustain:

Time to stay at full volume. Default is to stretch to length of sample (minus attack and release times).

release:

Time (from the end of the sample) to go from full amplitude to 0. Default is 0.

start:

Position in sample as a fraction between 0 and 1 to start playback. Default is 0.

finish:

Position in sample as a fraction between 0 and 1 to end playback. Default is 1.

pan:

Stereo position of audio. -1 is left ear only, 1 is right ear only, and values in between position the sound accordingly. Default is 0.

amp:

Amplitude of playback.

pre_amp:

Amplitude multiplier which takes place immediately before any internal FX such as the low pass filter, compressor or pitch modification. Use this opt if you want to overload the compressor.

norm:

Normalise the audio (make quieter parts of the sample louder and louder parts quieter) - this is similar to the normaliser FX. This may emphasise any clicks caused by clipping.

lpf:

Cutoff value of the built-in low pass filter (lpf) in MIDI notes. Unless specified, the lpf is not added to the signal chain.

lpf_init_level:

The initial low pass filter envelope value as a MIDI note. This envelope is bypassed if no lpf env opts are specified. Default value is to match the lpf_min: opt.

lpf_attack_level:

The peak lpf cutoff (value of cutoff at peak of attack) as a MIDI note. Default value is to match the lpf_decay_level: opt.

lpf_decay_level:

The level of lpf cutoff after the decay phase as a MIDI note. Default value is to match the lpf_sustain_level: opt.

lpf_sustain_level:

The sustain cutoff (value of lpf cutoff at sustain time) as a MIDI note. Default value is to match the lpf_release_level: opt.

lpf_release_level:

The final value of the low pass filter envelope as a MIDI note. This envelope is bypassed if no lpf env opts are specified. Default value is to match the lpf: opt.

lpf_attack:

Attack time for lpf cutoff filter. Amount of time (in beats) for sound to reach full cutoff value. Default value is set to match amp envelope’s attack value.

lpf_decay:

Decay time for lpf cutoff filter. Amount of time (in beats) for sound to move from full cutoff value (cutoff attack level) to the cutoff sustain level. Default value is set to match amp envelope’s decay value.

lpf_sustain:

Amount of time for lpf cutoff value to remain at sustain level in beats. When -1 (the default) will auto-stretch.

lpf_release:

Amount of time (in beats) for sound to move from lpf cutoff sustain value to lpf cutoff min value. Default value is set to match amp envelope’s release value.

lpf_min:

Starting value of the lpf cutoff envelope. Default is 30.

lpf_env_curve:

Select the shape of the curve between levels in the lpf cutoff envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed.

hpf:

Cutoff value of the built-in high pass filter (hpf) in MIDI notes. Unless specified, the hpf is not added to the signal chain.

hpf_init_level:

The initial high pass filter envelope value as a MIDI note. This envelope is bypassed if no hpf env opts are specified. Default value is set to 130.

hpf_attack_level:

The peak hpf cutoff (value of cutoff at peak of attack) as a MIDI note. Default value is to match the hpf_decay_level: opt.

hpf_decay_level:

The level of hpf cutoff after the decay phase as a MIDI note. Default value is to match the hpf_sustain_level: opt.

hpf_sustain_level:

The sustain cutoff (value of hpf cutoff at sustain time) as a MIDI note. Default value is to match the hpf_release_level: opt.

hpf_release_level:

The sustain hpf cutoff (value of hpf cutoff at sustain time) as a MIDI note. Default value is to match the hpf: opt.

hpf_attack:

Attack time for hpf cutoff filter. Amount of time (in beats) for sound to reach full cutoff value. Default value is set to match amp envelope’s attack value.

hpf_decay:

Decay time for hpf cutoff filter. Amount of time (in beats) for sound to move from full cutoff value (cutoff attack level) to the cutoff sustain level. Default value is set to match amp envelope’s decay value.

hpf_sustain:

Amount of time for hpf cutoff value to remain at sustain level in beats. When -1 (the default) will auto-stretch.

hpf_release:

Amount of time (in beats) for sound to move from hpf cutoff sustain value to hpf cutoff min value. Default value is set to match amp envelope’s release value.

hpf_env_curve:

Select the shape of the curve between levels in the hpf cutoff envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed.

hpf_max:

Maximum value of the high pass filter envelope. Default is 200.

rpitch:

Rate modified pitch. Multiplies the rate by the appropriate ratio to shift up or down the specified amount in MIDI notes. Please note - this does not keep the duration and rhythmical rate constant and is essentially the same as modifying the rate directly.

pitch:

Pitch adjustment in semitones. 1 is up a semitone, 12 is up an octave, -12 is down an octave etc. Maximum upper limit of 24 (up 2 octaves). Lower limit of -72 (down 6 octaves). Decimal numbers can be used for fine tuning.

window_size:

Pitch shift-specific opt - only honoured if the pitch: opt is used. Pitch shift works by chopping the input into tiny slices, then playing these slices at a higher or lower rate. If we make the slices small enough and overlap them, it sounds like the original sound with the pitch changed. The window_size is the length of the slices and is measured in seconds. It needs to be around 0.2 (200ms) or greater for pitched sounds like guitar or bass, and needs to be around 0.02 (20ms) or lower for percussive sounds like drum loops. You can experiment with this to get the best sound for your input.

pitch_dis:

Pitch shift-specific opt - only honoured if the pitch: opt is used. Pitch dispersion - how much random variation in pitch to add. Using a low value like 0.001 can help to “soften up” the metallic sounds, especially on drum loops. To be really technical, pitch_dispersion is the maximum random deviation of the pitch from the pitch ratio (which is set by the pitch: opt).

time_dis:

Pitch shift-specific opt - only honoured if the pitch: opt is used. Time dispersion - how much random delay before playing each grain (measured in seconds). Again, low values here like 0.001 can help to soften up metallic sounds introduced by the effect. Large values are also fun as they can make soundscapes and textures from the input, although you will most likely lose the rhythm of the original. NB - This won’t have an effect if it’s larger than window_size.

compress:

Enable the compressor. This sits at the end of the internal FX chain immediately before the amp: opt. Therefore to drive the compressor use the pre_amp: opt which will amplify the signal before it hits any internal FX. The compressor compresses the dynamic range of the incoming signal. Equivalent to automatically turning the amp down when the signal gets too loud and then back up again when it’s quiet. Useful for ensuring the containing signal doesn’t overwhelm other aspects of the sound. Also a general purpose hard-knee dynamic range processor which can be tuned via the opts to both expand and compress the signal.

threshold:

Threshold value determining the break point between slope_below and slope_above. Only valid if the compressor is enabled by turning on the compress: opt.

slope_below:

Slope of the amplitude curve below the threshold. A value of 1 means that the output of signals with amplitude below the threshold will be unaffected. Greater values will magnify and smaller values will attenuate the signal. Only valid if the compressor is enabled by turning on the compress: opt.

slope_above:

Slope of the amplitude curve above the threshold. A value of 1 means that the output of signals with amplitude above the threshold will be unaffected. Greater values will magnify and smaller values will attenuate the signal. Only valid if the compressor is enabled by turning on the compress: opt.

clamp_time:

Time taken for the amplitude adjustments to kick in fully (in seconds). This is usually pretty small (not much more than 10 milliseconds). Also known as the time of the attack phase. Only valid if the compressor is enabled by turning on the compress: opt.

relax_time:

Time taken for the amplitude adjustments to be released. Usually a little longer than clamp_time. If both times are too short, you can get some (possibly unwanted) artefacts. Also known as the time of the release phase. Only valid if the compressor is enabled by turning on the compress: opt.

slide:

Default slide time in beats for all slide opts. Individually specified slide opts will override this value.

Examples

# Example 1



sample :loop_amen



# Play a built-in sample
 
# Plays the Amen break



# Example 2




sample :loop_amen
sample :ambi_lunar_land
                       



# Play two samples at the same time
# with incredible timing accuracy
 
 
# Note, for timing guarantees select the pref:
#   Studio -> Synths and FX -> Enforce timing guarantees



# Example 3



live_loop :bass do
  sample :bd_haus
  sleep 0.5
end


# Create a simple repeating bass drum
 
 
 
 
 



# Example 4



live_loop :rhythm do
  sample :tabla_ghe3 if (spread 5, 7).tick
  sleep 0.125
end

live_loop :bd, sync: :rhythm do
  sample :bd_haus, lpf: 90, amp: 2
  sleep 0.5
end


# Create a more complex rhythm with multiple live loops:
 
 
 
 
 
 
 
 
 
 



# Example 5



sample :loop_amen, rate: 0.5
                            



# Change the playback speed of the sample using rate:
 
# Play the Amen break at half speed
# for old school hip-hop



# Example 6



sample :loop_amen, rate: 1.5
                            



# Speed things up
 
# Play the Amen break at 1.5x speed
# for a jungle/gabba sound



# Example 7



sample :loop_amen, rate: -1



# Go backwards
 
# Negative rates play the sample backwards



# Example 8



sample :loop_amen, rate: -3



# Fast rewind
 
# Play backwards at 3x speed for a fast rewind effect



# Example 9



sample :loop_amen, start: 0.5



# Start mid sample
 
# Start playback half way through



# Example 10



sample :loop_amen, finish: 0.5



# Finish mid sample
 
# Finish playback half way through



# Example 11



sample :loop_amen, start: 0.125, finish: 0.25



# Play part of a sample
 
# Play the second eighth of the sample



# Example 12



sample :loop_amen, start: 0.25, finish: 0.125



# Finishing before the start plays backwards
 
# Play the second eighth of the sample backwards



# Example 13



sample :loop_amen, start: 0.125, finish: 0.25, rate: -0.25
                                                          
                                                          



# Play a section of a sample half speed backwards
 
# Play the second eighth of the
# amen break backwards at a
# quarter speed



# Example 14



use_sample_bpm :loop_amen                   

live_loop :beat_slicer do
  n = 8                                     
                                            

  d = 1.0 / n                               
                                            

  s = (line 0, 1, steps: n).choose          
                                            

  f = s + d                                 

  sample :loop_amen, start: s, finish: f    

  sleep d                                   
end


# Build a simple beat slicer
 
# Set the BPM to match the amen break sample
 
 
# Set number of slices. Try changing this
# to 2, 4, 6, 16 or 32
 
# Calculate the duration of a slice as a
# fraction of the sample
 
# Create a ring of starting points and
# randomly choose one
 
# Calculate the finish point
 
# Play the specific part of the sample
 
# Sleep for the duration of the slice
 



# Example 15



sample :loop_amen, lpf: 80, hpf: 70, compress: 1, pre_amp: 10



# Play with the built-in low pass filter, high pass filter and compressor
 
# Make the amen break sound punchy.



# Example 16



sample :loop_garzul, lpf_attack: 8
sleep 8
sample :loop_garzul, hpf_attack: 8



# Use the cutoff filter envelopes
 
# Sweep the low pass filter up over 8 beats
 
# Sweep the high pass filter down over 8 beats



# Example 17



puts sample_duration :loop_industrial                  
puts sample_duration :loop_industrial, beat_stretch: 1 

live_loop :industrial do
  sample :loop_industrial, beat_stretch: 1             
  sleep 1                                              
                                                       
                                                       
end


# Sample stretching
 
# => 0.88347
# => 1
 
 
# Stretch the sample to make it 1 beat long
# This now loops perfectly.
# However, note that stretching/shrinking
# also modifies the pitch.
 



# Example 18



puts sample_duration :loop_garzul                      
puts sample_duration :loop_garzul, beat_stretch: 6     

live_loop :garzul do
  sample :loop_garzul, beat_stretch: 6                 
                                                       
                                                       

  sleep 6
end


# Sample shrinking
 
# => 8
# => 6
 
 
# As :loop_garzul is longer than 6 beats
# it is shrunk to fit. This increases the
# pitch.
 
 
 



# Example 19



use_bpm 30                                             

puts sample_duration :loop_garzul                      
puts sample_duration :loop_garzul, beat_stretch: 6     

live_loop :garzul do
  sample :loop_garzul, beat_stretch: 6                 
  sleep 6
end


# Sample stretching matches the BPM
 
# Set the BPM to 30
 
# => 4.0 (at 30 BPM the sample lasts for 4 beats)
# => 6.0
 
 
# The sample is stretched to match 6 beats at 30 BPM
 
 



# Example 20



sample "/path/to/sample.wav"                         
                                                       
                                                       



# External samples
 
# Play any Wav, Aif or FLAC sample on your computer
# by simply passing a string representing the full
# path



# Example 21



dir = "/path/to/dir/of/samples"                      

sample dir                                             
                                                       

sample dir, 1                                          

sample dir, 99                                         
                                                       
                                                       
                                                       
                                                       

sample dir, "120"                                    
                                                       
                                                       

sample dir, "120", 1                                 
                                                       
                                                       

sample dir, /beat[0-9]/                                
                                                       
                                                       
                                                       
                                                       

sample dir, /beat[0-9]0/, "100"                      
                                                       
                                                       
                                                       



# Sample pack filtering
 
# You can easily work with a directory of samples
 
# Play the first sample in the directory
# (it is sorted alphabetically)
 
# Play the second sample in the directory
 
# Play the 99th sample in the directory, or if there
# are fewer, treat the directory like a ring and keep
# wrapping the index round until a sample is found.
# For example, if there are 90 samples, the 10th sample
# is played (index 9).
 
# Play the first sample in the directory that contains
# the substring "120".
# For example, this may be "beat1_120_rave.wav"
 
# Play the second sample in the directory that contains
# the substring "100".
# For example, this may be "beat2_120_rave.wav"
 
# Play the first sample in the directory that matches
# the regular expression /beat[0-9]/.
# For example, this may be "beat0_100_trance.wav"
# You may use the full power of Ruby's regular expression
# system here: http://ruby-doc.org/core-2.1.1/Regexp.html
 
# Play the first sample in the directory that both matches
# the regular expression /beat[0-9]0/ and contains the
# the substring "100".
# For example, this may be "beat10_100_rave.wav"



# Example 22



                                                       
                                                       
sample "tabla_"                                      
                                                       

sample "tabla_", 2                                   
                                                       



# Filtering built-in samples
 
# If you don't pass a directory source, you can filter over
# the built-in samples.
# Play the first built-in sample that contains the substring
# "tabla"
 
# Play the second built-in sample that contains the substring
# "tabla"



# Example 23



load_samples "tabla_"                                
                                                       
                                                       

live_loop :tabla do
  sample "tabla_", tick                              
  sleep 0.125
end


# Play with whole directories of samples
 
# You may pass any of the source/filter options to load_samples
# to load all matching samples. This will load all the built-in
# samples containing the substring "tabla_"
 
 
# Treat the matching samples as a ring and tick through them
 
 



# Example 24



dir1 = "/path/to/sample/directory"
dir2 = "/path/to/other/sample/directory"

sample dir1, dir2, "foo"                             
                                                       

                                                       



# Specify multiple sources
 
 
 
 
# Match the first sample that contains the string "foo" out of
# all the samples in dir1 and dir2 combined.
 
# Note that the sources must be listed before any filters.



# Example 25


dir = "/path/to/sample/directory"                    
                                                       
dir_recursive = "/path/to/sample/directory/**"       
                                                       
                                                       

sample dir, 0                                          

sample dir_recursive, 0                                
                                                       
                                                       
                                                       
                                                       



# List contents recursively
# By default the list of all top-level samples within the directory
# is considered.
# However, if you finish your directory string with ** then if that
# directory contains other directories then the samples within the
# subdirectories and their subsubdirectories in turn are considered.
 
# Play the first top-level sample in the directory
 
# Play the first sample found after combinining all samples found in
# the directory and all directories within it recursively.
# Note that if there are many sub directories this may take some time
# to execute. However, the result is cached so subsequent calls will
# be fast.



# Example 26




filter = lambda do |candidates|                        
  [candidates.choose]                                  
end                                                    
                                                       
8.times do
  sample "drum_", filter                             
  sleep 0.25                                           
end


# Bespoke filters
 
 
# If the built-in String, Regexp and index filters are not sufficient
# you may write your own. They need to be a function which takes a list
# of paths to samples and return a list of samples. This one returns a
# list of a single randomly selected sample.
 
# Play 8 randomly selected samples from the built-in sample set that also
# contain the substring "drum_"
 




Get sample data

sample_buffer  path (string)

Alias for the load_sample method. Loads sample if necessary and returns buffer information.

Introduced in v2.0

Example

# Example 1

see load_sample


 




Get duration of sample in beats

sample_duration  path (string)

Given the name of a loaded sample, or a path to a .wav, .wave, .aif, .aiff or .flac file returns the length of time in beats that the sample would play for. sample_duration understands and accounts for all the opts you can pass to sample which have an effect on the playback duration such as rate:. The time returned is scaled to the current BPM.

Note: avoid using sample_duration to set the sleep time in live_loops, prefer stretching the sample with the beat_stretch: opt or changing the BPM instead. See the examples below for details.

Introduced in v2.0

Options

rate:

Rate modifier. For example, doubling the rate will halve the duration.

start:

Start position of sample playback as a value from 0 to 1

finish:

Finish position of sample playback as a value from 0 to 1

attack:

Duration of the attack phase of the envelope.

decay:

Duration of the decay phase of the envelope.

sustain:

Duration of the sustain phase of the envelope.

release:

Duration of the release phase of the envelope.

beat_stretch:

Change the rate of the sample so that its new duration matches the specified number of beats.

pitch_stretch:

Change the rate of the sample so that its new duration matches the specified number of beats but attempt to preserve pitch.

rpitch:

Change the rate to shift the pitch up or down the specified number of MIDI notes.

Examples

# Example 1


puts sample_duration(:loop_garzul)



# Simple use
# returns 8.0 because this sample is 8 seconds long



# Example 2


use_bpm 120
puts sample_duration(:loop_garzul)
use_bpm 90
puts sample_duration(:loop_garzul)
use_bpm 21
puts sample_duration(:loop_garzul)



# The result is scaled to the current BPM
 
# => 16.0
 
# => 12.0
 
# => 2.8



# Example 3



live_loop :avoid_this do              
  with_fx :slicer do                  
    sample :loop_amen                 
    sleep sample_duration(:loop_amen) 
  end                                 
end

live_loop :prefer_this do             
  use_sample_bpm :loop_amen           
  with_fx :slicer do                  
    sample :loop_amen
    sleep 1
  end
end

live_loop :or_this do                 
  with_fx :slicer do                  
    sample :loop_amen, beat_stretch: 1
    sleep 1
  end
end


# Avoid using sample_duration to set the sleep time in live_loops
 
# It is possible to use sample_duration to drive the frequency of a live loop.
# However, if you're using a rhythmical sample such as a drum beat and it isn't
# in the same BPM as the current BPM, then the FX such as this slicer will be
# badly out of sync. This is because the slicer slices at the current BPM and
# this live_loop is looping at a different BPM (that of the sample)
 
 
# Instead prefer to set the BPM of the live_loop to match the sample. It has
# two benefits. Now our sleep is a nice and simple 1 (as it's one beat).
# Also, our slicer now works with the beat and sounds much better.
 
 
 
 
 
# Alternatively we can beat_stretch the sample to match the current BPM. This has the
# side effect of changing the rate of the sample (and hence the pitch). However, the
# FX works nicely in time and the sleep time is also a simple 1.
 
 
 



# Example 4



                                                                 
sample_duration :loop_garzul, rate: 1                            

                                                                 
sample_duration :loop_garzul, rate: 0.5                          

                                                                 
sample_duration :loop_garzul, rate: 2                            

                                                                 
sample_duration :loop_garzul, rate: -2                           

                                                                 
sample_duration :loop_garzul, attack: 1                          
sample_duration :loop_garzul, attack: 100                        
sample_duration :loop_garzul, attack: 0                          

                                                                 
sample_duration :loop_garzul, release: 1                         
sample_duration :loop_garzul, release: 100                       
sample_duration :loop_garzul, release: 0                         

                                                                 
sample_duration :loop_garzul, decay: 1                           
sample_duration :loop_garzul, decay: 100                         
sample_duration :loop_garzul, decay: 0                           

                                                                 
                                                                 
                                                                 
sample_duration :loop_garzul, sustain: 0, attack: 0.5            
sample_duration :loop_garzul, sustain: 0, decay: 0.1             
sample_duration :loop_garzul, sustain: 0, release: 1             
sample_duration :loop_garzul, sustain: 2, attack: 0.5, release: 1

                                                                 
                                                                 
sample_duration :loop_garzul, sustain: 0, attack: 8, release: 3  


                                                                 
sample_duration :loop_garzul, rate: 10                           
sample_duration :loop_garzul, sustain: 0, attack: 0.9, rate: 10  


                                                                 
                                                                 
sample_duration :loop_garzul, rpitch: 12                         
sample_duration :loop_garzul, rpitch: -12                        

                                                                 
sample_duration :loop_garzul, rpitch: 12, rate: 2                

                                                                 
                                                                 
sample_duration :loop_garzul, beat_stretch: 3                    
sample_duration :loop_garzul, beat_stretch: 3, rate: 0.5         

                                                                 
                                                                 
sample_duration :loop_garzul, pitch_stretch: 3                   
sample_duration :loop_garzul, pitch_stretch: 3, rate: 0.5        

                                                                 
                                                                 
sample_duration :loop_garzul, start: 0.5                         
sample_duration :loop_garzul, start: 0.5, finish: 0.75           
sample_duration :loop_garzul, finish: 0.5, start: 0.75           
sample_duration :loop_garzul, rate: 2, finish: 0.5, start: 0.75



# The standard sample opts are also honoured
 
# Playing a sample at standard speed will return standard length
# => 8.0
 
# Playing a sample at half speed will double duration
# => 16.0
 
# Playing a sample at double speed will halve duration
# => 4.0
 
# Playing a sample backwards at double speed will halve duration
# => 4.0
 
# Without an explicit sustain: opt attack: just affects amplitude not duration
# => 8.0
# => 8.0
# => 8.0
 
# Without an explicit sustain: opt release: just affects amplitude not duration
# => 8.0
# => 8.0
# => 8.0
 
# Without an explicit sustain: opt decay: just affects amplitude not duration
# => 8.0
# => 8.0
# => 8.0
 
# With an explicit sustain: opt, if the attack + decay + sustain + release envelope
# duration is less than the sample duration time, the envelope will shorten the
# sample time.
# => 0.5
# => 0.1
# => 1.0
# => 3.5
 
# If the envelope duration is longer than the sample it will not affect the
# sample duration
# => 8
 
 
# All other opts are taken into account before the comparison with the envelope opts.
# => 0.8
# => 0.8 (The duration of the sample is less than the envelope length so wins)
 
 
# The rpitch: opt will modify the rate to shift the pitch of the sample up and down
# and therefore affects duration.
# => 4.0
# => 16
 
# The rpitch: and rate: opts combine together.
# => 2.0
 
# The beat_stretch: opt stretches the sample so that its duration matches the value.
# It also combines with rate:
# => 3.0
# => 6.0
 
# The pitch_stretch: opt acts identically to beat_stretch when just considering sample
# duration.
# => 3.0
# => 6.0
 
# The start: and finish: opts can also shorten the sample duration and also combine
# with other opts such as rate:
# => 4.0
# => 2.0
# => 2.0
# => 1.0



# Example 5



sample :loop_amen                   
sleep sample_duration(:loop_amen)   
sample :loop_amen                   



# Triggering samples one after another
 
# start the :loop_amen sample
# wait for the duration of :loop_amen before
# starting it again




Free a sample on the synth server

sample_free  path (string)

Frees the memory and resources consumed by loading the sample on the server. Subsequent calls to sample and friends will re-load the sample on the server.

You may also specify the same set of source and filter pre-args available to sample itself. sample_free will then free all matching samples. See sample’s docs for more information.

Introduced in v2.9

Examples

# Example 1

sample :loop_amen
sleep 2
sample :loop_amen
sleep 2
sample_free :loop_amen
sample :loop_amen



# The Amen break is now loaded into memory and played
 
# The Amen break is not loaded but played from memory
 
# The Amen break is freed from memory
# the Amen break is re-loaded and played



# Example 2

puts sample_info(:loop_amen).to_i
puts sample_info(:loop_amen).to_i
                                 
sample_free :loop_amen
puts sample_info(:loop_amen).to_i



# This returns the buffer id of the sample i.e. 1
# The buffer id remains constant whilst the sample
# is loaded in memory
 
# The Amen break is re-loaded and gets a *new* id.



# Example 3

sample :loop_amen
sample :ambi_lunar_land
sleep 2
sample_free :loop_amen, :ambi_lunar_land
sample :loop_amen                       
sample :ambi_lunar_land                 



 
 
 
 
# re-loads and plays amen
# re-loads and plays lunar land



# Example 4


dir = "/path/to/sample/dir"
sample_free dir
sample_free dir, 1
sample_free dir, :foo
sample_free dir, /[Bb]ar/



# Using source and filter pre-args
 
# frees any loaded samples in "/path/to/sample/dir"
# frees sample with index 1 in "/path/to/sample/dir"
# frees sample with name "foo" in "/path/to/sample/dir"
# frees sample which matches regex /[Bb]ar/ in "/path/to/sample/dir"




Free all loaded samples on the synth server

sample_free_all   ()

Unloads all samples therefore freeing the memory and resources consumed. Subsequent calls to sample and friends will re-load the sample on the server.

Introduced in v2.9

Example

# Example 1

sample :loop_amen       
sample :ambi_lunar_land 
sleep 2
sample_free_all
sample :loop_amen       



# load and play :loop_amen
# load and play :ambi_lunar_land
 
 
# re-loads and plays amen




Get all sample groups

sample_groups  

Return a list of all the sample groups available

Introduced in v2.0


Get sample information

sample_info  path (string)

Alias for the load_sample method. Loads sample if necessary and returns sample information.

Introduced in v2.0

Example

# Example 1

see load_sample


 




Test if sample was pre-loaded

sample_loaded?  path (string)

Given a path to a .wav, .wave, .aif, .aiff or .flac file, returns true if the sample has already been loaded.

Introduced in v2.2

Example

# Example 1

load_sample :elec_blip
puts sample_loaded? :elec_blip
puts sample_loaded? :misc_burp



# :elec_blip is now loaded and ready to play as a sample
# prints true because it has been pre-loaded
# prints false because it has not been loaded




Get sample names

sample_names  group (symbol)

Return a ring of sample names for the specified group

Introduced in v2.0


Sample Pack Filter Resolution

sample_paths  pre_args (source_and_filter_types)

Accepts the same pre-args and opts as sample and returns a ring of matched sample paths.

Introduced in v2.10

Examples

# Example 1

sample_paths "/path/to/samples/"



#=> ring of all top-level samples in /path/to/samples



# Example 2

sample_paths "/path/to/samples/**"



#=> ring of all nested samples in /path/to/samples



# Example 3

sample_paths "/path/to/samples/", "foo"
                                                containing the string "foo" in their filename.


#=> ring of all samples in /path/to/samples
 




Create scale

scale  tonic (symbol), name (symbol)

Creates a ring of MIDI note numbers when given a tonic note and a scale name. Also takes an optional num_octaves: parameter (octave 1 is the default). If only passed the scale name, the tonic defaults to 0. See examples.

Introduced in v2.0

Options

num_octaves:

The number of octaves you’d like the scale to consist of. More octaves means a larger scale. Default is 1.

Examples

# Example 1

puts (scale :C, :major)



# returns the following ring of MIDI note numbers: (ring 60, 62, 64, 65, 67, 69, 71, 72)



# Example 2


play_pattern (scale :C, :major)


# anywhere you can use a list or ring of notes, you can also use scale
 



# Example 3


play_pattern (scale :C, :major, num_octaves: 2)


# you can use the :num_octaves parameter to get more notes
 



# Example 4


puts (scale 50, :minor)
puts (scale 50.1, :minor)
puts (scale :minor)



# Scales can start with any note:
#=> (ring 50, 52, 53, 55, 57, 58, 60, 62)
#=> (ring 50.1, 52.1, 53.1, 55.1, 57.1, 58.1, 60.1, 62.1)
#=> (ring 0, 2, 3, 5, 7, 8, 10, 12)



# Example 5


live_loop :scale_player do
  play (scale :Eb3, :super_locrian).tick, release: 0.1
  sleep 0.125
end


# scales are also rings
 
 
 
 



# Example 6


live_loop :scaled_sample do
  sample :bass_trance_c, rpitch: (scale 0, :minor).tick
  sleep 1
end


# scales starting with 0 are useful in combination with sample's rpitch:
 
 
 
 



# Example 7



(scale :C, :diatonic)
(scale :C, :ionian)
(scale :C, :major)
(scale :C, :dorian)
(scale :C, :phrygian)
(scale :C, :lydian)
(scale :C, :mixolydian)
(scale :C, :aeolian)
(scale :C, :minor)
(scale :C, :locrian)
(scale :C, :hex_major6)
(scale :C, :hex_dorian)
(scale :C, :hex_phrygian)
(scale :C, :hex_major7)
(scale :C, :hex_sus)
(scale :C, :hex_aeolian)
(scale :C, :minor_pentatonic)
(scale :C, :yu)
(scale :C, :major_pentatonic)
(scale :C, :gong)
(scale :C, :egyptian)
(scale :C, :shang)
(scale :C, :jiao)
(scale :C, :zhi)
(scale :C, :ritusen)
(scale :C, :whole_tone)
(scale :C, :whole)
(scale :C, :chromatic)
(scale :C, :harmonic_minor)
(scale :C, :melodic_minor_asc)
(scale :C, :hungarian_minor)
(scale :C, :octatonic)
(scale :C, :messiaen1)
(scale :C, :messiaen2)
(scale :C, :messiaen3)
(scale :C, :messiaen4)
(scale :C, :messiaen5)
(scale :C, :messiaen6)
(scale :C, :messiaen7)
(scale :C, :super_locrian)
(scale :C, :hirajoshi)
(scale :C, :kumoi)
(scale :C, :neapolitan_major)
(scale :C, :bartok)
(scale :C, :bhairav)
(scale :C, :locrian_major)
(scale :C, :ahirbhairav)
(scale :C, :enigmatic)
(scale :C, :neapolitan_minor)
(scale :C, :pelog)
(scale :C, :augmented2)
(scale :C, :scriabin)
(scale :C, :harmonic_major)
(scale :C, :melodic_minor_desc)
(scale :C, :romanian_minor)
(scale :C, :hindu)
(scale :C, :iwato)
(scale :C, :melodic_minor)
(scale :C, :diminished2)
(scale :C, :marva)
(scale :C, :melodic_major)
(scale :C, :indian)
(scale :C, :spanish)
(scale :C, :prometheus)
(scale :C, :diminished)
(scale :C, :todi)
(scale :C, :leading_whole)
(scale :C, :augmented)
(scale :C, :purvi)
(scale :C, :chinese)
(scale :C, :lydian_minor)


# Sonic Pi supports a large range of scales:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 




All scale names

scale_names  

Returns a ring containing all scale names known to Sonic Pi

Introduced in v2.6

Example

# Example 1

puts scale_names



#=>  prints a list of all the scales




Global Cent tuning

set_cent_tuning!  cent_shift (number)

Globally tune Sonic Pi to play with another external instrument.

Uniformly tunes your music by shifting all notes played by the specified number of cents. To shift up by a cent use a cent tuning of 1. To shift down use negative numbers. One semitone consists of 100 cents.

See use_cent_tuning for setting the cent tuning value locally for a specific thread or live_loop. This is a global value and will shift the tuning for all notes. It will also persist for the entire session.

Important note: the cent tuning set by set_cent_tuning! is independent of any thread-local cent tuning values set by use_cent_tuning or with_cent_tuning.

Introduced in v2.10

Example

# Example 1

play 50
set_cent_tuning! 1
play 50



# Plays note 50
 
# Plays note 50.01




Set control delta globally

set_control_delta!  time (number)

Specify how many seconds between successive modifications (i.e. trigger then controls) of a specific node on a specific thread. Set larger if you are missing control messages sent extremely close together in time.

Introduced in v2.1

Example

# Example 1

set_control_delta! 0.1                

s = play 70, release: 8, note_slide: 8
control s, note: 82                   
                                      
                                      
                                      
                                      
                                      



# Set control delta to 0.1
 
# Play a note and set the slide time
# immediately start sliding note.
# This control message might not be
# correctly handled as it is sent at the
# same virtual time as the trigger.
# If you don't hear a slide, try increasing the
# control delta until you do.




Control master mixer

set_mixer_control!  

The master mixer is the final mixer that all sound passes through. This fn gives you control over the master mixer allowing you to manipulate all the sound playing through Sonic Pi at once. For example, you can sweep a lpf or hpf over the entire sound. You can reset the controls back to their defaults with reset_mixer!.

Introduced in v2.7

Options

pre_amp:

Controls the amplitude of the signal prior to the FX stage of the mixer (prior to lpf/hpf stages). Has slide opts. Default 1.

amp:

Controls the amplitude of the signal after the FX stage. Has slide opts. Default 1.

hpf:

Global hpf FX. Has slide opts. Default 0.

lpf:

Global lpf FX. Has slide opts. Default 135.5.

hpf_bypass:

Bypass the global hpf. 0=no bypass, 1=bypass. Default 0.

lpf_bypass:

Bypass the global lpf. 0=no bypass, 1=bypass. Default 0.

limiter_bypass:

Bypass the final limiter. 0=no bypass, 1=bypass. Default 0.

leak_dc_bypass:

Bypass the final DC leak correction FX. 0=no bypass, 1=bypass. Default 0.

Example

# Example 1

set_mixer_control! lpf: 30, lpf_slide: 16



# slide the global lpf to 30 over 16 beats.




Set sched ahead time globally

set_sched_ahead_time!  time (number)

Specify how many seconds ahead of time the synths should be triggered. This represents the amount of time between pressing ‘Run’ and hearing audio. A larger time gives the system more room to work with and can reduce performance issues in playing fast sections on slower platforms. However, a larger time also increases latency between modifying code and hearing the result whilst live coding.

Introduced in v2.0

Example

# Example 1

set_sched_ahead_time! 1



# Code will now run approximately 1 second ahead of audio.




Set Volume globally

set_volume!  vol (number)

Set the main system volume to vol. Accepts a value between 0 and 5 inclusive. Vols greater or smaller than the allowed values are trimmed to keep them within range. Default is 1.

Introduced in v2.0

Examples

# Example 1

set_volume! 2



# Set the main system volume to 2



# Example 2

set_volume! -1



# Out of range, so sets main system volume to 0



# Example 3

set_volume! 7



# Out of range, so sets main system volume to 5




Randomise order of a list

shuffle  list (array)

Returns a new list with the same elements as the original but with their order shuffled. Also works for strings

Introduced in v2.1

Examples

# Example 1

shuffle [1, 2, 3, 4]



#=> Would return something like: [3, 4, 2, 1]



# Example 2

shuffle "foobar" 



#=> Would return something like: "roobfa"




Wait for beat duration

sleep  beats (number)

Wait for a number of beats before triggering the next command. Beats are converted to seconds by scaling to the current bpm setting.

Introduced in v2.0

Examples

# Example 1



  play 50 
  play 55
  play 62

  sleep 1 

  play 50 
  sleep 0.5
  play 55
  sleep 0.5
  play 62


# Without calls to sleep, all sounds would happen at once:
 
# This is actually a chord with all notes played simultaneously
 
 
 
# Create a gap, to allow a moment's pause for reflection...
 
# Let's try the chord again, but this time with sleeps:
# With the sleeps, we turn a chord into an arpeggio
 
 
 



# Example 2



  use_bpm 120
  play 50
  sleep 1
  play 55
  sleep 1
  play 62

 

  use_bpm 30
  play 50
  sleep 1
  play 55
  sleep 1
  play 62


# The amount of time sleep pauses for is scaled to match the current bpm. The default bpm is 60. Let's double it:
 
 
 
# This actually sleeps for 0.5 seconds as we're now at double speed
 
 
 
 
# Let's go down to half speed:
 
 
 
# This now sleeps for 2 seconds as we're now at half speed.
 
 
 




Print a string representing a list of numeric values as a spark graph/bar chart

spark  

Given a list of numeric values, this method turns them into a string of bar heights and prints them out. Useful for quickly graphing the shape of an array.

Introduced in v2.5

Examples

# Example 1

spark (range 1, 5))   



#=> ▁▃▅█



# Example 2

spark (range 1, 5).shuffle)



#=> ▃█▅▁




Returns a string representing a list of numeric values as a spark graph/bar chart

spark_graph  

Given a list of numeric values, this method turns them into a string of bar heights. Useful for quickly graphing the shape of an array. Remember to use puts so you can see the output. See spark for a simple way of printing a spark graph.

Introduced in v2.5

Examples

# Example 1

puts (spark_graph (range 1, 5))   



#=> ▁▃▅█



# Example 2

puts (spark_graph (range 1, 5).shuffle)



#=> ▃█▅▁




Euclidean distribution for beats

spread  num_accents (number), size (number)

Creates a new ring of boolean values which space a given number of accents as evenly as possible throughout a bar. This is an implementation of the process described in ‘The Euclidean Algorithm Generates Traditional Musical Rhythms’ (Toussaint 2005).

Introduced in v2.4

Options

rotate:

rotate to the next strong beat allowing for easy permutations of the original rhythmic grouping (see example)

Examples

# Example 1

(spread 3, 8)   



#=> (ring true, false, false, true, false, false, true, false) a spacing of 332



# Example 2

(spread 3, 8, rotate: 1)



#=> (ring true, false, false, true, false, true, false, false) a spacing of 323



# Example 3


  live_loop :euclid_beat do
    sample :elec_bong, amp: 1.5 if (spread 3, 8).tick
    sample :perc_snap, amp: 0.8 if (spread 7, 11).look
    sample :bd_haus, amp: 2 if (spread 1, 4).look
    sleep 0.125
  end


# Easily create interesting polyrhythmic beats
 
# Spread 3 bongs over 8
# Spread 7 snaps over 11
# Spread 1 bd over 4
 
 



# Example 4


 
  (spread 2, 5) 

  (spread 3, 4) 
                

  (spread 3, 5) 
                
                

  (spread 3, 7) 

  (spread 3, 8) 

  (spread 4, 7) 

  (spread 4, 9) 

  (spread 4, 11)

  (spread 5, 6) 
                

  (spread 5, 7) 

  (spread 5, 8) 

  (spread 5, 9) 

  (spread 5, 11)
                

  (spread 5, 12)
                

  (spread 5, 16)

  (spread 7, 8) 

  (spread 7, 12)

  (spread 7, 16)

  (spread 9, 16)

  (spread 11, 24)

  (spread 13, 24)
                 



# Spread descriptions from
# 'The Euclidean Algorithm Generates Traditional Musical Rhythms' (Toussaint 2005).
# A thirteenth century Persian rhythm called Khafif-e-ramal.
 
# The archetypal pattern of the Cumbria from Columbia, as well
# as a Calypso rhythm from Trinidad
 
# When started on the second onset, is another thirteenth
# century Persian rhythm by the name of Khafif-e-ramal, as well
# as a Romanian folk-dance rhythm.
 
# A ruchenitza rhythm used in a Bulgarian folk-dance.
 
# The Cuban tresillo pattern
 
# Another Ruchenitza Bulgarian folk-dance rhythm
 
# The Aksak rhythm of Turkey.
 
# The metric pattern used by Frank Zappa in his piece Outside Now
 
# Yields the York-Samai pattern, a popular Arab rhythm, when
# started on the second onset.
 
# The Nawakhat pattern, another popular Arab rhythm.
 
# The Cuban cinquillo pattern.
 
# A popular Arab rhythm called Agsag-Samai.
 
# The metric pattern used by Moussorgsky in Pictures at an
# Exhibition
 
# The Venda clapping pattern of a South African children's
# song.
 
# The Bossa-Nova rhythm necklace of Brazil.
 
# A typical rhythm played on the Bendir (frame drum)
 
# A common West African bell pattern.
 
# A Samba rhythm necklace from Brazil.
 
# A rhythm necklace used in the Central African Republic.
 
# A rhythm necklace of the Aka Pygmies of Central Africa.
 
# Another rhythm necklace of the Aka Pygmies of the upper
# Sangha.




Get server status

status  

This returns a Hash of information about the synthesis environment. Mostly used for debugging purposes.

Introduced in v2.0

Example

# Example 1

puts status
           
           
           
           
           
           
           
           
           
           
           
           



# Returns something similar to:
# {
#   :ugens=>10,
#   :synths=>1,
#   :groups=>7,
#   :sdefs=>61,
#   :avg_cpu=>0.20156468451023102,
#   :peak_cpu=>0.36655542254447937,
#   :nom_samp_rate=>44100.0,
#   :act_samp_rate=>44099.9998411752,
#   :audio_busses=>2,
#   :control_busses=>0
# }




Stop current thread or run

stop  

Stops the current thread or if not in a thread, stops the current run. Does not stop any running synths triggered previously in the run/thread or kill any existing sub-threads.

Introduced in v2.5

Examples

# Example 1

sample :loop_amen
  sleep 0.5
  stop               
  sample :loop_garzul



#=> this sample is played until completion
 
#=> signal to stop executing this run
#=> this never executes



# Example 2

in_thread do
    play 60     
    stop
    sleep 0.5   
    play 72     
  end

  play 80 



 
#=> this note plays
 
#=> this sleep never happens
#=> this play never happens
 
 
#=> this plays as the stop only affected the above thread



# Example 3


  live_loop :foo
    sample :bd_haus
    sleep 1
    stop              
  end

  live_loop :bar      
    sample :elec_blip
    sleep 0.25
  end


# Stopping live loops
 
 
 
# live loop :foo will now stop and no longer loop
 
 
# live loop :bar will continue looping
 
 
 




Stretch a sequence of values

stretch  list (anything), count (number)

Stretches a list of values each value repeated count times. Always returns a ring regardless of the type of the list that is stretched. To preserve type, consider using .stretch i.e. (ramp 1, 2, 3).stretch(2) #=> (ramp 1, 1, 2, 2, 3, 3)

Introduced in v2.6

Examples

# Example 1

(stretch [1,2], 3)   



#=> (ring 1, 1, 1, 2, 2, 2)



# Example 2

(stretch [:e2, :c3], 1, [:c2, :d3], 2)



#=> (ring :e2, :c3, :c2, :c2, :d3, :d3)




Sync with other threads

sync  cue_id (symbol)

Pause/block the current thread until a cue heartbeat with a matching cue_id is received. When a matching cue message is received, unblock the current thread, and continue execution with the virtual time set to match the thread that sent the cue heartbeat. The current thread is therefore synced to the cue thread. If multiple cue ids are passed as arguments, it will sync on the first matching cue_id. By default the BPM of the cueing thread is inherited. This can be disabled using the bpm_sync: opt.

Introduced in v2.0

Options

bpm_sync:

Inherit the BPM of the cueing thread. Default is false

Examples

# Example 1

in_thread do
    sync :foo
    sample :ambi_lunar_land
  end

  sleep 5

  cue :foo
           



 
# this parks the current thread waiting for a foo sync message to be received.
 
 
 
 
 
# We send a sync message from the main thread.
# This then unblocks the thread above and we then hear the sample



# Example 2

in_thread do  
    loop do     
      cue :tick
      sleep 0.5 
    end
  end

 
  loop do                   
    sync :tick              
    sample :drum_heavy_kick 
  end


# Start a metronome thread
# Loop forever:
# sending tick heartbeat messages
# and sleeping for 0.5 beats between ticks
 
 
 
# We can now play sounds using the metronome.
# In the main thread, just loop
# waiting for :tick sync messages
# after which play the drum kick sample
 



# Example 3

sync :foo, :bar



# Wait for either a :foo or :bar cue



# Example 4

in_thread do  
    loop do     
      cue [:foo, :bar, :baz].choose
      sleep 0.5 
    end
  end

 

  in_thread do
    loop do                   
      sync :foo              
      sample :elec_beep 
    end
  end

  in_thread do
    loop do                   
      sync :bar              
      sample :elec_flip 
    end
  end

  in_thread do
    loop do                   
      sync :baz              
      sample :elec_blup 
    end
  end


# Start a metronome thread
# Loop forever:
# sending one of three tick heartbeat messages randomly
# and sleeping for 0.5 beats between ticks
 
 
 
# We can now play sounds using the metronome:
 
 
# In the main thread, just loop
# waiting for :foo sync messages
# after which play the elec beep sample
 
 
 
 
# In the main thread, just loop
# waiting for :bar sync messages
# after which play the elec flip sample
 
 
 
 
# In the main thread, just loop
# waiting for :baz sync messages
# after which play the elec blup sample
 
 




Sync and inherit BPM from other threads

sync_bpm  cue_id (symbol)

An alias for sync with the bpm_sync: opt set to true.`

Introduced in v2.10

Example

# Example 1

See examples for sync


 




Trigger specific synth

synth  synth_name (symbol)

Trigger specified synth with given opts. Bypasses current_synth value, yet still honours current_synth_defaults. When using synth, the note is no longer an explicit argument but an opt with the key note:.

If note: opt is nil, :r or :rest, play is ignored and treated as a rest. Also, if the on: opt is specified and returns false, or nil then play is similarly ignored and treated as a rest.

If the synth name is nil behaviour is identical to that of play in that the current_synth will determine the actual synth triggered.

Note that the default opts listed are only a guide to the most common opts across all the synths. Not all synths support all the default opts and each synth typically supports many more opts specific to that synth. For example, the :tb303 synth supports 45 unique opts. For a full list of a synth’s opts see its documentation in the Help system. This can be accessed directly by clicking on the name of the synth and using the shortcut C-i

Introduced in v2.0

Options

amp:

The amplitude of the note

amp_slide:

The duration in beats for amplitude changes to take place

pan:

The stereo position of the sound. -1 is left, 0 is in the middle and 1 is on the right. You may use a value in between -1 and 1 such as 0.25

pan_slide:

The duration in beats for the pan value to change

attack:

Amount of time (in beats) for sound to reach full amplitude (attack_level). A short attack (i.e. 0.01) makes the initial part of the sound very percussive like a sharp tap. A longer attack (i.e 1) fades the sound in gently.

decay:

Amount of time (in beats) for the sound to move from full amplitude (attack_level) to the sustain amplitude (sustain_level).

sustain:

Amount of time (in beats) for sound to remain at sustain level amplitude. Longer sustain values result in longer sounds. Full length of sound is attack + decay + sustain + release.

release:

Amount of time (in beats) for sound to move from sustain level amplitude to silent. A short release (i.e. 0.01) makes the final part of the sound very percussive (potentially resulting in a click). A longer release (i.e 1) fades the sound out gently.

attack_level:

Amplitude level reached after attack phase and immediately before decay phase

decay_level:

Amplitude level reached after decay phase and immediately before sustain phase. Defaults to sustain_level unless explicitly set

sustain_level:

Amplitude level reached after decay phase and immediately before release phase.

env_curve:

Select the shape of the curve between levels in the envelope. 1=linear, 2=exponential, 3=sine, 4=welch, 6=squared, 7=cubed

slide:

Default slide time in beats for all slide opts. Individually specified slide opts will override this value

pitch:

Pitch adjustment in semitones. 1 is up a semitone, 12 is up an octave, -12 is down an octave etc. Decimal numbers can be used for fine tuning.

on:

If specified and false/nil/0 will stop the synth from being played. Ensures all opts are evaluated.

Examples

# Example 1

use_synth :beep           
play 60                   

synth :dsaw, note: 60   
                        



# Set current synth to :beep
# Play note 60 with opt defaults
 
# Bypass current synth and play :dsaw
# with note 60 and opt defaults



# Example 2

synth :fm, note: 60, amp: 0.5



# Play note 60 of the :fm synth with an amplitude of 0.5



# Example 3

use_synth_defaults release: 5
synth :dsaw, note: 50



 
# Play note 50 of the :dsaw synth with a release of 5



# Example 4


synth :dsaw, notes: (chord :e3, :minor)


# You can play chords with the notes: opt:
 



# Example 5


notes = (scale :e3, :minor_pentatonic, num_octaves: 2)

live_loop :rhyth do
  8.times do
    trig = (spread 3, 7).tick(:rhyth)
    synth :tri, on: trig, note: notes.tick, release: 0.1 
                                                         
                                                         
    sleep 0.125
  end
end


live_loop :rhyth2 do
  8.times do
    trig = (spread 3, 7).tick(:rhyth)
    synth :saw, note: notes.tick, release: 0.1 if trig 
                                                       
                                                       
    sleep 0.125
  end
end


# on: vs if
 
 
 
 
 
# Here, we're calling notes.tick
# every time we attempt to play the synth
# so the notes rise faster than rhyth2
 
 
 
 
 
 
 
 
# Here, we're calling notes.tick
# only when the spread says to play
# so the notes rise slower than rhyth
 
 
 




Get all synth names

synth_names  

Return a list of all the synths available

Introduced in v2.9


Increment a tick and return value

tick  key (symbol)

Increment the default tick by 1 and return value. Successive calls to tick will continue to increment the default tick. If a key is specified, increment that specific tick. If an increment value is specified, increment key by that value rather than 1. Ticks are in_thread and live_loop local, so incrementing a tick only affects the current thread’s version of that tick. See tick_reset and tick_set for directly manipulating the tick vals.

Introduced in v2.6

Options

step:

The amount to tick up by. Default is 1.

offset:

Offset to add to index returned. Useful when calling tick on lists, rings and vectors to offset the returned value. Default is 0.

Examples

# Example 1

puts tick
  puts tick
  puts tick
  puts tick



#=> 0
#=> 1
#=> 2
#=> 3



# Example 2

puts tick(:foo)
  puts tick(:foo)
  puts tick(:foo)
  puts tick(:bar)



#=> 0 # named ticks have their own counts
#=> 1
#=> 2
#=> 0 # tick :bar is independent of tick :foo



# Example 3


  live_loop :fast_tick do
    puts tick  
    sleep 2    
  end

  live_loop :slow_tick do
    puts tick  
    sleep 4    
               
               
  end


# Each_live loop has its own separate ticks
 
# the fast_tick live_loop's tick will
# be updated every 2 seconds
 
 
 
# the slow_tick live_loop's tick is
# totally independent from the fast_tick
# live loop and will be updated every 4
# seconds
 



# Example 4

live_loop :regular_tick do
    puts tick  
    sleep 1    
  end

  live_loop :random_reset_tick do
    if one_in 3
      tick_reset
      puts "reset tick!"
    end
    puts tick  
    sleep 1    
               
  end


 
# the regular_tick live_loop's tick will
# be updated every second
 
 
 
# randomly reset tick
 
 
 
# this live_loop's tick is totally
# independent and the reset only affects
# this tick.
 



# Example 5


 
  live_loop :scale do
    play [:c, :d, :e, :f, :g].tick  
    sleep 1
  end


# Ticks work directly on lists, and will tick through each element
# However, once they get to the end, they'll return nil
 
# play all notes just once, then rests
 
 



# Example 6


  live_loop :odd_scale do
    tick 
    play [:c, :d, :e, :f, :g, :a].tick  
                                        
    sleep 1
  end


# Normal ticks interact directly with list ticks
 
# Increment the default tick
# this now play every *other* note just once,
# then rests
 
 



# Example 7


 
 
 
  live_loop :looped_scale do
    play (ring :c, :d, :e, :f, :g).tick  
    sleep 1
  end


# Ticks work wonderfully with rings
# as the ring ensures the tick wraps
# round internally always returning a
# value
 
# play all notes just once, then repeats
 
 



# Example 8


 
  live_loop :looped_scale do
    play (scale :e3, :minor_pentatonic).tick  
    sleep 0.25
  end


# Ticks work wonderfully with scales
# which are also rings
 
# play all notes just once, then repeats
 
 




Reset tick to 0

tick_reset  

Reset default tick to 0. If a key is referenced, set that tick to 0 instead. Same as calling tick_set(0)

Introduced in v2.6

Examples

# Example 1


  tick
  tick
  tick
  puts look
  tick_set 0
  puts look



# increment default tick a few times
 
 
 
#=> 2 (default tick is now 2)
# default tick is now 0
#=> 0 (default tick is now 0



# Example 2


  tick :foo
  tick :foo
  tick :foo
  puts look(:foo)
  tick_set 0
  puts look(:foo)
  tick_set :foo, 0
  puts look(:foo)



# increment tick :foo a few times
 
 
 
#=> 2 (tick :foo is now 2)
# default tick is now 0
#=> 2 (tick :foo is still 2)
#  reset tick :foo
#=> 0 (tick :foo is now 0)




Reset all ticks

tick_reset_all  value (number)

Reset all ticks - default and keyed

Introduced in v2.6

Example

# Example 1

tick     
  tick
  tick :foo
  tick :foo
  tick :foo
  puts look
  puts look(:foo)
  tick_reset_all
  puts look
  puts look(:foo)



# increment default tick and tick :foo
 
 
 
 
#=> 1
#=> 2
 
#=> 0
#=> 0




Set tick to a specific value

tick_set  value (number)

Set the default tick to the specified value. If a key is referenced, set that tick to value instead. Next call to look will return value.

Introduced in v2.6

Examples

# Example 1

tick_set 40
  puts look  



# set default tick to 40
#=> 40



# Example 2

tick_set :foo, 40
  puts look(:foo)  
  puts look        



# set tick :foo to 40
#=> 40 (tick :foo is now 40)
#=> 0 (default tick is unaffected)




Block level comment ignoring

uncomment  

Evaluates all of the code within the block. Use to reverse the effect of the comment without having to explicitly remove it.

Introduced in v2.0

Example

# Example 1

uncomment do
    play 50
    sleep 1
    play 62
  end


# starting a block level comment:
# played
# sleep happens
# played
 




Enable and disable BPM scaling

use_arg_bpm_scaling  bool (boolean)

Turn synth argument bpm scaling on or off for the current thread. This is on by default. Note, using rt for args will result in incorrect times when used after turning arg bpm scaling off.

Introduced in v2.0

Examples

# Example 1

use_bpm 120
play 50, release: 2
sleep 2            
use_arg_bpm_scaling false
play 50, release: 2
sleep 2            



 
# release is actually 1 due to bpm scaling
# actually sleeps for 1 second
 
# release is now 2
# still sleeps for 1 second



# Example 2


use_bpm 120
play 50, release: rt(2)
sleep rt(2)            
use_arg_bpm_scaling false
play 50, release: rt(2)
sleep rt(2)            



# Interaction with rt
 
# release is 2 seconds
# sleeps for 2 seconds
 
# ** Warning: release is NOT 2 seconds! **
# still sleeps for 2 seconds




Enable and disable arg checks

use_arg_checks  true_or_false (boolean)

When triggering synths, each argument is checked to see if it is sensible. When argument checking is enabled and an argument isn’t sensible, you’ll see an error in the debug pane. This setting allows you to explicitly enable and disable the checking mechanism. See with_arg_checks for enabling/disabling argument checking only for a specific do/end block.

Introduced in v2.0

Example

# Example 1

play 50, release: 5
use_arg_checks false
play 50, release: 5



# Args are checked
 
# Args are not checked




Set the tempo

use_bpm  bpm (number)

Sets the tempo in bpm (beats per minute) for everything afterwards. Affects all subsequent calls to sleep and all temporal synth arguments which will be scaled to match the new bpm. If you wish to bypass scaling in calls to sleep, see the fn rt. Also, if you wish to bypass time scaling in synth args see use_arg_bpm_scaling. See also with_bpm for a block scoped version of use_bpm.

For dance music here’s a rough guide for which BPM to aim for depending on your genre:

Introduced in v2.0

Example

# Example 1


  4.times do
    play 50, attack: 0.5, release: 0.25
    sleep 1
  end

  sleep 2 

 
  use_bpm 120 
  4.times do
    play 62, attack: 0.5, release: 0.25
    sleep 1
  end

  sleep 2

 
  use_bpm 240 
  8.times do
    play 62, attack: 0.5, release: 0.25
    sleep 1
  end


# default tempo is 60 bpm
 
# attack is 0.5s and release is 0.25s
# sleep for 1 second
 
 
# sleep for 2 seconds
 
# Let's make it go faster...
# double the bpm
 
# attack is scaled to 0.25s and release is now 0.125s
# actually sleeps for 0.5 seconds
 
 
# sleep for 1 second
 
# Let's make it go even faster...
#  bpm is 4x original speed!
 
# attack is scaled to 0.125s and release is now 0.0625s
# actually sleeps for 0.25 seconds
 




Set new tempo as a multiple of current tempo

use_bpm_mul  mul (number)

Sets the tempo in bpm (beats per minute) as a multiplication of the current tempo. Affects all containing calls to sleep and all temporal synth arguments which will be scaled to match the new bpm. See also use_bpm

Introduced in v2.3

Example

# Example 1

use_bpm 60  
  play 50
  sleep 1     
  play 62
  sleep 2     
  use_bpm_mul 0.5
  play 50
  sleep 1          
  play 62


# Set the BPM to 60
 
# Sleeps for 1 seconds
 
# Sleeps for 2 seconds
# BPM is now (60 * 0.5) == 30
 
# Sleeps for 2 seconds
 




Cent tuning

use_cent_tuning  cent_shift (number)

Uniformly tunes your music by shifting all notes played by the specified number of cents. To shift up by a cent use a cent tuning of 1. To shift down use negative numbers. One semitone consists of 100 cents.

See with_cent_tuning for setting the cent tuning value only for a specific do/end block. To tranpose entire semitones see use_transpose.

Introduced in v2.9

Example

# Example 1

play 50
use_cent_tuning 1
play 50



# Plays note 50
 
# Plays note 50.01




Enable and disable cue logging

use_cue_logging  true_or_false (boolean)

Enable or disable log messages created on cues. This does not disable the cues themselves, it just stops them from being printed to the log

Introduced in v2.6

Examples

# Example 1

use_cue_logging true



# Turn on cue messages



# Example 2

use_cue_logging false



# Disable cue messages




Enable and disable debug

use_debug  true_or_false (boolean)

Enable or disable messages created on synth triggers. If this is set to false, the synths will be silent until debug is turned back on. Silencing debug messages can reduce output noise and also increase performance on slower platforms. See with_debug for setting the debug value only for a specific do/end block.

Introduced in v2.0

Examples

# Example 1

use_debug true



# Turn on debug messages



# Example 2

use_debug false



# Disable debug messages




Merge new sample defaults

use_merged_sample_defaults  

Specify new default values to be used by all subsequent calls to sample. Merges the specified values with any previous defaults, rather than replacing them.

Introduced in v2.9

Example

# Example 1

sample :loop_amen

use_merged_sample_defaults amp: 0.5, cutoff: 70

sample :loop_amen

use_merged_sample_defaults cutoff: 90

sample :loop_amen 



# plays amen break with default arguments
 
 
 
# plays amen break with an amp of 0.5, cutoff of 70 and defaults for rest of args
 
 
 
# plays amen break with a cutoff of 90 and and an amp of 0.5 with defaults for rest of args




Merge synth defaults

use_merged_synth_defaults  

Specify synth arg values to be used by any following call to play. Merges the specified values with any previous defaults, rather than replacing them.

Introduced in v2.0

Examples

# Example 1

play 50

use_merged_synth_defaults amp: 0.5
play 50

use_merged_synth_defaults cutoff: 80
play 50

use_merged_synth_defaults amp: 0.7
play 50



#=> Plays note 50
 
 
#=> Plays note 50 with amp 0.5
 
 
#=> Plays note 50 with amp 0.5 and cutoff 80
 
 
#=> Plays note 50 with amp 0.7 and cutoff 80



# Example 2

use_synth_defaults amp: 0.5, cutoff: 80, pan: -1
use_merged_synth_defaults amp: 0.7
play 50



 
 
#=> Plays note 50 with amp 0.7, cutoff 80 and pan -1




Note octave transposition

use_octave  octave_shift (number)

Transposes your music by shifting all notes played by the specified number of octaves. To shift up by an octave use a transpose of 1. To shift down use negative numbers. See with_octave for setting the octave shift only for a specific do/end block. For transposing the notes within the octave range see use_transpose.

Introduced in v2.9

Examples

# Example 1

play 50
use_octave 1
play 50



# Plays note 50
 
# Plays note 62



# Example 2


play 62
use_octave -1
play 62
use_octave 2
play 62



# You may change the transposition multiple times:
# Plays note 62
 
# Plays note 50
 
# Plays note 86




Set random seed generator to known seed

use_random_seed  seed (number)

Resets the random number generator to the specified seed. All subsequently generated random numbers and randomisation functions such as shuffle and choose will use this new generator and the current generator is discarded. Use this to change the sequence of random numbers in your piece in a way that can be reproduced. Especially useful if combined with iteration. See examples.

Introduced in v2.0

Examples

# Example 1



  use_random_seed 1
  puts rand
  use_random_seed 1
  puts rand 



# Basic usage
 
# reset random seed to 1
# => 0.417022004702574
# reset random seed back to 1
#=> 0.417022004702574



# Example 2


  notes = (scale :eb3, :minor_pentatonic) 
                                          

  with_fx :reverb do
    live_loop :repeating_melody do        

      use_random_seed 300                 
                                          
                                          
                                          
                                          

      8.times do                          
                                          
                                          

        play notes.choose, release: 0.1   
                                          
                                          
                                          
        sleep 0.125
      end
    end
  end


# Generating melodies
# Create a set of notes to choose from.
# Scales work well for this
 
 
# Create a live loop
 
# Set the random seed to a known value every
# time around the loop. This seed is the key
# to our melody. Try changing the number to
# something else. Different numbers produce
# different melodies
 
# Now iterate a number of times. The size of
# the iteration will be the length of the
# repeating melody.
 
# 'Randomly' choose a note from our ring of
# notes. See how this isn't actually random
# but uses a reproducible method! These notes
# are therefore repeated over and over...
 
 
 
 




Sample-duration-based bpm modification

use_sample_bpm  string_or_number (sample_name_or_duration)

Modify bpm so that sleeping for 1 will sleep for the duration of the sample.

Introduced in v2.1

Options

num_beats:

The number of beats within the sample. By default this is 1.

Examples

# Example 1

use_sample_bpm :loop_amen 

live_loop :dnb do
  sample :bass_dnb_f
  sample :loop_amen
  sleep 1                 
end


#Set bpm based on :loop_amen duration
 
 
 
 
#`sleep`ing for 1 actually sleeps for duration of :loop_amen
 



# Example 2

use_sample_bpm :loop_amen, num_beats: 4 
                                        
                                        

live_loop :dnb do
  sample :bass_dnb_f
  sample :loop_amen
  sleep 4                 
                          
                          
end


# Set bpm based on :loop_amen duration
# but also specify that the sample duration
# is actually 4 beats long.
 
 
 
 
#`sleep`ing for 4 actually sleeps for duration of :loop_amen
# as we specified that the sample consisted of
# 4 beats
 




Use new sample defaults

use_sample_defaults  

Specify new default values to be used by all subsequent calls to sample. Will remove and override any previous defaults.

Introduced in v2.5

Example

# Example 1

sample :loop_amen

use_sample_defaults amp: 0.5, cutoff: 70

sample :loop_amen

use_sample_defaults cutoff: 90

sample :loop_amen 



# plays amen break with default arguments
 
 
 
# plays amen break with an amp of 0.5, cutoff of 70 and defaults for rest of args
 
 
 
# plays amen break with a cutoff of 90 and defaults for rest of args - note that amp is no longer 0.5




Use sample pack

use_sample_pack  pack_path (string)

Given a path to a folder of samples on your filesystem, this method makes any .wav, .wave, .aif, .aiff or .flac files in that folder available as samples. Use use_sample_pack :default To revert back to the default built-in samples.

Introduced in v2.0

Example

# Example 1

use_sample_pack '/home/yourname/path/to/sample/dir'
sample :foo 
            
sample :bd_haus
               
use_sample_pack :default
sample :bd_haus



 
#=> plays /home/yourname/path/to/sample/dir/foo.{wav|wave|aif|aiff|flac}
#   where {wav|wave|aif|aiff|flac} means one of wav, wave, aif, aiff or flac.
#=> will not work unless there's a sample in '/home/yourname/path/to/sample/dir'
#   called bd_haus.{wav|wave|aif|aiff|flac}
 
#=> will play the built-in bd_haus.wav sample




Switch current synth

use_synth  synth_name (symbol)

Switch the current synth to synth_name. Affects all further calls to play. See with_synth for changing the current synth only for a specific do/end block.

Introduced in v2.0

Example

# Example 1

play 50
use_synth :mod_sine
play 50



# Plays with default synth
 
# Plays with mod_sine synth




Use new synth defaults

use_synth_defaults  

Specify new default values to be used by all subsequent calls to play. Will remove and override any previous defaults.

Introduced in v2.0

Example

# Example 1

play 50

use_synth_defaults amp: 0.5, cutoff: 70

play 50

use_synth_defaults cutoff: 90

play 50



# plays note 50 with default arguments
 
 
 
# plays note 50 with an amp of 0.5, cutoff of 70 and defaults for rest of args
 
 
 
# plays note 50 with a cutoff of 90 and defaults for rest of args - note that amp is no longer 0.5




Inhibit synth triggers if too late

use_timing_guarantees  bool (true_or_false)

If set to true, synths will not trigger if it is too late. If false, some synth triggers may be late.

Introduced in v2.10

Examples

# Example 1

use_timing_guarantees true

sample :loop_amen 



 
 
#=> if time is behind by any margin, this will not trigger



# Example 2

use_timing_guarantees false

sample :loop_amen 



 
 
#=> unless time is too far behind, this will trigger even when late.




Note transposition

use_transpose  note_shift (number)

Transposes your music by shifting all notes played by the specified amount. To shift up by a semitone use a transpose of 1. To shift down use negative numbers. See with_transpose for setting the transpose value only for a specific do/end block. To transpose entire octaves see use_octave.

Introduced in v2.0

Examples

# Example 1

play 50
use_transpose 1
play 50



# Plays note 50
 
# Plays note 51



# Example 2


play 62
use_transpose -12
play 62
use_transpose 3
play 62



# You may change the transposition multiple times:
# Plays note 62
 
# Plays note 50
 
# Plays note 65




Use alternative tuning systems

use_tuning  tuning (symbol), fundamental_note (symbol_or_number)

In most music we make semitones by dividing the octave into 12 equal parts, which is known as equal temperament. However there are lots of other ways to tune the 12 notes. This method adjusts each midi note into the specified tuning system. Because the ratios between notes aren’t always equal, be careful to pick a centre note that is in the key of the music you’re making for the best sound. Currently available tunings are :just, :pythagorean, :meantone and the default of :equal

Introduced in v2.6

Examples

# Example 1

play :e4
use_tuning :just, :c
play :e4

play 64



# Plays note 64
 
# Plays note 63.8631
# transparently changes midi notes too
# Plays note 63.8631



# Example 2


play 64
use_tuning :just
play 64
use_tuning :equal
play 64



# You may change the tuning multiple times:
# Plays note 64
 
# Plays note 63.8631
 
# Plays note 64




Create a vector

vector  list (array)

Create a new immutable vector from args. Out of range indexes return nil.

Introduced in v2.6

Examples

# Example 1

(vector 1, 2, 3)[0]



#=> 1



# Example 2

(vector 1, 2, 3)[1]



#=> 2



# Example 3

(vector 1, 2, 3)[2]



#=> 3



# Example 4

(vector 1, 2, 3)[3]



#=> nil



# Example 5

(vector 1, 2, 3)[1000]



#=> nil



# Example 6

(vector 1, 2, 3)[-1]



#=> nil



# Example 7

(vector 1, 2, 3)[-1000]



#=> nil




Get current version information

version  

Return information representing the current version of Sonic Pi. This information may be further inspected with version.major, version.minor, version.patch and version.dev

Introduced in v2.0

Examples

# Example 1

puts version



# => Prints out the current version such as v2.0.1



# Example 2

puts version.major



# => Prints out the major version number such as 2



# Example 3

puts version.minor



# => Prints out the minor version number such as 0



# Example 4

puts version.patch



# => Prints out the patch level for this version such as 0




Get virtual time

vt  

Get the virtual time of the current thread.

Introduced in v2.1

Example

# Example 1

puts vt
   sleep 1
   puts vt



# prints 0
 
# prints 1




Wait for duration

wait  beats (number)

Synonym for sleep - see sleep

Introduced in v2.0


Block-level enable and disable BPM scaling

with_arg_bpm_scaling  

Turn synth argument bpm scaling on or off for the supplied block. Note, using rt for args will result in incorrect times when used within this block.

Introduced in v2.0

Examples

# Example 1

use_bpm 120
play 50, release: 2
with_arg_bpm_scaling false do
  play 50, release: 2
end


 
# release is actually 1 due to bpm scaling
 
# release is now 2
 



# Example 2


use_bpm 120
play 50, release: rt(2)  
sleep rt(2)              
with_arg_bpm_scaling false do
  play 50, release: rt(2)
  sleep rt(2)            
end


# Interaction with rt
 
# release is 2 seconds
# sleeps for 2 seconds
 
# ** Warning: release is NOT 2 seconds! **
# still sleeps for 2 seconds
 




Block-level enable and disable arg checks

with_arg_checks  true_or_false (boolean)

Similar to use_arg_checks except only applies to code within supplied do/end block. Previous arg check value is restored after block.

Introduced in v2.0

Example

# Example 1


use_arg_checks true

play 80, cutoff: 100

with_arg_checks false do
 
  play 50, release: 3
  sleep 1
  play 72            
end


play 90



# Turn on arg checking:
 
 
# Args are checked
 
 
#Arg checking is now disabled
# Args are not checked
 
# Arg is not checked
 
 
# Arg checking is re-enabled
# Args are checked




Set the tempo for the code block

with_bpm  bpm (number)

Sets the tempo in bpm (beats per minute) for everything in the given block. Affects all containing calls to sleep and all temporal synth arguments which will be scaled to match the new bpm. See also use_bpm

For dance music here’s a rough guide for which BPM to aim for depending on your genre:

Introduced in v2.0

Example

# Example 1


  4.times do
    sample :drum_bass_hard
    sleep 1
  end

  sleep 5

 
 
  with_bpm 120 do 
    4.times do
      sample :drum_bass_hard
      sleep 1
    end
  end

  sleep 5

 
  4.times do
    sample :drum_bass_hard
    sleep 1
  end


# default tempo is 60 bpm
 
 
# sleeps for 1 second
 
 
# sleeps for 5 seconds
 
# with_bpm sets a tempo for everything between do ... end (a block)
# Hear how it gets faster?
# set bpm to be twice as fast
 
 
# now sleeps for 0.5 seconds
 
 
 
 
 
# bpm goes back to normal
 
 
# sleeps for 1 second
 




Set new tempo as a multiple of current tempo for block

with_bpm_mul  mul (number)

Sets the tempo in bpm (beats per minute) for everything in the given block as a multiplication of the current tempo. Affects all containing calls to sleep and all temporal synth arguments which will be scaled to match the new bpm. See also with_bpm

Introduced in v2.3

Example

# Example 1

use_bpm 60  
  play 50
  sleep 1     
  play 62
  sleep 2     
  with_bpm_mul 0.5 do
    play 50
    sleep 1          
    play 62
  end
  sleep 1           



# Set the BPM to 60
 
# Sleeps for 1 second
 
# Sleeps for 2 seconds
# BPM is now (60 * 0.5) == 30
 
# Sleeps for 2 seconds
 
 
# BPM is now back to 60, therefore sleep is 1 second




Block-level cent tuning

with_cent_tuning  cent_shift (number)

Similar to use_cent_tuning except only applies cent shift to code within supplied do/end block. Previous cent tuning value is restored after block. One semitone consists of 100 cents. To tranpose entire semitones see with_transpose.

Introduced in v2.9

Example

# Example 1

use_cent_tuning 1
play 50

with_cent_tuning 2 do
  play 50
end


play 50



 
# Plays note 50.01
 
 
# Plays note 50.02
 
 
# Original cent tuning value is restored
# Plays note 50.01




Block-level enable and disable cue logging

with_cue_logging  true_or_false (boolean)

Similar to use_cue_logging except only applies to code within supplied do/end block. Previous cue log value is restored after block.

Introduced in v2.6

Example

# Example 1


  use_cue_logging true

  cue :foo

  with_cue_logging false do
   
    cue :bar
  end
  sleep 1
 
  cue :quux



# Turn on debugging:
 
 
# cue message is printed to log
 
 
#Cue logging is now disabled
# cue *is* sent but not displayed in log
 
 
# Debug is re-enabled
# cue is displayed in log




Block-level enable and disable debug

with_debug  true_or_false (boolean)

Similar to use_debug except only applies to code within supplied do/end block. Previous debug value is restored after block.

Introduced in v2.0

Example

# Example 1


use_debug true

play 80

with_debug false do
 
  play 50
  sleep 1
  play 72
end


play 90



# Turn on debugging:
 
 
# Debug message is sent
 
 
#Debug is now disabled
# Debug message is not sent
 
# Debug message is not sent
 
 
# Debug is re-enabled
# Debug message is sent




Use Studio FX

with_fx  fx_name (symbol)

This applies the named effect (FX) to everything within a given do/end block. Effects may take extra parameters to modify their behaviour. See FX help for parameter details.

For advanced control, it is also possible to modify the parameters of an effect within the body of the block. If you define the block with a single argument, the argument becomes a reference to the current effect and can be used to control its parameters (see examples).

Introduced in v2.0

Options

reps:

Number of times to repeat the block in an iteration.

kill_delay:

Amount of time to wait after all synths triggered by the block have completed before stopping and freeing the effect synthesiser.

Examples

# Example 1


with_fx :distortion do
  play 50
  sleep 1
  sample :loop_amen
end


# Basic usage
# Use the distortion effect with default parameters
# => plays note 50 with distortion
 
# => plays the loop_amen sample with distortion too
 



# Example 2


with_fx :level, amp: 0.3 do
  play 50
  sleep 1
  sample :loop_amen
end


# Specify effect parameters
# Use the level effect with the amp parameter set to 0.3
 
 
 
 



# Example 3


with_fx :reverb, mix: 0.1 do |fx|
 
 

  play 60
  sleep 2

  control fx, mix: 0.5
  play 60
  sleep 2

  control fx, mix: 1
  play 60
  sleep 2
end


# Controlling the effect parameters within the block
 
# here we set the reverb level quite low to start with (0.1)
# and we can change it later by using the 'fx' reference we've set up
 
# plays note 60 with a little bit of reverb
 
 
# change the parameters of the effect to add more reverb
# again note 60 but with more reverb
 
 
# change the parameters of the effect to add more reverb
# plays note 60 with loads of reverb
 
 



# Example 4


with_fx :reverb, reps: 16 do
  play (scale :e3, :minor_pentatonic), release: 0.1
  sleep 0.125
end


with_fx :reverb do
  16.times do
    play (scale :e3, :minor_pentatonic), release: 0.1
    sleep 0.125
  end
end


# Repeat the block 16 times internally
 
 
 
 
 
# The above is a shorthand for this:
 
 
 
 
 
 




Block-level use merged sample defaults

with_merged_sample_defaults  

Specify new default values to be used by all subsequent calls to sample within the do/end block. Merges the specified values with any previous sample defaults, rather than replacing them. After the do/end block has completed, the previous sampled defaults (if any) are restored.

Introduced in v2.9

Example

# Example 1

sample :loop_amen

use_merged_sample_defaults amp: 0.5, cutoff: 70

sample :loop_amen

with_merged_sample_defaults cutoff: 90 do
  sample :loop_amen 
end

sample :loop_amen 



# plays amen break with default arguments
 
 
 
# plays amen break with an amp of 0.5, cutoff of 70 and defaults for rest of args
 
 
# plays amen break with a cutoff of 90 and amp of 0.5
 
 
# plays amen break with a cutoff of 70 and amp is 0.5 again as the previous defaults are restored.




Block-level merge synth defaults

with_merged_synth_defaults  

Specify synth arg values to be used by any following call to play within the specified do/end block. Merges the specified values with any previous synth defaults, rather than replacing them. After the do/end block has completed, previous defaults (if any) are restored.

Introduced in v2.0

Examples

# Example 1

with_merged_synth_defaults amp: 0.5, pan: 1 do
  play 50
end


 
# => plays note 50 with amp 0.5 and pan 1
 



# Example 2

play 50
with_merged_synth_defaults amp: 0.5 do
  play 50

  with_merged_synth_defaults pan: -1 do
    with_merged_synth_defaults amp: 0.7 do
      play 50
    end
  end
  play 50
end


#=> plays note 50
 
#=> plays note 50 with amp 0.5
 
 
 
#=> plays note 50 with amp 0.7 and pan -1
 
 
#=> plays note 50 with amp 0.5
 




Block level octave transposition

with_octave  octave_shift (number)

Transposes your music by shifting all notes played by the specified number of octaves within the specified block. To shift up by an octave use a transpose of 1. To shift down use negative numbers. For transposing the notes within the octave range see with_transpose.

Introduced in v2.9

Example

# Example 1

play 50
sleep 1
with_octave 1 do
 play 50
end
sleep 1
play 50



# Plays note 50
 
 
# Plays note 62
 
 
# Plays note 50




Specify random seed for code block

with_random_seed  seed (number)

Resets the random number generator to the specified seed for the specified code block. All generated random numbers and randomisation functions such as shuffle and choose within the code block will use this new generator. Once the code block has completed, the original generator is restored and the code block generator is discarded. Use this to change the sequence of random numbers in your piece in a way that can be reproduced. Especially useful if combined with iteration. See examples.

Introduced in v2.0

Examples

# Example 1

use_random_seed 1
  puts rand
  puts rand 
  use_random_seed 1
  puts rand
  with_random_seed 1 do
    puts rand
    puts rand
  end
  puts rand
           



# reset random seed to 1
# => 0.417022004702574
#=> 0.7203244934421581
# reset it back to 1
# => 0.417022004702574
# reset seed back to 1 just for this block
# => 0.417022004702574
#=> 0.7203244934421581
 
# => 0.7203244934421581
# notice how the original generator is restored



# Example 2


  notes = (scale :eb3, :minor_pentatonic, num_octaves: 2) 
                                          

  with_fx :reverb do
    live_loop :repeating_melody do        

      with_random_seed 300 do             
                                          
                                          
                                          
                                          

        8.times do                        
                                          
                                          

          play notes.choose, release: 0.1 
                                          
                                          
                                          
          sleep 0.125
        end
      end

      play notes.choose, amp: 1.5, release: 0.5
                                               
                                               
                                               
    end
  end


# Generating melodies
# Create a set of notes to choose from.
# Scales work well for this
 
 
# Create a live loop
 
# Set the random seed to a known value every
# time around the loop. This seed is the key
# to our melody. Try changing the number to
# something else. Different numbers produce
# different melodies
 
# Now iterate a number of times. The size of
# the iteration will be the length of the
# repeating melody.
 
# 'Randomly' choose a note from our ring of
# notes. See how this isn't actually random
# but uses a reproducible method! These notes
# are therefore repeated over and over...
 
 
 
 
# Note that this line is outside of
# the with_random_seed block and therefore
# the randomisation never gets reset and this
# part of the melody never repeats.
 
 




Block-scoped sample-duration-based bpm modification

with_sample_bpm  string_or_number (sample_name_or_duration)

Block-scoped modification of bpm so that sleeping for 1 will sleep for the duration of the sample.

Introduced in v2.1

Options

num_beats:

The number of beats within the sample. By default this is 1.

Examples

# Example 1

live_loop :dnb do
  with_sample_bpm :loop_amen do
    sample :bass_dnb_f
    sample :loop_amen
    sleep 1                    
  end
end


 
#Set bpm based on :loop_amen duration
 
 
#`sleep`ing for 1 sleeps for duration of :loop_amen
 
 



# Example 2

live_loop :dnb do
  with_sample_bpm :loop_amen, num_beats: 4 do
                                             
                                             
    sample :bass_dnb_f
    sample :loop_amen
    sleep 4                    
                               
                               
  end
end


 
# Set bpm based on :loop_amen duration
# but also specify that the sample duration
# is actually 4 beats long.
 
 
#`sleep`ing for 4 sleeps for duration of :loop_amen
# as we specified that the sample consisted of
# 4 beats
 
 




Block-level use new sample defaults

with_sample_defaults  

Specify new default values to be used by all subsequent calls to sample within the do/end block. After the do/end block has completed, the previous sampled defaults (if any) are restored. For the contents of the block, will remove and override any previous defaults.

Introduced in v2.5

Example

# Example 1

sample :loop_amen

use_sample_defaults amp: 0.5, cutoff: 70

sample :loop_amen

with_sample_defaults cutoff: 90 do
  sample :loop_amen 
end

sample :loop_amen 



# plays amen break with default arguments
 
 
 
# plays amen break with an amp of 0.5, cutoff of 70 and defaults for rest of args
 
 
# plays amen break with a cutoff of 90 and defaults for rest of args - note that amp is no longer 0.5
 
 
# plays amen break with a cutoff of 70 and amp is 0.5 again as the previous defaults are restored.




Block-level use sample pack

with_sample_pack  pack_path (string)

Given a path to a folder of samples on your filesystem, this method makes any .wav, .wave, .aif, .aiff or .flac files in that folder available as samples inside the given block.

Introduced in v2.0

Example

# Example 1

with_sample_pack '/path/to/sample/dir' do
  sample :foo 
end


 
#=> plays /path/to/sample/dir/foo.{wav|wave|aif|aiff|flac}
 




Block-level synth switching

with_synth  synth_name (symbol)

Switch the current synth to synth_name but only for the duration of the do/end block. After the do/end block has completed, the previous synth is restored.

Introduced in v2.0

Example

# Example 1

play 50
sleep 2
use_synth :supersaw
play 50
sleep 2
with_synth :saw_beep do
  play 50
end
sleep 2

play 50



# Plays with default synth
 
 
# Plays with supersaw synth
 
 
# Plays with saw_beep synth
 
 
# Previous synth is restored
# Plays with supersaw synth




Block-level use new synth defaults

with_synth_defaults  

Specify new default values to be used by all calls to play within the do/end block. After the do/end block has completed the previous synth defaults (if any) are restored.

Introduced in v2.0

Example

# Example 1

play 50

use_synth_defaults amp: 0.5, pan: -1

play 50

with_synth_defaults amp: 0.6, cutoff: 80 do
  play 50
end

play 60



# plays note 50 with default arguments
 
 
 
# plays note 50 with an amp of 0.5, pan of -1 and defaults for rest of args
 
 
# plays note 50 with an amp of 0.6, cutoff of 80 and defaults for rest of args (including pan)
 
 
# plays note 60 with an amp of 0.5, pan of -1 and defaults for rest of args




Block-scoped inhibition of synth triggers if too late

with_timing_guarantees  bool (true_or_false)

For the given block, if set to true, synths will not trigger if it is too late. If false, some synth triggers may be late. After the block has completed, the previous value is restored.

Introduced in v2.10

Examples

# Example 1

with_timing_guarantees true
  sample :loop_amen 
end


 
#=> if time is behind by any margin, this will not trigger
 



# Example 2

with_timing_guarantees false
  sample :loop_amen 
end


 
#=> unless time is too far behind, this will trigger even when late.
 




Block-level note transposition

with_transpose  note_shift (number)

Similar to use_transpose except only applies to code within supplied do/end block. Previous transpose value is restored after block. To transpose entire octaves see with_octave.

Introduced in v2.0

Example

# Example 1

use_transpose 3
play 62

with_transpose 12 do
  play 50
  sleep 1
  play 72
end


play 80



 
# Plays note 65
 
 
# Plays note 62
 
# Plays note 84
 
 
# Original transpose value is restored
# Plays note 83




Block-level tuning modification

with_tuning  tuning (symbol), fundamental_note (symbol_or_number)

Similar to use_tuning except only applies to code within supplied do/end block. Previous tuning value is restored after block.

Introduced in v2.6

Example

# Example 1

use_tuning :equal, :c
play :e4
with_tuning :just, :c do
  play :e4
  sleep 1
  play :c4
end

play :e4



 
# Plays note 64
 
# Plays note 63.8631
 
# Plays note 60
 
# Original tuning value is restored
# Plays note 64