Iedereen leert rekenen en schrijven op school, maar programmeren is geen kernvak. Daar moet verandering in komen. Niet omdat we allemaal programmeur willen worden (niet iedereen wil tenslotte schrijver worden), maar omdat het leerzaam is en ons blikveld verbreed. Aldus Sam Aaron, het meesterbrein achter Sonic Pi.

Auteur: Martin ? (achternaam onbekend bij eindredactie)

Waarom Sonic Pi?

Tegenwoordig zijn veel tools beschikbaar om (jonge) leerlingen de beginselen van het programmeren bij te brengen. Hiervan is Scratch (https://scratch.mit.edu/) misschien wel de meest bekende. Ontwikkeld aan het MIT is het de standaard voor programmeeronderwijs op de lagere school geworden.

Sam Aaron wil echter van Sonic Pi een educatief leermiddel en tegelijkertijd volwaardig muziekinstrument maken waar zowel beginnende leerlingen als professionele muzikanten mee uit de voeten kunnen. Dat lijkt een ambitieuze doelstelling, maar vergelijk het eens met een gitaar. Van de eerste les tot een Jimmy Hendrix solo worden met hetzelfde instrument gespeeld. Het verschil zit alleen in het talent en de studie van de muzikant.

Sonic Pi

 

Aan de slag

Sonic Pi wordt ontwikkeld met de Raspberry Pi in gedachten. Dat maakt het een draagbaar instrument is, dat goedkoop en gemakkelijk overal in te zetten is. De nadruk bij de ontwikkeling ligt dan ook op die versie. Maar gelukkig wordt er ook voldoende tijd en moeite gestoken in een courante Windows- en Macversie. De Linux variant is, hoe onwaarschijnlijk het ook mag klinken, wat minder bij de tijd om redenen waar ik straks op terug zal komen. Op dit moment is er voor Ubuntu (of Mint) een iets verouderde versie 2.10 in de repositories beschikbaar, maar als je avontuurlijk aangelegd bent, dan kan je versie 3.1.0 downloaden van git (https://github.com/samaaron/sonic-pi.git) en zelf compileren.

Exclusieve Audio

Sonic Pi is ontworpen om live performances mee te verzorgen. Dat stelt hoge eisen aan timing, beschikbaarheid en bedrijfszekerheid van bronnen in je systeem. Normale Linux desktops worden tegenwoordig vaak geconfigureerd met pulseaudio voor het routeren van verschillende geluidsbronnen naar de beschikbare uitvoerapparaten, zoals de geluidskaart in je computer of de bluetooth speakers waar je mee verbonden bent.

Voor Sonic Pi is dat niet goed genoeg. Daarom is gekozen voor de Jack audioserver. Jack garandeert sample nauwkeurige onderlinge synchronisatie van audiobronnen, maar dat gaat ten koste van de gebruiksvriendelijkheid van pulseaudio. Jackd, en daarmee Sonic Pi, kaapt je ALSA default audio device zolang Sonic Pi draait. Mocht je tijdens het werken met Sonic Pi toch gebruik willen maken van andere geluidsbronnen, dan kan je pulseaudio wel zo configureren dat het de Jack server als audio uitgang gebruikt door het installeren van de pulseaudio-module-jack package. Het meest gelezen advies blijft toch: “Gebruik pulseaudio en jack niet door elkaar” (http://jackaudio.org/faq/pulseaudio_and_jack.html). Op de Raspberry Pi wordt dit allemaal automatisch voor je geregeld. Onder Linux is dat een kleine uitdaging. Bovendien helpt het ook niet dat Sam Sonic Pi zelf ontwikkelt op z’n Mac. Desondanks wordt momenteel een kickstarter project ingericht om het gebrek aan Linux packages op te pakken.

Eerste kennismaking

Na het opstarten, worden we verwelkomd door een wit scherm met een paar afzonderlijke vlakken, waarvan de code editor prominent aanwezig is aan de linkerkant. Rechts bevindt zich de debug log waar we later op terugkomen. Het editor scherm heeft negen verschillende buffers. Dit betekent dat negen afzonderlijke bestanden tegelijkertijd naast elkaar geopend zijn. Onderaan bevindt zich een helpscherm met een uitgebreide tutorial, leerzame voorbeelden, uitleg over verschillende effecten en instrumenten en documentatie van de taal(constructies).

Ruby

Daar waar Scratch zwaar leunt op de grafische representatie van code in blokken, heeft Sam besloten zijn tool en daarmee de taal van Sonic Pi te baseren op Ruby. Hoewel het voor sommigen misschien even wennen is, biedt Ruby een elegante syntax en constructies om de muzikale eigenschappen van Sonic Pi uit te drukken. Het meest simpele voorbeeld om één enkele noot te spelen, ziet er als volgt uit:

play 60

Druk op de ‘Run’-knop en hoor hoe de eerste noot door Sonic Pi gespeeld wordt (Sonic Pi kent gelukkig ook short-cuts, zodat we vlot kunnen luisteren hoe ons experiment klinkt met de toetsencombinatie alt-r). Misschien denk je nu: “60? Wat is er mis met de centrale C op mijn piano?”. De 60 in bovenstaand commando is de toon die bij MIDI-noot 60 hoort, maar de opdracht had net zo goed op deze manier geschreven kunnen worden:

play :C4

De reden waarom Sam een sterke voorkeur heeft voor de numerieke notatie is dat jonge leerlingen intuïtief begrijpen dat een hoger getal een hogere noot oplevert en vice versa. Het staat natuurlijk iedereen vrij om de traditionele muzieksymbolen te gebruiken, maar ook breuken, zoals 60.5 zijn in tegenstelling tot de piano een geldige toon (C# is namelijk MIDI noot 61) en met play hz_to_midi(440) speel je een toon van 440Hz, ook wel bekend als :A4.

Als we nu twee noten willen spelen, doet zich iets vreemds voor:

play 60
play 72

Klik op ‘Run’ en luister naar het resultaat. Is dit wat je had verwacht of niet? De reden waarom we de noten nu tegelijk horen is, omdat Sonic Pi tijd-synchroon ontworpen is (kijk maar eens naar het debugscherm aan de rechterkant, beide tonen worden precies op tijdstip 0.0 uitgevoerd). Om tonen na elkaar te spelen, introduceren we een sleep instructie:

play 60
sleep 1
play 72

De sleep 1 staat in Sonic Pi voor één tel (beat) rust. Omdat de standaard instelling 60 bpm (beats per minute) is, horen we één seconde rust tussen de tonen. Om dit patroon vier keer te herhalen, komen we -in mijn ogen- op één van de mooiste taalconstructies van Sonic Pi:

4.times do
  play 60
  sleep 1
  play 72
  sleep 1
end

Klik weer op ‘Run’ en hoor hoe de twee afzonderlijk tonen vier keer na elkaar gespeeld worden. Met deze twee commando’s is het gros van de westerse muziek te spelen en hebben we de beschikking over een volwaardig muziekinstrument.

Optreden in de Royal Albert Hall, credit Pete Jones.

De klank die we horen als we play gebruiken, is een standaard sinusgolf. Dit is niet het meest inspirerende geluid. Sonic Pi kent gelukkig veel ingebouwde synthesizers en dus kunnen we met een simpel commando wisselen tussen verschillende geluiden. Zet boven de loop hierboven maar eens use_synth :piano en let daarbij ook op de ingebouwde code completion van Sonic Pi, daar ga je veel plezier van hebben. Voer de code opnieuw uit en hoor hoe de tonen nu door een pianoklank gespeeld worden.

Random

Hoewel Sonic Pi uitermate geschikt is voor het componeren van melodieën, wordt het in een live context vaak gebruikt voor generatieve muziek. De randomgenerator is hierbij een onmisbaar instrument. Luister eens naar de volgende code:

use_synth :piano
loop do
  play (scale :C3, :minor_pentatonic, num_octaves: 2).choose
  sleep [0.25, 0.5].choose
end

Wat je hier ziet. is een oneindige loop die uit de pentatonische toonladder van C-mineur in het derde en vierde octaaf een willekeurige noot kiest en daarna een kwart of een halve tel wacht. Geen hoogstandje, maar de basis van wat wellicht een intrigerend stuk zou kunnen worden. Stop de uitvoering door op de ‘Stop’-knop te klikken of met de toetsencombinatie alt-s.

Random is niet random?

Speel bovenstaande code een paar keer snel achter elkaar (alt-r/alt-s) en luister of je iets opvalt. Sonic Pi zal steeds dezelfde willekeurige noten kiezen. De random generator van Sonic Pi is namelijk deterministisch, zodat bij elke uitvoering de muziek reproduceerbaar is. Ook als de code uitgewisseld wordt tussen verschillende systemen. De random generator wordt gevoed uit een seed die aangepast kan worden. Met use_random_seed kan gevarieerd worden in de gekozen variatie:

use_random_seed 4782

Waarbij 4782 een willekeurig gekozen getal is. Door dit getal te variëren, kan de random melodie reproduceerbaar aangepast worden.

Gimme a Beat!

Naast gesynthetiseerde geluiden kan Sonic Pi ook samples afspelen. Hiermee zijn complexe ritmes te bouwen. Om het ons makkelijk (en leuk) te maken, kunnen we handig gebruik maken van voorgekauwde ritme samples. Iets wat vooral ook het jongere publiek aan zal spreken. Eén van de bekendste ritmeloops van de afgelopen tijd is de zogenaamde Amen-loop die ook beschikbaar is in Sonic Pi:

sample :loop_amen

Speel bovenstaande code in een lege buffer en hoor de bekende riedel uit je speakers komen. Speel daarna de sample ook eens op halve snelheid voor een meer HipHop waardige versie:

sample :loop_amen, rate: 0.5

Als we deze loop doorlopend als achtergrond willen gebruiken, dan kunnen we hem in een loop opnemen:

loop do
  sample :loop_amen
end

Deze code geeft een foutmelding en om dat te begrijpen, moeten we terug naar de uitleg over synchroniciteit. Wat we vragen, is de sample oneindig vaak, oneindig snel achter elkaar te spelen. Iets wat zelfs de beste computer vroeg of laat teveel wordt en wat Sonic Pi bij het compileren dan ook netjes detecteert. Om de sample in een loop af te spelen, voegen we dus weer een sleep toe:

loop do
  sample :loop_amen
  sleep 1
end

Dit geeft alleen ook niet het gewenste resultaat, omdat de Amen-loop langer is dan één seconde bij 60bpm (om precies te zijn: 1.75331 seconde). We kunnen dit als volgt oplossen:

loop do
  sample :loop_amen, rate: 1
  sleep sample_duration(:loop_amen)
end

Maar als we deze loop willen combineren met het pianostuk hiervoor, dan komen we met de sleep sample_duration() in de (tel)problemen. Althans, tellen tot 1.75331 is niet heel praktisch. De andere oplossing is dan ook de sample op te rekken naar een veelvoud van hele beats en precies een heel aantal tellen sleep te gebruiken:

loop do
  sample :loop_amen, beat_stretch: 2
  sleep 2
end

Live loops

Misschien wel het spannendste onderdeel van Sonic Pi zijn de live loops. Ze vormen het hart van een live performance met Sonic Pi en worden gebruikt om tijdens een optreden de muziek te ‘kneden’ door voortdurend aan de knoppen te draaien. Live loops kunnen het best vergeleken worden met threads in computerjargon, maar met synchronisatie als randvoorwaarde. We kunnen de piano en Amen-loop met de volgende twee live loops combineren:

use_bpm 70
use_synth :piano

live_loop :melodie do
  play (scale :C3, :minor_pentatonic, num_octaves: 2).choose
  sleep [0.25, 0.5].choose
end

live_loop :drums do
  sample :loop_amen, beat_stretch: 2
  sleep 2
end

De loops zijn vervangen door live_loop en hebben een beschrijvende naam gekregen. Bij een start zullen beide loops tegelijk gestart worden en dankzij het feit dat de drum loop sleep een veelvoud is van de piano loop sleeps, netjes met elkaar in de maat blijven lopen.

Door nu al spelend de code wat aan te passen en op ‘Run’ te klikken (of alt-r te gebruiken), wordt de muziek tijdens het afspelen bij de eerstvolgende iteratie van de loops aangepast, terwijl ze onverstoorbaar door blijven spelen. Dit is de bijzondere eigenschap van live_loops. Verander de Amen sample loop regel eens door de volgende, gevolgd door alt-r:

sample :loop_amen, beat_stretch: 2, amp: 2

Bij de eerst volgende Amen-loop zal deze nu twee keer zo hard afgespeeld worden. De pianonoten kunnen we met wat willekeur ook iets meer leven inblazen (vergeet alt-r niet):

play (scale :C3, :minor_pentatonic, num_octaves: 2).choose, release: 2, amp: rrand(0.5,1.5)

We verlengen hiermee de duur van de noten tot twee tellen (release:) zodat ze elkaar wat overlappen (alsof we het pedaal van de piano intrappen) en geven ze een willekeurig volume (amp:) tussen 0.5 en 1.5.

Daarnaast heeft Sonic Pi een uitgebreid assortiment effecten. Om dat te demonstreren, plaatsen we om de play code van de piano een reverb effect waarmee onze piano ineens in een grote hal lijkt te staan:

with_fx :reverb, room: 0.9 do

    play (scale :C3, :minor_pentatonic, num_octaves: 2).choose, amp: rrand(0.5,1.5)

end

Tenslotte

Dit artikel is veel te kort om alle mogelijkheden en commando’s van Sonic Pi te behandelen. Daarvoor is de tutorial een goed begin, maar wil ik je zeker ook aanraden een paar van de vele praatjes die Sam gegeven heeft op YouTube te bekijken. Het is prachtig en inspirerend om de meester zelf aan het werk te zien. Mocht je je echter tijdens het programmeren afvragen wat de mogelijkheden van een commando, synth of effect zijn, gebruik dan de toetsencombinatie ctrl-i om snel in het helpscherm naar de betreffende uitleg te springen.

Optreden Sam Aaron

Happy Sonic Pi coding!

# Something Stranger
use_bpm 60
p = (ring :e4, :g4, :b4, :c5)
p = p + p.reverse
s = (ring 1.0, 0.75, 0.25, 1.0, 1.0)

live_loop :theme do
  play p.tick, amp: 0.6
  sleep 0.25
end

live_loop :heartbeat do
  loop do
    sample :bd_boom, rate: 1.0, amp: 2
    sleep s.tick
  end
end

live_loop :bass do
  use_synth :dsaw
  play :e1, release: 2
  sleep 2
end