0

我一直在尝试使用 Web Audio API 创建一个 88 键钢琴。计划是首先以适当的频率运行所有 88 个振荡器,然后在按下和释放钢琴键时在各个振荡器上使用Oscillator.connect()和方法。将始终处于“运行Oscillator.disconnect()”状态。现在,我有两个问题,AudioContext

  1. 这是正确的方法吗?
  2. 当我播放这些声音时,我会在声音的开头和结尾听到咔哒声。为什么会发生这种情况以及如何摆脱它?

PS:创作这样一架钢琴的原因是为了让自己沉迷于从零开始创作的乐趣。所以使用预先录制的声音不是一种选择。

4

2 回答 2

1

如果您想这样做,请为每个振荡器添加一个增益节点,然后关闭和打开增益,而不是断开并重新连接。

这可能是导致您的点击和快照的原因。更多内容如下。

但是......这仍然有点过分,有 88 个振荡器。键盘执行此操作的标准方式是使用有限的复音。

创建一个由十个振荡器组成的阵列,所有振荡器都连接到自己的增益,每个增益都连接到目标。

跟踪按下了多少键,以及使用了多少个振荡器。

keysPressed = {}

// on key down
keysPressed["60"] = nextAvailableOsc()

在任何给定时间,都有十个振荡器准备就绪,每个手指一个。如果由于某种原因您需要更多,请动态添加它们。


咔哒声是因为您很难断开和重新连接正在运行的振荡器。在 osc 和目标之间使用增益节点,然后打开和关闭它。

此外,您可能会在硬更改值时获得点击,例如

gainNode.gain.value = 0

这可能会在声音流中产生故障。它应该是:

gainNode.gain.setValueAtTime(0, ctx.currentTime + 1)

也许+ 1是必要的。还有 setTargetAtTime 和 rampToAtTime 方法可以让事情变得更顺畅:

https://developer.mozilla.org/en-US/docs/Web/API/AudioParam

于 2020-07-07T05:42:24.263 回答
0

另一种方法是按需创建振荡器。当按下一个键时,创建一个或多个振荡器(用于谐波)。这些可以馈入一个(或多个?)增益节点,该节点具有攻击和维持阶段的自动化。当按键被释放时,自动化释放阶段的增益并安排振荡器在释放阶段结束后停止。现在删除对所有振荡器的引用。

我发现这比拥有一组振荡器更容易推理,而且复音没有限制。但是这种方法会产生更多的垃圾,最终必须由收集器处理。

于 2020-07-07T14:56:58.730 回答