Generative melody big challenge for me :)

hi everyone thanks for your help so far :slight_smile: so now comes a big challenge for me :slight_smile:
this is the code example:

β€œβ€"

live_loop :random_riff do
  use_random_seed 0
  8.times do
    play rrand_i(50, 95), release: 0.1
    sleep 0.125
  end
end
``` I want to create a random melody that is confined to a specific octave, with the seed randomly changing after a certain number of bars for example 8, and I would like to output it over midi. please can some one explain to me how to to do this thanks very much :)

:grinning:

use_bpm 120
tonalidad = scale(:g4, :major_pentatonic)
acordes = (ring chord(:e3,:minor), chord(:g3,:major), chord(:c3,:major), chord(:d3,:major))
tiempos = (ring 2,2,2,2)
count = 0
live_loop :fd do
  use_synth :tb303
  if count == 48
    stop
  else
    count +=1
    with_fx :flanger do
      with_fx :echo, phase: 0.5 do
        play acordes.tick,amp: 0.6, release: 1.5,pan: 0.4,cutoff: 120
        sleep tiempos.look
        play acordes.look,amp: 0.6, release: 0.75,pan: -0.2,cutoff: 120
        sleep tiempos.look/2
        play acordes.look,amp: 0.6, release: 0.75,pan: -0.4,cutoff: 120
        sleep tiempos.look/2
      end
    end
  end
end

sleep 16

live_loop :de do
  if count > 44
    stop
  else
    use_synth :tech_saws
    use_random_seed (ring 1,1,1,1,2,1,1,2,3,1,1,2,3,5).tick
    
    with_fx :reverb do
      8.times do
        nota = tonalidad.choose
        play nota + 0.2,amp: 0.3,pan: -0.8
        sleep 0.05
        play nota,amp: 0.3,pan: 0.8
        sleep (ring 0.45,0.45,0.95).choose
      end
    end
  end
end

To confine the notes to a specific octave, you can just adjust the limits of the rrand_i function so that the low and high bounds differ by 12 semitones, e.g. rrand_i(60, 72). Alternatively you can limit them to a specific scale using something like scale(:c, :major).choose, where the scale function generates the notes of the scale, and choose selects a random note from that scale.
To change the random seed, you could store the current seed with set, then use tick to count bars and every 8th loop add some arbitrary number to the seed.
Finally to send a note as midi, just use the midi function instead of play. The main difference is that you don’t have full control over the envelope, you can only use sustain: to control the length of the note.
Putting it all together, you might get something like the following:

set :seed, 0
live_loop :random_riff do
  set :seed, (get(:seed) + 971) if tick % 8 == 0
  use_random_seed get(:seed)
  8.times do
    midi scale(:c3, :minor_pentatonic).choose, sustain: 0.1
    sleep 0.125
  end
end
1 Like

hi @raul please can you explain what this code is doing? thanks :slight_smile:

hi @emlyn what does ==0 mean here? and is there any way of making rests between the notes? also is there anyway of bassing this off a riff ring E.G. (ring :c, :r :g, :r, :f, :r, :c, :r)

Hi @soundwarrior,
The == 0 tests whether the number to the left is equal to zero. The tick % 8 part takes the remainder of the tick counter when divided by 8, which will be 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2… etc. as the tick increments. Together, they will only be true on every 8th iteration, so that we only update the seed every 8th time.

There are also other ways to achieve the same thing, for example ticking through a ring of boolean values:

set :seed, (get(:seed) + 971) if bools(1, 0, 0, 0, 0, 0, 0, 0).tick

One way to add rests is to use the on: option together with spread:

midi scale(:c3, :minor_pentatonic).choose, sustain: 0.1, on: spread(5, 8).tick(:a)

This will only trigger the node 5 out of each 8 times, the other times will be rests (and you can of course change those numbers).

Regarding basing it off a riff, the way to do it depends on what you mean exactly. Do you want to play the riff instead of the random notes, or do you want to select the notes randomly from the riff instead of from a scale, or something else?

1 Like

Hello @soundwarrior:

tonalidad = scale(:g4, :major_pentatonic)
the notes that are used are those that are part of the scale of g pentatonica (g, a, b, d, e, g)

acordes = (ring chord(:e3,:minor), chord(:g3,:major), chord(:c3,:major), chord(:d3,:major))
is the harmonic progression that will be used

With these two premises we make sure that any of the notes are heard at random, it sounds good in the harmonic-melodic set

use_random_seed (ring 1,1,1,1,2,1,1,2,3,1,1,2,3,5).tick
We make the seed is based on the fibonacci series, our ears are used to melodic patterns repeat or vary little

nota = tonalidad.choose
play nota + 0.2,amp: 0.3,pan: -0.8
sleep 0.05
play nota,amp: 0.3,pan: 0.8
sleep (ring 0.45,0.45,0.95).choose

A note is generated at random, for a channel 20% is detuned, on the other 5% of the bmp is delayed.
The duration of the note plus the delay is 0.5 or 1.

It does not matter if the melodic rifle fits perfectly with the chord change … any note sounds good with any of the chords.

hi all, thanks for your help so far :slight_smile: I’ve got this code to run but how do I set the midi channel? thanks gang heres the code
β€œβ€"
set :seed, 0
live_loop :random_riff do
use_bpm 140
set :seed, (get(:seed) + 971) if tick % 16 == 0
use_random_seed get(:seed)
8.times do
midi scale(:c3, :minor_pentatonic).choose, sustain: 0.1
sleep 0.3
end
end

You can either add channel: 1 #or whatever number
to the end of the midi scale(:c3, :minor_pentatonic).choose, sustain: 0.1
line, or you could use
use_midi_defaults channel: 1
somewhere at the beginning of your program.
giving either of the following:

set :seed, 0
live_loop :random_riff2 do
  use_bpm 140
  set :seed, (get(:seed) + 971) if tick % 16 == 0
  use_random_seed get(:seed)
  8.times do
    midi scale(:c3, :minor_pentatonic).choose, sustain: 0.1,channel: 3
    sleep 0.3
  end
end

or

use_midi_defaults channel: 1
set :seed, 0
live_loop :random_riff do
  use_bpm 140
  set :seed, (get(:seed) + 971) if tick % 16 == 0
  use_random_seed get(:seed)
  8.times do
    midi scale(:c3, :minor_pentatonic).choose, sustain: 0.1
    sleep 0.3
  end
end

hi everyone thanks for your help :slight_smile: @robin.newman are you able to use the set_midi defaults command with different live loops to set them to different midi channels? thanks guys :slight_smile:

For differnt live loops, you could use the channel number separately for ach loop as per the first of my examples.
Alternatively you could use

with_midi_defaults channel: n do
…
…
end
wrapped around each separate live_loop
(the live loop goes where the two … lines are)

EDIT hint… with any command you can ctrl+I click it and the help window will display examples of the command in use.

hi everyone I’ve tried outputting this code to my Moog Sirin via midi but it only plays one note then stops anyone know why this is? heres the code:
β€œβ€"
midi scale(:c3, :minor_pentatonic).choose, sustain: 0.1, on: spread(5, 8).tick(:a)

Hi @soundwarrior,
Is that the whole code? To play more than one note you need to put it in some kind of loop, for example:

live_loop :test do
  midi scale(:c3, :minor_pentatonic).choose, sustain: 0.1, on: spread(5, 8).tick
  sleep 0.125
end

Note that in this case you don’t need to pass the parameter :a to the tick function. I think you got that from an earlier example where there were two ticks in the same loop, so they had to be kept separate by giving one of them a name, but if there is only one, the parameter is not needed.

hi everyone thanks for your help so far :slight_smile: I was able to get the Sirin to play generative melodies :slight_smile:

1 Like