我一直在尝试使用WebAudio API创建一架88键钢琴。计划是首先以适当的频率运行所有88个振荡器,然后在按下和释放钢琴键时在相应的振荡器上使用Oscillator.connect()
和Oscillator.disconnect()
方法。CCD_ 3的状态将是"0">运行";总是现在,我有两个问题,
- 这样做对吗
- 当我播放这些声音时,在声音的开头和结尾都会有咔嗒声。为什么会发生这种情况,以及如何消除这种情况
PS:创作这样一架钢琴的原因是为了让自己沉浸在从头开始创作的喜悦中。因此,使用预先录制的声音不是一种选择。
如果您想这样做,请为每个振荡器添加一个增益节点,然后关闭和打开增益,而不是断开和重新连接。
这可能就是你点击和点击的原因。下文将详细介绍。
但是。。。这仍然相当夸张,有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
另一种方法是根据需要创建振荡器。按下某个键时,创建一个或多个振荡器(用于谐波(。这些可以馈入一个(或多个?(增益节点,该节点在攻击和维持阶段具有自动化功能。当释放键时,使释放阶段的增益自动化,并安排振荡器在释放阶段结束后停止。现在删除对所有振荡器的引用。
我发现这比拥有一组振荡器更容易推理,复调也没有限制。但是这种方法会生成更多的垃圾,最终必须由收集器处理。