AudioContext.decodeAudioData, кажется, создает потрескивающий шум - PullRequest
2 голосов
/ 23 мая 2019

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

1 голос
/ 23 мая 2019

В принципе, decodeAudioData не должен давать трещинный шум, если только исходный источник его не имел.

Однако , если частота дискретизации сжатого аудиофайла отличается от частоты дискретизации AudioContext, декодированный звук повторно дискретизируется в соответствии с контекстом. Как правило, это не заметно, но вы объединяете буферы для воспроизведения, может быть разрыв, которого нет в оригинале. Вы должны проверить, отличается ли частота дискретизации аудиофайла от частоты контекста. Если они разные, повторите попытку с аудиофайлом с частотой дискретизации, соответствующей контексту. Или создайте контекст с частотой дискретизации, соответствующей файлу. (Пока доступно не во всех браузерах.)

Наконец, если это не решит проблему, подайте проблему в браузере и обязательно включите короткий, но полный тестовый пример.

...