Как воспроизводить аудио без использования обратного вызова с помощью AudioUnit

Я использую AudioUnit для записи и воспроизведения звука с частотой дискретизации 8 кГц и 8-битным аудиосэмплом. Я использую пример из следующего источника: https://github.com/fuxx/MicInput

Часть воспроизведения основана на шаблоне обратного вызова. С помощью этого метода я не могу контролировать, когда воспроизводить аудио, Core Audio вызывает обратный вызов, когда ему нужно воспроизвести больше аудиоданных.

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

Можно ли рендерить звук немедленно, не дожидаясь обратного вызова? С AudioQueue это возможно, вызвав AudioQueueEnqueueBuffer(), я не знаю, как это сделать с AudioUnit. Я надеюсь, что вы можете мне помочь.


person AndaluZ    schedule 15.05.2018    source источник


Ответы (1)


Невозможно воспроизвести звук «немедленно», не дожидаясь обратного вызова (возможно, скрытого API), даже игнорируя такие проблемы, как время прерывания аппаратного DMA, буферизация данных и задержка ЦАП.

ЦАП (цифро-аналоговый преобразователь) выводит аудиосэмплы с фиксированной частотой дискретизации. Либо у вас есть готовые данные, когда аудиосэмплы должны быть отправлены через ЦАП, либо какой-то мусор (щелчки, паузы и т. д.) преобразуется в аналоговое аудио.

Аудиоустройства основаны на модели вытягивания (вероятно, из-за потребностей базовой аппаратной системы прямого доступа к памяти и драйвера устройства ОС). Аудио очереди (и другие API, такие как AVAudioPlayer) построены поверх аудиомодулей. Поэтому, когда вы ставите буфер в очередь аудио, он не воспроизводится сразу. Вместо этого этот буфер очереди все еще ожидает обратного вызова Audio Unit "под капотом".

person hotpaw2    schedule 15.05.2018
comment
Я не имею в виду немедленную запись в модуль DAC напрямую, а больше похоже на добавление во внутренний буфер, который немедленно отображает, если буфер был пуст раньше. +1 за полезный ответ, но я надеялся найти решение для устранения отсутствующих пакетов, если в ближайшее время будет вызван обратный вызов. - person AndaluZ; 16.05.2018
comment
@AndaluZ: Сокрытие ошибок или что делать с отсутствующими аудиопакетами заслуживает отдельного нового вопроса. Это гораздо большая тема, чем просто аудиоустройства iOS. - person hotpaw2; 16.05.2018
comment
Добавление к следующему доступному внутреннему буферу - это то, что делает обратный вызов аудиоустройства. Предыдущие буферы уже отправлены на другие аппаратные блоки. - person hotpaw2; 16.05.2018