web audio highpass filter

by jib1

HTML

<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<audio id="audio" controls autoplay></audio><br>
Frequency <input id="frequency" type="range" min="10" max="10000" value="1000"><br>
<div id="div"></div>

JavaScript

const console = { log: msg => div.innerHTML += msg + "<br>" };

(async () => {
  try {
    const stream = await navigator.mediaDevices.getUserMedia({audio: true});
    const ctx = new AudioContext();
    const src = ctx.createMediaStreamSource(stream);
    const dst = ctx.createMediaStreamDestination();
    const biquad = ctx.createBiquadFilter();
    [src, biquad, dst].reduce((a, b) => a && a.connect(b));
    audio.srcObject = spectrum(dst.stream);

    biquad.type = "highpass";
    biquad.gain = 25;
    biquad.frequency.value = 1000;
    frequency.oninput = () => biquad.frequency.value = frequency.value;
  } catch (e) {
    console.log(e);
  }
})();

function spectrum(stream) {
  const audioCtx = new AudioContext();
  const analyser = audioCtx.createAnalyser();
  audioCtx.createMediaStreamSource(stream).connect(analyser);

  const canvas = div.appendChild(document.createElement("canvas"));
  const canvasCtx = canvas.getContext("2d");
  const data = new Uint8Array(canvas.width);

  let interval = setInterval(() => {
    canvasCtx.fillStyle = "#ffffff";
    canvasCtx.clearRect(0, 0, canvas.width, canvas.height);
    analyser.getByteFrequencyData(data);
    canvasCtx.lineWidth = 2;
    let x = 0;
    for (let y of data) {
      y = canvas.height - (y / 128) * canvas.height / 4;
      let c = Math.floor((x*255)/canvas.width);
      canvasCtx.fillStyle = "rgb("+c+",0,"+(255-x)+")";
      canvasCtx.fillRect(x, y, 2, canvas.height - y)
      x++;
    }
    analyser.getByteTimeDomainData(data);
    canvasCtx.lineWidth = 5;
    canvasCtx.beginPath();
    canvasCtx.stroke();
  }, 1000 * canvas.width / audioCtx.sampleRate);
  return stream;
}