Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Web Audio API, setting treble and bass

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.

like image 524
Livi17 Avatar asked Dec 25 '22 21:12

Livi17


1 Answers

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.

like image 170
cwilso Avatar answered Dec 28 '22 11:12

cwilso