【问题标题】:Audioworklet loopAudioworklet 循环
【发布时间】:2021-04-25 11:21:32
【问题描述】:

我正在尝试创建一个可循环播放单个声音实例以创建一种延音效果的 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 个通道)。然后,一旦该数组已满,我会循环遍历该数组以填充输出,直到该节点被禁用。

【问题讨论】:

  • 您必须提供有关您正在做什么的更多详细信息。
  • @RaymondToy,我添加了一些代码来给你一个更好的主意。如果这有帮助,请告诉我。
  • 这有帮助,但我看不出有什么问题。如果可以,您能否在 jsfiddle.net 或 codepen.io 上创建一个更完整(但仍然很简单)的示例?对于测试,您不需要麦克风输入。只需使用振荡器或其他东西作为输入。这会很有帮助!
  • @RaymondToy,我创建了一个使用脚本处理器的 jsfiddle,因为我无法在该站点上创建一个 audioworklet。但它给出了我面临的相同结果和问题。 jsfiddle.net/5jh0qcoe 要关注的代码是第 31-51 行。谢谢

标签: web-audio-api audio-worklet


【解决方案1】:

感谢您的提琴。很有帮助。

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

// @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 并查找输出中的不连续性。

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

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

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

【讨论】:

    猜你喜欢
    • 2021-12-21
    • 2019-04-05
    • 1970-01-01
    • 2022-08-02
    • 2020-02-01
    • 2018-10-02
    • 1970-01-01
    • 2023-01-15
    • 2012-12-22
    相关资源
    最近更新 更多