代码之家  ›  专栏  ›  技术社区  ›  user3340575

如何使用JavaScript应用基本音频过滤器

  •  6
  • user3340575  · 技术社区  · 12 年前

    我正在试着让基本的音频过滤器工作。我想评估至少3-4个例子。

    下面是我正在评估并尝试使用的JS代码:

    var QUAL_MUL = 30;
    
    function FilterSample() {
      this.isPlaying = false;
      loadSounds(this, {buffer: 'techno.wav'});
    };
    
    FilterSample.prototype.play = function() {
      // Create the source.
      var source = context.createBufferSource();
      source.buffer = this.buffer;
      // Create the filter.
      var filter = context.createBiquadFilter();
      filter.type = filter.LOWPASS;
      filter.frequency.value = 5000;
      // Connect source to filter, filter to destination.
      source.connect(filter);
      filter.connect(context.destination);
      // Play!
      source.start(0);
      source.loop = true;
      // Save source and filterNode for later access.
      this.source = source;
      this.filter = filter;
    };
    
    FilterSample.prototype.stop = function() {
      this.source.stop(0);
    };
    
    FilterSample.prototype.toggle = function() {
      this.isPlaying ? this.stop() : this.play();
      this.isPlaying = !this.isPlaying;
    };
    
    FilterSample.prototype.changeFrequency = function(element) {
      // Clamp the frequency between the minimum value (40 Hz) and half of the
      // sampling rate.
      var minValue = 40;
      var maxValue = context.sampleRate / 2;
      // Logarithm (base 2) to compute how many octaves fall in the range.
      var numberOfOctaves = Math.log(maxValue / minValue) / Math.LN2;
      // Compute a multiplier from 0 to 1 based on an exponential scale.
      var multiplier = Math.pow(2, numberOfOctaves * (element.value - 1.0));
      // Get back to the frequency value between min and max.
      this.filter.frequency.value = maxValue * multiplier;
    };
    
    FilterSample.prototype.changeQuality = function(element) {
      this.filter.Q.value = element.value * QUAL_MUL;
    };
    
    FilterSample.prototype.toggleFilter = function(element) {
      this.source.disconnect(0);
      this.filter.disconnect(0);
      // Check if we want to enable the filter.
      if (element.checked) {
        // Connect through the filter.
        this.source.connect(this.filter);
        this.filter.connect(context.destination);
      } else {
        // Otherwise, connect directly.
        this.source.connect(context.destination);
      }
    };
    

    如果有人能解释或更好地提供一个使用JS应用过滤器的简单工作示例,那将非常好。

    提前谢谢。

    1 回复  |  直到 12 年前
        1
  •  17
  •   MarijnS95    10 年前

    (演示 here )

    让我们从创建源代码开始(这是HTML,非常简单)

    <audio controls="" preload="" src="add/src/here" autoplay=""></audio>
    

    您应该在以下位置插入音频文件url add/src/here 例如,在dropbox上放置一个文件并将其添加到那里。

    现在我们要创建音频上下文并连接 <audio> 标记到webAudio节点:

    context = new AudioContext();
    source = context.createMediaElementSource(document.getElementsByTagName('audio')[0]);
    

    这是一些基本的音频API编程。现在我们要创建一个过滤器节点,并将源连接到过滤器,然后将过滤器连接到扬声器:

    filter = context.createBiquadFilter();
    source.connect(filter);
    filter.connect(context.destination);
    

    现在,你应该选择你想要的过滤器。您可以找到所有筛选器 here (basically all information about the biquadFilter) 请注意,有8种不同的过滤器类型:

    “低通”, “高通”, “带通”, “低货架”, “高位”, “峰值”, “缺口”, “全通”

    您可以通过获取其数值来设置这些类型之一。根据上面的列表,Lowpass为0,highpass为1,依此类推。如果您不知道,只需在 <#biquadFilter> 对象,如下所示: filter.LOWPASS 。这将返回0。现在让我们告诉过滤器,它应该是一个低货架。这是类型3:

    filter.type = 3;
    

    编辑:定义类型的标准已经改变了几次,显然你现在可以直接使用字符串了。 https://www.w3.org/TR/webaudio/#the-biquadfilternode-interface

    现在,低架意味着:将给定的增益提升/降低应用于包含和低于给定频率的所有频率。所以如果我给滤波器一个95的频率:

    filter.frequency.value = 95;
    

    滤波器将增益加到95以下的所有频率上。 还要注意 .value 。这是因为有更多的函数 filter.frequency.linearRampToValueAtTime() 。如果您希望频率渐变到某个值,或者一次设置该值,这些函数很方便。如果你想了解更多信息,请随时询问。我想告诉你这件事,因为我知道研究它的工作原理需要花费很多时间。这方面似乎没有任何信息,但至少我做到了。

    现在我们要实际设置增益,这也是一个 价值 :

    filter.gain.value = 30;
    

    并非所有滤波器都需要增益。例如,低通意味着让低于给定频率的所有频率通过,而不做任何特殊的事情。低架确实会增强/减弱,因此您需要指定多少。

    某些过滤器还需要Q值。这决定了截止点(你的频带结束处)的峰值。由于我不擅长解释这一点,我直接从w3.org得到了这一点:

    控制截止频率下的响应峰值。较大的值会使响应更为峰值。请注意,对于这种滤波器类型,该值不是传统的Q值,而是以分贝为单位的共振值。

    现在让我们假设我们真的想用坡道做点什么。我希望频率在10秒内从0增加到120。由于这仍然是实验性的,它并不像你所期望的那样工作。让我们首先使用时间初始化设置值。我们只需在当前时间将频率值设置为0:

    filter.frequency.setValueAtTime(0.0, context.currentTime);
    

    现在我们希望10秒后达到120:

    filter.frequency.linearRampToValueAtTime(120.0, context.currentTime+10);
    

    听到频率增加很清楚。(但听起来不太清楚……)。 你可以找到它的一个小演示 here

    使用脚本处理器内的数学函数也可以自己进行所有编辑,但这只是一件痛苦的事情,因为对它的支持是如此实验性的,脚本处理器所使用的chrome版本很少。

    我希望这能帮助您了解过滤器的工作原理。请注意,使用过多的过滤器会使输出听起来很奇怪。在末端添加一个压缩器可以使一切正常化。

    如果你还需要知道什么,请随时询问。