3.7 Paczki z samplami

# Paczki z samplami

**Uwaga: Ten rozdział samouczka omawia kwestię pracy z dużymi katalogami zawierającymi Twoje sample. Jest to przypadek, w którym pobrałeś lub kupiłeś swoje własne paczki z samplami i chciałbyś ich użyć w Sonic Pi.**

**Możesz spokojnie pominąć ten rozdział, jeśli wystarcza Ci zestaw sampli domyślnie dostarczonych z Sonic Pi.**

Kiedy pracujemy z katalogami zawierającymi duże ilości zewnętrznych sampli, wpisywanie ścieżki do każdego pliku może być bardzo uciążliwe.

Na przykład przypuśćmy, że masz na swoim komputerze następujący folder:

```
/path/to/my/samples/
```

Kiedy zajrzymy do tego katalogu, znajdziemy w nim następujące sample:

* `100_A#_melody1.wav`
* `100_A#_melody2.wav`
* `100_A#_melody3.wav`
* `120_A#_melody4.wav`
* `120_Bb_guit1.wav`
* `120_Bb_piano1.wav`

Zazwyczaj, jeśli chcielibyśmy użyć sampla pianino (piano), możemy użyć pełnej ścieżki do danego pliku:

```
sample "/path/to/my/samples/120_Bb_piano1.wav"
```

Jeśli chcemy później użyć sampla o brzmieniu gitary (guitar), to też możemy użyć pełnej ścieżki:

```
sample "/path/to/my/samples/120_Bb_guit.wav"
```

Jednakże w obu tych przypadkach polecenie sample wymaga od nas, żebyśmy *znali* nazwy sampli znajdujących się w naszym katalogu. A co, jeśli chcielibyśmy tylko szybko przesłuchać każdy z nich?

## Sporządzanie indeksu dla paczki z samplami

Jeśli chcemy pierwszy sampel znajdujący się w danym katalogu, wystarczy, że przekażemy do polecenia `sample` nazwę tego katalogu oraz indeks `0`, tak jak poniżej:

```
sample "/path/to/my/samples/", 0
```

Możemy nawet stworzyć skrót do naszego katalogu, używając zmiennej:

```
samps = "/path/to/my/samples/"
sample samps, 0
```

Teraz, jeśli chcielibyśmy zagrać drugi sampel z naszego katalogu, wystarczy, że do naszego indeksu dodamy 1:

```
samps = "/path/to/my/samples/"
sample samps, 1
```

Zauważ, że nie potrzebujemy znać nazw sampli znajdujących się naszym katalogu - musimy tylko wiedzieć, gdzie znajduje się ten katalog (lub posiadać skrót do niego). Jeśli użyjemy indeksu, który jest większy niż ilość sampli w danym katalogu, to wrócimy znowu do pierwszego sampla, tak samo jak w przypadku pracy z pierścieniami. Dlatego też niezależnie od tego, jakiej liczby użyjemy, to zawsze mamy zagwarantowane, że otrzymamy jakiegoś sampla znajdującego się w naszym katalogu.

## Filtrowanie paczek z samplami

Zazwyczaj indeksowanie jest wystarczające, ale czasami potrzebujemy więcej możliwości, aby móc sortować i organizować nasze sample. Na szczęście wiele paczek z samplami umieszcza przydatne informacje w nazwach poszczególnych gotowców. Spójrzmy jeszcze raz na ich nazwy znajdujące się w naszym katalogu:

* `100_A#_melody1.wav`
* `100_A#_melody2.wav`
* `100_A#_melody3.wav`
* `120_A#_melody4.wav`
* `120_Bb_guit1.wav`
* `120_Bb_piano1.wav`

Zauważ, że nazwy plików zawierają całkiem sporo informacji. Po pierwsze mamy informację o tempie sampla wyrażonym w BPM (ilość uderzeń na minutę, z ang. beats per minute). Widać więc, że sampel z dźwiękiem pianina ma 120 BPM, a pozostałe trzy próbki mają po 100 BPM. Ponadto nazwy sampli zawierają informację o tonacji. Sampel z gitarą ma więc tonację B mol (Bb), a pozostałe melodie są w tonacji A fis (A#). Informacje te są bardzo przydatne, gdy chcemy użyć danego sampla w naszym kodzie. Na przykład wiemy, że możemy użyć sampla z pianinem tylko wtedy, gdy nasz kod ma tempo 120 BPM i jest w tonacji B mol (Bb).

Okazuje się, że możemy użyć tej specyficznej konwencji nazewnictwa dla naszych sampli w kodzie, żeby móc filtrować i znajdywać te, których właśnie potrzebujemy. Na przykład jeśli akurat pracujemy w tempie 120 BPM, to możemy odfiltrować tylko takie sample, które posiadają ciąg znaków `"120"` w następujący sposób:

```
samps = "/path/to/my/samples/"
sample samps, "120"
```

Spowoduje to, że zagramy pierwszy pasujący do tego wzorca dźwięk. Jeśli chcemy drugi sampel, który pasuje do tego wzorca, wystarczy, że użyjemy indeksu:

```
samps = "/path/to/my/samples/"
sample samps, "120", 1
```

Możemy nawet użyć kilku filtrów jednocześnie. Na przykład jeśli chcemy wszystkie sample, których nazwa pliku zawiera zarówno ciąg znaków `"120"` oraz `"A#"`, możemy znaleźć je bardzo łatwo, wykorzystując taki kawałek kodu:

```
samps = "/path/to/my/samples/"
sample samps, "120", "A#"
```

Oczywiście wciąż możemy dodawać do poleceń `sample` nasze standardowe opcje:

```
samps = "/path/to/my/samples/"
sample samps, "120", "Bb", 1, lpf: 70, amp: 2
```

## Źródła

System wstępnego przetwarzania parametrów dla funkcji filtrującej sample rozumie dwa typy informacji: *źródła* oraz *filtry*. Źródła są informacją wykorzystywaną do stworzenia listy potencjalnych kandydatów. Źródło może przyjmować 2 formy:

1. `"/ścieżka/do/sampli"` - ciąg znaków reprezentujący poprawną ścieżkę do katalogu
2. `"/ścieżka/do/sampli/foo.wav"` - ciąg znaków reprezentujący poprawną ścieżkę do sampla

Funkcja `sample` najpierw zbierze wszystkie źródła, a następnie użyje ich do stworzenia dużej listy kandydatów. Lista ta jest konstruowana najpierw poprzez dodanie wszystkich poprawnych ścieżek, następnie zostają dodane wszystkie poprawne pliki o rozszerzeniach `.flac`, `.aif`, `.aiff`, `.wav`, `.wave`, które znajdują się w podanych katalogach.

Dla przykładu przyjrzyjmy się następującemu kawałkowi kodu:

```
samps = "/path/to/my/samples/"
samps2 = "/path/to/my/samples2/"
path = "/path/to/my/samples3/foo.wav"
sample samps, samps2, path, 0
```

W powyższym przykładzie łączymy wykorzystanie sampli znajdujących się w dwóch katalogach oraz dodanie jednego konkretnego sampla. Jeśli `"/path/to/my/samples/"` zawiera 3 sample, a `"/path/to/my/samples2/"` zawiera 12, to mamy w sumie 16 potencjalnych sampli do dodania do naszego indeksu i filtrów (3 + 12 + 1).

Domyślnie, tylko do listy kandydatów zostają dołączone tylko sample znajdujące się w danym katalogu. Czasami może się zdarzyć, że będziesz posiadał wiele zagnieżdżonych katalogów z samplami, które chciałbyś móc przeszukiwać i filtrować. Możesz wykonać wyszukiwanie rekurencyjne wszystkich sampli we wszystkich podfolderach danego katalogu poprzez dodanie na końcu ścieżki `**`:

```
samps = "/path/to/nested/samples/**"
sample samps, 0
```

Przeglądanie i wyszukiwanie sampli wśród wielu katalogów może zająć sporo czasu. Jednakże zawartość wszystkich katalogów jest buforowana, opóźnienie wystąpi więc tylko za pierwszym razem.

Na koniec zauważ, że źródła *muszą iść jako pierwsze*. Jeśli żadne źródła nie zostaną podane, wtedy zestaw wbudowanych sampli będzie wybrany jako domyślna lista kandydatów, z którymi będziesz pracować.

## Filtry

Gdy już masz listę kandydatów, możesz wtedy użyć następującego filtrowania typów, aby ograniczyć wybór:

* `"foo"` Ciągi znaków filtrują podzbiór znaków występujących w danej nazwie pliku (z pominięciem ścieżki katalogu oraz rozszerzenia).
* `/fo[oO]/` Wyrażenie Regularne odfiltruje wszystkie nazwy plików pasujące do podanego wzorca (pomijając ścieżkę do pliku i rozszerzenie).
* `:foo` - Słowa kluczowe odfiltrują kandydatów, dla których słowo kluczowe jest dokładnym dopasowaniem do nazwy pliku (bez ścieżki do katalogu i rozszerzenia tego pliku).
* `lambda{|a| ... }` - Prócz z jednym argumentem będą traktowane jako kandydat do odfiltrowania lub jako funkcja generującą. Zostanie do niej przekazana lustra aktualnych kandydatów i musi sycić nową listę kandydatów (listę poprawnych ścieżek do plików z samplami).
* `1` - Liczby spowodują wybranie kandydata pod podanym indeksem (zataczając rundę tak jak pierścień, jeśli będzie to konieczne).

Na przykład możemy odfiltrować wszystkie sample z danego katalogu, które zawierają ciąg znaków `"foo"` i zagrać pierwszy pasujący sampel z prędkością równej połowie normalnego tempa:

```
sample "/path/to/samples", "foo", rate: 0.5
```

Zajrzyj do pomocy, gdzie opisane jest polecenie `sample`, żeby zobaczyć wiele szczegółowych przykładów użycia. Zwróć uwagę na to, iż kolejność nakładania filtrów ma znaczenie.

## Kompozyty (obiekty złożone)

I na koniec chciałbym, żebyś wiedział, że wszędzie tam, gdzie wykorzystujesz źródła i filtry, możesz użyć list. Lista zostanie automatycznie spłaszczona, a jej zawartość zostanie użyta w taki sam sposób jak regularne źródła i filtry. Dlatego też poniższe użycia polecenia `sample` są semantycznie tożsame:

```
sample "/path/to/dir", "100", "C#"
sample ["/path/to/dir", "100", "C#"]
sample "/path/to/dir", ["100", "C#"]
sample ["/path/to/dir", ["100", ["C#"]]
```

## Pakowanie

To była zaawansowana sekcja dla osób, które potrzebują potężnego narzędzia do manipulacji paczkami sampli. Nie przejmuj się, jeśli znaczna część tej sekcji jest dla Ciebie niezrozumiała. Bardzo prawdopodobne jest to, że na razie nie będzie Ci to do niczego potrzebne. Jednak będziesz tego wymagał, kiedy nadejdzie odpowiednia pora. Możesz wtedy wrócić do tej sekcji i ponownie przeczytać, w jaki sposób można radzić sobie z dużymi katalogami sampli.
