我正在创建一个电子应用程序,允许用户裁剪和重排多个音频样本,并无视地播放它们。样本的总持续时间比小时长,因此我不能将它们全部解码,并将它们存储为PCM数据。下面是我实现的:
-首先解码音频ArrayBuffers
,创建第一段AudioBufferSourceNode
所需的音频。
在播放第一个AudioBufferSourceNode
时,以相同的方式创建下一个缓冲区,并在第一个缓冲区结束后立即播放它们。
问题是,音频有时似乎有一个爆裂的声音。每一个缓冲区都在一个接一个地播放,我在音频的开头和结尾应用了几毫秒的衰变,所以我确信这不是因为音频的突然启动/停止。
奇怪的是,只有当音频解码异步运行时,才会出现破裂噪声。我已经实现了这个功能来存储最近解码的pcm,当从缓存中播放时,没有这样的破解噪声。此外,当我在背景中运行无限循环的音频解码时,音频中显然会有更多的裂缝。
我一直在寻找谷歌的这种问题,但我找不到任何人谁也有同样的问题。所以我的问题是,decodeAudioData
真的会引起爆裂声吗?如果是的话,我该怎么解决呢?
这在每台计算机上都会发生,但低性能计算机似乎有更多的裂缝。
这里是我用来解码的代码,它是一个针对cc*>的单独的代码。
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),
);
});
};
}
最佳答案
原则上,除非原声源有裂纹噪声,否则decodeAudioData
不应产生裂纹噪声。
但是,如果压缩音频文件的采样率与AudioContext
的采样率不同,则解码音频将重新采样以匹配上下文。一般来说,这是不明显的,但你连接缓冲区播放,可能有一个不连续性,不在原来的。您应该检查音频文件的采样率是否与上下文的采样率不同。如果它们不同,请使用采样率与上下文匹配的音频文件重试。或者用与文件匹配的采样率构造上下文。(尚未在所有浏览器上可用。)
最后,如果这不能解决问题,请向浏览器提交一个问题,并确保包含一个简短但完整的测试用例。