如何使用createPeriodicWave代替createScriptProcessor和getChannelData

24
我发现了一些使用Web Audio API进行乐器合成的库。其中一个库(Band.js)结合振荡器类型(正弦、方波等)使用createOscillator()函数,详见 源代码。但它听起来太合成了(可以听一下示例)。我想要更真实的声音,但是我不想使用任何预编译的声音字体,所以应该是合成的,并且可以在移动设备上使用。
因此,我找到了另一个库(musical.js),它将前32个谐波作为矩阵与createPeriodicWave函数结合使用,详见 源代码。音色非常棒,可以听一下
正如源代码的注释中所述,这些谐波来自于这个钢琴样本文件。还有其他乐器的样本文件。我尝试替换谐波,甚至所有2000个,但它始终听起来像钢琴。
还有一些值可以调整和插值谐波和ADSR值。也许它们只是为钢琴音色进行了优化?
然后我找到了另一个库(guitar-synth),它具有非常好的吉他音色,听一下。但是这个库没有使用createPeriodicWaveAPI。相反,它使用createScriptProcessorgetChannelData函数,结合一些“简单”的计算,但与其他库中的谐波无关,详见源代码

所以我的主要问题是

能否将吉他合成器改用createPeriodicWaveAPI?我想在musicaljs中使用吉他音色,这样我就可以在钢琴音色和吉他音色之间切换。
顺便说一下:还发现了另一个合成声音乐器的库。这里是演示源代码。声音也很好,但是musical.js库有更美丽的音色。但它似乎也使用类似于getChannelData的东西,只是编码为WAVE。它也无法在我的Android手机上使用。

我不能说我玩过它,但仅从看musical.js代码 - 当您尝试使用其他非标准波形时,您是否也调整了ADSR和共振变量?这可能是“所有声音都像钢琴”的原因,因为它会更具冲击性并且持续时间更短。 - Bangkokian
我没有调整ADSR,我应该如何获得吉他的正确ADSR值呢?它们可以从guitar-synth存储库中提取吗? - timaschew
我发现了一些听起来很棒的安卓软件。也许你可以从这里 https://play.google.com/store/apps/details?id=com.levien.synthesizer&hl=en 和 https://github.com/google/music-synthesizer-for-android 获取一些提示。 - activedecay
1个回答

3
这不是一个答案,只是关于这个话题的一些想法和注释。
这个问题对我来说很有趣,我弹吉他,但从未有机会(直到现在)接触代码中的音乐。 我读了一些理论,玩了一下musical.js,感觉离解决方案还很远。
以下是一些笔记,希望能有用:
1)我组合了从musical.js中提取的简化代码示例,请参见web-audio-test.jsweb-audio.html
如果我没错,musical.js的音频节点设置如下:
其中有一个“尾”部分,对所有节点都是相同的且保持不变,“头”是为播放每个音符创建的节点集。
| ------ HEAD (for each note)------ | --- TAIL (for all notes)----------- |
|                                   |                                     |
[ |Oscillator|->|Biquad|->|Gain|-> ] [|Gain|->|Dynamics  |->|Destination| ]
  | Periodic |  |Filter|  |ADSR|              |Compressor|
  | Wave     |

注意:第一个振荡器可以通过另一个振荡器加倍以播放音高频率+音色失调。
因此,我们创建一个(或两个)振荡器+滤波器+ADSR增益来播放每个音符。这样我们创建了许多音频节点。Musicial.js通过创建音符队列并仅传递有限的一组音符到Web Audio API来处理此问题。
吉他合成设置看起来更简单,只是一个|脚本处理器|-> |输出|。吉他声音样本是从代码生成并馈送到ScriptProcessor节点中,该节点充当声源(就像您从文件加载样本一样)。不确定,但也许musical.js可以使用这种方法来简化代码。
2)我在musicial.js中尝试了不同的参数,但仍然听起来像钢琴。
当我应用波表示例中的低音或吉他系数时,听起来不同,但仍然像钢琴(特别是高音)。ADSR设置不会改变这种“钢琴”声音,但我认为它们实际上无法将一个乐器的声音转换为另一个乐器的声音。 multfreq数组用于将实数/虚数的谐波插值到更高频率,这可能更重要,但是如果我们保持它们为空(不进行插值),乐器仍然像钢琴一样发声。

实际上需要改变什么来调整声音对我来说仍然是个谜。

我看到了你在github上发布的问题,希望musicial.js的作者至少能给出一些提示。

3)有用的链接/工具

Google音频样本中没有任何我们需要的内容。最接近的是一个 wavetable synth example,您可以在其中在不同的波表之间切换。

Firefox有一个"Web Audio Editor",您可以看到音频节点的图形,非常方便学习音频设置。

4)实用解决方案。

您可能已经想到了,在目前,我会同时使用musical.js和guitar-synth。

一个简单的包装器可以统一接口,并提供钢琴和吉他两种乐器。

感谢您的输入。对我来说,直接使用吉他合成器并不是一个解决方案,因为我需要一个API来定义一种带有音高和持续时间的乐谱。吉他合成器只是通过吉他弦和品来定义音高,这很酷,但持续时间用嵌套的异步setTimout函数实现真的很丑陋:https://github.com/timaschew/guitar-synth/blob/master/example/index.html#L13-L30 - timaschew
@timaschew 可以不需要许多嵌套调用来设置持续时间,可以参考以下示例 - https://gist.github.com/serebrov/a90aaab533156a914e71 - Borys Serebrov
哇,很棒的捕捉 :) 谢谢 - timaschew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接