Muzyka algorytmiczna

Zajęcia 4 (2025-03-18)

Zadanie (na 2026-03-25)

Przygotowanie krótkiego utworu (~1min) w środowisku Sonic Pi, spełniającego następujące wymagania:

  1. Utwór minimalistyczny (wg definicji z wykładu)
  2. Wykorzystujący pseudolosowość (co najmniej jedna wylosowana liczba)
  3. Wykorzystujący wielowątkowość (co najmniej dwa równolegle działające fragmenty programu)
  4. Staramy się nie używać sampli!

Terry Riley's "In C" - artykuł anglojęzyczny stanowiący dobry wstęp do minimalizmu.

Zadania na zajęciach

  1. (Rozwiązanie) Stwórz utwór, realizujący następujący algorytm:
    1. Wybierz dźwięk początkowy
    2. Uruchom dwa wątki, każdy z nich losuje losowe przesunięcie dźwięku początkowego w zakresie od -12 do 12, odtwarza go i śpi 1 uderzenie. Jeśli dźwięk jest poza zakresem od :c2 do :c6 powraca do dźwięku początkowego.
  2. (Rozwiązanie) Stwórz utwór o następującej strukturze:
    1. Wylosuj 30 dźwięków o losowej wysokości od 200Hz do 400Hz. Tworzą one akord początkowy.
    2. Odtwórz akord początkowy, stopniowo zwiększając jego głośność (pamiętaj by przed wykonaniem akordu zmienić dźwięki z Hz na MIDI przy pomocy funkcji hz_to_midi)
    3. Powoli przejdź z akordu początkowego do następującego: (ring :d1, :d2, :a2, :d3, :a3, :d4, :a4, :d5, :a5, :d6, :fs6), cały czas zwiększając głośność aż do osiągnięcia maksymalnej głośności (pełnej, 1.0)

Funkcja control

Funkcja control pozwala na zmianę stanu syntezatora po jego uruchomieniu. W Sonic Pi wyrażenie play :c4 tworzy instancję domyślnego syntezatora. Stworzoną instancję możemy zapisać w zmiennej:

c = play :c4

Po uruchomieniu i zapisaniu syntezatora możemy kontrolować jego parametry przy pomocy control

control c, note: :e4 # zmień odtwarzaną nutę na e4
control c, amp: 0.5 # zmień głośność o połowę

Niektóre parametry syntezatora (patrz wbudowana dokumentacja, stwierdzenie „Has slide options”) możemy zmieniać w sposób płynny (np. liniowo, wykładniczo, krokowo). Płynne przechodzenie parametru kontrolujemy przez [nazwa parametru]_slide (np. dla amp mamy amp_slide), które konfiguruje czas przechodzenia pomiędzy starą, a nową wartością:

c = play :c4, note_slide: 1, sustain: 2, release: 1 # przejście pomiędzy dźwiękami będzie trwać jedno uderzenie
control c, note: :e4 # od razu po rozpoczęciu przechodzimy z :c4 do :e4
sleep 1 # czekamy aż przejście się skończy
control c, note: :g4 # i przechodzimy do g4 w trakcie jak dźwięk stopniowo zanika

Generowanie liczb pseudolosowych

Sonic Pi posiada wbudowany generator liczb pseudolosowych, którego stan początkowy jest taki sam przy każdym uruchomieniu.

Tworzenie losowego akordu

akord = []

# Akord ma 12 dźwięków
12.times do
  # Akord składa się z dźwięków od 60 do 72
  akord.push(rrand_i(60, 72))
end

# Odtwarzamy akord
play akord

Płynne prejście z akordu na akord

x = play [:c4, :e4, :g4], duration: 4, note_slide: 1
sleep 1
control x, notes: [:f4, :d4, :a4]

Zadanie 1

początkowy = rrand_i 40, 72

2.times do
  in_thread do
    dźwięk = początkowy
    loop do
      dźwięk += rrand_i -12, 12
      play dźwięk
      sleep 1
      if dźwięk < note(:c2) or dźwięk > note(:c6) then
        dźwięk = początkowy
      end
    end
  end
end

Zadanie 2

akord = []

30.times do
  dźwięk = rrand 200, 400
  akord.push(hz_to_midi(dźwięk))
end

dron = play akord, sustain: 100000, amp: 0, amp_slide: 24, note_slide: 12
control dron, amp: 1
control dron, notes: (ring :d1, :d2, :a2, :d3, :a3, :d4, :a4, :d5, :a5, :d6, :fs6)
thx deep note

Struktura do „In C”

2.times do
  in_thread do
    rand_i(6).times do
      # Pierwszy fragment in C
      play :c4
      sleep 1
    end
    
    rand_i(6).times do
      # Drugi fragment in C
      play :e4
      sleep 1
    end
    
    rand_i(6).times do
      # Trzeci fragment in C
      play :g4
      sleep 1
    end

    # i tak dalej
  end
end