Przygotowanie krótkiego utworu (~30s) w środowisku Sonic Pi, spełniającego następujące wymagania:
cue
, sync
Plik: 04.rb
Sonic Pi posiada wbudowany generator liczb pseudolosowych, którego stan początkowy jest taki sam przy każdym uruchomieniu.
rand n
- losowa liczba zmiennoprzecinkowa od 0 do n
rand_i n
- losowa liczba całkowita od 0 do n
(bez n
)rrand min, max
- losowa liczba całkowita od min
do max
rrand_i min, max
- losowa liczba całkowita od min
do max
(bez n
)Kolejne wywołania wszystkich funkcji losujących w ramach tego samego wątku korzystają z tego samego generatora liczb. Poniższy przykład zwraca ten sam wynik, niezależnie od kolejności wykonania wątków:
print("x=", rand_i(100))
in_thread do
sleep 2
print("y=", rand_i(100))
end
in_thread do
sleep 1
print("z=", rand_i(100))
end
set(:nazwa, wartość)
ustawia wartość, a get[:nazwa]
pobiera wartość
# Pętla kontroluje czas przez zmniejszanie czasu sleep'ów
# halves(1, 4) = (ring 1.0, 0.5, 0.25, 0.125)
live_loop :czas do
set :shared, halves(1, 4).tick
sleep 4
end
live_loop :wysokie do
synth :piano, note: :e4
sleep get[:shared]
synth :piano, note: :f4
sleep get[:shared]
end
live_loop :niskie do
with_fx :lpf, cutoff: :c4 do |f|
f.control cutoff: :g2, cutoff_slide: get[:shared]
synth :piano, note: :c2, duration: 4 * get[:shared]
synth :piano, note: :e2, duration: 4 * get[:shared]
synth :piano, note: :g2, duration: 4 * get[:shared]
end
sleep 2 * get[:shared]
end
beat
zwraca aktualny czas w utworze.
Zakładając, że wykonanie pojedyńczej iteracji każdej pętli zajmuje zawsze tyle samo czasu (dla danej pętli) oraz znając czas wykonania każdej z nich można wprowadzić wspólne przerwania wykonania.
Wykonanie pętli :a
zajmuje 2 uderzenia, :b
3, :c
5.
Oznacza to, że pętla :a
wydaje dźwięk w momencie 0, 2, 4, 6...; pętla :b
w momencie 0, 3, 6, 9...; pętla :c
w momencie 0, 5, 10, 15...
Pierwszym momentem w którym wydadzą wspólny dźwięk jest 30 (= NWW(2, 3, 5)
).
Można wykorzystać ten punkt wspólny jako przerwanie i wykonanie innego zbioru dźwięków, jak w przykładzie poniżej:
Na zajęciach zidentyfikowano problem z poniższym kodem w Sonic Pi od wersji 4.0.0. W pliku z zajęć dostępne jest rozwiązanie dla wymienionej wersji. Poniższe rozwiązanie działa dla wersji starszych niż 4.0.0.
use_bpm 240
use_synth :tri
live_loop :a do
if beat > 0 and beat % 30 == 0 then sync :drop end
play :c4
sleep 2
end
live_loop :b do
if beat > 0 and beat % 30 == 0 then sync :drop end
play :g4
sleep 3
end
live_loop :c do
if beat > 0 and beat % 30 == 0 then sync :drop end
play :e4
sleep 5
end
sleep 30
loop do
sleep(30 * (beat / 30r).ceil - beat)
s = synth :prophet, note: :c2, cutoff: :c9, duration: 8.1
control s, cutoff: :c2, cutoff_slide: 8
sleep 8
cue :drop
end
Proces ten można zautomatyzować, co pokazuje ten przykład.