text: // https://github.com/cwilso/AudioContext-MonkeyPatch/blob/gh-pages/AudioContextMonkeyPatch.js
  
  function fixAudioContext(global, exports, perf) {
    "use strict";
  
    function fixSetTarget(param) {
      if (!param)
        // if NYI, just return
        return;
      if (!param.setTargetAtTime)
        param.setTargetAtTime = param.setTargetValueAtTime;
    }
  
    if (
      window.hasOwnProperty("webkitAudioContext") &&
      !window.hasOwnProperty("AudioContext")
    ) {
      window.AudioContext = webkitAudioContext;
  
      if (!AudioContext.prototype.hasOwnProperty("createGain"))
        AudioContext.prototype.createGain = AudioContext.prototype.createGainNode;
      if (!AudioContext.prototype.hasOwnProperty("createDelay"))
        AudioContext.prototype.createDelay =
          AudioContext.prototype.createDelayNode;
      if (!AudioContext.prototype.hasOwnProperty("createScriptProcessor"))
        AudioContext.prototype.createScriptProcessor =
          AudioContext.prototype.createJavaScriptNode;
      if (!AudioContext.prototype.hasOwnProperty("createPeriodicWave"))
        AudioContext.prototype.createPeriodicWave =
          AudioContext.prototype.createWaveTable;
  
      AudioContext.prototype.internal_createGain =
        AudioContext.prototype.createGain;
      AudioContext.prototype.createGain = function () {
        var node = this.internal_createGain();
        fixSetTarget(node.gain);
        return node;
      };
  
      AudioContext.prototype.internal_createDelay =
        AudioContext.prototype.createDelay;
      AudioContext.prototype.createDelay = function (maxDelayTime) {
        var node = maxDelayTime
          ? this.internal_createDelay(maxDelayTime)
          : this.internal_createDelay();
        fixSetTarget(node.delayTime);
        return node;
      };
  
      AudioContext.prototype.internal_createBufferSource =
        AudioContext.prototype.createBufferSource;
      AudioContext.prototype.createBufferSource = function () {
        var node = this.internal_createBufferSource();
        if (!node.start) {
          node.start = function (when, offset, duration) {
            if (offset || duration) this.noteGrainOn(when || 0, offset, duration);
            else this.noteOn(when || 0);
          };
        } else {
          node.internal_start = node.start;
          node.start = function (when, offset, duration) {
            if (typeof duration !== "undefined")
              node.internal_start(when || 0, offset, duration);
            else node.internal_start(when || 0, offset || 0);
          };
        }
        if (!node.stop) {
          node.stop = function (when) {
            this.noteOff(when || 0);
          };
        } else {
          node.internal_stop = node.stop;
          node.stop = function (when) {
            node.internal_stop(when || 0);
          };
        }
        fixSetTarget(node.playbackRate);
        return node;
      };
  
      AudioContext.prototype.internal_createDynamicsCompressor =
        AudioContext.prototype.createDynamicsCompressor;
      AudioContext.prototype.createDynamicsCompressor = function () {
        var node = this.internal_createDynamicsCompressor();
        fixSetTarget(node.threshold);
        fixSetTarget(node.knee);
        fixSetTarget(node.ratio);
        fixSetTarget(node.reduction);
        fixSetTarget(node.attack);
        fixSetTarget(node.release);
        return node;
      };
  
      AudioContext.prototype.internal_createBiquadFilter =
        AudioContext.prototype.createBiquadFilter;
      AudioContext.prototype.createBiquadFilter = function () {
        var node = this.internal_createBiquadFilter();
        fixSetTarget(node.frequency);
        fixSetTarget(node.detune);
        fixSetTarget(node.Q);
        fixSetTarget(node.gain);
        return node;
      };
  
      if (AudioContext.prototype.hasOwnProperty("createOscillator")) {
        AudioContext.prototype.internal_createOscillator =
          AudioContext.prototype.createOscillator;
        AudioContext.prototype.createOscillator = function () {
          var node = this.internal_createOscillator();
          if (!node.start) {
            node.start = function (when) {
              this.noteOn(when || 0);
            };
          } else {
            node.internal_start = node.start;
            node.start = function (when) {
              node.internal_start(when || 0);
            };
          }
          if (!node.stop) {
            node.stop = function (when) {
              this.noteOff(when || 0);
            };
          } else {
            node.internal_stop = node.stop;
            node.stop = function (when) {
              node.internal_stop(when || 0);
            };
          }
          if (!node.setPeriodicWave) node.setPeriodicWave = node.setWaveTable;
          fixSetTarget(node.frequency);
          fixSetTarget(node.detune);
          return node;
        };
      }
    }
  
    if (
      window.hasOwnProperty("webkitOfflineAudioContext") &&
      !window.hasOwnProperty("OfflineAudioContext")
    ) {
      window.OfflineAudioContext = webkitOfflineAudioContext;
    }
  }
  