Muzyka algorytmiczna

Zajęcia 3 (2025-11-07)

Zadanie domowe (na 2025-11-14)

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

OEIS

Źródło inspiracji i wiedzy na temat sekwencji liczb całkowitych: Online Encyclopedia of Integer Sequences

Zmienne

Zapis jabłko = 2 oznacza stworzenie zmiennej jabłko, która zawiera wartość 2. Jeśli potem użyjemy zmiennej, np. zapisując sleep jabłko to otrzymamy przerwę o długości 2 uderzeń.

Zmienne można aktualizować, ponownie przypisując do nich wartość. Zademonstrowane jest to w poniższym fragmencie kodu:

banan = 1
play :c4
sleep banan
banan = 0.5
play :c4
sleep banan
play :c4

Do aktualizacji zmiennej możemy wykorzystać jej poprzednią wartość. Poniższy kod demonstruje to zastosowanie odtwarzając kolejne półtony:

truskawka = 0
play(60 + truskawka)
sleep 1
truskawka = truskawka + 1
play(60 + truskawka)
sleep 1
truskawka = truskawka + 1
play(60 + truskawka)

Łącząc aktualizację zmiennych z pętlami możemy stworzyć wyliczaną „na żywo” sekwencję liczb:

licznik = 40
loop do
    play(licznik)
    sleep 1
    licznik = licznik + 1
end

Operacja modulo (reszta z dzielenia)

Problemem z powyższym przykładem pętli i licznika jest nieskończony wzrost. Jedną z podstawowych metod ograniczenia dźwięku do pewnego wybranego zakresu jest operacja modulo - operacja reszty z dzielenia.

Przykładowe zastosowanie:

n = 1
loop do
  play 60 + n % 12, release: 0.1 + ((n % 4) / 3.0) * 2
  n = n + 3
  sleep 1
end

Instrukcja warunkowa

Instrukcja warunkowa pozwala na wybór który kod ma zostać wykonany bądź nie na podstawie testu. Test nazywamy warunkiem, a całość - instrukcją warunkową. Ma ona formę if warunek then kod end

n = 0
if n == 1 then
    play :c4 # nie zostanie wykonane ponieważ n jest równe 0
end

n = 1
if n == 1 then
    play :c4 # zostanie wykonane ponieważs n jest równie 1
end

Popularnym zastosowaniem instrukcji warunkowej jest różnicowanie wykonania w zależności od tego czy liczba jest parzysta lub nieparzysta. Możemy wykorzystać konstrukcję if warunek then kod else kod. Część else jest wykonywana wtedy i tylko wtedy kiedy warunek nie zostanie spełniony.

n = 0
loop do
    if n % 2 == 0 then
        # jeśli parzysta (podzielna przez 2 bez reszty)
        play :e4
    else
        # jeśli nieparzysta
        play :f4
    end
    n = n + 1
end

play_pattern_timed i tablice

Odtwarzanie sekwencji dźwięków z użyciem play i sleep może być kłopotliwe - stąd Sonic Pi pozwala na krótszy zapis z użyciem play_pattern_timed.

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

Powyższy zapis można skrócić z wykorzystaniem play_pattern_timed i tablic:

play_pattern_timed [:c4, :e4, :g4], 1