9

I have been looking around for creating an audio equalizer using the Web audio API: http://webaudio.github.io/web-audio-api/

I found a lot of threads about creating a visualizer, but that is of course not what I want to do. I simply want to be able to alter the sound using frequency sliders. I found that the biquadFilter should do the work, but I can't get a good result. The sound is altered consistently when I change any frequency value, but it just lowers the quality of the sound while it should alter the frequencies.

I first load a sound:

Audio.prototype.init = function(callback){
    var $this = this;
    this.gainScale = d3.scale.linear().domain([0,1]).range([-40,40]);
    this.context = new AudioContext();
    this.loadSounds(function(){
        $this.loadSound(0);
        $this.play();
        callback.call();
    });
};

Everything works well, the sound plays when ready.

I have 10 sliders for frequencies [32,64,125,250,500,1000,2000,4000,8000,16000]. For each slider I create a filter and I connect it to the source, as is described here: Creating a 10-Band Equalizer Using Web Audio API :

Audio.prototype.createFilter = function(index,frequency){
    if(this.filters == undefined) this.filters = [];
    var filter = this.context.createBiquadFilter();
    filter = this.context.createBiquadFilter();
    filter.type = 2;
    filter.frequency.value = frequency;
    // Connect source to filter, filter to destination.
    this.source.connect(filter);
    filter.connect(this.context.destination);
    this.filters[index] = filter;
};

Finally, when I change the value of a slider I update the filter:

Audio.prototype.updateFilter = function(index,newVal){
    this.filters[index].frequency.gain = this.gainScale(newVal);
};

NB: my this.gainScale function takes as input a value in [0,1] and returns a value in [-40,40] to set the gain between -40 and 40 for each frequency.

Would appreciate any help !

4

2 に答える 2

15

ここで複数のこと。

1) イコライザーを実装するためにバンドパス フィルターを並列に使用しないでください。他の問題の中でも、バイカッド フィルタリングは信号のさまざまな部分の位相を変更するため、さまざまな帯域がさまざまな位相になり、再結合時にサウンドにかなり悪い影響を与える可能性があります。

2) 必要なアプローチは、ボトムエンドにローシェルフフィルター、トップエンドにハイシェルフフィルター、および中間に任意の数のピーキングフィルターを配置することです. これらは直列に接続する必要があります (つまり、入力信号が 1 つのフィルターに接続され、別のフィルターに接続され、別のフィルターに接続され、最後のフィルターのみが audiocontext.destination に接続されます。Q 値は次のようになります。調整され (以下を参照)、フィルターのゲインがブースト/カットを決定します (フラットな応答を得るには、すべてのフィルター ゲインをゼロに設定する必要があります)。

3) filter.type は列挙型であり、数値ではなく文字列として設定する必要があります。「lowshelf」、「highshelf」、「peaking」は、ここで探しているものです。

私の DJ アプリで簡単な 3 バンド イコライザーの例を確認できます。これをマルチバンド イコライザーに変更するには、各フィルターの Q 値を微調整して、帯域がオーバーラップしすぎないようにする必要があります (オーバーラップしても問題ありませんが、調整すると帯域がより正確になります)。 . http://googlechrome.github.io/web-audio-samples/samples/audio/frequency-response.htmlを使用して、特定の Q とフィルタ タイプの周波数応答を調べることができます。

于 2015-05-06T07:00:18.453 に答える
0

1 つの問題は、フィルター周波数自体ではなく、特定の周波数でフィルターのゲインをスライダーで制御することです。仕様によると、バンドパス フィルターのゲインは制御できません。これはビット制限です。幸いなことに、各フィルターの最後にゲイン ノードを配置できます。

var filter = this.context.createBiquadFilter();
filter = this.context.createBiquadFilter();
filter.type = 2;
filter.frequency.value = frequency;

var gain = this.context.createGainNode();

// Connect source to filter, filter to the gain, gain to destination.
this.source.connect(filter);
filter.connect(gain);
gain.connect(this.context.destination);
this.filters[index] = filter;
this.gains[index] = gain;

次に、スライダーをゲイン コントロールのゲイン パラメータに接続する必要があります。私はウェブオーディオについてよく知らないので、あなたに任せます。最後に、フィルターの Q を指定する必要があります。周波数のリストから、オクターブ幅のフィルターを作成しようとしているという印象を受けるので、Q ファクターはおそらく 1.414 前後になるでしょう。これを正しく行いたい場合は、少し調査を行う必要があります。

于 2015-05-05T23:53:54.137 に答える