-1

我正在尝试创建一个 audioworklet 循环单个声音实例以创建一种持续效果。无论我循环输入多少个部分,我都会不断听到一种跳动的声音。一个实例有多少次对处理器的调用?

为了给你一个想法,这就是我到目前为止所拥有的:

        constructor() {
            super();
            this.sound = [];
            this.count = 20;
            this.step = [0, 0];
        }
        process(inputs, outputs, parameters) {
            if (inputs && inputs.length) {
                for (var i = 0; i < inputs[0].length; i++) {
                    var input = inputs[0][i];
                    var output = outputs[0][i];
                    if (!this.sound[i]) {
                        this.sound[i] = [];
                    }
                    if (this.sound[i].length < this.count) {
                        this.sound[i].push([]);
                        for (var j = 0; j < input.length; j++) {
                            this.sound[i][this.sound[i].length - 1][j] = input[j];
                        }
                    } else if (this.sound[i]) {
                        var s = this.sound[i][this.step[i] % this.sound[i].length];

                        for (var j = 0; j < s.length; j++) {
                            output[j] = s[j];
                        }

                        this.step[i]++;
                    }
                }
            }
            return true;
        }

所以我的想法是我在每个通道的 N 长度数组中捕获输入输入(在我的情况下有 2 个通道)。然后,一旦该数组已满,我会循环遍历该数组以填充输出,直到该节点被禁用。

4

1 回答 1

0

谢谢你的小提琴。非常有帮助。

我没有看到导致点击的原因,但我以您的示例为例并对其进行了非常轻微的修改,如下所示:

// @channels 2
// @duration 1.0
// @sampleRate 44100

var bufferSize = 4096;
let ctx = context;
let osc = ctx.createOscillator();
osc.start();

let myPCMProcessingNode = ctx.createScriptProcessor(bufferSize, 2, 2);

let _count = 1;
var sound = [];
var count = _count++;
console.log(count)
var hesitate = 0;
var step = [0, 0];

//Logic to pay attention to
myPCMProcessingNode.onaudioprocess = function(e) {
    for(var i = 0; i<2; i++){
    var input = e.inputBuffer.getChannelData(i);
    var output = e.outputBuffer.getChannelData(i);
    if (!sound[i]) {
      sound[i] = [];
    }
    if (sound[i].length < count) {
      sound[i].push([]);
      for (var j = 0; j < input.length; j++) {
        sound[i][sound[i].length - 1][j] = input[j];
      }
    } else if (sound[i]) {
      var s = sound[i][step[i] % sound[i].length];
      for (var j = 0; j < s.length; j++) {
        output[j] = s[j];
      }
      step[i]++;
    }
  }
}
        //To hear

osc.connect(myPCMProcessingNode).connect(ctx.destination);

我将其粘贴在https://hoch.github.io/canopy的代码窗口中。按代码窗口左侧的左上角按钮(箭头),您可以看到渲染的音频。您可以看到输出(频率为 10 而不是 440 以便于查看)是不连续的。这会导致您听到咔嗒声。您还可以将频率更改为 100 并查找输出中的不连续性。

我希望这足以帮助您找出缓冲的问题。

AudioBufferSourceNode另一种方法是使用基本样本创建一个AudioBuffer。您可以设置AudioBufferSourceNode循环整个缓冲区。这并不能解决点击问题,但它更简单一些。

但这是循环任何缓冲区的一般问题。除非您将最后一个样本安排在靠近第一个样本的位置,否则您在环绕时会听到咔嗒声。您要么需要抓取第一个和最后一个样本几乎相同的块,要么修改这些块,使它们在开始时以某种方式上升并在结束时以某种方式下降。

于 2021-01-25T22:59:36.120 回答