Aus Raspberry Pi Geek 06/2019

Audio-Programmierung mit Sonic Pi, Teil 4 (Seite 2)

Abbildung 2: Das im Beispielaufbau verwendete Keyboard stellt nicht weniger als 12 Drehregler bereit.

Abbildung 2: Das im Beispielaufbau verwendete Keyboard stellt nicht weniger als 12 Drehregler bereit.

Listing 2

live_loop :ctl_monitor do
  ctl, val = sync ".../*/*/control_change"
  puts "#{ctl}, #{val}"
end

In vielen Situationen ist es besser, Controller-Nachrichten mit der Funktion get abzufragen. Anders als sync wartet get nicht auf ein Ereignis, sondern liefert die jeweils zuletzt empfangene Nachricht. Listing 3 zeigt ein entsprechendes Anwendungsbeispiel: Der erste Drehregler steuert die Lautstärke der Bassdrum (Zeile 6), der zweite die Lautstärke der Hi-Hat (Zeile 7).

Listing 3

bd_amp = 0.5
hh_amp = 0.5
live_loop :mixer do
  ctl, val = get ".../*/*/control_change"
  bd_amp = val/127.0 if ctl == 1
  hh_amp = val/127.0 if ctl == 2
  sample :bd_haus, amp: bd_amp
  sleep 0.25
  sample :drum_cymbal_closed, amp: hh_amp
  sleep 0.25
end

Die in Listing 3 gezeigte Lösung funktioniert zwar zuverlässig, erfordert aber viel Tipparbeit. Listing 4 demonstriert einen alternativen Weg: Die erste Zeile legt einen leeren Hash namens vals an. Hashes speichern Schlüssel-Wert-Paare, wobei die Schlüssel hier die Controller-Nummer repräsentieren. Die 64 steht für die Voreinstellung: Ist unter einem gegebenen Schlüssel nichts gespeichert, liefert der Hash diesen Wert.

Für die Aktualisierung des Hashes gibt es einen eigenen Live-Loop. Dort wartet wie gehabt sync auf eine Controller-Nachricht (Zeile 4). Die Zuweisung macht sich die Tatsache zunutze, dass die Auswertung von Ausdrücken von links nach rechts abläuft: Zunächst speichert ctl die Controller-Nummer, dann schreibt vals[ctl] den entsprechenden Wert in den Hash. In den Zeilen 9 und 11 liefern vals[1] und vals[2] dann die jeweils gespeicherten Werte.

Listing 4

vals = Hash.new(64)
live_loop :val_updater do
  ctl, vals[ctl] = sync ".../*/*/control_change"
  puts vals
end
live_loop :beat do
  sample :bd_haus, amp: vals[1]/127.0
  sleep 0.25
  sample :drum_cymbal_closed, amp: vals[2]/127.0
  sleep 0.25
end

Notennachrichten senden

Externe Klangerzeuger mit MIDI-Eingang (Abbildung 3) steuern Sie mit der Funktion midi_note_on an. Das erste Argument bezeichnet die Note, das zweite optional die Anschlagsstärke. Lassen Sie das zweite Argument weg, setzt das die Anschlagsstärke auf den maximalen Wert 127.

Abbildung 3: Auch externe Klangerzeuger wie dieser Korg Microkorg lassen sich in Sonic Pi problemlos nutzen.

Abbildung 3: Auch externe Klangerzeuger wie dieser Korg Microkorg lassen sich in Sonic Pi problemlos nutzen.

Zwischen Sonic-Pi-internen Klangereignissen und MIDI-Ereignissen gibt es einen fundamentalen Unterschied: Bei einem play-Befehl unter Sonic Pi ist von vornherein klar, wie lang die Note klingen soll: play 42, release: 3 dauert drei Schläge.

Anders bei MIDI, wo Beginn und Ende einer Note separate Ereignisse sind: Führen Sie einen Befehl wie midi_note_on 42 aus, ertönt die Note so lange, bis Sie explizit ein midi_note_off 42 folgen lassen (Listing 5). Es kommt daher häufig vor, dass Noten “hängen”, also nicht aufhören zu spielen. In diesen Fällen hilft der Befehl midi_all_notes_off aus der Klemme.

Listing 5

midi_note_on 42
sleep 3
midi_note_off 42

Der Code aus Listing 5 schickt die Nachricht auf allen Kanälen an alle angeschlossenen MIDI-Geräte. Mittels der Optionen port und channel können Sie das aber einschränken (Listing 6). Die Bezeichnungen der verfügbaren Ports erfahren Sie unter Preferences | IO. Statt die Optionen bei jedem einzelnen Aufruf von midi_note_on anzugeben, können Sie diese auch einmalig an use_midi_defaults übergeben.

Listing 6

midi_note_on 42,
  port: "midisport_2x4_midi_1",
  channel: 1
sleep 2
midi_note_off 42,
  port: "midisport_2x4_midi_1",
  channel: 1

Open Sound Control

Open Sound Control oder kurz OSC überwindet einige Beschränkungen von MIDI, wie etwa dessen Begrenzung der Auflösung für Controller-Werte auf 7 Bit und damit 128 Abstufungen. Unter OSC stehen für Ganz- und Gleitkommazahlen jeweils 32 Bit und damit quasi beliebig feine Auflösungen zur Verfügung.

Zudem lassen sich per OSC auch Zeichenketten und – mittels sogenannter Blob-Nachrichten – sogar Audio-, Bild- und Videodaten verschicken. OSC ist plattformübergreifend weit verbreitet, es gibt OSC-Schnittstellen für alle gängigen Programmiersprachen und die meisten Audioanwendungen.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 8 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
RASPBERRY PI GEEK KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Raspberry Pi Geek bei Google Play Readly Logo
Nach oben