A journey with Sonic Pi

Recent comments on the sonic pi google group got me thinking about my own journey with this incredibly versatile program.

I first came across Sonic Pi on version 1, img_5301but on my first visit to the program I think I played with it for about 5 minutes and thought h’m this is quite nice, but is rather limited in what it can do, particularly within the limitations of the original Raspberry Pi on which I was trying it out. I did however persevere, and returned to it for further experimentation. In those early days there was little documentation, apart from a cheatsheet (pdf) which had one or two very brief examples of some of the commands available, which weren’t that many. At that stage I had never come across github, and certainly had not looked at all at the coding of Sonic Pi. I had also never used Ruby, but I had over the years been very interested in programs that let you generate music, something that I had started doing with a Nascom kit computer in the 1970s and later with an early Apple Computer and with the BBC Micro. On that machine, things became quite advanced, and I used a tape based program called The Music System (TMS) which I converted to run on an Econet network, and on which using note input directly from a keyboard was able to get 24 BBC computers playing a rendition of the last movement of Bach’s Brandenburg Concerto no 2. The machines were triggered to start via the network, and ran on their own thereafter, remaining more or less in sync until the end of the piece. (Something not yet realised on Sonic Pi 35 years or so later) Here is a video of TMS playing a Rondo by Mozart I found

Later I used programs like Sibelius and Logic Pro on Mac computers, but although these enabled you to enter and play music, they lacked the buzz of working with the early BBC TMS program. On the Raspberry Pi I started making music using Python together with the lilypond music engraver program, and the Timidity midi player. This brought back some of the buzz, and I enjoyed working with Mozart minuets with the bars selected by throwing dice.

When I started to play with Sonic Pi version 1 around Summer 2013, I experimented with the commands and the synths available, and had fun particularly with the FM synth, trying out different parameter settings experimentally in the absence of much documentation and making some musical noises utilising various counting loops. At the same time I was learning basic Ruby constructs, and the midi numbers associated with different notes. A midi number/note chart became a permanent feature as an image displayed on my desktop. Good as it was to experiment in this way, my interest has always been in trying to play classical pieces by electronic means. This also meant that I had to explore how to play more than one part at a time. I began to explore the use of threads. In version 1 these were not all that satisfactory, and the synchronism sometimes began to drift if the threads were too long. However it was possible to start playing simple piano pieces using the (then) :saw_beep synth, and looking at my archives I’ve dug out several pieces including a version of Eleanor Rigby, and a Bach Two Part Invention both dated October 2013, and  stuck them on my original Pi. They sound OK, although the timing is sometimes a bit wobbly because they are both running near the limit of what was then obtainable. Also a piece I called Strange noises, which explored the use of the FM synth which I mentioned above. At this stage I was also beginning to get to grips with github and learning how to download and build Sonic Pi. You can find some of these files in Sonic Pi 1 format here Note they WILL need some amending to play on Sonic Pi 2.x

Sonic Pi really started to get interesting, and to afford greater possibilities as far as Classical Music was concerned with the advent of version 2.0. Because I was by this stage au-fait with downloading and building the source, I was able to use many of the features of this for several months before it was officially released on 2nd September 2014, and in fact, ever since I have been utilising the cutting edge version of Sonic Pi, and have built it for both Raspberry Pi, Mac, Windows and Linux (Ubuntu). This in itself has been quite an education, especially getting to grips with building on Windows, and I have learned a lot about the procedures involved in the process. In the process I have gained a fairly good understanding of how Sonic Pi is put together, and how the code of the various parts operates. This has also been very useful in becoming more confident in building other packages, unrelated to Sonic Pi, and in debugging some of the problems, for example when I added an IQAudio interface, there were initially problems which prevented it from working, and even when the driver for the i2s interface was made compatible with jackd the program which interfaces audio output to Sonic Pi, there were further problems to get it working satisfactorily.

However, back to Sonic Pi. With the advent of the 2.x series, there were immediately some code breaking changes, but it was possible to amend my existing code, to accommodate the changes, which were all to the good. One immediate benefit was that the timing system made it possible for threads to work properly, and so it was much easier to produce polyphonic music that played accurately. Another benefit was the introduction of musical notation, which made it much easier for me (as a classical musician) to enter note data into Sonic Pi. The introduction of better envelope control, initially Attack Sustain Release, but in later versions full Attack Decay Sustain Release made it easier to control note shapes and durations. By this stage I had come across the Ruby zip command which enabled me to join or zip together lists of notes and associated durations and then to use .each notation in a loop to process each pair in playing a particular note. This enabled me to play passages of legato notes, and by using the ADSR envelope to alter the degree to which the notes were legato or staccato.

The next major headway in trying to accurately play classical music came with an investigation of using samples to generate notes. Now parameters such as rpitch make this fairly easy to do, but initially I played with the ambi_glass_rub sample built in to Sonic Pi. This had a fairly pure defined pitch of :Fs5 (F sharp in octave 5). By playing it at rate: 2 you could go up an octave and at rate: 0.5 down an octave. At first I found other notes by experiment, but later realised that to move from one semitone to the next you merely multiplied the rate by the twelfth root of 2. Thus if you do this 12 times, you end up increasing the pitch by 12 semitones or one octave resulting in( 2**(1.0/12)) **12 = 2
i.e. a doubling of the initial rate.

I wrote a little procedure definition to enable me to play any specified note accurately at pitch, and used this sample based “synth” to play an Adagio by Mozart which he wrote for a Glass Armonica, an instrument in which wet glass disks are rubbed to produce a sound, just as you can with your finger on a wine glass. I had just been to Brussels where I had seen this instrument in the superb Musical Instruments Museum. I did several other projects around this time, including a peal of Church Bells, and a harp playing some Bach. I came across a collection of orchestral samples entitled Sonatina Symphonic Orchestra, and I began to use samples from these to produce realistic instrument sounds. Some of the first efforts, particularly to produce a Piano sample based voice (this was before the piano synth was added to Sonic Pi), were a bit tedious, involving experimentally based settings for the rate multipliers to use. Six months later I revisited this sample source and wrote a comprehensive set of procedures to enable up to 55 different instruments to be utilised as sample based “synths” for Sonic Pi. (further modifications added later) However, this also highlighted a problem which had become increasingly exasperating for me in using Sonic Pi. Because of the mechanism used to enable the three major parts of Sonic Pi – the GUI (Graphical User Interface which you see) the Ruby based code which processes the code in the buffers and sends it to the third part, the SuperCollider synth (scsynth) which produces the sounds you hear –  to communicate internally there is a maximum character count that you can have in a single buffer, which if exceeded prevents Sonic Pi from working. In the early days of version 2.x some work was done to try to eliminate this by using an alternative mechanism (TCP instead of UDP) to allow this communication to happen. Although it worked, and eliminated the limit, it was not fast enough, particularly on the Pi, and following some further upgrades to Sonic Pi code, it has not kept pace and is currently not useable. This led me to explore ways to overcome this limitation and I discovered that the cue and sync system in Sonic Pi would actually work between different buffers. So the work around was to put most of the procedure definitions for a piece in one buffer, and the cue a second buffer to run (and sometimes a third!) once the first buffer had been “run” Sometimes some code had to be duplicated in the tow buffers, but it was possible to run pieces that were too long to work from a single buffer. It made it a bit more complex to set things up, and you had to start the second buffer running (waiting for a cue) and then the first (which provide that cue when it had finished its run) to get things to work.

In April 2015 Sam Aaron added an interface to allow the Sonic Pi version of Minecraft to interact with Sonic Pi. Although I am not very interested in Minecraft per se, I enjoyed writing some code to produce various patterns, shapes and even buildings, and have them displayed with a musical accompaniment from Sonic Pi. Again for some of these I used two buffers, and in particular in a project in which a display of exploding fireworks (in Minecraft) was accompanied by Handel’s Fireworks Music, playing in Sonic Pi.

Every now and then I looked more towards using live_loops in sonic Pi, and I enjoyed doing work on producing percussion rhythms, and various other projects outside the classical music genre. You can delve through my SoundCloud  (2nd SoundCloud site) and gist repositories to see some of these. I also did some projects which involved using Sonic Pi with other devices or software. Thanks to Nick Johnstone’s superb sonic_pi_cli gem which enables you to send commands from a command line, I produced projects to build a Sonic Pi jukebox, which could be controlled either by a ruby program, or by a smart phone using the Telegram app, or in a separate project by the Raspberry Pi Touch Screen, and a project to interface Sonic Pi with Pimoroni’s Flotilla Project I also revisited the Mozart Dice Game and with the aid of an external Ruby program that interacted with Sonic Pi, produced a version where Sonic Pi generated the pieces, and played them whilst displaying the music on a Web-browser on the Raspberry Pi. More recently I did some work interfacing a midi-controller and a computer keyboard to play on Sonic Pi in real time. This has many “warts” but was fun to do, and lately several others have been doing useful work in this area. I also did some projects which utilised Sonic Pi as a source to drive led displays, particularly with 4Tronix McRoboFace

Returning to Classical Music, the next two things which have given great impetus to being able to play significant works on Sonic Pi have been the introduction of the run_file command in Sonic Pi 2.11, which overcomes the size limitation discussed above, by sending Sonic Pi code directly from a file rather than from one of the built in buffers. It has the drawback that the code is not directly visible, and debugging can be a bit harder, but also has the great advantage that more extensive pieces can be played on Sonic Pi. The other main drawback was the large amount of time required to enter note/duration information into Sonic Pi. Even although I have become fairly proficient at doing it, it still was a major part of the time required to prepare a piece for Sonic Pi to play. However, there is a large body of classical music which is available in midi format and which can be displayed on free software such as MuseScore. In looking to see what might be involved in converting midi format files to Sonic Pi code format, I came across an article by Japanese user Hiroshi Tachibana in which he had written a script for the program “processing” which was able to parse midi files containing a single instrument part, which could include chords, provided that they didn’t include tied notes, into Sonic Pi code. Although the description was in Japanese, I managed to get this script working, and then modified it slightly so that it could be used to build up the parts for many instruments in a piece, and thus make it easier to convert pieces from midi to Sonic Pi. In the process I learned how to use the program Muse Score, which has become indispensable in modifying the parts for a classical piece which don’t fit the constraints of the script so that they can be converted. This mainly consists of duplicating complex parts and then sharing the notes between the two ( or sometimes three or four) duplicate parts so that each part obeys the rules and can be converted. For example in a recent conversion I had to split a printed part from one instrument into six different parts, some only containing perhaps two or three notes, so that each part could be converted, and when they were played together in separate threads, they still sounded the same as the initial source part. The other reason for using MuseScore is that it can export parts in various formats, including midi and MusicXML which is the required source format for the conversion script to work. Having used this system for two or three months now, I have developed a work flow which makes it quite easy and not too time consuming to convert even large complex scores to work with Sonic Pi. One I was particulary pleased with, and which has been an ambition for many years, was to convert the score of a large (23 minute) double fugue for string orchestra, written by my late Father, who was Professor of Music at Edinburgh University, so that it could be played successfully by Sonic Pi. One or two of these pieces sound fine with built in synths in Sonic Pi, but I have also combined the conversions with my work to produce sample based “synths” for Sonic Pi using the Sonatina Symphonic Orchestra samples, and some other ones besides, to produce a more realistic end effect.

As the techniques for producing these classical pieces have become better, I have also been trying to take more care to render appropriate dynamics (louds and softs) to the music. In many of my more recent conversions, a large part of the time is taken in adjusting the sustain release settings for the various instruments, the use of reverb or gverb to make it sound more realistic and the panposition of the instruments to help the stereo image, and the use of techniques such as the fx_level command to enable dynamic variations to be added to the parts. This can be very time consuming, but is generally easier than having to add individual :amp parameters to every note.

Currently I am working through Mozart’s Requiem in D minor and converting the various movements for use with Sonic Pi. This requires quite a lot of time to adjust the relative emphasis given to each part, and also has the challenge of trying to represent vocal parts, using two sets of vocal sound samples. Although by no means perfect, I get great satisfaction from being able to produce something that can be played from a Raspberry Pi3, and which gives a pleasing rendition of such large scale classical works. Nothing will sound quite like it, and to be able to create such nice sounding music in this way is more than recompense for the time taken to do so. And when I think of what is involved: selection of a suitable source, preparation and checking of individual parts, converting these parts from musicXML to Sonic Pi code, building up the parts in a text editor, and assigning musical instruments voices to each part (sometimes up to 30 distinct parts so far), checking the parts for accuracy and doing any debugging, adjusting envelopes and adding a “track” for dynamic changes: – it all seems very satisfying.

sp2-11Sonic Pi 2.11 in action, with new Scope interrface

And so to the future. Already SP2.12beta is underway. Who knows where this will lead. Whatever happens, I am sure there will be much to continue my interest in utilising all that Sonic Pi has to offer, both in programming, experimenting with music code, trying out additional interfaces and much more. It is an amazing program. It can interest an 8 year old trying to pick out a simple tune using only note x, sleep y combinations of commands, to experimenting with a simple rhythm track and building up some live coding, to myself (nearly 69) who finds it a much more satisfying medium to work with, even than Logic Pro which I have on my Mac. I know there are many out there who feel likewise. If you have not tried out Sonic Pi, then I would urge you to have a go. I am sure you will not regret it, but be warned. It is highly addictive!

Perhaps I should end by saying that there is a fantastic community of Sonic Pi users. I have enjoyed meeting some and conversing with many. I am very grateful to many who have helped me in so many areas of computing connected with Sonic Pi, and with the music that many have shared. However I think the biggest accolade must go to Sam Aaron which has produced a truly phenomenal program in Sonic Pi, which has had an amazing impact upon so many.
Here he is in action

 

Boot to Sonic Pi from a USB stick (no SD card) on Pi3

Recently I ran up an image on a USB stick which can be used to boot a Pi3 (NOT Pi2 or earlier) straight into Sonic Pi 2.11, without needing an SD card. This is based on excellent documentation on the Raspberry Pi website at https://www.raspberrypi.org/documentation/hardware/raspberrypi/bootmodes/msd.md and I claim no credit for this whatsoever other than having tried it out successfully.

Note this is still an experimental procedure to a certain extent, although with the USB drive I specify below I had no problem in getting to to work with two different Pi3. Your Pi3 will still be bootable as normal from a standard SD card after you have carried out this procedure.

In order to set this up you will need the following:
1 A Pi3 (it will not work on a Pi2 as it uses bootcode built into the Pi3)****
2 A freshSD card on which to build the image which will be transferred to your USB stick. I used a 16Gb Sandisk Ultra miscroSDHC
3 A usb stick. I used a Sandisk Cruzer SDCZ50 16GB from Amazon for £4.99 (not every usb stick will work. The article give a list of some which have been tested)
4 An internet connection for your Pi3

*** It is possible to change this to boot from a Pi2 or earlier, using just one boot file on an SD card. Thereafter the USB stick takes over. See https://www.raspberrypi.org/documentation/hardware/raspberrypi/bootmodes/ for details.

Follow the details of the first part of the article to build up your SD card image Use the Raspbian image dated 2016-09-23 from raspberrypi.org/downloads  Before the second stage, where you transfer the image to your USB stick, install Sonic Pi 2.11 (just released) onto the SD card. You can get it from
http://sonic-pi.net/files/releases/v2.11.0/
download the file sonic-pi_1-2.11.0-2_armhf.deb
I downloaded this via the Chromium browser on the Pi3 to the Downloads folder
Then I installed it with:-

cd ~/Downloads
sudo dpkg -i sonic-pi_1-2.11.0-2_armhf.deb
sudo apt-get install -f

You may find it then lists some redundant packages which you can remove as suggested with

sudo apt-get autoremove

I also added dtoverlays for my IQaudio amp to config.txt using sudo nano /boot/config.txt

dtoverlay=iqaudio-dacplus,auto_mute_amp
dtoverlay=i2s-mmap

which you can do also if you have one, or else any overlays required for an alternative eg HiFiBerry card.

In order to add an auto boot into Sonic Pi you do the following.

mkdir -p ~/.config/autostart
cp /usr/share/applications/sonic-pi.desktop ~/.config/autostart

If you have an IQaudio (or alternative audio card) installed on your Pi3, you should select it as the default card in the Audio Device Settings on the Menu -> Preferences tab

Once you are happy with the SD card, you should complete the second section of the article setting up the USB stick with parted as discussed in the raspberry pi boot documentation article.

All being well, once you have finished you should be able to boot your Pi3 from the usb stick you have set up. Note it does take some time to boot, as it first checks to see if you have an SD card installed, and then switches to search for a USB card after a 5 second timeout. You will see a large rainbow coloured square on your monitor during this process.

I advise you to remove the line added to config.txt

program_usb_boot_mode=1

which was added to program the One Time Programmable memory (OTP) in your Pi3 to enable USB booting. This is an irreversible process, and you may not wish to inflict it on any other Pi3 that the card is subsequently used to boot, although the Pi3 can still boot normally with an SD card even if this has been programmed.

The original github page for the procedure is at
https://github.com/raspberrypi/documentation/blob/master/hardware/raspberrypi/bootmodes/msd.md

and there is more useful information in the parent folder (bootmodes)

This project requires some care to follow the procedures accurately, and it takes a little time to transfer the card contents to the USB stick. Although the boot time is quite long, the performance thereafter is not noticeably different from that of the SD card. Apparently you can add a resistor to one of the GPIO pins to speed up the booting by getting it to ignore the SD card, but I haven’t managed to find out documentation as to which pin is involved. You can also leave a blank SD card in the Pi3 which will also speed up the boot time, by eliminating the timeout wait.