Reaktor Core Cell搭建日记(四)

分享到微信朋友圈

· 曾照南 添加于 2017-04-17 · 暂无评论

第一天

在过去的一段时间,我们几乎已经把Reaktor事件处理这一大类下的所有模块都搭建完了,当然除了Event Table这个还真的无能为力以外,我们似乎还漏掉了一两个模块,没错,如果你有去看的话,那你肯定知道它们分别是Randomizer和Frequency Divider。(图1.1)

图1.1

首先,对于Randomizer模块,想要在Core Cell里实现它并不难,但前提是你怎么去生成一个随机数,当然我们知道Randomizer模块它本身产生的是伪随机数,并且我们还可以通过Set Random模块去控制它随机的走向;可问题是回到了Core Cell上,我们就无能为力了吗???不不不,实际上,Core Cell有为我们提供一个产生伪随机数的Macro。(图1.2)

图1.2

对于这个产生伪随机数的Macro,你可以点击去看看它的内部结构,或许你能看懂,也或许你看不懂,但如果你去改变它里面任何一个数字的话,那结果可能又完全不同了;好的,我们暂且不去关心它是怎么产生的,因为对于随机这个领域要探寻的东西太多了,我们只需要考虑这个Macro的特性,然后它对我们去搭建一个新的Randomizer模块有什么帮助。

从图1.2,我们看到这个Macro有两个输入,一个标签为C,另外一个标签为Seed,至于输出不用讲了,肯定是产生一个伪随机数;首先标签C的输入,如果刚刚你有点进去看看这个Macro的内部搭建,你可能会马上知道它实际是一个事件触发,应该确切地说,它是一个时钟信号,是用来触发事件产生的,也就是说,如果这里有个事件到达C输入,那么这个Macro将会在其输出产生一个伪随机数;OK,这个好理解了,那么Seed输入呢?它又是什么呢?其实,它就是相当于Set Random模块,举个例子,如果Seed等于0的时候,然后我们把它产生的伪随机数用函数坐标图画出来的跟Seed等于1的结果是不同的,所以这又可以让我们改变这个数值的变化,让伪随机数变得再随机点,哈哈。

好的,有了上面大体的了解,我相信要搭建一个Randomizer模块已经没什么难度了吧,来来来,直接给出结果:(图1.3)


图1.3

当然大家肯定也会发现一些问题,比如初始化后,跟原有的Randomizer模块不大一样,更关键的是,每次得到的数值都是-1,这是因为Seed数值设定的问题,当然我们可以手动地去设置这个数值的变化,不过要注意的是,这个数值不会自动变化,你设置成什么样的数值,它就永远是什么样的数值,这同时也导致了产生伪随机数永远都是一样的结果,而原有的Randomizer模块为何每次初始化产生的结果都不同是因为 Set Random 模块会自动变化,前提是Set Random模块没有被加进来,如果你添加了 Set Random 模块,并设定了 Set Random 模块一个固定的输入数值,那么对于你添加的所有 Randomizer 模块,它们初始化后产生的伪随机数每次都一样,尽管每个 Randomizer 模块一开始产生的伪随机数不同。

第二天

如果你觉得Randomizer还算好搞定的话,那么接下来的Frequency Divider你估计要懵逼了。

Frequency Divider顾名思义就是“频率切分”的意思,那么怎么来理解这个频率切分呢?我们来看一张图:(图2.1)


图2.1

从图2.1我们可以看出事件流在经过 Frequency Divider 后发生了变化,从原来的12 个事件变成了 6 个事件,也就是说事件个数变成原来的一半,如果从频率的角度来解释的话,那么就是频率12变成了频率6,所以这里我们大体知道Frequency Divider 所谓的频率切分差不多是这个意思了。

但实际上 Frequency Divider 模块远远不只如此,它还更深一步,它会产生一个Gate 事件信号,所谓 Gate 事件信号,就是指正值事件和零值事件交替出现,但是究竟这个交替的变化规律是如何的呢?也就是说什么时候会发送一个正值事件然后接着又什么时候会发送一个零值事件?好的,让我们再来看看 Frequency Divider 模块是什么样子的。(图2.2)


图2.2

从图 2.2 我们可以看出 Frequency Divider 模块有4个输入和1个输出,对于 Trig输入,我们很好去理解,因为它是事件触发的接收,不过要注意的是,它只针对正值事件才有效,那么 N 输入、W 输入和 Rst 输入呢?我们上面已经提到了Frequency Divider 实际上会在其输出产生一个 Gate 事件信号,但它有一个前提,那就是 N 输入的数值必须大于等于 2 才会产生 Gate 事件信号,而这个Gate事件信号的正值事件数值刚好等于 Trig 输入接收到的正值事件的数值,可问题还是什么时候会回到一个零值事件?于是W就是用来控制这两个事件交替的时间间隔,其实,Frequency Divider 模块的原理是非常简单,简单到它的内部实际上就是一个计数器,就相当于我们之前搭建过的 Counter 模块一样,通过 Trig 输入的正值事件去触发这个计数器累计读数,然后当累计数大于等于N乘以W,它就发送一个数值 0 的事件,而当累计数大于等于 N,它就发送一个数值1的事件,接着计数器又重新回到0开始计数,当然对于计数器,它也可以随时复位,于是Rst输入就是用来复位内部计数器从0重新开始计数。

OK,到了这边,我们已经差不多对 Frequency Divider 的运作原理了解更深一步了,于是我们可以开始动手在 Core Cell 里开始搭建它,首先我们依然创建好一个Core Cell,命名好,添加相应名称的输入和输出。(图2.3)


图2.3

首先,对于Trig事件的到达,我们需要一个计数器,也就是说我们需要去搭建一个Counter,说到搭建Counter,想必不会很难了吧,我就直接给出结果吧。(图2.4)

图2.4

从图 2.4,我们可以看出它跟之前搭建过真正的 Counter 还是有点差别的,也就是说我们省掉了 Up 和 Down 的功能,整合成了一个 Trig,然后累计只能是加的,没有减的部分,一旦到了峰值  N,它又立马折回到0并重新开始数数;但虽然搭建好了,不过对于 Trig 的部分,我们还需要考虑它必须是正值事件才有效,因为上面的 Trig 对事件的到达并没有做特殊处理,所以不管 Trig 的数值多少,甚至是负值事件,依然可以触发累计,因此,我们还需要对 Trig 做一下过滤处理,让大于 0 的部分通过。(图2.5)

图2.5

好的,搭建完了计数器的部分,我们接下来就要开始判断了,大于等于N*W的时候触发正值事件,大于等于N的时候触发零值事件。(图2.6)

图2.6

上面差不多已经算完成了Frequency Divider整个核心的部分,但仍然有些细节我们需要注意,比如对于N的数值,尽管它的要求是要大于0,但原有的Frequency Divider模块仅仅只是要求N必须要大于等于2,小于2的部分是无效的,也就是说它可以是带有小数点的数,像一点几或者零点几的浮点数,而对于这样的数,N是无效的,也就是说在这之前,浮点数会先转化成整数,那么究竟是往上取整还是往下取整呢?实际上,只要你有看过Frequency Divider模块对N的描述,你就知道,它是往下取整的,所以我们需要一个floor,而这个floor的搭建对我们来说已经不是件陌生的事了,好吧,直接给出结果。(图2.7)

图2.7

注意上面Trigger?和Reset?的部分是一样的,它们都是来确保Trig输入和Rst输入的数值必须要大于0才有效。

(注意:其实对于W输入还是有一定的限制的,实际上经过测试,它的取值范围是在0.01到1)

第三天

从这里开始,我们已经把所有事件处理的模块都搭建完了,然后我们也发现搭建那么多,无非都是用到那几个简单的模块组合,只要稍微知道一下原理,想去实现并非是一件很困难的事,所以接下来,我们要利用前面的搭建经验来搭建一个看似简单,但又经常会用到的模块,它就是 Audio Smoother。(图3.1)

图3.1

首先,肯定有人会疑问为什么会想要来搭建这个模块呢?原因是这样的,对于我来说,我经常会使用 Puredata,不是因为我要用到它,而是我觉得它本身是一个不错的软件,通过它能学到一些不一样的东西,尤其它还是开源软件,不比它同类的商业软件 Max,当然 Max 有它自己的优势,相反 Puredata 也有它自己的优势,尽管在某些东西上这两个软件可以互通,但我更喜欢 Puredata,因为它更纯粹。

然后讲一下重点的部分,在 Puredata 里,我经常会用到一个叫 line~的物件,它其实就是一个 Audio Smoother,而且这个line~物件能去实现一个ADSR Envelope包络器,出于这个想法,我就开始思考怎么在Reaktor里搭建一个像line~物件,也就是 Audio Smoother 模块。

我们知道对于  Reaktor Audio Smoother 模块,它有一个固定值的属性是用设置平滑过渡的时间,通常默认是 100 毫秒,也就是说如果 Audio Smoother 的输入从 0 突然变成 1,那么在其输出将会有一个连续变化的数值,并在特定的时间内变成了1,而这个特定的时间就是 100 毫秒,当然我们是可以去手动设置这个时间,不过也由于这样,让我觉得 Audio Smoother 不够灵活,如果我想动态去变化这个时间呢?那该怎么办?哈哈,显然我在钻牛角尖,因为大部分情况下我们只要设置一次这个 Audio Smoother 到一个特定的值,我们就没太多必要去改变了,除非特殊情况,不过,我觉得能在 Core Cell 尝试做一下,或许能更清楚它是怎么用的。

好的,让我们开始在 Core Cell 搭建一个 Audio Smoother 模块吧。首先添加一个 Core Cell 并给它命名为 Audio Smoother,然后再添加相应的输入和输出。(图3.1)


图3.1

我们看到有个T的输入,它是代表时间,通常性我们都是以秒的单位来衡量,所以对于这个输入的数值,如果是1的话,那么它代表是1秒。

接下来我们来思考 Audio Smoother 的运作原理是什么呢?它是怎么产生连续趋近变化的数值?其实 Audio Smoother 的运作原理是很简单的,我们只需要知道下一个数值和当前数值的差值,就能够利用这个差值变化到下一个数值;可能这样讲,大家觉得会很抽象,来举个简单的例子吧,比如当前数值是 0.1,而下一个数值是 0.2,那么它们之间的差值就是 0.1,因此当前数值要想变成 0.2,那么它必须要加上差值 0.1,这是一个非常简单的算术问题,但对于 Audio Smoother不同的是,它把这个差值细化,它不让你马上就能到达 0.2,而是经过一段时间后才变化到 0.2,如果我们把差值分成 10 份的话,那么每次累加的数值就是0.01;可同时问题也来了,我们怎么跟T这个时间属性挂钩上呢?实际上这个问题不难,我们只需要搭建一个能计算时间的 Macro 就可以,然后这个 Macro 输出的结果必须要符合 0 到1 ,这样一来它跟差值相乘就会变成从0变化到差值,OK,我们来搭建一下。(图3.2)



图3.2

从图3.2,我们看到了T的部分已经被转换了,我们可以来假设下,比如采样率固定为44100不变,那么对于1/44100的结果就是指1秒,那么如果是100毫秒呢,也就是0.1秒,应该是多少除以44100呢?我们可以来导一个公式就能知道了。(图3.3)

图3.3

当然从图3.3,我们可以马上知道如果要让0在100毫秒内到达1,那么它累加的最小数值是1/4410;好的,有了这个,接下来,我们可以开始求两个数的差值,好吧,也是直接给个结果吧。(图3.4)

图3.4

哈哈,具体为什么是这样,开动你们的脑筋想想吧,顺便也思考下 Event Smoother 怎么做。


本文出自《midifan月刊》2017年4月第133期


可下载 Midifan for iOS 应用在手机或平板上阅读(直接在App Store里搜索Midifan即可找到,或扫描下面的二维码直接下载),在 iPad 或 iPhone 上下载并阅读。




文章出处:http://magazine.midifan.com/detail.php?month=2017-04#19做人要厚道,转载文章请注明出自 midifan.com,谢谢

暂无评论

添加评论