如何使用网络音频javascript更改无噪音的语音音调?

时间:2017-12-12 08:03:00

标签: javascript node.js web computer-vision web-audio

如何在JavaScript中使用网络音频更改语音音高而无噪音?

我尝试了下面的代码。

我的声音嘈杂,有点回声混合。

我想要一个无声的语音模块。

var pitchShifter = (function () {
  var context, audioContext, pitchShifterProcessor, spectrumAudioAnalyser,
    sonogramAudioAnalyser;

  var validGranSizes = [256, 512, 1024, 2048, 4096, 8192],
    grainSize = validGranSizes[1],
    pitchRatio = 2.0,
    overlapRatio = 0.50;

  var filter, compressor;

  hannWindow = function (length) {

    var window = new Float32Array(length);
    for (var i = 0; i < length; i++) {
      window[i] = 0.5 * (1 - Math.cos(2 * Math.PI * i / (length - 1)));
    }
    return window;
  };
  linearInterpolation = function (a, b, t) {
    return a + (b - a) * t;
  };
  initProcessor = function () {
    if (navigator.getUserMedia) {
      navigator.getUserMedia({
          audio: true
        },
        function (stream) {
          var convolver = audioContext.createConvolver();
          compressor = audioContext.createDynamicsCompressor();
          compressor.threshold.value = -50;
          compressor.knee.value = 40;
          compressor.ratio.value = 12;
          compressor.reduction.value = -20;
          compressor.attack.value = 0;
          compressor.release.value = 0.25;
          filter = audioContext.createBiquadFilter();
          filter.Q.value = 8.30;
          filter.frequency.value = 355;
          filter.gain.value = 3.0;
          filter.type = 'bandpass';
          filter.connect(compressor);
          compressor.connect(audioContext.destination);
          filter.connect(audioContext.destination);
          var microphone_stream = audioContext.createMediaStreamSource(
            stream);
          microphone_stream.connect(filter);
          var source = audioContext.createBufferSource();
          microphone_stream.connect(pitchShifterProcessor);
        },
        function (e) {
          alert('Error capturing audio.');
        }
      );
    }

    if (pitchShifterProcessor) {
      pitchShifterProcessor.disconnect();
    }

    if (audioContext.createScriptProcessor) {
      pitchShifterProcessor = audioContext.createScriptProcessor(
        grainSize, 1, 1);
    } else if (audioContext.createJavaScriptNode) {
      pitchShifterProcessor = audioContext.createJavaScriptNode(grainSize,
        1, 1);
    }
    pitchShifterProcessor.buffer = new Float32Array(grainSize * 2);
    pitchShifterProcessor.grainWindow = hannWindow(grainSize);
    pitchShifterProcessor.onaudioprocess = function (event) {
      var inputData = event.inputBuffer.getChannelData(0);
      var outputData = event.outputBuffer.getChannelData(0);
      for (i = 0; i < inputData.length; i++) {
        // Apply the window to the input buffer
        inputData[i] *= this.grainWindow[i];
        // Shift half of the buffer
        this.buffer[i] = this.buffer[i + grainSize];
        // Empty the buffer tail
        this.buffer[i + grainSize] = 0.0;
      }
      // Calculate the pitch shifted grain re-sampling and looping the input
      var grainData = new Float32Array(grainSize * 2);
      for (var i = 0, j = 0.0; i < grainSize; i++, j += pitchRatio) {
        var index = Math.floor(j) % grainSize;
        var a = inputData[index];
        var b = inputData[(index + 1) % grainSize];
        grainData[i] += linearInterpolation(a, b, j % 1.0) * this.grainWindow[
          i];
      }
      // Copy the grain multiple times overlapping it
      for (i = 0; i < grainSize; i += Math.round(grainSize * (1 -
          overlapRatio))) {
        for (j = 0; j <= grainSize; j++) {
          this.buffer[i + j] += grainData[j];
        }
      }
      // Output the first half of the buffer
      for (i = 0; i < grainSize; i++) {
        outputData[i] = this.buffer[i];
      }
    };
    pitchShifterProcessor.connect(audioContext.destination);
  };
  return {
    init: function () {
      if ('AudioContext' in window) {
        audioContext = new AudioContext();
      } else {
        alert('Your browser does not support the Web Audio API');
        return;
      }
      initProcessor();
    }
  }
}());
window.requestAnimFrame = (function () {
  return (window.requestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    function (callback) {
      window.setTimeout(callback, 1000 / 60);
    });
})();
window.addEventListener("DOMContentLoaded", pitchShifter.init, true);

1 个答案:

答案 0 :(得分:0)

您可以在SoundTouchJS中使用PitchShifter。我目前在CDGPlayer中使用它来更改用户的“密钥”。