4

I'm trying to learn how to use the web audio api properly and I'm running into a bit of confusion.

In my project, I'm trying to replicate the functionality of an old 1982 Harman/Kardon receiver. (click link to see photo)

This receiver has separate dials for the treble and bass control. I'll just deal with treble in this question. I'm sure I can figure out the bass equivalent once I'm pointed in the right direction.

In an initialization function I create the context and filter nodes.

window.AudioContext = window.AudioContext || window.webkitAudioContext;
    context = new AudioContext();
    source = context.createMediaElementSource(document.getElementById('audio'));
    gainNode = context.createGain();

//filter nodes
bassTurnoverFilter = context.createBiquadFilter();
trebleTurnoverFilter = context.createBiquadFilter();
loudnessTrebFilter = context.createBiquadFilter();
loudnessBassFilter = context.createBiquadFilter();
trebleLevelFilter = context.createBiquadFilter();
bassLevelFilter = context.createBiquadFilter();

I am currently using the jogDial plugin to control the dials. The dials do work and I can get a range for the "treble" variable between 0 and 1 when the dials turn from 0% to 100%.

This is the current mousemove function I am using for the treble dial:

.on("mousemove", function(event){

var treble = (event.target.rotation + 140) / 280;

    if(trebleLevelFilter !== undefined){
        trebleLevelFilter.disconnect();
    }
    source.connect(trebleLevelFilter); 
    trebleLevelFilter.type = "highshelf"; 
    trebleLevelFilter.frequency.value = 200; 
    trebleLevelFilter.gain.value = treble; 
    trebleLevelFilter.connect(context.destination);
});

My question, or multi-part question is... which of the 6 types should I use? ("lowpass","highpass", "bandpass", "lowshelf", "highshelf", "peaking", "notch", "allpass") I'm guessing it is the highpass or highself.

What frequency should I set?

Is the gain.value what should be dynamic when the dial turns?

Am I going in completely the wrong direction?

I have the gain.value set to the treble variable value, and it seems like it is increasing the volume a little when turned to 100%... but i don't think that is the correct functionality I am trying to accomplish.

Livi17
  • 1,620
  • 3
  • 25
  • 43
  • See also [Creating a 10-Band Equalizer Using Web Audio API](https://stackoverflow.com/questions/12738056/creating-a-10-band-equalizer-using-web-audio-api?rq=1) – ggorlen Aug 02 '21 at 01:20

2 Answers2

8

I'm not sure why you're creating six different filters - you should only need two, one for treble and one for bass.

I think that the HK amp you're looking at has no midrange control- which is a bit odd, but okay. The bass filter is likely a low shelf, and the treble is a high shelf; the buttons control what the cutoff frequency for each is. Remember, a shelving filter is flat response at zero gain - you can play with the filters at http://googlechrome.github.io/web-audio-samples/samples/audio/frequency-response.html see what they'll look like. Select a low shelf, freq= ~200, and then play with the gain.

So, for example you're close with the treble filter, EXCEPT the "treble" and "bass" gain values shouldn't go [0,1] - it should go between [-maxgain,+maxgain]. "maxgain" is probably 2-3? You'll have to play around with it and pick a good range - I couldn't find that in the HK manual (http://www.manualslib.com/manual/279084/Harman-Kardon-Hk590i.html). It's also quite important to connect the filters in series, not in parallel (otherwise you will have phase problems).

// if treble=0 and bass=0 you'll have a flat response
bassFilter = context.createBiquadFilter();
bassFilter.type = "lowshelf"; 
bassFilter.frequency.value = 200;  // switches to 400 in UI
bassFilter.gain.value = bass;  // you'll need to hook this to UI too

trebleFilter = context.createBiquadFilter();
trebleFilter.type = "highshelf"; 
trebleFilter.frequency.value = 2000;  // switches to 6000 in UI
trebleFilter.gain.value = treble;  // you'll need to hook this to UI too

source.connect(bassFilter); 
bassFilter.connect(trebleFilter); 
trebleFilter.connect(context.destination);

Also, there's no reason to disconnect the filter and reconnect it - you can make live changes to the .gain.value while it's connected.

cwilso
  • 13,610
  • 1
  • 30
  • 35
  • Thanks... I'll have to try this tomorrow. However, that is very informative. I created the different filters because I set up functionality for the treble turnover, bass turnover and tone defeat before tackling the treble and bass dials. My intention was that I would connect/disconnect those filters when the buttons were toggled. I am guessing that I am probably doing this incorrectly now by connecting in parallel. I was disconnecting each filter and saving that setting. Like I said, I'm just learning the api, and I'm not an audio technician. – Livi17 Mar 17 '15 at 23:13
  • Yep. Doing good EQ controls is less easy than it would seem. 1) Put the filters in series, not parallel. 2) you only need one filter per "band" - if you had a center band, you'd only need three (a "peak" filter for the middle) 3) you don't want to disconnect if you don't need to (and you don't need to) 4) the bass/treble turnover switch just switches the frequency of the relevant shelving filter, it's not a separate filter. – cwilso Mar 18 '15 at 17:18
  • Oh, and "tone defeat" should be implemented with two gain nodes in parallel in front of the filter bands, with the output of one connected to the destination and the other connected to the filters, to set up a bypass - one of the gain nodes should always have value zero and one should have value 1. (The switch should switch which node is zero.) Does that make sense? – cwilso Mar 18 '15 at 17:22
  • I'm about to give this a try. I think it makes sense, however I was under the impression that the gainNode could only go between 0-1. I guess that's not the case. I also wanted to note that there is also a loudness button on the receiver. I'm guessing that loudness would just boost the gain on both bands a little further than when the tone defeat is at 1 or zero. – Livi17 Mar 19 '15 at 17:54
  • gain nodes can have any value. In this case (a shelving filter), the .gain param is a boost to the the shelf - so if the gain is 0, it's a flat response. If it's 1, it's boosting the level of the shelf. If it's -1, it's lowering the response of the shelf. – cwilso Mar 19 '15 at 20:03
  • I'm not sure about the loudness button, BTW - from the description in the manual, it seems sort of like that, but there might be some level component (i.e. a complex multi-band-compressor kinda thing). – cwilso Mar 19 '15 at 20:08
  • Having to switch everything into a series instead of parallel and without disconnecting any nodes, I created an eq function. However, now it doesn't seem to be live changing. From what I can tell, there is nothing happening here with my bass and treble turnover now. I've simplified my app so it's just the player and the two buttons controlling the bass and treble turnover buttons. Can I ask you to have a look at it?http://aceroinc.ca/harmanKardon/test.html – Livi17 Mar 23 '15 at 00:03
  • I know what I did wrong in that test.html... I was't changing the gain.values at all with the bass and treble buttons. I had it set for 0 regardless of what you click. This seems to match my receiver functionality the closest: http://aceroinc.ca/harmanKardon/test2.html – Livi17 Mar 23 '15 at 01:14
2

The following shows some recommendations for choosing which filter type to use for various purposes:

Web Audio API

pasted from that page:

There are many kinds of filters that can be used to achieve certain kinds of effects:

Low-pass filter Makes sounds more muffled

High-pass filter Makes sounds more tinny

Band-pass filter Cuts off lows and highs (e.g., telephone filter)

Low-shelf filter Affects the amount of bass in a sound (like the bass knob on a stereo)

High-shelf filter Affects the amount of treble in a sound (like the treble knob on a stereo)

Peaking filter Affects the amount of midrange in a sound (like the mid knob on a stereo)

Notch filter Removes unwanted sounds in a narrow frequency range

All-pass filter Creates phaser effects

Community
  • 1
  • 1
David Tansey
  • 5,813
  • 4
  • 35
  • 51
  • I guessed high-shelf filter... but what am I increasing or decreasing with the turning of the knob? The gain value isn't doing it. Am I supposed to increase the gain AND the frequency simultaneously for the right effect? The gain increases as a float only between 0 and 1, whereas the frequency has a huge range. – Livi17 Mar 17 '15 at 22:52
  • Check your Harmon-Kardon manual for the center frequency of both the Treble and Bass controls. Can you successfully influence the 'tone/eq' with hardocded values? (IOW -- skip the UI widget for testing) – David Tansey Mar 17 '15 at 23:25
  • The manual doesn't say what the center frequency is. http://www.harmankardon.com/images/media/HK590i_OM_EN.pdf – Livi17 Mar 17 '15 at 23:29
  • The bass turnover button says "400Hz" when in the up position. "200Hz" when in the pressed position. The treble turnover says "2kHz" in the up position. "6kHz" in the pressed position. Since both buttons have to be in the up or down position, I am going to guess that 300Hz for bass, and 4kHz for treble is the center frequencies? – Livi17 Mar 17 '15 at 23:36