非常规的,与音乐相关的反应式编程示例,包括代码示例和详细说明
Von Franjo,前端开发人员@comsysto
介绍
最近,我对亚当·尼利(Adam Neely)关于多节律的演讲很感兴趣。 所以我决定创建一个小程序,让您聆听不同节奏的声音。 这个想法是使用RxJS库。
本文假定您对反应式编程有所了解,最好是RxJS。
您如何演奏多节奏?
摘自Wikipedia:“ 多节奏是同时使用两个或多个相互矛盾的节奏”。 让我们以3到4的多节奏为例:3/4的多节奏是指您听到3个均匀间隔的脉冲的时间与4个均匀间隔的脉冲的时间相同(并且该序列重复)。 如果重复周期为1秒长,则将在0秒,1/3秒,2/3秒(每1/3秒)内听到一个脉冲。 第二个脉冲将在0秒,1/4秒,2/4秒和3/4秒(每1/4秒)处听到。
一种以编程方式实现此目的的简单方法是将一个周期分为12个间隔(3 * 4 = 12),并在每个间隔的开始处都有一个时钟生成数字(如果周期为1秒,则间隔将为1/12秒)。 然后,我们可以在生成这些数字时对其进行处理,如果一个数字可被3或4整除,我们会发出声音。

如果您是机器人,如何演奏节奏
这张表代表一个3/4复律的循环。 以规则的间隔(第一行)生成增加的数字(第二行)。 第三和第四行显示播放声音的时间。 IE,在时间t = 3/12 s,发出数字3,并且由于3被3整除,因此播放了声音(由X表示)。
该程序
您可以在此处在线查看和编辑代码。
回购在这里 。
让我们从头开始:这是应用程序的外观以及应做的事情。

功能摘要:
- 我们可以在2个输入中输入节奏
- 我们可以输入每分钟的BPM节拍(BPM是音乐中的标准单位)
- 我们有一个播放/停止按钮
- 播放节奏时,我们希望能够即时更改这些参数中的任何一个
让我们一步一步地看一下实现。
1个
我们想对输入元素的更改和按钮单击做出反应。 让我们根据这些事件创建可观察的序列:
节奏序列稍微复杂一点-我们从可观察序列的数组开始,每个输入一个( rhythmChangeEvents $ )。 从那里开始,我们使用CombineLatest运算符,因此每次输入值更改时,我们只会得到一个发出的序列。 它发出一个输入值数组。
2
我们需要一个Observable发出布尔值,可以将其用作播放/停止声音的信号。 为此,我们将使用BehaviorSubject :
我们创建一个BehaviorSubject ,并在每次单击播放按钮时从中发出值。 每次点击,我们都会发出最后发出的值的补码。
3
接下来,我们将3个序列组合为1,这应该控制“可观察”的“时钟”(即定期生成数字)。
以下是顺序:
- rhythm $ -影响时钟速度和声音制作者
- bpmChanges $ —影响时钟速度(时间间隔)
- play $ —开始/停止计时
因此,每次发出任何单独的Observable时, config $ observable都会发出一个数组对象。
4
接下来,每次config $发出一个新值时,我们需要对该值做出反应。 有两个流程:
- config.play为假-值信号我们应该停止,因此我们将该值映射到一个永不发射的新Observable序列(“ NEVER”)
- config.play是正确的-我们将值映射到新的Observable序列(时钟)。 间隔是根据BPM和节奏设置的(计算是在convertToMs函数中完成的)。
在这种情况下, switchMap运算符很方便,因为它仅从最近映射(投影)的Observable发出值。 换句话说,当发出新的配置对象时,switchMap停止发出最后一个时钟序列,并开始发出新创建的时钟序列。
在tap操作符中,我们拦截发出的配置值,并在必要时更改按钮文本。
5
好的,现在我们有了一个时钟,它可以定期发射数字。 我们可以使用开头所述的逻辑来发出声音。
为了演奏节奏,我们需要访问节奏$和clock $ 。 再次,我们使用CombineLatest创建一个可发射复合对象的Observable。 对于每个节奏,我们执行一个函数(“声音产生器”)。 该功能检查数字(时钟)是否可被“节奏”数字整除并播放声音。
使用HTML5音频api播放声音。 此功能仅获取网络上可用的样本并进行播放。
资料
所有使用的操作员的文档:
结合最新
轻拍
switchMap
间隔
fromEvent
地图