Question

I'm trying to wrap my head around using the Web Audio API to recreate something like
Winamp's 10-band equalizer.

Winamp's 10-band equalizer
(source: head-fi.org)

From what I can gather, I have to create 10 Biquad Filters, set their type to 2 (for a Bandpass filter) and set their frequency to [60, 170, 310, 600, 1000, 3000, 6000, 12000, 14000, 16000] respectively. Once I have done that (and here's where I'm getting a little confused) I would then create a separate Gain Node for each frequency "band" and bind its value to a slider.

<input id="someFreqBand" type="range" min="-12" max="12" step="0.1" value="0" onchange="slide()"/>

Assuming all of that is correct, then the only remaining step is to connect all 10 gain nodes to the Audio Context destination (which I imagine will take all 10 frequency "bands" and mix/sync them back together). Is this the right way to go about creating a Web Audio 10-band equalizer?

The major thing I'm confused about is how I go about "connecting" the source to the 10 frequency band filters (+ associated gain node) since all the nodes only have a single input or output (including the destination).

Was it helpful?

Solution

As Matt D said, there should be no problem connecting the filters to the same destination.

I would however say that you probably want to use filters with type 5 (peaking), which lets all frequencies through and only amplifies/reduce at the frequency at which you've set the respective filter.frequency.value. That lets you connect the filters in series so you don't need 10 separate audio paths. You could also consider using a low-shelf filter as the first filter, and a hi-shelf filter as the tenth, which is rather common in equalizers. I can't remember if that's what winamp does, though.

Finally, if you go with the peaking filters in series, you don't need a separate gain node for each frequency, you just set the filter.gain.value for the specific filters.

OTHER TIPS

By connecting every filter with the destination you are creating 5 paths (routes) so you will hear quintupling amplification of the source sound. It's not the correct way. You have to connect each filter in one line.

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

The major thing I'm confused about is how I go about "connecting" the source to the 10 frequency band filters (+ associated gain node) since all the nodes only have a single input or output (including the destination).

This is true, but don't think about it like a physical output that can only be connected to another physical input. A single output of a Web Audio node can be connected to multiple nodes, and a node can also receive multiple inputs. For example, let's say you wanted to chain an input node through 5 filters in parallel and then join them back together. You could do something like this:

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);

The key insight here is that calling .connect multiple times will not switch the output to a different node, but will simply add additional output connections. In other words, it's a "fan out/fan in" system.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top