使用Web Audio API创建一个10频段均衡器

17
我正在努力理解如何使用Web Audio API来重新创建类似Winamp 10段均衡器的东西。 Winamp 10段均衡器
(来源: head-fi.org) 根据我的了解,我需要创建10个Biquad Filters,将它们的type设置为2(代表带通滤波器),并将它们的frequency分别设置为[60, 170, 310, 600, 1000, 3000, 6000, 12000, 14000, 16000]。一旦完成这些步骤(在这里我有点困惑),我将会为每个频率"段"创建一个独立的Gain Node,并将其值绑定到滑块上。
<input id="someFreqBand" type="range" min="-12" max="12" step="0.1" value="0" onchange="slide()"/>

假设上述所有内容都是正确的,那么唯一剩下的步骤就是将所有10个增益节点连接到音频上下文destination(我想这将把所有10个频率“带”混合/同步在一起)。这是创建Web音频10段均衡器的正确方法吗?
我困惑的主要问题是如何“连接”源到10个频率带滤波器(+相关增益节点),因为所有节点只有单个输入或输出(包括目标)。
3个回答

15

将每个滤波器都连接到目标,你会创建5条路径(路线),因此你会听到源声音的五倍放大。但这不是正确的方法。你必须将每个滤波器以一条线连接起来。

source.connect(filter1);
filter1.connect(filter2);
filter2.connect(filter3);
filter3.connect(filter4);
filter4.connect(filter5);
filter5.connect(context.destination);

10

正如Matt D所说,将过滤器连接到同一目的地应该不会有问题。

然而,我建议您使用类型为5(尖峰)的过滤器,它可以让所有频率通过,并仅在您设置了相应的filter.frequency.value的频率上放大/减少。这样,您就可以将过滤器串联起来,而不需要10个单独的音频路径。您还可以考虑将低架滤波器用作第一个过滤器,将高架滤波器用作第十个过滤器,这在均衡器中非常常见。不过我不记得winamp是否采用此方法。

最后,如果您选择将尖峰过滤器串联起来,您不需要为每个频率设置单独的增益节点,只需为特定的过滤器设置filter.gain.value即可。


除非我错了,所有的图形均衡器都使用带通滤波器。请看这里第4页:https://rs6.eporia.com/company_38/techpaper106.pdf低频货架、高频货架和峰值滤波器可以让你直接在滤波节点上调整增益,但是带通滤波器却不能,这似乎很奇怪... - idbehold
我不确定所有的图形均衡器是否使用带通滤波器,但我确信使用串联的峰值滤波器将是获得所需行为的更简单方法。 - Oskar Eriksson
过滤器应该像Jagi提到的那样连接成系列。 - Martin Schulz
是的,我也是。 :) - Oskar Eriksson

2
我最困惑的是如何将源与10个频率带滤波器(+相关增益节点)“连接”,因为所有节点都只有单个输入或输出(包括目标节点)。
这是事实,但不要把它看作是只能连接到另一个物理输入的物理输出。 Web Audio节点的单个输出可以连接到多个节点,并且节点也可以接收多个输入。例如,假设您想通过5个并行滤波器链式传递输入节点,然后将它们重新组合在一起。您可以像这样操作:
source.connect(filter1);
source.connect(filter2);
source.connect(filter3);
source.connect(filter4);
source.connect(filter5);

filter1.connect(context.destination);
filter2.connect(context.destination);
filter3.connect(context.destination);
filter4.connect(context.destination);
filter5.connect(context.destination);

这里的关键是多次调用.connect()方法不会将输出切换到另一个节点,而只会添加额外的输出连接。换言之,这是一个“扇出/扇入”系统。

当规范说明“numberOfInputs: 1. numberOfOutputs: 1.”时,这似乎是文档不足之处。当他们用“1”表示“many”时。 - idbehold
2
我承认它可能不够清晰,但那份文档仍然是正确的。一个输出可以连接到多个输入。更多地考虑它像是输出端口的数量而不是输出数量。 - Matt Diamond

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