AudioContext.decodeAudioData似乎会产生crack啪声

时间:2019-05-23 08:00:45

标签: javascript typescript web-audio

我正在创建一个电子应用程序,允许用户剪切和重新排列多个音频样本,然后播放它们。样本的总持续时间可能会长于一个小时,因此我无法将其全部解码并存储为pcm数据。所以这是我实现的:
 -首先解码创建ArrayBuffers的第一段所需的音频AudioBufferSourceNode
 -在播放第一个AudioBufferSourceNode时,以相同的方式创建下一个缓冲区,并在第一个缓冲区结束后立即播放它们。

问题在于,音频似乎偶尔会发出嘶哑的声音。每个缓冲区都紧接着播放,并且我在剪切音频的开始和结束部分施加了几毫秒的衰减,因此我确定这不是突然开始/停止音频引起的。
奇怪的是,只有在音频解码异步运行时才会产生开裂噪声。我已经实现了此功能来存储最近解码的pcm,并且从高速缓存播放时没有这种开裂的噪音。此外,当我在后台运行音频解码的无限循环时,音频中显然会有更多裂缝。

我已经在Google中搜索了此类问题,但找不到任何遇到相同问题的人。所以我的问题是,decodeAudioData真的会引起破裂的声音吗?如果是的话,我该如何解决?

这种情况在每台计算机上都会发生,但是性能低下的计算机似乎有更多的漏洞。

这是我用来解码的代码,它是AudioContext的单例代码。

class AudioDecoder {
  // Number of audioContext of limited,
  // using a singleton to prevent hitting the limit
  private audioCtx: AudioContext;
  private static instance: AudioDecoder;
  private constructor() {
    const AudioContextClass =
      (window as any).AudioContext || (window as any).webkitAudioContext;
    this.audioCtx = new AudioContextClass();
  }
  public static decode = (arrayBuffer: ArrayBuffer) => {
    if (!AudioDecoder.instance) {
      AudioDecoder.instance = new AudioDecoder();
    }
    return new Promise<AudioBuffer>((resolve, reject) => {
      AudioDecoder.instance.audioCtx.decodeAudioData(
        arrayBuffer,
        buffer => {
          resolve(buffer);
        },
        error => reject(error),
      );
    });
  };
}

1 个答案:

答案 0 :(得分:1)

原则上,decodeAudioData除非原始声源具有裂化噪声,否则不应产生裂化噪声。

但是,如果压缩音频文件的采样率与AudioContext的采样率不同,则对解码的音频进行重新采样以匹配上下文。通常,这并不引人注意,但您是在串联缓冲区以进行回放,因此可能存在原始文件中不存在的不连续性。您应该检查音频文件的采样率是否与上下文的采样率不同。如果它们不同,请尝试使用与上下文匹配的采样率的音频文件。或使用与文件匹配的采样率构造上下文。 (尚未在所有浏览器上都可用。)

最后,如果这不能解决问题,请向浏览器提出问题,并确保包含简短但完整的测试用例。