6.2 Efekty w praktyce

# Efekty w praktyce

Pomimo że na pierwszy rzut oka wyglądają one na zwodniczo łatwe, to od środka efekty są tak naprawdę bardzo złożonymi bestiami. Ich prostota bardzo często kusi ludzi, by nadużywać ich w swoich kawałkach. Może to być w porządku, jeśli masz dobry i wydajny komputer, ale jeśli tak jak ja korzystasz z Raspberry Pi do jamowania, musisz być wtedy bardzo ostrożny z tym, ile pracy mu zlecisz do wykonania, jeżeli chcesz być pewien, że beat zachowa swą płynność.

Rozważ taki kawałek kodu:

```
loop do
  with_fx :reverb do
    play 60, release: 0.1
    sleep 0.125
  end
end
```

W powyższym kawałku zagraliśmy nutę 60 z bardzo krótkim czasem zanikania (release), więc jest ona niezwykle krótka. Chcemy również nałożyć na nią efekt reverb, więc opakowaliśmy ją w blok związany z nim. Jak na razie wszystko w porządku. Z wyjątkiem...

Przyjrzyjmy się, co ten kod tak naprawdę robi. Na początku mamy pętlę `loop`, co oznacza, że wszystko wewnątrz niej będzie powtarzane w nieskończoność. Następnie mamy blok `with_fx`. Oznacza to, że utworzymy nowych efekt FX *dla każdej iteracji pętli `loop`*. To tak, jakbyśmy chcieli mieć oddzielny efekt gitarowy reverb przy każdym jednym uderzeniu w strunę gitary. Fajnie, że możemy tak zrobić, ale nie zawsze jest to coś, co chciałbyś osiągnąć. Na przykład ten kawałek kodu czeka niezła walka, aby został on ładnie uruchomiony na Raspberry Pi. Cała praca potrzebna do stworzenia efektu reverb, a potem czekanie do momentu, w którym będzie wymagał zatrzymania i usunięcia, jest obsługiwana za Ciebie przez funkcję `with_fx`, zajmie to jednak sporo mocy procesora (CPU), która może okazać się bardzo cenna.

A co, jeśli sprawimy, by ten kod był bardziej podobny do tradycyjnego zestawu, gdzie nasz gitarzysta posiada tylko *jeden* efekt reverb i to przez niego przechodzą wszystkie dźwięki? Łatwizna:

```
with_fx :reverb do
  loop do
    play 60, release: 0.1
    sleep 0.125
  end
end
```

Umieściliśmy naszą pętlę *wewnątrz* bloku `with_fx`. W ten sposób tworzymy tylko jeden efekt reverb dla wszystkich nut, które zostaną w niej zagrane. Taki kod jest dużo bardziej wydajny i na pewno będzie działał w porządku na Raspberry Pi.

Kompromisem może też być użycie efektu `with_fx` wewnątrz pętli loop, ale powyżej iteracji wewnętrznej:

```
loop do
  with_fx :reverb do
    16.times do
      play 60, release: 0.1
      sleep 0.125
    end
  end
end
```

W ten sposób przenieśliśmy efekt `with_fx` na zewnątrz wewnętrznej części pętli `loop` i teraz tworzymy nowy efekt reverb tylko co 16 zagranych nut.

To jest tak często używany wzorzec, że funkcja `with_fx` posiada dodatkową opcję, która umożliwia nam to samo, ale bez konieczności pisania bloku `16.times`:

```
loop do
  with_fx :reverb, reps: 16 do
    play 60, release: 0.1
    sleep 0.125
  end
end
```

Oba przykłady `reps: 16` i `16.times do` zachowają się tak samo. Zasadniczo kawałek ` reps: 16` spowoduje powtórzenie kodu znajdującego się w bloku `do/end`. Możesz więc używać obu konstrukcji zamiennie i wybrać tę, która odpowiada Ci bardziej.

Pamiętaj jedno - błędów nie ma, są tylko nowe możliwości. Jednakże każdy z powyższych podejść będzie miał inne brzmienie oraz inną charakterystykę wydajności. Staraj się więc używać takiego podejścia, które będzie brzmiało najlepiej, mając jednocześnie na uwadze fakt pracy z ograniczeniami wydajnościowymi Twojego komputera/platformy, na której pracujesz.
