Melody improvisation

hehe, ‘biologically plausible structure’… i guess i kind of lapse into testing ideas against my original field of atmospheric science. so, when i’m like, ‘dj, play that funky methanogenic cyanobacteria!’ that’s what that’s about

but, more concretely, musical structure and time-series analysis are pretty closely related, so when looking for historical ‘event onset’ information and laying out ‘plausible outcomes,’ thinking in musical terms helps to keep things tangible

Hi @ds604,

yes, I think I see what you mean. For me (coming not from the hard-boiled science but from the arts) in the end its about patterns, which have been established in certain genres/forms/styles/periods (including the option to establish new patterns, which break/develop the old ones). These are probably something similar to what you were refering to as ‘biologically plausible structure’ (to put it simple: things we are culturally used to).

Of course things are much more complicated when you look at it more closely… :wink:

SampleRadar has a whole pack of ‘Eastern’ drums and instruments, which slice nicely into your own
home grown Eastern beats.

Or just with the built-in samples…

## Eastern pluck
## Coded by Nanomancer
## Modifications by Eli. April 2018.

set_volume! 0.55
set_mixer_control! amp: 0.1, amp_slide: 0.1
sleep 1
set_mixer_control! amp: 5, amp_slide: 12
use_bpm 90

seeds = [1024,2048,3072,4096,5120,6144,7168,8192,9212,512].ring
use_random_seed 999
vol=0.3

live_loop :low_boom, delay: 8 do
  sample :bd_boom, rate: 0.75, amp: 1
  sleep [7,1,8].ring.tick
end

live_loop :drums do
  use_bpm 45
  this_sample = [:loop_compus, :loop_tabla, :loop_safari].ring
  start = [ 0.0 , 0.125 , 0.25 , 0.375 , 0.5 , 0.625 , 0.75 , 0.875 ].ring
  sample this_sample.look , beat_stretch: 4, start: start.look, rate: 0.5
  sleep 1
  tick
end

live_loop :eastern_twang do |idx|
  use_synth :pluck
  if rand() > 0.75 then
    seeds = [1024,2048,3072,4096,5120,6144,7168,8192,9212,512].ring
  else
    seeds =seeds.shuffle
  end
  with_random_seed seeds[idx] do
    notes = scale(:a3, :harmonic_minor, num_octaves: dice(2)).pick(4)
    multi = [0.5,1,1.5,2].choose
    cut = range(50, 130, step: 2.5).mirror.ring
    slp = [1,1.5,0.5,1].ring
    
    if multi == 0.5 || multi == 1 then
      reps = 16
    else
      reps = 8
    end
    
    with_fx :echo, mix: 0.4, phase: 2, max_phase: 4 do
      with_fx :reverb, mix: 0.65, room: 0.85 do
        reps.times do
          play notes.tick, amp: vol*rdist(0.09, 1),
            cutoff: rdist(15, 115), pitch: rdist(0.1, 0)
          sleep slp.look*multi
        end
      end
    end
    
    if one_in(3) then
      sleep 8
    end
    
    idx+=1
  end
end

Eli…

3 Likes

I really enjoyed this. Definitely a creative way of generating more human like improvisations. I started playing around with making a function to imitate what you are doing to make the code a little more concise. It doesn’t afford all the options you have, but you can make quick changes to the repetition values and/or sleep values and the function will automatically figure out how much additional sleep time is needed at the end to make an even 4 beats. I also included parameters to decide if the scale will tick or choose notes.

I didn’t include any accompaniment but feel free to try it out over your pre-existing code.

define :bar do |t1, r1, t2, r2, tc1, tc2|
  s = 4-((t1*r1)+(t2*r2))
  use_synth :piano
  with_fx :gverb do
    if tc1
      t1.times do
        play scale(:e4, :minor_pentatonic, num_octaves: 2).tick
        sleep r1
      end
    else
      t1.times do
        play scale(:e4, :minor_pentatonic, num_octaves: 2).choose
        sleep r1
      end
    end
    
    if tc2
      t2.times do
        play scale(:e4, :minor_pentatonic, num_octaves: 2).tick
        sleep r2
      end
    else
      t2.times do
        play scale(:e4, :minor_pentatonic, num_octaves: 2).choose
        sleep r2
      end
    end
    sleep s
  end
end
use_bpm 110

#Change values for different patterns.
#Changing the last two arguments between true and false will change from tick to choose
live_loop :solo do
  bar 4, 0.25, 6, 0.667, true, false
  bar 4, 0.5, 2, 0.75, false, true
  bar 3, 0.1667, 6, 0.25, false, true
  bar 9, 0.25, 4, 0.5, true, false
end

3 Likes

Somehow, this reminds me of traditional Chinese/Japanese tonal music played in various
ceremonies and in temples in both countries. Exploring it could be interesting…

Eli…

@Eli Thank you for sharing the performance from @NanoMan (really beautiful…) and the MusicRadar resource! I also coincidentally found this post from 2017 on this forum the same day I wrote the comment on middle eastern music:

Maqam Music with Sonic Pi - Performance

I think I will try and see if I can create my own fork of SonicPi and customize it the same way :smiley:

@mrbombmusic That function is quite nice and actually gives a result that is not so far off from what I achieved manually! I learned a lot by examining your code, I started to play around with it to see if I can add a bit more functionality like chord changes and timing variations. If I come up with anything interesting I will post it here :grinning:

Thanks all of you for the amazing inspiration! This forum is quickly becoming one of my favourite online hangout places :grin:

2 Likes
#..........A.M.I.
mn=[:r]; for jn in 1..1023
  mn[jn]=hz_to_midi(24*jn).round
end

c=[6,5,8,9]
h=[48,54,60,72,81,96,0]
m=[0.25,0.5,0.75]

live_loop :keys do
  for x in 0..3
    synth :dtri, note: mn[c[x]], detune: 7,
      sustain: 2, release: 0,amp: 0.3
sleep 2; end;end

live_loop :lead do
  n=choose(h)
  t=choose(m)
  synth :pluck, note: mn[n/8]
sleep t; end
2 Likes

This sounds very nice and works well.

Thank You ! … :slight_smile:
A lesson I have learned
is that ‘music’ is in the ear
of the beholder. There is a
threshold where chaos transforms
into beauty. (Or at least tunefulness)

I agree with Robin, it works well.

There are several people who post code here in the
same… ‘style’?

To me it seems very mathematical, far more so than
musical… is it a syntax from a different programme that
people know about?

Eli…

Thank You !
Do You mean it sounds mathematical, or looks mathematical ?
Here is the essence …

 mn=[:r]; for jn in 1..1023# midi-number[just-number]
  mn[jn]=hz_to_midi(24*jn).round; end
#just intonation uses the mathematical relationships
#of the frequencies of pitch as the framework
#I.E.
c=[6,5,8,9]
#6,8,9 are the relationships of (key of C) C,F,G
#tonic, sub-dominant, dominant
#5 is the relative Minor ... A

sorry but where does this come from ? a wizard hat ?

Derivation of C scale @ A 440 Hz using just intonation …
Sequence of lowest integers that represent the ratios of frequencies of a major scale …
24, 27, 30, 32, 36, 40, 45, 48
In the key of C
C, D, E, F, G, A, B, C
We see that ’ A ’ is represented by ’ 40 ’
If we want to normalize the scale to A - 440 Hz
440 / n = 40 … therefore n = 11
If we want to produce the scale numerically using
midi numbers ( as with Sonic Pi ) …
Then …
midi-number [ just-number ] = hz_to_midi ( just-number * 11 )

1 Like

I mean it -looks- mathematical. The sound does not -sound- mathematical, nor just ‘random’…
it sounds natural.

Eli…

Random , but with ’ steerage ’
The ’ chords ’ are 1 rst & 5 th pairs .
The notes are a pentatonic scale
in C … Sort of like a harmonica …
hard to go wrong . The one possible
rest in each choice helps . The timing
is random … but on intervals that imply
4 / 4 time . It was a lucky try :slight_smile:

mn=[:r]; for jn in 1..1023
mn[jn]=hz_to_midi(jn*1.5); end

o=[1,2,4]
m=[9,9,10,10,11,11,10,10]
c=[9,8,6,9,6,6,6,6,8,8,6,6]

loop do
  for x in 0..11; for y in 0..7
      synth :piano, note: mn[12*choose(o)*c[x]]
      synth :piano, note: mn[m[y]*choose(o)*c[x]]
sleep 0.3; end; end; end

I know this might seem weird for some. But this kind of code helps me learn more about music because it makes more sense for me. There is no right way just your way. Thanks all for sharing codes and thoughts.

hi @hitsware

may i suggest some improvements ? Explain what this code does with comments to help people to understand and learn about your code :slight_smile:

There has been some brief discussion on the code further up this thread.

# Since normally a piano melody is played with the right hand
# ( higher notes ) while the left plays the rhythym , our mind
# translates the random high octave notes as an improvision .

midinumber=[:r]
# create array with '0' element as rest

for justnumber in 1..1023
  # array index 1 to 1023 (ratiometric notes)
  # I.E. octave = 2 : 1 .... fifth = 3 : 2
  
  midinumber [justnumber] = hz_to_midi(justnumber * 1.5)
  # set midinumbers to desired frequencies
end

chord=[9,8,6,9,6,6,6,6,8,8,6,6]
# 12 bar blues progression
# key = 6 ... forth = 8 ... fifth = 9

multiplier = [9,9,10,10,11,11,10,10]
# boogie style note pattern

octave=[1,2,4]
# possible note octaves

loop do
  for x in 0..11
    for y in 0..7
      # 12 bars of eighth notes
      
      synth :piano, note: midinumber [12*choose(octave)*chord[x]]
      # finger one plays root chord notes (random octaves)
      
      synth :piano, note: midinumber[multiplier[y]*choose(octave)*chord[x]]
      # finger two plays pattern (random octaves)
      
sleep 0.3; end; end; end
2 Likes