Веб-аудио API getByteTimeDomainData возвращает плоские 128 (все нули)

#angular #web-audio-api

#угловатый #веб-аудио-api

Вопрос:

Я использую Web Audio API, чтобы ничего не делать, кроме как показывать индикатор активности микрофона, чтобы показать пользователю, что его микрофон подключен и ввод принимается.

Это веб-проект Angular, и я использую таймер для создания моментального снимка входных данных с помощью getByteTimeDomainData().

Когда я запускаюсь, каждый снимок, который я делаю, равен 128 (нулю), независимо от того, сколько шума я создаю.

Код:

 private setupMicInputListener(stream: MediaStream): void {
    const threshold = 10;
    const timerSource = timer(0, 100);
    timerSource.subscribe((val) => {
      const audioLevel = this.getCurrentAverageMicInputLevel(stream);
      console.log(audioLevel);
      this.audioInputDetected = audioLevel > threshold;
    });
  }

  private getCurrentAverageMicInputLevel(stream: MediaStream): number {
    const audioContext = new window.AudioContext();
    const analyser = audioContext.createAnalyser();
    const microphone = audioContext.createMediaStreamSource(stream);
    microphone.connect(analyser);

    analyser.smoothingTimeConstant = 0.8;
    analyser.fftSize = 2048;
    const buffer = new Uint8Array(analyser.fftSize);
    analyser.getByteTimeDomainData(buffer);
    let values = 0;

    const length = buffer.length;
    for (let i = 0; i < length; i  ) {
      values  = (buffer[i]);
    }

    const averageLevel = values / length;

    return averageLevel;
  }
 

Я читал, что если он не подключен к выходу, сигналу некуда «идти», но когда я пытаюсь

 microphone.connect(audioContext.destination)
 

Я получаю сумасшедшую обратную связь через своих спикеров. Я знаю, что поток, в котором я прохожу, правильный. Вне этого кода я получаю устройства пользователей, и я могу заметить, что это устройство является моим микрофоном. Я создаю медиапоток и добавляю в него звуковую дорожку моего микрофона, прежде чем передавать поток этому компоненту. Кроме того, когда я использую приведенную выше строку кода, я слышу шум, который я издаю во всех отзывах.

Ответ №1:

Я не знаком с angular, но, глядя на код, кажется, что вы периодически вызываете getCurrentAverageMicInputLevel . Это создает новый звуковой контекст каждый раз с соответствующим AnalyserNode . А затем вы сразу же запрашиваете 2048 выборок данных временной области. На данный момент маловероятно, что анализатор действительно получил какие-либо данные с микрофона, поэтому вы просто получаете буфер из 2048 нулей.

Чтобы исправить это, создайте контекст, анализатор (включая настройку параметров анализатора) и микрофон только один раз, возможно, в setupMicInputListener . Тогда пусть getCurrentAverageMicInputLevel позвонят getByteTimeDomainData . Я думаю, тогда вы увидите ненулевые значения, если микрофон не отключен.

Для Chrome, как правило, вам действительно нужно, чтобы узел в конечном итоге был подключен к месту назначения, но есть исключения, и узел анализатора является одним из исключений. Но убедитесь, что вывод вообще ни к чему не подключен, чтобы это работало.

Комментарии:

1. Я только что заметил это на самом деле и изменил свою логику. Подумать только, я так долго на этом зацикливался. Спасибо, что взглянули.

2. Рад, что вы это исправили!