【问题标题】:Filtering and Web Audio过滤和网络音频
【发布时间】:2015-03-26 03:27:15
【问题描述】:

我正在尝试使用 Web Audio 实现一些过滤器。

我有以下设置,只有低通滤波器有效,但即使这样我似乎也无法让它停止。

          //Creating filters, setting their types and setting up booleans for later use.
      //Lowpass Filter Setup
      lowpass = context.createBiquadFilter();
      lp_bool=false;
      lowpass.type="lowpass";
      lowpass.type=LOWPASS;

      //Highpass Filter Setup
      highpass = context.createBiquadFilter();
      highpass.type="highpass";
      highpass.type=HIGHPASS;
      hp_bool=false;

      //Bandpass Filter Setup
      bandpass = context.createBiquadFilter();
      bandpass.type="bandpass";
      bandpass.type=BANDPASS;
      bp_bool=false;

      //Lowshelf Filter Setup
      lowshelf = context.createBiquadFilter();
      lowshelf.type="lowshelf";
      lowshelf.type=LOWSHELF;
      ls_bool=false;
      /*
      lowshelf.frequency.value = 440;
      lowshelf.gain.value = 0;*/

      //Highshelf Filter Setup
      highshelf = context.createBiquadFilter();
      highshelf.type="highshelf";
      highshelf.type=HIGHSHELF;
      hs_bool=false;/*
      highshelf.frequency.value = 440;
      highshelf.gain.value = 0;*/

      //Peaking Filter Setup
      peaking = context.createBiquadFilter();
      peaking.type="peaking";
      peaking.type=PEAKING;
      pk_bool=false;/*
      peaking.frequency.value = 440;
      peaking.Q.value = 0;
      peaking.gain.value = 0;*/

      //Notch Filter Setup
      notch = context.createBiquadFilter();
      notch.type="notch";
      notch.type=NOTCH;
      nh_bool=false;/*
      notch.frequency.value = 440;
      notch.Q.value = 0;*/

      //Allpass Filter Setup
      allpass = context.createBiquadFilter();
      allpass.type="allpass";
      allpass.type=ALLPASS;
      ap_bool=false;/*
      allpass.frequency.value = 440;
      allpass.Q.value = 0;*/
    };

切换功能:

function toggle_filter(filter_name,filter_bool) {
      masterVolume.disconnect(0);
      // Check if we want to enable the filter.
      if (filter_bool==false) {
        // Connect through the filter.
        masterVolume.connect(filter_name);
        filter_name.connect(context.destination);
        filter_bool=true;
      } else if(filter_bool==true){
        filter_name.disconnect(0);
        // Otherwise, connect directly.
        masterVolume.connect(context.destination);
        filter_bool=false;
      }
    };

从按钮调用:

<div id="filter-container">
<a onclick="toggle_filter(lowpass,lp_bool);" id="filter-button">Lowpass</a>
<a onclick="toggle_filter(highpass,hp_bool);" id="filter-button">Highpass</a>
<a onclick="toggle_filter(bandpass,bp_bool);" id="filter-button">Bandpass</a>
<a onclick="toggle_filter(lowshelf,ls_bool);" id="filter-button">Lowshelf</a>
<a onclick="toggle_filter(highshelf,hs_bool);" id="filter-button">Highshelf</a>
<a onclick="toggle_filter(peaking,pk_bool);" id="filter-button">Peaking</a>
<a onclick="toggle_filter(notch,nh_bool);" id="filter-button">Notch</a>
<a onclick="toggle_filter(allpass,ap_bool);" id="filter-button">Allpass</a>
<div>

谁能指出我哪里出错了?

【问题讨论】:

    标签: audio filter filtering web-audio-api


    【解决方案1】:

    在每次将类型正确设置为字符串后,您将类型设置为未知值。最终将其重置为默认值 - 低通。剪掉设置.type=HIPASS等的行(或者移到对应的字符串集合之前)

    【讨论】:

    • I've made that change, but I still have the issue that only the lowpass filtering is applied, when any of the other filter types are selected its like nothing is happening?
    • 酷,我解决了这个问题。唯一的问题是我只能让低通滤波器工作,我该如何解决这个问题?
    • 这看起来很奇怪。你有一个活生生的例子吗?顺便说一句,我不认为您的切换功能不会切换全局变量。
    【解决方案2】:

    你必须像这样设置过滤器类型:

    filter.type = "highpass";
    

    【讨论】:

      【解决方案3】:

      首先,您在 DOM 中不能有多个唯一 id。如果您希望多个节点共享一个标识符,请使用class=""

      其次,立即重新分配通常没有意义。

      allpass.type="allpass";
      allpass.type=ALLPASS;
      

      立即用其他内容覆盖第一个值集。目前尚不清楚变量 ALLPASS 是如何在您的代码中定义的,但请删除其中的一行——它要么是多余的,要么是最坏的情况(可能是后者)。

      第三,有很多repeated code。使用一系列滤波器类型,以及用于 Q、频率、增益等的旋钮(如果需要)。一遍又一遍地复制粘贴代码的那种编码容易出错,不必要地冗长,难以维护,如果有数百种过滤器类型,几乎不可能手写。

      这是一个基本的概念证明:

      const makeOsc = ({type, freq}) => {
        const oscillator = audioCtx.createOscillator();
        oscillator.type = type;
        oscillator.frequency.setValueAtTime(freq, audioCtx.currentTime);
        return oscillator;
      };
      
      const makeFilter = ({type, freq, q, gain}) => {
        const filter = audioCtx.createBiquadFilter();
        filter.type = type;
        filter.frequency.value = freq;
        filter.Q.value = q;
        filter.gain.value = gain;
        return filter;
      };
      
      const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
      
      const filters = [
        "lowpass", "highpass", "bandpass", "lowshelf",
        "highshelf", "peaking", "notch", "allpass",
      ];
      
      const filterTest = (() => {
        let osc;
        let filter;
        
        const start = filterType => {
          if (osc) {
            stop();
          }
          
          osc = makeOsc({type: "sawtooth", freq: 220});
          filter = makeFilter({
            type: filterType,
            freq: 200,
            q: 3,
            gain: 0
          });
          osc.connect(filter);
          filter.connect(audioCtx.destination);
          osc.start();
        };
        
        const stop = () => {
          if (osc) {
            osc.stop();
            osc.disconnect();
            filter.disconnect();
            osc = null;
          }
        };
        
        const playing = () => !!osc;
        
        return {start, stop, playing};
      })();
      
      let filterType = filters[0];
      document.querySelector(".filter-type")
        .innerHTML = filters.map(e => `<option>${e}</option>`)
      ;
      document.querySelector(".start")
        .addEventListener("click", e => filterTest.start(filterType))
      ;
      document.querySelector(".stop")
        .addEventListener("click", e => filterTest.stop())
      ;
      document.querySelector(".filter-type")
        .addEventListener("change", e => {
          const {target: sel} = e;
          filterType = sel.options[sel.selectedIndex].value;
          
          if (filterTest.playing()) {
            filterTest.start(filterType);
          }
        });
      ;
      <h1>warning: loud noise</h1>
      <select class="filter-type"></select>
      <button class="start">start</button>
      <button class="stop">stop</button>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-11-03
        • 1970-01-01
        • 2015-02-10
        • 2013-09-22
        • 2020-11-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多