如何使用RxJS播放多节奏

非常规的,与音乐相关的反应式编程示例,包括代码示例和详细说明

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表示)。

该程序

您可以在此处在线查看和编辑代码。

回购在这里

让我们从头开始:这是应用程序的外观以及应做的事情。

功能摘要:

  1. 我们可以在2个输入中输入节奏
  2. 我们可以输入每分钟的BPM节拍(BPM是音乐中的标准单位)
  3. 我们有一个播放/停止按钮
  4. 播放节奏时,我们希望能够即时更改这些参数中的任何一个

让我们一步一步地看一下实现。

1个

我们想对输入元素的更改和按钮单击做出反应。 让我们根据这些事件创建可观察的序列:

节奏序列稍微复杂一点-我们从可观察序列的数组开始,每个输入一个( rhythmChangeEvents $ )。 从那里开始,我们使用CombineLatest运算符,因此每次输入值更改时,我们只会得到一个发出的序列。 它发出一个输入值数组。

2

我们需要一个Observable发出布尔值,可以将其用作播放/停止声音的信号。 为此,我们将使用BehaviorSubject

我们创建一个BehaviorSubject ,并在每次单击播放按钮时从中发出值。 每次点击,我们都会发出最后发出的值的补码。

3

接下来,我们将3个序列组合为1,这应该控制“可观察”的“时钟”(即定期生成数字)。

以下是顺序:

  1. rhythm $ -影响时钟速度和声音制作者
  2. bpmChanges $ —影响时钟速度(时间间隔)
  3. 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

地图