Sonic Pi Coding Class 004

It was agreed to give a small prize to the student who worked the hardest during the class and who also worked the hardest in producing their final piece/s of music based on a brief.  I’ve created links here to the more obscure parts of the prize so that the recipient has a starting point to work out what they can be used for!

Arduino code for the Ultrasonic Ruler that was worked on in class can be found in my GitHub repository, here.

Sonic Pi Coding Class 003

Last week we wrote a function to set the volume based on musical dynamics like ‘ppp’ or ‘fff’

Functions can also be used to return information to us.

An example of a function that returns a value is below. Type it in and see how it works.

define :get_volume do |music_notation|
  # Write your code here to work out volume level
  # corresponding to music_notation like 'ppp'
  
  # Return the volume level like this
  # return volume_level
  
  # Or we could just return a number for this
  # example to see how it works
  return 0.1234
end

# Now write some code to use the function get_volume
my_volume = get_volume("ppp")
print my_volume

What I would like you to do is to modify last weeks function so that when you pass it a musical notation for volume, like ‘ppp’, it returns a number between 0 and 1.0 for Sonic Pi to use as part of an :amp property.

Once you have that function working, make your own piece of music up that uses this function as many times as you can!

Below is one way of achieving the task. If you are stuck, type this in yourself and then make your own piece of music up that uses this function as many times as you can!

# First, we define the function
#
# Function: get_volume
#
# Input:
#          Gets an amp level for a musical notation passed
#          in as a string.
#          Examples of musical notation: ppp, fff, mf etc
#
# Returns:
#          A number between 0 and max_amp
#
# Reference: https://en.wikipedia.org/wiki/Dynamics_(music)
#
define :get_volume do |music_notation|
  max_velocity = 127.0
  max_amp = 1.0
  velocity_ratio = max_amp / max_velocity
  
  case music_notation
  when "ppp"
    return velocity_ratio * 16
  when "pp"
    return velocity_ratio * 33
  when "p"
    return velocity_ratio * 49
  when "mp"
    return velocity_ratio * 64
  when "mf"
    return velocity_ratio * 80
  when "f"
    return velocity_ratio * 96
  when "ff"
    return velocity_ratio * 112
  when "fff"
    return velocity_ratio * 127
  else
    # Unknown music notation so return max volume
    return velocity_ratio * 127
  end
end

# This is where we start to play our music

# Use the variable my_volume to hold the volume level returned from the function get_volume
my_volume = get_volume("mf")

# Play a note and set the amp (amplifier) level to the value stored in the variable my_volume
play 80, amp: my_volume
sleep 1

# Another way we can do it is like this
play 80, amp: get_volume("fff")
sleep 1

 

Choosing a Random Synth in Sonic Pi

Towards the end of our coding class at school today, one of the children asked me how they would choose a random synth in their code.  I couldn’t give them the answer off of the top of my head so I came home and have placed two different solutions below:

# Choosing a Random Synth in Sonic Pi

# Solution 1
10.times do
  use_synth [:beep, :blade, :cnoise, :dpulse].choose
  play :C3
  sleep 1
end

# Solution 2
10.times do
 use_synth choose([:beep, :blade, :cnoise, :dpulse])
 play :C3
 sleep 1
end

 

Sonic Pi Coding Class – 002

My little boy, James, has been taking piano lessons for two terms now. Last week, his teacher asked him to do an assignment on a minuet.

James knows I’ve been running a coding group at school with Sonic Pi so he asked his teacher if he could write his minuet in Sonic Pi as part of his work.  It was his first coding in a non block type language like Scratch.  I think he did a super job!  James’ version is on his own web page, here.

I thought it would be a good opportunity for me to have a go too so that I could become more familiar with what I am talking to the children about in the class.  Here’s my version which includes the student and the teachers parts played as a duet.  It took me a couple of hours to figure it all out so it was a good challenge!

Press the play button, below, to see how it turned out.

#
# Petit Minuet
#
# 170704
#
# From page 47 of Piano Adventures by Nancy and Randall Faber
# Lesson Book : Primer Level
#

# I have no idea how I originally came up with this number!
speed_multiplier = 0.5 / 8

q = 4 * speed_multiplier      # Quaver          1/8
c = 8 * speed_multiplier      # Crotchet        1/4
m = 16 * speed_multiplier     # Minim           1/2
md = 24 * speed_multiplier    # Dotted minim
s = 32 * speed_multiplier     # Semibreve       1/1

# Extend the default release time of 1 second to
# give a slightly more pleasant sound
use_synth_defaults attack: 0.0125, release: s * 8

# Student
in_thread do
  use_synth :piano
  
  play_pattern_timed [:c5, :c5, :b4], [c, c, c]
  play_pattern_timed [:c5, :d5], [m, c]
  play_pattern_timed [:e5, :e5, :d5], [c, c, c]
  play_pattern_timed [:e5, :f5], [m, c]
  play_pattern_timed [:g5, :g5, :c5], [c, c, c]
  play_pattern_timed [:b4, :c5], [m, c]
  play_pattern_timed [:f5, :e5, :d5], [c, c, c]
  play_pattern_timed [:c5], [md]
end

# Teacher right hand
in_thread do
  use_synth :piano
  
  # Bar 1
  play_pattern_timed [:e4, :e4, :d4], [c, c, c]
  
  # Bar 2
  play_pattern_timed [:e4, :d4], [m, c]
  
  # Bar 3
  2.times do
    play_chord [:c4, :a3]
    sleep c
  end
  
  play_pattern_timed [:b3], [c]
  
  # Bar 4
  play_pattern_timed [:c4, :f4, :e4, :d4], [c, q, q, c]
  
  # Bar 5
  play_pattern_timed [:e4, :e4, :e4], [c, c, c]
  
  # Bar 6
  play_pattern_timed [:d4, :e4], [m, c]
  
  # Bar 7
  play_chord [:f3, :a3]
  sleep q
  
  play :d4
  sleep q
  
  play_chord [:g3, :c4]
  sleep c
  
  play_pattern_timed [:b3], [c]
  
  # Bar 8
  play_pattern_timed [:c4], [md]
end

# Teacher left hand
in_thread do
  use_synth :piano
  
  # Bar 1
  play_pattern_timed [:c3, :c3, :g3], [c, c, c]
  
  # Bar 2
  play_pattern_timed [:c3, :d3, :e3, :f3, :g3], [q, q, q, q, c]
  
  # Bar 3
  play_pattern_timed [:r, :r, :e3], [c, c, c]
  
  # Bar 4
  play_pattern_timed [:a2, :b2], [m, c]
  
  # Bar 5
  play_pattern_timed [:c3, :r, :c3], [c, c, c]
  
  # Bar 6
  play_pattern_timed [:g2, :b2, :c3], [c, c, c]
  
  # Bar 7
  play_pattern_timed [:r, :r, :g2], [c, c, c]
  
  # Bar 8
  play_pattern_timed [:c3, :g2, :c2], [c, c, c]
end