Basic question about arpeggios

Hi, Im new to sonic Pi and I have a musician background but not a coding background so I am struggling on how to do some simple things. Right now I would like to know how would I write a live loop of arpeggios that goes with the next sequence of chords. I have been trying multiple ways but I cant seem to find the correct way.

live_loop :keys do
use_synth :dtri
play [(chord :c3, :major), (chord :g3, :major), (chord :a3, :minor)].ring.tick, release: 2, attack: 0.4
sleep 2
end
end

Hi Ttecero,

Welcome to the forums.

There are so many ways to code arps that I think it would be
more useful to you if I just tidied up your code a little, rather
than confuse you with lots of other code.

I think this is what you were trying to do?

Eli…

live_loop :keys do
  use_synth :dtri
  play (ring (chord :c3, :major), (chord :g3, :major), (chord :a3, :minor)).tick, release: 2, attack: 0.4
  sleep 2
end

Hi Eli, thank you very much for your response. I just tried using the code you gave me but I didnt get the result I am looking for. Sorry for not being clear about my intention in the first post. The code i posted is like a layer of chords, what I want to do is place another layer which is indeed the same chords but with the notes of each chord getting played one after another in the correct timing of the first loop. If you could help me out with this it would be of great help, thanks

Hi,

Yeah, I’m afraid I dont see what you are asking, as I’m not a musical
person.

Lets wait a little while, there are plenty of people who will see what you
are after, and post code… thats one of the many nice things about this
forum.

Eli…

Hi ttercero. I’ll take a look at this later on this evening and get back to you.

Hi Eli and Robin. Thanks for your responses. I know this would be the code for the arpeggio of the first chord on the chord sequence

live_loop :keys5 do
play chord(:c3, :major).tick
sleep 0.25
end

What I would like to know if there a simpler way of writing a code that goes trough the arpeggios of each chord and synced with it without having to write a whole bunch of "play chord(:c3, :major).tick " one after another. That is what I am trying to figure out. Thank you very much for your help.

Hi @ttercero,

maybe not exactly what you are looking for, but very worthwhile to play with and analyse in terms of logic and efficient use of code:

The included example “Chord Inventions”:

# Coded by Adrian Cheater

# (in a single tweet)
# https://twitter.com/wpgFactoid/status/666692596605976576

[1, 3, 6, 4].each do |d|
  (range -3, 3).each do |i|
    play_chord (chord_degree d, :c, :major, 3, invert: i)
    sleep 0.25
  end
end
1 Like

Hi @Martin, i just tried the code and indeed it is not exactly what I am looking for but it does work the way I would like some stuff im thinking about to work. It does sound great and I do understand whats happening when you play the code but could you get me through to help me understand what this line is doing “(range -3, 3).each do |i|”

Hi @ttercero,

these are two nested loops, which makes the thing a bit tricky. I’d recommend to simplify to get to the bottom of it; let me give some suggestions:

puts (range -3, 3) # what is this returning?

You will probably have guessed that each takes each item of the list before (so range returns a list of items resp. numbers) and the parameter |i| (exactly as |d|) is a kind of door through which each list item gets entry into the loop, meaning it does some change every new loop run.

EDIT: Actually each does not take each item but counts the list items; so if the list - like here - contains 6 items each means: 6.times. The parameter |i| takes care of the fact that the list items itself can be used within the loop.

Having that in mind the following changes might shed some light on what is going on in the inner loop:

[1, 3, 6, 4].each do |d|
  (ring 0).each do |i| # give the list just one value
    play_chord (chord_degree d, :c, :major, 3, invert: i)
    puts "d -> #{d}" # some additional help
    puts "i -> #{i}"
    sleep 0.25
  end
  sleep 1 # more time between each run of the outer loop
end 

To understand I have to take some time, simplify and think about what exactly is going on because abstract processes like e. g. two nested loops somehow tend to escape my understanding :wink: . But mostly it is fun for me to take the time and solve the riddle.

Still not sure if its exactly what you want, but I played around with the example Martin gave (which I remember thinking was very cool at the time that it was first posted) and came up with this to do some chord progressions for you.

use_synth :dtri
define :ch do |note,type,dur=0.25|
  use_synth_defaults detune: 0.01 #play with the detune parameter
  play note,sustain: dur*8*0.9,release: dur*4*0.1
  
  [0,1,2,3,3,2,1,0].each do |i| #change to [0,1,2,3,3,2,1,0].shuffle.each
    #next line try type,2 as well as type,3
    play_chord (chord_degree 1, note, type, 3, invert: i),sustain: dur*0.9,release: dur*0.1
    sleep dur
  end
  
end
live_loop :progressions do
  d=0.4 #arpeggio note duration
  plist=[:c3,:g3,:a3,:e3,:f3,:c3,:g3,:g2]
  typelist=[:major,:major,:minor,:minor,:major,:major,:major,:major,:major]
  plist.zip(typelist).each do |p,type|
    ch(p,type,d)
  end
end

This was fun to do. There are so many tweaks you can do to vary the sound the tempo the number of notes playing etc.

1 Like

Hi Robin, sorry for the late response. That indeed is a very cool way of handling arpeggios. Thank you very much for taking the time to help me sort this out. Its been fun watching your solutions, thanks a lot, cheers