# 采样包

注意：这部分教程包含了关于处理大量自定义采样文件的操作，只有在你下载或购买了自己的采样包，并且想在Sonic Pi中使用的时候，才需要参考这部分内容。

如果你用内置采样包就能玩得很开心，就跳过这部分教程吧。

当你要大量使用外置采样文件的时候，每次都输入相应文件的完整路径会非常麻烦。

例如你想在自己的机器上找到如下文件夹：

    /path/to/my/samples/

我们打开这个文件夹后可以找到下面这些采样：

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

要播放钢琴采样时，我们可以用完整的路径：

    采样样本 "/path/to/my/samples/120_Bb_piano1.wav"

又或者如果我们要播放吉他采样，也可以用完整的路径：

    采样样本 "/path/to/my/samples/120_Bb_guit.wav"

但是，使用这些采样需要我们事先知道我们目录中采样的名字。如果我们只是想快速地从头到尾听一遍每个采样，该怎么做呢？

## 索引采样包

如果我们想播放一个目录下的第一个采样，只需要像这样，在’sample’后加上目录名和索引号’0’ ：

    采样样本 "/path/to/my/samples/", 0

我们还可以利用变量来快速调用某个文件路径：

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

如果我们想播放目录中的第二个采样，只需要在索引号后加1：

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

注意我们已经不需要知道目录中采样的文件名，只需要知道文件夹的路径（或者有一个指向它的快捷方式）。如果我们输入了一个比文件数目更大的索引号，它会又从头开始算起，就像ring列表一样。因此不管我们输入什么样的索引号，总能得到目录中的某个采样。

## 过滤采样包

通常用索引就够了，但有时我们还需要更强大的方式来分类整理我们的采样文件。有很多采样包会在文件名中附带有用的信息，让我们再仔细看看目录中的采样文件名：

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

可以看到这些文件名包含了不少信息。首先在开始处可以看到采样的BPM（每分钟节拍数）。所以钢琴采样的BPM是120，而我们前面的三段旋律BPM是100。还可以看到文件名标明了采样的调性。比如吉他采样是Bb调，而我们旋律是A#调。我们在代码中编入这些采样时，这些信息是很有用的。比如说，我们可以知道只能在BPM为120且调性为Bb的旋律中使用这个钢琴采样。

实际上我们可以利用采样包的这个命名规则，在代码中过滤筛选出我们想要的采样。例如，如果我们当前的BPM是120，我们可以过滤出所有文件名中含有”120”的采样文件：

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

这样会播放第一个符合这个条件的采样。如果想用第二个符合条件的采样，只需要加入索引号：

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

甚至还能同时使用多个过滤规则。例如，如果我们想要文件名同时包含了”120”和”A#”的采样，我们可以用下面的代码来过滤：

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

最后我们还是可以自由地加上sample常用的选项：

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

## 采样来源

采样过滤器的前置参数系统可以解析两种类型的信息：采样来源（sources）和过滤选项（filters）。采样来源信息可以用来产生一系列的备选采样，采样来源可以有两种形式：

1. `"/path/to/samples"` - 代表采样文件路径的字符串
2. `"/path/to/samples/foo.wav"` - 代表某个路径下的采样文件的字符串

`sample`的这个功能首先会搜集所有的采样来源，形成一个备选采样的大列表。这个列表由所有可用的采样来源目录下的`.flac`, `.aif`, `.aiff`, `.wav`, `.wave`这几类文件组成。

观察一下下面的代码：

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

我们可以用这种方式把两个目录中包含的采样和另一个特定的采样都加入到备选列表中，如果`"/path/to/my/samples/"`中有3个采样， `"/path/to/my/samples2/"` 中有12个采样，那么我们的备选列表中就有3+12+1个采样，可以用前面讲过的索引和过滤器的方式来处理它们。

默认情况只有直接包含在目录下面的采样文件会包含到列表中，但有时候你可能会想要搜索和过滤子文件夹中包含的采样文件，你可以在某个文件路径后加`**`来实现：

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

但是要注意，搜索大量的文件夹可能会耗费很长的时间。不过所有的采样来源会写入到缓存中，所有只有第一次搜索会耗时间。

最后需要注意的是采样来源的参数要放在最前面。如果没有设定来源，就会使用内置的采样库作为备选列表。

## 过滤器

拥有一个备选列表后，你可以用下面的过滤类型进一步缩小选择范围：

- `"foo"`会过滤出文件名中含有对应字符串的采样（不包括文件路径和扩展名）。
- `/fo[oO]/`正则表达式会过滤出匹配相应规则的文件名（不含文件路径和扩展名）。
- `:foo` 这个形式会过滤出完全匹配关键词的采样文件名（不含文件路径和扩展名）。
- `lambda{|a| ... }` - Procs with one argument will be treated as a candidate filter or generator function. It will be passed the list of current candidates and must return a new list of candidates (a list of valid paths to sample files).
- `1`会以索引号形式在备选列表中选出相应的采样（采用ring的方式循环选择）。

例如，我们可以从一个目录中包含的所有采样中过滤出文件名含有`"foo"`的采样，并播放第一个匹配的采样，用原来的一半速度：

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

具体的使用例子可以参考`sample`函数的文档，注意过滤器的顺序会影响结果。

## 复合参数

采样来源和过滤器都可以用列表的形式来表示，列表会自动打散，里面的元素会像普通的采样来源和过滤器一样被读取，因此以下的几个`sample`例子表示的是同样的意思：

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

## 小结

这部分内容是给那些想要更有效地使用采样包的人参考的，如果你啥都看不明白也没关系，很可能你目前根本用不着这些内容。未来你有可能有需要，你可以重新回来看看这部分关于如何使用大量采样包的内容。