Werk des Monats: Informatik trifft Musik

Yannis Laumann (10b) hat im Informatikunterricht ein eigenes Lied mit Hilfe des Open-Source-Programms Sonic Pi programmiert. Hier gibt er uns einen Einblick in sein Projekt!

Die Idee

Meine erste Idee war, ein Spiel mit Python zu programmieren, weil ich es sehr spannend fand. In dem Umfang und der Qualität wie ich es mir vorgestellt habe, hätte die Programmierung und die dazugehörige Ausarbeitung allerdings den Rahmen dieser Projektarbeit gesprengt.

Eines meiner Hobbies ist es, bei Veranstaltungen von Familie oder Freunden als DJ tätig zu sein. Um professioneller zu werden, besuche ich wöchentlich einen DJ-Kurs im Jugendzentrum Lükaz in Lünen. Ich habe viel Spaß an verschiedensten Songs, Beats und Musikrichtungen und verbringe viel Zeit damit, mir harmonische Übergänge zu überlegen und einzuüben. Vor diesem Hintergrund habe ich mich dazu entschieden, einen Beat mit Sonic Pi zu programmieren.

Vorbereitung: Analyse eines Beispiel-Codes

In jedem Sonic Pi Programm kommen die Befehle „play :…“ und „sleep …“ vor. Sie sind die Grundlage jedes Songs. So ist es auch bei dem Programm zu dem Titel „Corridors of Time“ (https://gist.github.com/thisismitch/be9287c80903cad151fe).

Mit „play :a2“ beispielsweise wird ein tiefes a gespielt. Je größer die Zahl ist, desto höher ist der Ton. Der sleep-Befehl gibt an, wieviel Beats zwischen zwei Noten liegen. 

Bsp: „play :a2 sleep 1.5 play :e2.“

Der Beispielcode beginnt mit dem Befehl „use_bpm 112“. Dieser legt fest, dass die Noten mit 112 Beats pro Minute abgespielt werden. 

Zu der Funktion in Abbildung 1 hatten Frau Högele und ich im Unterricht bereits gemeinsam die Vermutung angestellt, dass die Funktion festlegt, dass eine Note, die kürzer als ein Beat ist, automatisch auf einen Beat verlängert wird. Diese Vermutung haben wir mit KI überprüft. Sie wurde bestätigt. Die beiden letzten Befehle der Funktion bewirken, dass die Note, die vom User in der Funktion angegeben wird, mit der angegebenen Dauer (in Beats) abgespielt wird.

Abbildung 1

In den darauffolgenden Zeilen kommt mehrfach der Befehl: „play_pattern_timed [:d4, :fs4, :b4, :cs5, :fs5, :fs4, :b4, :cs5],[0.5], amp: 0.5“ vor. Durch Ausprobieren in Sonic Pi habe ich herausgefunden, dass dieser Befehl, die in der ersten eckigen Klammer angegebenen Noten, nacheinander abspielt.

In der eckigen Klammer nach dem Komma wird festgelegt, wie viele Beats vergehen sollen, bis die nächste Note gespielt wird. Am Ende wird noch mit „amp: 0.5“ festgelegt, wie laut die Noten gespielt werden sollen.

In den folgenden Zeilen nutzt das Programm sogenannte „Defining Functions“. Diese habe ich mir auf der Seite https://sonic-pi.net/tutorial.html#section-5-5 genauer angeschaut und bemerkt, dass sie den Code verkürzen und dadurch deutlich übersichtlicher machen. Wenn man zum Beispiel eine Tonfolge hat, die im Verlauf des Liedes mehrmals abgespielt werden soll, kann man sie entweder jedes Mal neu schreiben oder sie zunächst einmal in einer Defining Function speichern. Später kann man sie dann so oft wie man sie braucht wiederverwenden. Man muss dann nur noch den zuvor festgelegten Namen der Funktion angeben. Ein Beispiel dafür findet man unter anderem in den Zeilen 33-42.

In Zeile 94-108 findet man einen „live_loop“ und auch einen normalen „loop“. Ich hatte eine grobe Vorstellung davon, was diese Befehle bewirken, da wir im Unterricht schon while- und for-Schleifen besprochen hatten. Durch Ausprobieren habe ich herausgefunden, dass ein normaler loop (loop do … end) die Befehle, die zwischen do und end stehen, immer wiederholt, bis das Programm angehalten wird. Ergänzend habe ich mir auf der offiziellen Seite von Sonic Pi die Erklärung zum live_loop durchgelesen (https://sonic-pi.net/tutorial.html#section-9-2). Ein live_loop (live_loop :BeispielName do … end) macht fast genau das gleiche wie ein loop, nur mit folgender Besonderheit: Man kann den Code verändern während der Loop bereits läuft. Drückt man danach wieder auf Play, wird der alte Loop beendet und der neue mit allen Änderungen startet automatisch perfekt im Takt.

Um verschiedene Instrumente oder Klänge zu benutzen, gibt es in Sonic Pi den Befehl „use_synth : …“. Einen solchen Befehl findet man zum Beispiel in Zeile 159 des Codes (use_synth :prophet). Dieser Befehl bewirkt, dass alle darauffolgenden Töne sehr elektronisch klingen. Es gibt aber nicht nur den Synthesizer „:prophet“, sondern viele verschiedene Synthesizer (elektronische Instrumente).

Mein Entwurf

Für mein Projekt komponiere ich einen eigenen House Beat mit Hilfe von Sonic Pi. Dafür verwende ich u.a. einige Befehle aus dem zuvor analysierten Programm, wie zum Beispiel „def“ und „use_synth :prophet“ und mache mir Threads zunutze, um meinem Beat mehr Volumen zu verleihen.

Implementation

In folgenden Schritten bin ich vorgegangen:

  • Da House Beats immer zwischen 115 und 130 bpm haben, habe ich zunächst mit dem Befehl „use_bpm 120“ die bpm auf 120 gesetzt.
  • Dann habe ich online nach einem Drum Pattern (Schlagzeugmuster) gesucht, weil das das Wichtigste für einen guten House Beat ist. Ich habe leider keins gefunden, welches mir direkt gefiel, weshalb ich mich schnell dazu entschlossen habe, ein eigenes in Garage Band zu komponieren und anschließend in Sonic Pi zu übertragen. 
  • Beim Übertragen von Garage Band in Sonic Pi ist das Problem aufgetreten, dass die Bass Drum, die Snare und die Hi-Hat nacheinander abgespielt wurden und nicht wie in Garage Band gleichzeitig. Nach einigem Suchen auf der Seite von Sonic Pi, habe ich dann in der Sektion „Threads“ den Befehl „in_thread do … end“ gefunden. Dieser Befehl legt einen neuen Thread an, wodurch die Noten parallel abgespielt werden. Ich habe dann jeweils für die Kick, Snare und Hi-Hat einen Thread angelegt. Damit war das Drum Pattern fertig.
  • Da mir der Beat aber noch zu langweilig war, habe ich ein bisschen mit dem Befehl „use_synth“ herumspielt und zum Beispiel elektronische Töne und eine Bassgitarre ausprobiert. Letztendlich habe ich mich für eine Pianomelodie entschieden.
  • Ich habe getestet, welche Töne mit welchem Abstand gut zusammenpassen und habe mich für die Tonfolge f2- f2- g2 mit den Abständen 3, 1 und 4 Beats entschieden.
  • Die Pianomelodie wollte ich allerdings nicht nur einmal, sondern mehrmals abspielen lassen. Aus dem Beispielcode kannte ich bisher nur den „loop“ und den „live_loop“. Ich wollte aber nicht, dass die Melodie den Rest des Liedes läuft. Auf der offiziellen Seite von Sonic Pi habe ich den Befehl „3.times do …. end“ gefunden. Dieser Befehl funktioniert genauso wie ein loop, aber man kann mit der eingefügten Zahl am Anfang angeben, wie oft der loop ausgeführt werden soll. Durch diesen Befehl konnte ich meine Melodie gezielt 4-mal abspielen lassen.
  • Als nächstes wollte ich dann einen Drop einfügen, um das Lied spannender zu machen. Dafür habe ich mich an dem Drop in den ersten 15 Sekunden des Liedes „Yeah 3x“ von Chris Brown orientiert. Ich habe mir die Stelle einige Male angehört und konnte den Drop dann relativ schnell und gut in Sonic Pi Befehle übertragen.
  • Mir kam die Idee, dass die bekannte Anfangsmelodie aus dem Pianostück „Solas“ von Jamie Duffy sehr gut zu meinem Drum Pattern passen könnte. Auf TikTok habe ich dazu ein gutes Video mit Noten gefunden, welche ich zum Teil übertragen habe (https://vm.tiktok.com/ZGdmkeCV4/).
  • Als ich die Noten übertragen hatte, klang die Melodie mit den Drums allerdings zunächst noch zu chaotisch, weshalb ich sowohl die Snare als auch die Hi-Hat in diesem Part komplett weggelassen habe.
  • Damit sich der Beat nicht so eintönig anhört, wollte ich noch ein anderes Instrument einfügen. Ich habe die Solar-Noten, die ich schon hatte, kopiert und habe dann das Instrument mit „use_synth :fm“ zu einer Gitarre geändert. Die Gitarre setzt kurz vor dem Ende der ersten Stimme ein und läuft parallel mit.
  • Um die Melodie direkt nach dem Drop noch besser klingen zu lassen, kam mir noch die Idee ein bisschen Reverb (Hall) hinzuzufügen. Auf der Sonic Pi Seite habe ich dafür den Befehl „with_fx“ gefunden, mit welchem man verschiedene Effekte wie Reverb auf Instrumente anwenden kann. Die Intensität des Halls habe ich mit „room: 0.7“ angepasst.
  • Als mein Beat fast fertig war, habe ich der Kick, Snare und Hi-Hat jeweils eine eigene Funktion mit dem Befehl „def“ gegeben. Dadurch wurde der Code übersichtlicher.
  • Als ich meinem Vater diesen ersten Entwurf meines Beats vorspielte, schlug dieser vor, dem ganzen durch den Einsatz einer Bassgitarre mehr Volumen zu verleihen. Er erklärte mir, dass die Noten F und B häufig abwechselnd im Hintergrund eines Liedes mit der Bassgitarre gespielt werden, um mehr Volumen zu erzeugen.
  • Ich habe die KI gefragt, welchen Synthesizer ich benutzen kann, um diese Tonfolge mit dem Sound einer Bassgitarre spielen zu können, da ich im Internet nichts Passendes gefunden hatte. Die Optionen, die die KI mir gegeben hat, habe ich ausprobiert und mich am Ende für den Synthesizer „:fm“ entschieden.
  • Anschließend habe ich für die oben genannte Tonfolge einen neuen Thread angelegt, um sie im Hintergrund parallel zum Piano abspielen zu können.
  • Vor dem Drop habe ich zusätzlich noch ein Bassgitarrensolo eingefügt. Dafür habe ich programmiert, dass die Tonleiter von F nach B hinaufgespielt wird und dann dreimal die Tonfolge F-B anschließt.
  • Diese Abfolge wird insgesamt vier Mal gespielt. Beim vierten Mal aber sollte der letzte Ton der Bassgitarre 3 anstatt 1.5 Beats ausklingen, weshalb ich erst mit dem Befehl „3.times do … end“ drei Mal die ganze Tonfolge abspiele, anschließend unter diese Schleife noch einmal die gleiche Tonfolge gesetzt und beim letzten Ton die Release Time auf 3 gesetzt habe.
  • Die Lautstärke der Bassnoten habe ich sowohl in der Sektion vor dem Drop als auch in der Pianosektion auf „amp:0.75“ „amp: 0.5“ geändert, da der Bass sonst zu dominant gewesen wäre.
  • Anschließend habe mich noch dazu entschieden das Drum Pattern vor dem Drop leicht zu ändern, indem ich die Snare komplett weggenommen und die Hi-Hat nur noch alle zwei Beats spielen lassen habe.

Abschlussreflexion

Ich bin mit meiner Projektarbeit und dem daraus resultierenden House Beat „My First Beat“ sehr zufrieden. Der Code wird sauber ausgeführt und alles wird wie geplant abgespielt. Der Beat klingt harmonisch. 

Es war nicht leicht einen eigenen harmonischen Beat zu komponieren, aber ich finde, es ist mir letztendlich gut gelungen. Bei der Soundentwicklung hat das Erstellen und das Übertragen des Drum Patterns in Sonic Pi am längsten gedauert. Ich musste sehr viel ausprobieren, bis alle Zeiten richtig aufeinander abgestimmt waren. Insgesamt hat die Projektdokumentation am meisten Zeit in Anspruch genommen. Die größte Heraus-forderung war, so zu formulieren, dass auch ein Laie meine Programmierungsschritte gut nachvollziehen kann.

Und hier kann in „My first beat“ reingehört werden:

Text, Bilder und Audio von Yannis Laumann (10b)