Showing posts with label Sonic Pi. Show all posts
Showing posts with label Sonic Pi. Show all posts

Tuesday, August 9, 2016

Learn music for programmers with Sonci Pi - 04 - Jam Session

In second lesson we created random Chinese music generator just by randomly playing tones from pentatonic scale. But pentatonic scale is not the only one of course.

Theory


Diatonic Scale


The basic and most known is of course diatonic scale. It's the one all of you know C-D-E-F-G-A-B(H)-C. I will not go in to further details. First of all we already touch the basic in first lesson and second you can ready more on wikipedia.

Pentatonic Scale


We touch pentatonic scale in second lesson and we said it's the black keys on the piano, so C# D# F# G# A#. However in the music the difference between tones matter more then the frequencies so if you move all of them by half tones you again get pentatonic scale. If you are interested more you can go on and again wikipedia is good source

Jazz Scale


There is also jazz scale. A great deal of modern jazz harmony arises from the modes of the ascending form of the melodic minor scale, also known as the jazz melodic minor scale C D E-flat F G A B
Well there are many jazz scales and again rather then explain all, you can read wikipedia.

There are also other scales, but for today enough of theory.


Sonic PI


So the question is if  we can create the Chinese music by just randomly playing pentatonic scale can we create Jam session by "randomly" playing jazz scale?

Let's start with little repetition

Function

Just use define :name do |prametr1, parametr2| to define function, if you want it to be function  you must return some value, so then before the end use name = value
Below example is factorial function.

define :fact do |n|
  fact = (1..n).reduce(:*)||1
end

So with factorial and combination functions, I've create ghoose function from second lesson, choose "randomly" with Gaussian probability distribution, but this time it's general for any list.

define :gchoose do |list|
  fl = list.length
  choosen_index = (fl/2).to_i
  base = 2**(fl-1)
  index = 0
  (fl). times do
    #puts (combination (fl-1), index)
    choosen_index = index if one_in((base/(combination (fl-1), index)).to_i)
    index = inc index
  end
  ghoose = list[choosen_index]
end


Now we just play random notes from Jazz scale with random duration

loop do
  play (gchoose jazz_scale)
  sleep (gchoose durations)
end

Here is the complete code on github if you will play it you find out that it's not what you would expect. The problem is that it miss one important think, rhythm.

OK, let's add underlying rhythm (jazz use 4/4 time signature so easiest would be 4 quarter notes, F D D D for example).

#Basic rhythm
in_thread do
  loop do
    play (F-12)
    sleep 1
    3. times do
      play (D-12)
      sleep 1
    end
  end
end

We also need to sync the our "improvisation" part to reflect the time signature. We just set Total Duration to 4 and initiate Remaining Duration to the same. Choose Current Duration, if it's higher then remaining we cut it short and use remaining. Once RD is 0 we reset it to TD.

#Total Duration
TD = 4
#Remaining Duration
RD = TD

loop do
  play (gchoose jazz_scale)
  #Choosen Duration
  CD = gchoose durations
  if CD > RD
    CD = CD - RD
  end
  sleep CD
  RD = RD - CD
  if RD <= 0
    RD = TD
  end
end

The complete code is my github. If you will try to play it I think you find that even we add rhythm and it sound little more like jazz, it's actually terrible. If you use default choose function instead of my gchoose it sound better, but still not jam session.

So let's can we create Jam session by "randomly" playing jazz scale?
No, not even if add rhythm to it.

Tuesday, August 2, 2016

Learn music for programmers with Sonci Pi - 03 - Rythm

Theory


Beat

One beat is basic time unit. One beat equals (most often) 1/4 note (because it's most common time measure in music).

Measure or Bar(line)

Measure or sometimes referred as bar is musical time unit which divides the song into larger units

Time signature

Time signature actually is telling us how many notes (the blue number) of and how long (the red number) we shall play. In example below it 3 quarter notes. if it would be 4/4 it would be 4 quarter notes, 2/2 would be 2 half notes, 4/8 would be 4 eights notes, etc.
Now as you can see in example below you don't have to play quarter notes, but if you summarize you shall get time corresponding to the time signature.
Take example of part between green lines(the end part). It's six 1/8 notes hence 6/8 = 3/4.

Rhythm

Rhythm is event repeating over time. Main beat and unstressed off beat or Accented back beat, repeating in pattern. To distinct them we use different drums, high and low, long and short beats.

Except using the traditional notation to understand and follow the rhythm, instead of linear display we can use circle, so one circle equals to one measure. Hence the measure with 3/4 time signature we can divide into 3 parts which each correspond to 1/4 note. (If tempo is 60 bpm then the full circle is 3 seconds).

In below section I show you few examples of rhythms, how they look on the "rhythm circle" and how we can write that in Sonic PI

Sonic PI


Waltz

Waltz use 3/4 time signature. Below we can see the basic simple waltz rhythm the first tone higher(main beat) next two lower(off and secondary beat).



It divides the rhythm circle below in to 3 equal parts each is for one 1/4 note.
In sonic code example below it corresponds to F and two D


Sonic Pi code:
# Welcome to Sonic Pi v2.10
use_bpm 90
use_synth :piano

#Let first define basic tones
D = 63
F = 66

#Basic rhythm
loop do
  play F
  sleep 1
  play D
  sleep 1
  play D
  sleep 1
end

Polka

Polka use 2/4 time signature. Below we can see it on rhythm circle. It's pretty easy one note (let it be E) starts on "12 o'clock" and last 1/4 as we have 2/4 = full circle, then 1/4 is one half of the circle so second note(let it be F) starts on "6 o'clock"


And here is the same in Sonic Pi

loop do
  play E
  sleep 1
  play F
  sleep 1
end

Let's try something little more interesting.


It's not hard we only need to play more things at once so lets do threads. It's easy syntax:
in_thread do
  commands
end

Complete Sonic PI code for polka rhythm above, the main rhythm(2 quarter F notes) are played in thread 1/8ths in "main" part:

# Welcome to Sonic Pi v2.10
use_bpm 90
use_synth :piano

#Let first define basic tones
C = 61
F = 66

#Basic rhythm
in_thread do
  loop do
    2.times do 
      play F
      sleep 1
    end
 end
end

loop do
  sleep 0.5
  play C+12
  sleep 0.5
  sleep 0.5
  play C+12
  sleep 0.5
end

Tango

Tango is in use 4/4 time signature. If we little simplify it's long, short, short, long. If you learn tango in dancing lesson you might remember the step pattern, slow, slow, quick, quick.

So here we go this one is pretty simple two long C to short E. (The dot behind the C means 1/8 longer)

Here it's on the rhythm circle



And here is the Sonic Pi code:
# Welcome to Sonic Pi v2.10
use_bpm 78
use_synth :piano
loop do
  play 61
  sleep 1
  sleep 0.5
  play 65
  sleep 0.5
  play 65
  sleep 1
  play 61
  sleep 1
end


Here is one little more complected as it's more changing the pitches but the timing is important (not the pitch)


You can try to write Sonic Pi code your self and then compare with my on github


Tuesday, July 26, 2016

Learn music for programmers with Sonci Pi - 02 - Random Chinese music generator

If you play just black keys on the piano in randomly you'll generate a Chinese music.

Pentatonic scale


Now this time it makes sense Penta tonic = 5 tones. Which is exactly what it is.
There are several pentatonic scales, but as suggested lets start with black piano keys which are:
C#, D#, F#, G#, A#, c#, d#, f#, g#, a#
However most important is the difference between them if we take the number for those tones from Sonic Pi it's:
62, 64, 67, 69, 71, (74, 76, 79, 81, 83)
Hence differences are:
2, 3, 2, 2, (3, 2, 3, 2, 2)
I guess you can see the pattern there, so if you choose any tone and just do the differences, you got pentatonic scale.

Sonic Pi

OK so musical theory we have, what we will need to create simple generator. Endless loop and randomly choose tone and duration in each go run through in the loop.


Loop

Loop just do commands in endless loop.

loop do
  commands
end

Field

Field is the list of items in square brackets separated by comma(s)
[62, 64, 67, 69, 71]
pentatonic_scale = [62, 64, 67, 69, 71]

Choose

Randomly choose one of the item in the give field
choose(field)
choose([62, 64, 67, 69, 71])

One_in

This returns true with probability of 1/X
one_in(X)
For example gives true with probability of 1/5
one_in(5)

Function/Procedure

Just use define :name do |prametr1, parametr2| to define procedure or function, if you want it to return some value then before the end use name = value

define :gchoose_note do
  note = 67
  note = 64 if one_in(5)
  note = 69 if one_in(5)
  note = 62 if one_in(10)
  note = 71 if one_in(10)
  gchoose_note = note
end

Random Chines music generator v1


loop do
  play choose([62, 64, 67, 69, 71])
  sleep choose([0.125, 0.25, 0.5, 1])
end

The problem with this is that it's too random and it doesn't sound as much as Chines music as if you really play the black keys your self randomly.
The reason is that people often misunderstand the randomness and if you ask group of the people to stay in the room randomly they will distribute them self's more or less evenly.
So they do when the play black keys, they tend to play one tone (in the middle often) and going around back and forth.

Random Chines music generator v2


So let's try a Gaussian distribution of probability with which we choose the tone to play.

# Welcome to Sonic Pi v2.10
use_bpm 60
use_synth :dull_bell

define :gchoose_note do
  note = 67
  note = 64 if one_in(5)
  note = 69 if one_in(5)
  note = 62 if one_in(10)
  note = 71 if one_in(10)
  gchoose_note = note
end

define :gchoose_duration do
  duration = 0.25
  duration = 0.5 if one_in(3)
  duration = 1 if one_in(6)
  duration = 0.125 if one_in(6)
  gchoose_duration = duration
end

loop do
  play gchoose_note
  sleep gchoose_duration
end

Saturday, July 16, 2016

Learn music for programmers with Sonic Pi - 01 - Brother John

I my self don't have any musical education and they try to teach me in school it was completely nonsense for me. The reason is that it's basically substitution cipher for basic physics. So let's start with few basic substitutions.

Tones/Notes

There is 12 half-tones which musicians call octave(Latin name for 8)
It's actually 7 tones (C,D,E,F,G,A,B) + 5 Sharp tones(C#, D#, F#, G#, A#). - To be more complicated German notation use H instead of B.
Reference tone is A = 440Hz, A octave higher have frequency 2*A (880Hz) and octave lower is 1/2*A (220Hz)

Now if we check the notation we can find where it's C, D, E etc. based on the position, as you can see on the we start with C on the line below "standard lines". D is under first line, E on the first line F between 1st and 2nd, etc. If you would like to ask where are the # (Sharps), there are not there if the note is sharp would see symbol # in front  of the note. (If you try to find logic in it I'm not able to help sorry, it's a cipher, really it is Bb read as B flat = A# read as A Sharp or Ais, 4 names for one frequency, see not only simple substitution it's almost like enigma)


Duration

Tones have duration, whole, half, quarter, 1/8, 1/16 etc.



This is what every musician explains, but still you don't know anything. Half of what? Second, minute, year.... ?
The answer is it depends on tempo. Tempo is number of whole notes which you can play in the minute, BPM, beats per minute.
Hence if tempo is 60 bpm it 60 wholes per minute, hence whole note plays for 1 second,  or half note 0.5 second, etc.

Tones/Notes in Sonic Pi


One more substitution we need to learn this time easy for Sonic Pi. Sonic Pi don't use names of tones it use simple integers.
1 is lowest C
2 is C#
3 is D
4 is D#
etc.
This is however way too low, to get something which we can hear we will start at 61 so

CC#DD#EFF#GG#AA#B
616263646566676869707172

Let's play in Sonic Pi


It's easy we will use command play to play a note and sleep to say how long.
Hence

play 61
sleep 0.25

plays quarter C

Now we just need to define what we are going to play and how fast (tempo). We will use piano and tempo 60 BPM

use_bpm 60
use_synth :piano

And last for today we need to learn to repeat certain parts for that we will use X. times do cyckle it have easy syntax:

X. times do
  commands
end

Will do X times commands between do and end. In below song we use 2 times do.

Brother John

An finally let's play very easy song, which have mutation in various languages, Brother Jacob.

Sonic Pi code:

# Welcome to Sonic Pi v2.10
use_bpm 60
use_synth :piano

#Let first define basic tones
C = 61
CSharp = 62
D = 63
DSharp = 64
E = 65
F = 66
FSharp = 67
G = 68
GSharp = 69
A = 70
ASharp = 71
H = 72
B = 72

#Now lets play the song Brother Jacob

#1st Part 2 times
#Are you slee - pin'
2. times do
  play C
  sleep 0.50
  play D
  sleep 0.50
  play E
  sleep 0.50
  play C
  sleep 0.50
end

#Second part 2 times
#Bro-ther John
2. times do
  play E
  sleep 0.5
  play F
  sleep 0.5
  play G
  sleep 1
end

#3rd part 2 times
#Mor- nin bells are ring-ing
2. times do
  play G
  sleep 0.25
  play A
  sleep 0.25
  play G
  sleep 0.25
  play F
  sleep 0.25
  play E
  sleep 0.5
  play C
  sleep 0.5
end

#4th and last part 2 times
# Bim bam boom
2. times do
  play C
  sleep 0.5
  play G
  sleep 0.5
  play C
  sleep 1
end