# Configurable arpeggiator

**URL:** <https://in-thread.sonic-pi.net/t/configurable-arpeggiator/7406>\
**Category:** Creations & Ideas\
**Created:** [January 1, 2023, 6:26pm UTC](https://in-thread.sonic-pi.net/t/configurable-arpeggiator/7406 "2023-01-01T18:26:33Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![rothen\_s](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/rothen_s/32/3051_2.png) [@rothen\_s](https://in-thread.sonic-pi.net/u/rothen_s)\
**Post date:** [January 1, 2023, 6:26pm UTC](https://in-thread.sonic-pi.net/t/configurable-arpeggiator/7406/1 "2023-01-01T18:26:34Z")

</div>

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

```ruby
# 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)

```

---

<div class="post-metadata">

**Author:** ![rothen\_s](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/rothen_s/32/3051_2.png) [@rothen\_s](https://in-thread.sonic-pi.net/u/rothen_s)\
**Post date:** [January 1, 2023, 8:32pm UTC](https://in-thread.sonic-pi.net/t/configurable-arpeggiator/7406/2 "2023-01-01T20:32:04Z")

</div>

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](https://on.soundcloud.com/7omqx)

---

<div class="post-metadata">

**Author:** ![robin.newman](https://avatars.discourse-cdn.com/v4/letter/r/76d3ee/32.png) [@robin.newman](https://in-thread.sonic-pi.net/u/robin.newman)\
**Post date:** [January 2, 2023, 11:41am UTC](https://in-thread.sonic-pi.net/t/configurable-arpeggiator/7406/3 "2023-01-02T11:41:14Z")

</div>

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

```ruby
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)

```ruby
#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.

---

<div class="post-metadata">

**Author:** ![rothen\_s](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/rothen_s/32/3051_2.png) [@rothen\_s](https://in-thread.sonic-pi.net/u/rothen_s)\
**Post date:** [January 2, 2023, 1:43pm UTC](https://in-thread.sonic-pi.net/t/configurable-arpeggiator/7406/4 "2023-01-02T13:43:46Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Doffu](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/doffu/32/2044_2.png) [@Doffu](https://in-thread.sonic-pi.net/u/Doffu)\
**Post date:** [February 21, 2023, 6:23pm UTC](https://in-thread.sonic-pi.net/t/configurable-arpeggiator/7406/5 "2023-02-21T18:23:32Z")

</div>

> [@robin.newman](#):
>
> defined chord names in Sonic Pi

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.

---

<div class="post-metadata">

**Author:** ![robin.newman](https://avatars.discourse-cdn.com/v4/letter/r/76d3ee/32.png) [@robin.newman](https://in-thread.sonic-pi.net/u/robin.newman)\
**Post date:** [February 21, 2023, 6:42pm UTC](https://in-thread.sonic-pi.net/t/configurable-arpeggiator/7406/6 "2023-02-21T18:42:53Z")

</div>

`puts chord_names` should do it

---

<div class="post-metadata">

**Author:** ![rothen\_s](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/rothen_s/32/3051_2.png) [@rothen\_s](https://in-thread.sonic-pi.net/u/rothen_s)\
**Post date:** [February 21, 2023, 6:43pm UTC](https://in-thread.sonic-pi.net/t/configurable-arpeggiator/7406/7 "2023-02-21T18:43:49Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Doffu](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/doffu/32/2044_2.png) [@Doffu](https://in-thread.sonic-pi.net/u/Doffu)\
**Post date:** [February 21, 2023, 7:50pm UTC](https://in-thread.sonic-pi.net/t/configurable-arpeggiator/7406/8 "2023-02-21T19:50:47Z")

</div>

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!
