我正在创建一个电子应用程序,允许用户剪切和重新排列多个音频样本,然后播放它们。样本的总持续时间可能会长于一个小时,因此我无法将其全部解码并存储为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),
);
});
};
}
答案 0 :(得分:1)
原则上,decodeAudioData
除非原始声源具有裂化噪声,否则不应产生裂化噪声。
但是,如果压缩音频文件的采样率与AudioContext
的采样率不同,则对解码的音频进行重新采样以匹配上下文。通常,这并不引人注意,但您是在串联缓冲区以进行回放,因此可能存在原始文件中不存在的不连续性。您应该检查音频文件的采样率是否与上下文的采样率不同。如果它们不同,请尝试使用与上下文匹配的采样率的音频文件。或使用与文件匹配的采样率构造上下文。 (尚未在所有浏览器上都可用。)
最后,如果这不能解决问题,请向浏览器提出问题,并确保包含简短但完整的测试用例。