# Configurable arpeggiator

Just made an arpeggiator method, which generates configurable arpeggios. It is also a nice example of a method with named parameters:

``````# p_tonic tonic of the chord
# p_name name of the chord
# p_length number of different pitches in the arpeggio
# p_invert inversion of the chord: 0, 1 or 2
# p_sleep number of beats for the arpeggio
# p_type: 0 ascending, 1 descending, 2 hill 3 valley
# p_random number of additional notes from 0 to 3 -> .shuffle gives a random selection
# p_has_basenote shall the base note be played (true or false)
def m_play_arpeggio(p_tonic: 60, p_name: :maj, p_length: 3, p_invert: 0, p_sleep: 2,
p_type: 0, p_random: 0, p_has_basenote: false, p_has_droplastnote: true)
# damit sich die Zufallswerte nicht wiederholen
use_random_seed Time.new.to_i

# Chord definieren
l_chord = (chord p_tonic, p_name, num_octaves: 4)

# Inversion
l_chord = l_chord.drop(p_invert)

l_basenote = l_chord.take(1) - 12
print l_basenote

# Wir holen aus jedem beliebigen Chord diese Anzahl Noten + p_random
l_chord = l_chord.take(p_length + p_random)
print l_chord.notes

# Jetzt mischeln wir diese, nehmen die ersten gemĂ¤ss Anzahl und Sortieren
l_chord = l_chord.shuffle.take(p_length).sort
print l_chord.notes

if p_type == 1 # absteigend
l_chord = l_chord.reverse
else
if p_type == 2 # auf- dann absteigend
# Mit .reflect hĂ¤ngen wir die Noten absteigend an
l_chord = l_chord.reflect
else
if p_type == 3 # ab- dann aufsteigend
l_chord = l_chord.reverse.reflect
end
end
end

# jetzt eventuell noch die letzte Note entfernen
if p_has_droplastnote == true && p_type > 1
l_chord = l_chord.drop_last(1)
end

print l_chord.notes
p_length_arp = l_chord.length

# spiele einen Grundton
if p_has_basenote
play l_basenote, sustain: p_sleep
end

l_chord.each do |p_note|
play p_note
sleep p_sleep * 1.0 / p_length_arp
end

end

use_synth :tri

m_play_arpeggio(p_name: :min, p_length: 4, p_type: 3, p_has_basenote: false)
sleep 0.25
m_play_arpeggio(p_name: :min, p_length: 5, p_invert: 1, p_sleep: 1)
sleep 0.25
m_play_arpeggio(p_name: :min, p_length: 6, p_invert: 2, p_type: 1)
sleep 0.25
m_play_arpeggio(p_name: :min, p_length: 6, p_type: 2)
``````
1 Like

In the meantime I tweaked my arpeggiator, inserted another parameter and some lines of code. Now I can change between the internal Sonic Pi sound and external midi, for example an external software synthesizer like SurgeXT. I just recorded an mp3 file and published it on SoundCloud:
https://on.soundcloud.com/7omqx

This function is very versatile. I have had fun playing with it.
One thing I did ws to alter to to use standard Sonic Pi

``````define :name do.|parameter list|
...
end

#rather than Ruby's
def :name(paramter list)
...
end
``````

I used the code below to cycle through all the defined chord names in Sonic Pi assigning varying parameters. Ended up with a rather mesmerising driving output. Other features spread the played arpeggios across the L-R spectrum. (Use phones to hear this better)

``````#perpetual meandering arpeggios based on Silvia Rothen's (@rothen_s) m_play+arpeggio code
#by Robin Newman Jan 2023

use_debug false
# p_tonic tonic of the chord
# p_name name of the chord
# p_length number of different pitches in the arpeggio
# p_invert inversion of the chord: 0, 1 or 2
# p_sleep number of beats for the arpeggio
# p_type: 0 ascending, 1 descending, 2 hill 3 valley
# p_random number of additional notes from 0 to 3 -> .shuffle gives a random selection
# p_has_basenote shall the base note be played (true or false)
# I changed the definition of m_play_arpeggio to standard Sonic Pi define.... do..end rather than def
define :m_play_arpeggio do |p_tonic: 60, p_name: :maj, p_length: 3, p_invert: 0, p_sleep: 2,
p_type: 0, p_random: 0, p_has_basenote: false, p_has_droplastnote: true|
# damit sich die Zufallswerte nicht wiederholen
use_random_seed Time.new.to_i

# Chord definieren
l_chord = (chord p_tonic, p_name, num_octaves: 4)

# Inversion
l_chord = l_chord.drop(p_invert)

l_basenote = l_chord.take(1) - 24 #bass note down two octaves
print "bassnote",l_basenote.to_a

# Wir holen aus jedem beliebigen Chord diese Anzahl Noten + p_random
l_chord = l_chord.take(p_length + p_random)
print "chordnotes",l_chord.notes

# Jetzt mischeln wir diese, nehmen die ersten gemĂ¤ss Anzahl und Sortieren
l_chord = l_chord.shuffle.take(p_length).sort
print "chord notes sorted",l_chord.notes

if p_type == 1 # absteigend
l_chord = l_chord.reverse
else
if p_type == 2 # auf- dann absteigend
# Mit .reflect hĂ¤ngen wir die Noten absteigend an
l_chord = l_chord.reflect
else
if p_type == 3 # ab- dann aufsteigend
l_chord = l_chord.reverse.reflect
end
end
end

# jetzt eventuell noch die letzte Note entfernen
if p_has_droplastnote == true && p_type > 1
l_chord = l_chord.drop_last(1)
end

print "Playing",l_chord.notes
p_length_arp = l_chord.length

# spiele einen Grundton
if p_has_basenote
play l_basenote, sustain: p_sleep,amp: 1
end

l_chord.each do |p_note|
play p_note,cutoff: 100,pan: rrand_i(-1,1)
sleep p_sleep * 1.0 / p_length_arp
end
end

with_fx :reverb, room: 0.7,mix: 0.7 do
live_loop :arps do
#change the synth each pass
syn = [:tb303,:pulse,:dsaw].tick(:sn)
use_synth syn
chord_names.length.times do #utilise all defined chord names in Sonic Pi
cn= chord_names.shuffle.tick #shuffle the order
if tick%5==0 #every 5 arpeggios changes transpose root note
use_transpose [0,5,7,-5].tick(:tr)
end

cl=chord(cn).length #number of notes in current chord

density dice(2) do #repeat some twice, twice as fast
puts cn,cl #print currentt chord aond length
m_play_arpeggio(p_name: cn,p_length: cl, p_invert: 0 , p_sleep: 1,
p_type: (rrand_i(0,3)), p_random: (rrand_i(0,3)), p_has_basenote: true, p_has_droplastnote: true)
sample :drum_tom_hi_hard,amp: 1
end
end
end
end
``````

Try altering the tempo slower or faster using the metronome.

Try also setting the p_has_basenote: parameter to false and commenting out the sample :drum_tom_hi_hard,amp: 1 line to just heard aprpeggio notes.

2 Likes

Hi Robin
Just tried out your code. I like it!

1 Like

Do you know if there is a list of all the defined chord names somewhere. I tried searching in the Sonic Pi tutorial documentations but didnâ€™t see it there.

`puts chord_names` should do it

Hi Doffu
I found the chords in the Sonic Pi itself: Thereâ€™s a file chord.rb, which can be opened with every text editor. In Windows I found it in the directory â€¦\Sonic Pi\app\server\ruby\lib\sonicpi. In this file you find all chords and the intervals. If you need other chords, you can hack them in. I did this because I needed some jazz chords.
Greetings
Silvia

1 Like

Awesome! Thank you. Especially good to know that I can populate it with my own chords. I like working with chordiods rather than chords in a lot of cases, so this will come in handy!