Я создаю электронное приложение, которое позволяет пользователю вырезать и переупорядочивать несколько аудиосэмплов и, по-видимому, воспроизводить их.Общая продолжительность сэмплов может быть больше часа, поэтому я не могу декодировать их все и сохранить как данные 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),
);
});
};
}