Ruby als Kompositionswerkzeug: Sonic Pi
(bhmt.dev)- Sonic Pi wird als Umgebung vorgestellt, in der man auch ohne Instrumente und Equipment Musik machen kann; mit einer Ruby-basierten DSL lassen sich Noten, Akkorde, Skalen und Timing direkt schreiben
- Mit Rubys Funktionen, Arrays, Bedingungen, Schleifen und Scopes lassen sich
play,sleep,play_pattern_timed,chordundscalebündeln, um wiederholte Patterns und Arpeggios knapp zu konstruieren - Kombiniert man
in_thread,ring,flatten, den Splat-Operator undwith_fx, kann man mehrere „Instrumente“ gleichzeitig ausführen und überlagerte Töne sowie unterschiedliche Rhythmen schichten - Die Steuerung von
attack,decay,sustainundreleaseder ADSR-Hüllkurve zielt weniger auf eine realistische Chor-Nachbildung als darauf, Haltezeit und Trennschärfe passend einzustellen live_loopkann laufenden Code aktualisieren und wiederholt ausführen; dadurch wird Sonic Pi zu einem Werkzeug für Live-Performances und lässt Code als lesbaren Text wie auch als schöpferische Handlung erscheinen
Sonic Pi per Code steuern
- Sonic Pi ist im Unterschied zu üblichen Audio-Anwendungen ein Software-Synthesizer, der ausschließlich per Code gesteuert wird
- Die eigene Steuersprache ist eine aus Ruby erweiterte domänenspezifische Sprache (DSL) und bildet Musik- und Audiokonzepte auf Ruby-Syntax ab
- Die Grundelemente bestehen aus Ruby-Werten und Sonic-Pi-Funktionen
- Notennamen wie
:c4werden als Symbole verwendet, die dem jeweiligen MIDI-Code entsprechen - Mit Argumenten für Grundton und Akkordstruktur, etwa
chord(:d3, :maj7), lassen sich Akkorde erzeugen playspielt einen Ton ab, und zusammen mit Rubyssleepwerden Zeitabstände gesteuertplay_pattern_timednimmt eine Liste von Tönen und Zeitabständen entgegen und verkürzt Code für wiederholte Wiedergabe
- Notennamen wie
- Ziel des Beispiels ist es, nur mit den Grundfunktionen von Sonic Pi und ohne externes MIDI oder Samples eine Demo-Begleitung per Code zu erstellen
- Nach der Installation der Sonic-Pi-App kann man den Beispielcode einfügen und nachvollziehen; Sprachdokumentation und Tutorials sind ebenfalls enthalten
Wiederholte Patterns mit Ruby-Syntax erstellen
- Das Grundbeispiel ändert mit
use_bpm 70das BPM und verwendet mituse_synth :pulsestatt der standardmäßigen Sinuswelle einen Pulse-Synthesizer - Wiederholt man
play :c2undsleep 0.25, lassen sich Töne der Reihe nach abspielen; mitplay_pattern_timed [ :c3, :d3, :e3, :g3 ], 0.25kann dieselbe Struktur kürzer geschrieben werden - Da die Steuersprache auf Ruby aufsetzt, lassen sich Patterns mit Funktionen und Schleifen abstrahieren
- Die Funktion
arpeggiatenimmt einen Grundton und optional die Angabe, ob es Moll sein soll, und erzeugt ein auf- und absteigendes Pattern - Mit einer
4.times-Schleife wird dasselbe Pattern über mehrere Oktaven hinweg ausgeführt - Eine Bedingung ändert bei Moll die Terz, und mit
mapauf einem Array wird durch Addieren von Intervallen zum Grundton eine Tonliste erzeugt
- Die Funktion
- Synthesizer-Standardoptionen lassen sich vorab setzen, etwa mit
use_synth_defaults amp: 0.1; Optionen können auch direkt anplayoderplay_pattern_timedübergeben werden - In Ruby sind Klammern bei Funktionsaufrufen optional, doch bei Fällen wie
play chord(:a3, maj7)kann es nötig sein, die Abgrenzung klarzumachen
Parallele Ausführung und Layering
in_thread do-Blöcke werden in Sonic Pi verwendet, um Code parallel auszuführen- Mit unterschiedlichen
in_thread-Blöcken können zwei separate „Instrumente“ gleichzeitig laufen- Ein Thread kann ein Arpeggio-Pattern übernehmen
- Ein anderer Thread kann mit
use_synth :sawsowie einem Melodie-Array und einem Rhythmus-Array eine eigene Linie spielen
play_pattern_timedkann nicht nur eine Tonliste, sondern auch eine Liste von Zeitabständen entgegennehmen[1] * 2verlängert ein Array und wiederholt dessen Inhalt, also etwa zu[1, 1]- Verschachtelte Arrays werden von
play_pattern_timednicht unverändert akzeptiert, daher nutzt manflatten, um sie zu einem Array auf einer Ebene aufzufalten
- Für überlagerte Töne wie in einem Chor lassen sich mehrere Töne mit
ring(:c5, :e5)zusammenfassen flattenkann auch die Liste innerhalb vonringzusammenführen; in diesem Fall nutzt man stattdessen den Splat-Operator*, um Listeninhalte in das übergeordnete Array zu entfalten
Scope, Effekte und Aufbau von Chorstimmen
- Mit verschachtelten
in_thread-Blöcken kann man Rhythmusfragmente aus dem äußeren Scope teilen und zugleich in jedem inneren Thread dieselben Variablennamen erneut verwenden - Teilt man Stimmen wie Sopran und Alt in eigene Threads auf, hat jeder Block seinen eigenen Scope und greift nicht direkt auf die Variablen der anderen zu
with_fx :reverb, mix: 0.2erzeugt einen Effektblock; der Signalfluss beginnt in der innersten Ebene und wandert nach außen durch die Effektkettemixbezeichnet das Mischverhältnis aus Wet- und Dry-Signal- Das Wet-Signal ist das Signal mit angewendetem Effekt
- Das Dry-Signal ist das Signal ohne Effekt
- Eine ganze Gruppe mit einem Effekt zu umhüllen, lässt sich ähnlich wie ein Bus in einer DAW verwenden; tieferes Routing ist jedoch manuell und muss wegen der Scopes meist von oben nach unten aufgebaut werden
- Sonic Pi behandelt man natürlicher als Instrument denn als präzises Produktionswerkzeug
Tonlängen mit der ADSR-Hüllkurve anpassen
play_pattern_timedergänzt einensustain-Wert, sodass sich die Haltezeiten langer und kurzer Akkorde direkt anpassen lassenattack,decay,sustainundreleasebilden die ADSR-Hüllkurve, die beschreibt, wie sich die Lautstärke über die Zeit verändertattackist die Zeit von 0 bis zum ersten Peak und entspricht dem anfänglichen Anschlag, etwa dem Zupfen einer Gitarrensaite oder dem Moment, in dem ein Klavierhammer trifftdecayist die Zeit des Abfalls vom ersten Peak und entspricht der Phase, in der der Klang allmählich leiser wird, auch wenn eine Klaviertaste oder Gitarrensaite gehalten wirdsustainist die Zeit, in der der Klang mit stabiler Lautstärke gehalten wird, etwa bei einer gestrichenen Saite oder einer lang gehaltenen Gesangsstimmereleaseist die Zeit nach dem Loslassen des Klangs, bis er tatsächlich verstummt
- Nicht jeder Klang besitzt alle ADSR-Elemente
- Synthesizer-Töne sind erzeugte Klänge und haben daher nicht zwangsläufig einen anfänglichen Aufbau oder Nachhall
- Bei natürlichen Instrumenten variiert das Verhältnis der Elemente je nach Spielweise
- Die Chorsimulation im Beispiel konzentriert sich weniger auf Realismus als darauf, Töne genau für die richtige Dauer zu halten und zwischen Akkorden etwas Trennung zu schaffen
- Die Funktion
choral_rings notes, susnimmt eine Tonliste und eine Haltezeit entgegen, spielt sie mitring(*notes)gemeinsam ab, berechnetsustainundreleaseund wartet dann mitsleep susbis zum nächsten Ereignis
Live-Coding mit live_loop
- Mit
live_looplässt sich Code unbegrenzt wiederholt ausführen - Sonic Pi ist stark auf Live-Performances ausgelegt, und Code innerhalb von
live_loopläuft, bis das Programm gestoppt wird - Auch während der Wiedergabe kann man den Loop-Inhalt ändern; führt man den Startbefehl erneut aus, wird der aktualisierte Loop ab der nächsten Wiederholung angewendet
- Vorhandene äußere
in_thread-Schleifen lassen sich in die Formlive_loop :some_unique_nameändern - Die Effektkette wird bei jedem Loop-Durchlauf erneut erzeugt; je mehr Effekte man stapelt, desto günstiger ist es aus Ressourcensicht, sie außerhalb von
live_loopzu platzieren - Das finale Beispiel besteht aus
live_loop :harpundlive_loop :choir- Der Loop
:harpverwendet den Synthesizer:squareund ein Arpeggio-Pattern der Länge 0.25 - Der Loop
:choirverwendet den Synthesizer:saw,sleep 64,with_fx :reverb, mix: 0.75und Aufrufe der Funktionchoral_rings, um Chorakkorde abzuspielen
- Der Loop
Programmieren als schöpferische Handlung verstehen
- Technische Arbeit wird meist aus der Perspektive der Informatik diskutiert, doch auch Programmierung kann Kunst sein
- Künstlerisch ist sie nicht nur dann, wenn sie bewusst kreative Ergebnisse erzeugt, etwa Audiogenerierung oder CSS-Layouts
- Code ist nicht nur ein für Maschinen optimierter Befehlssatz, sondern organisierter Text, den andere Menschen und das zukünftige Ich lesen
- Guter Code ist Code, der so geschrieben ist, dass andere oder man selbst in sechs Monaten ihn auf einen Blick verstehen können
- Manchmal wird die Kunstfertigkeit von Code zum Selbstzweck; das Sonic-Pi-Beispiel zeigt diesen Punkt anhand der Musikproduktion
1 Kommentare
Meinungen auf Hacker News
Wenn ihr euch für Live-Coding interessiert, ist auch Glicol(https://glicol.org) einen Versuch wert.
Es gibt auch TidalCycles, und die Fähigkeit von Haskell und Ruby, DSLs zu bauen, ist wirklich lobenswert.
Glicol konzentriert sich auf eine von Synthesizern inspirierte Syntax, Kompositionsgeschwindigkeit und Komfort beim Sounddesign. Die Idee ist, eine DSL zu entwerfen, die bestehende Programmiergewohnheiten aufgreift, ohne an eine bestimmte Sprache gebunden zu sein.
https://github.com/tidalcycles/strudel
Vor ein paar Jahren habe ich auf YouTube ein Video gesehen, in dem jemand mit Sonic Pi die THX Deep Note nachgebaut hat.
Am Anfang erklärte er nicht, was er bauen würde, sondern erzeugte einen einzelnen „Ton“ des Klangs und nannte ihn eine Biene. Er passte dieses Bienengeräusch nach und nach an und spielte es vor. Am Ende ging es dann ungefähr so weiter: „Machen wir ein paar hundert dieser Bienen und schauen wir, wie das in einem Bienenstock klingt“ — und in diesem Moment erschien die Deep Note.
Das Video war wirklich großartig, aber ich habe es seitdem nicht wiedergefunden. Wenn jemand den Link kennt, wäre es schön, wenn er ihn teilen könnte.
Ich denke, das ist einer der Fälle, in denen Ruby glänzt. Dank Metaprogrammierung kann man die Syntax fast wie Englisch aussehen lassen.
Vor ein paar Jahren habe ich Sam Aaron, also den Schöpfer von Sonic Pi, live mit Sonic Pi auftreten sehen.
Jedes Mal, wenn sich der Code in Echtzeit änderte, entwickelte sich auch die Musik weiter, und es war tatsächlich gut.
Wenn ihr Beispiele für Künstler sucht, die Sonic Pi verwenden: Vor einiger Zeit bin ich auf DJ_Dave gestoßen. Ich finde, das ist ein gutes Beispiel dafür, wie eine talentierte und erfahrene Musikerin dieses Tool gut einsetzt.
Sie hat früher auch ein AMA auf Reddit gemacht, und auf GitHub scheint es ebenfalls Arbeiten von ihr zu geben.
[1] https://www.youtube.com/watch?v=JiQHclg_648
[2] https://www.reddit.com/r/audius/comments/19dxmy6/hey_audius_...
[3] https://github.com/algorave-dave
Als Ruby-Entwickler sieht das wirklich cool aus. Für algorithmisch generierte Musik könnte es Spaß machen, und ich wollte schon einmal laute Ereignisse in einem git-Repository in irgendeine algorithmische Musik umwandeln; dafür scheint es gut zu passen.
Aus Sicht eines Musikers mit mehreren Tasteninstrumenten verstehe ich allerdings nicht so recht, warum man Musiksequenzen ausgerechnet in Ruby schreiben sollte, wenn man zum Komponieren einfach auf einem MIDI-Keyboard spielen oder ein akustisches Instrument aufnehmen und loopen kann. Ich verstehe, dass man in der Ruby-DSL eingeben kann, was man will, aber im Vergleich zu einer Klaviatur würde ich die User Experience nicht als besser bezeichnen.
Anders gesagt: Ich glaube nicht, dass ich das als Ersatz für Logic verwenden würde. Das ist natürlich persönliche Vorliebe.
Hinweis: http://listen.hatnote.com/
Tatsächlich denkt man manchmal in Begriffen wie „jetzt ein c-Moll-Arpeggio, jetzt ein F-Dur-Arpeggio“, und es ist schön, solche Absichten sehr klar als Funktionen komponieren zu können.
Der Kern scheint eher darin zu liegen, Musik algorithmisch zu erzeugen, statt jede einzelne Note einzuspielen.
Trotzdem passt es ziemlich gut zu den Interessen von Hacker News, ein Tool, das man normalerweise nicht verwenden würde, wegen ungewöhnlicher Einschränkungen auf interessante Weise einzusetzen.
Ich habe ein Keyboard, das mir gefällt, und theoretisch könnte ich es dafür verwenden, aber aus komplizierten persönlichen Gründen sind meine Instrumente seit einiger Zeit alle eingelagert.
Vor ein paar Tagen musste ich zufällig an Sonic Pi denken und habe mir ein paar Online-Videos angesehen.
Ich hatte es vor ein paar Jahren nur kurz ausprobiert und damals klassische Stücke wie Old MacDonald und Hot Cross Buns eingetippt.
Wenn ihr andere Ansätze für Musikprogrammierung sehen wollt: Nicht live, aber scamp[0] für Python ist ebenfalls einen Blick wert.
Der Entwickler hat auf YouTube viele Videos mit Arbeiten gepostet, die er damit gemacht hat, zum Beispiel das Video Fourier Elise[1].
[0] http://scamp.marcevanstein.com/
[1] https://www.youtube.com/watch?v=zq32bIud3OM
HTML-Kommentare scheinen nicht zu funktionieren. Der Editor hat wohl die zwei Bindestriche
--in einen einzelnen em dash—umgewandelt.Ich empfehle außerdem meinen liebsten Sonic-Pi-Live-Coder alsoknownasrox.
https://www.youtube.com/watch?v=wXIvXrBQFkE