Muzyka algorytmiczna

Zajęcia 2 (2025-10-24,31)

Poruszone zagadnienia

Zadanie domowe (na 2025-11-07)

Stwórz krótki (około 30 sekund) utwór w Sonic Pi spełniający następujące wymagania:

Zadania na zajęciach

  1. Znajdź 3 różne syntezatory i skonfiguruj je w ciekawy sposób
  2. Przygotuj następujące dźwięki:
  3. Stwórz program z dwiema równocześnie wykonywanymi pętlami live_loop. Jedna składala się będzie z szybkiej linii dźwięków w oktawie 5, druga będzie linią basową z dźwiękami w oktawie 2.

Odtwarzanie prostych dźwięków

Aby odtworzyć dźwięk należy użyć funkcji play:

# to jest komentarz. wszystko co jest za znakiem # jest ignorowane
# poniższa linijka odtworzy dźwięk C w oktawie 4 (MIDI 60)
play :c4

Po wpisaniu kodu do edytora należy kliknąć przycisk run.

Sonic Pi wykorzystuje notację angielską! Nie ma dźwięku H! Ściąga jak zapisywać dźwięki w Sonic Pi.

Chcąc odtworzyć kilka dźwięków po sobie zapisalibyśmy je kolejno (jak w kodzie poniżej). Nie jest to jednak prawidłowe rozwiązanie! Sonic Pi nie czeka na zakończenie dźwięku - sprawiając, że uruchamiając poniższy kod usłyszymy akord C-Dur:

play :c4
play :g4
play :e4

By móc odtwarzać dźwięki po sobie musimy poczekać aż dźwięk zakończy odtwarzanie. Domyślna długość dźwięku to 1 uderzenie, zatem chcemy poczekać 1 uderzenie. Możemy to osiągnąć z funkcją sleep:

play :c4
sleep 1
play :g4
sleep 1
play :e4

Zmiana tempa

Sonic Pi operuje na jednostce czasowej nazwanej uderzeniem. Nie wykorzystujemy standardowych określeń takich jak nuta, ćwierćnuta, itp. Osoba programistyczna może wybrać jaka liczba oznacza całą nutę dla ułatwienia procesu kompozycyjnego. Przyjmując całą nutę jako 1, ćwierćnutę zapiszemy jako 0.25. Przyjmując ćwierćnutę jako 1, całą nutę zapiszemy jako 4, a półnutę 2.

Możemy zmienić tempo z jakim przychodzą kolejne uderzenia - służy do tego funkcja use_bpm:

use_bpm 60
play :c4
sleep 1
play :g4
sleep 1
play :e4

use_bpm 120
play :c4
sleep 1
play :g4
sleep 1
play :e4

use_bpm określa ile uderzeń wystąpi w trakcie minuty.

Zmiana syntezatora

Aby zmienić syntezator używany przez funkcję play używamy use_synth. Aby użyć bezpośrednio któregoś z syntezatorów używamy funkcji synth.

use_synth :saw
play :c4
sleep 1
synth :prophet, note: :c4

Parametry syntezatora opisane są w dokumentacji Sonic Pi. W ekranie pomocy (na dole ekranu, jeśli niewidoczny to View < Show Help) można znaleźć dokumentację wbudowanych syntezatorów i ich parametrów (karta Synths).

Obwiednia dźwięku

Obwiednia dźwięku pozwala na kontrolę nad czasem oraz poziomem głośności w trakcie odtwarzania bądź syntezy dźwięku. Pozwala na symulowanie zachowania instrumentów fizycznych - jeśli uderzymy klawisz bądź pociągniemy za strunę na początku dźwięk jest głośny, ale z czasem się wycisza. Obwiednia dźwięku powszechnie znana jest jako ADSR - jest to akronim od pierwszych liter jej parametrów: Attack, Delay, Sustain, Release.

ADSR

Podstawowym parametrem jest sustain. Pozwala nam na określenie jak dlugo dany dźwięk powinien być „przytrzymany”:

play :c4, sustain: 2
sleep 2
play :e4
sleep 1
play :g4

Czas wykonywania dźwięku nie składa się wyłącznie z parametru sustain! Jest to powodem dlaczego dźwięki w powyższym przykładzie na siebie „nachodzą”. Możemy kontrolować w pełni czas wykonania dźwięku przez określenie pozostąłych parametrów:

play :c4, attack: 0.1, decay: 0.1, sustain: 1.7, release: 0.1
sleep 2
play :e4
sleep 1
play :g4

Pętle

Aby wykonać kod n-razy (np. 5) możemy użyć konstrukcji .times do ... end:

5.times do
    play :c4
    sleep 1
end

Aby wykonywać kod w nieskończoność (do manualnego zatrzymania przez nas programu) możemy wykorzystać pętlę loop:

loop do
    play :c4
    sleep 1
end

Równoległość

Aktualnie przedstawione techniki pozwalają nam na tworzenie akordów i sekwencyjne wykonywanie dźwięków. Wykonywanie przy ich pomocy wielu warstw jest możliwe, ale klopotliwe - musielibyśmy zapisywać każdą z warstw jako akordy o różnych długościach składających się na nie dźwięków. Sonic Pi umożliwia podzielenie wykonywanego programu na wątki - tworząc niejako nowego wykonawcę.


# Wykonujemy dźwięk c4
play :c4
sleep 1

# Rozdzielamy na dwa wątki - jeden kontynuje za end bloku in_thread, drugi wykonuje in_thread
# Wraz z dotarciem do end wykonawca w in_thread przestaje istnieć

in_thread do
    play :c3
    sleep 1
    play :c3
end

play :c5, sustain: 0.5
sleep 0.5
play :c5, sustain: 0.5
sleep 0.5
play :c5, sustain: 0.5
sleep 0.5
play :c5, sustain: 0.5

Łączenie pętl i wątków jest jednym z podstawowych działań w sonic pi - stąd posiada dedykowaną konstrukcję pętli live_loop:

# :foo jest nazwą wybraną przez osobę autorską, można użyć innej jak :apple bądź :melodia
live_loop :foo do
    play :c5, sustain: 0.5
    sleep 0.5
end

live_loop :bar do
    play :c2
    sleep 1
end