Transpose a measure in an array

n = [:d, :g,:g,:a,:g,:f, :e,:e,:e, :g,:g,:a,:g,:f] #notes
d = [1, 1,0.5,0.5,0.5,0.5, 1,1,1, 1,0.5,0.5,0.5,0.5] #duration

now I want to transpose this part [:e,:e,:e] to [:f,:f:f] inside the array n.

This is what I mean:
n = [:d, :g,:g,:a,:g,:f, :e,:e,:e, :g,:g,:a,:g,:f , (:e,:e,:e) + 1] #notes
d = [1, 1,0.5,0.5,0.5,0.5, 1,1,1, 1,0.5,0.5,0.5,0.5, 1,1,1] #duration

What is the correct syntax for this.

Hi @vinodv,

I’m not quite sure what you’re trying to do here still.
In what situation are you trying to use this code?

  • Is it just a static composition, where you just hit run and leave it at that? (eg you are not trying to manipulate the code on the fly once it is running?)
  • What other kind of code do you plan on using to play this sequence of notes and note lengths? does this ‘other code’ need to also manipulate the pattern, or just play it exactly as is?

(Ie, I guess what I’m also asking is - what is it about your code that you might need something more than just this):

n = [:d, :g,:g,:a,:g,:f, :e,:e,:e, :g,:g,:a,:g,:f, :f, :f, :f] #notes
d = [1, 1,0.5,0.5,0.5,0.5, 1,1,1, 1,0.5,0.5,0.5,0.5, 1,1,1] #duration


You can test for the note is a E and the add 1 before playing it. But it is quite not clear what is your goals :grinning:

Suppose that some four continuous measures of a melody is identical except that they are transpose to each other. I need not type the second set of continuous measures again right. This is my goal.

One of the simplest ways might be to use one of the built-in commands that do what you are interested in: use_transpose/with_transpose.

  • use_transpose X tells Sonic Pi that all following code in the same thread/live_loop is transposed by X amount.
  • with_transpose X do... end tells Sonic Pi that all code inside the with_transpose block is transposed by X amount.

(There are examples in the app Help window (in the Lang section) for those functions) :slight_smile:

1 Like

Another alternative: if you store the notes and durations as rings, once you have split the notes and durations into groups (the bits that repeat/are the same, and the bits that don’t repeat/aren’t the same) - you can just do things like add rings together, and use the ring helper functions (such as .repeat) to chain other bits and pieces of the melody together. The helper functions are useful for exactly that, creating new rings from existing ones.

@vinodv try this

use_synth :piano
use_bpm 120

live_loop :foo do

  use_transpose [0, 12, 0, 5].tick("transpose")

##| x = (ring 0,1,2,3,4,5,6,7,8,9,10,11,12).tick("transpose") # if you want to stay on ring
##| use_transpose x.to_i # need to be an integer

  sample :drum_bass_hard
  n = ( ring :d, :g,:g,:a,:g,:f, :e,:e,:e, :g,:g,:a,:g,:f, :f, :f, :f) #notes
  d = ( ring 1, 1,0.5,0.5,0.5,0.5, 1,1,1, 1,0.5,0.5,0.5,0.5, 1,1,1) #duration
  n = ( ring :c, :g, :a) #notes
  d = ( ring 2, 1, 1) #duration
  play_pattern_timed n, d

So first play, 0 transpose, next +12 so one octave upper , next 0, next 5.

Of course you have to comment my n and d lines to recover your melody

and tell us if it’s ok for you.

Edit : by the way what melody do you code ? is it a well known christmas tune ? sounds like “happy new year” but a bit weird :slight_smile: Tell us !

Given that it appears that vinodv wants to recreate the ‘we wish you a merry Christmas’ melody, there’d probably be more to the melody than just what they have printed above, so no doubt if using with/use_transpose there could be a bit more to it than just using them once for the entire loop :slightly_smiling_face:

1 Like


I think if you make the ring that x comes from a ring of integers, then x will already be an integer?

Oupss yep no need for to_i here :slight_smile:

1 Like