Onwards with Sonic Pi

Sonic Pi version 2.6 is hot off the press, but already Sam Aaron is pushing on with the development for version 2.7. Sonic Pi is a living program and it needs to grow and improve constantly. In the last couple of days I have noticed the addition of a large set of single cycle samples of a wide range of instruments – (the freely available http://www.adventurekid.se/akrt/waveforms/adventure-kid-waveforms/) As yet they are not fully incorporated in Sonic Pi, as they would normally be used to generate samples using them as raw material. As Sam says in the commit where they were added. “Samples – add the fabulous Adventure Kid Waveforms- for future use for wavetable synthesis”.

Being rather impatient, I resolved to take a look at these. You cannot use them directly as they consist of a single cycle of a particular waveform, but there are two tools you can use to help. First I came across a free download discussed here which is a tool which runs on a Mac to enable you to easily select and play one of these samples repeated indefinitely in time. The download is here
If you unzip and run this program you can drag one of the AKFW folders which are installed in the etc/wavetables folder in the latest sonic pi 2.7dev downloads and drop it onto the window of this tool as shown below.
singlecycleaudition
You can then use up and down arrow keys to select a sample and spacebar to toggle playing or silent.
Using this, I looked at one or two folder and selected three waveforms that I found interesting. I opened these using the freely available audacity app, and then used that to generate a sample which could be used with Sonic Pi. (Audacity is also available on the raspberry Pi Raspian distribution using sudo apt-get update followed by sudo apt-get install audacity)
To do this I followed the following steps.

  • Open the single cycle wave form in Audacity
  • From the effect menu  select repeat and choose 300 times (which give a sample of around 3 seconds)
  • select normalise from the effects menu
  • save the resulting sample as a wav file in an appropriate folder which can be used as a sample source for sonic pi. I  carried out this process for the files AKWF_sinharm_0005.wav, AKWF_granular_0043.wav and AKWF_fmsynth_0050.wav saving the resulting 3 sample files using the same names but without the initial AKWF_ in my sonic pi samples folder which I have on my Desktop at location /users/rbn/Desktop/sonic-pi/AKWF

I then played around with these three samples in sonic pi. I found that they all had a fundamental frequency equivalent to note :d3 and using this was able to produce different “notes” utilising the pitch_to_ration function.

The three samples sound like this:

use_sample_pack "Users/rbn/Desktop/samples/AKWF"
sample :sinharm_0005
sleep sample_duration :sinharm_0005
sample :granular_0043
sleep sample_duration :granular_0043
sample :fmsynth_0050
sleep sample_duration :fmsynth_0050

I then wrote a function to play a defined note using one of these samples

define :pl do |sname,n,d,r=1,sp=note(:d3) |
sample sname,rate: pitch_to_ratio(note(n)-snp)*r,sustain: d*0.95,release: d*0.05,amp: 2,cutoff: rrand(80,130)
end

sname was the sample name, n the note to be played, d the duration of the note, r a rate multiplier which I used to transpose an octave when required setting r = 2, and sp was the “normal” pitch of the sample.
You can test out playing a scale with this function as follows:

use_sample_pack "Users/rbn/Desktop/samples/AKWF"
sn=:granular_0043
snp=note(:d3)
define :pl do |sname,n,d,r=1,sp=note(:d3) |
 sample sname,rate: pitch_to_ratio(note(n)-snp)*r,sustain: d*0.95,release: d*0.05,amp: 2,cutoff: rrand(80,130)
end
sc=scale(:e2,:major,num_octaves: 2)
sc.each do |n|
 pl(sn,n,0.4)
 sleep 0.4
end

I then played with a live loop using these three samples and came up with the following code:

use_sample_pack "Users/rbn/Desktop/samples/AKWF"
sring = (ring :sinharm_0005,:granular_0043,:fmsynth_0050) #ring of available samples
snp=note(:d3)

define :pl do |sname,n,d,r=1,sp=note(:d3) |
  sample sname,rate: pitch_to_ratio(note(n)-snp)*r,sustain: d*0.95,release: d*0.05,amp: 2,cutoff: rrand(80,130)
end

live_loop :b do
  with_fx :panslicer,wave: 1,pulse_width: 0.2 do
    with_fx :echo,mix: 0.4 do
      tick
      tick_set :sam, look/30 #use to select the sample to be played
      sn =sring.look(:sam)
      notes=scale(:d3,:minor_pentatonic,num_octaves: 2)
      pl(sn,notes.choose ,0.15) if spread(5,13).look
      pl(sn,notes.choose,0.15,2) if !spread(5,13).look
      sleep 0.15
    end
  end
end

You can play with this to try out a range of different sounds. Try altering the two lines

     pl(sn,notes.choose ,0.15) if spread(5,13).look
     pl(sn,notes.choose,0.15,2) if !spread(5,13).look

Change one or other or both of the .choose to .look. Change the first one to .tick Change the spread(5,13) of one or the other to spread(7,13) or change both.
Finally, as a fixed performance I used the code below, which uses a separate control live_loop to fade the audio level up to max, and after a pause fade it out to zero again.

use_sample_pack "Users/rbn/Desktop/samples/AKWF"

sring = (ring :sinharm_0005,:granular_0043,:fmsynth_0050)
snp=note(:d3)

define :pl do |sname,n,d,r=1,sp=note(:d3) |
 sample sname,rate: pitch_to_ratio(note(n)-snp)*r,sustain: d*0.95,release: d*0.05,amp: 2,cutoff: rrand(80,130)
end

with_fx :level do |amp|

 control amp,amp: 0 #set initial level
 sleep 0.01 #allow initial level to settle without a click
 #three samples playing takes 30*3 ticks
 live_loop :b do
 with_fx :panslicer,wave: 1,pulse_width: 0.2 do
 with_fx :echo,mix: 0.4 do

 tick
 tick_set :sam, look/30
 sn =sring.look(:sam)
 notes=scale(:d3,:minor_pentatonic,num_octaves: 2)
 pl(sn,notes.choose ,0.15) if spread(7,13).look
 pl(sn,notes.look,0.15,2) if !spread(7,13).look
 sleep 0.15
 #puts "look b "+look.to_s
 stop if look >= 30*3*5+90 #stop after 3 samples played five times plus fade out time
 end

 end
 end

 live_loop :audio do
 tick
 #puts "audio look "+look.to_s #uncomment for debugging purposes
 #increase volume over the first 90 ticks
 control amp,amp: ( (look.to_f)/90) if look <= 90
 #decrease volume after 5 complete cycles of 3 samples
 control amp,amp: (1- (tick(:stop).to_f)/90) if look >= 30*3*5
 stop if look(:stop) >= 90 #stop loop after volume is zero (90 tick(:stop))
 sleep 0.15
 end
end

I  am always amazed at how versatile sonic-pi is. It is a great platform on which to make music, play with code and generally have an amazing creative time!
singlecyclesamplesYou can here the “performance” version here

You can download the code plus samples here

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s