Как правильно использовать функцию обратного вызова iOS AudioUnit - PullRequest
4 голосов
/ 24 ноября 2011

Я пишу приложение для iOS, которое будет воспроизводить звуковые инструкции как одну из его функций.

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

Несмотря на то, что у меня есть этот буфер с данными PCM, я не могу заставить приложение воспроизводить звук. После поиска документации по iOS я начал реализовывать AudioUnit. Проблема с этим AudioUnit заключается в использовании обратного вызова рендеринга (насколько я знаю, единственный способ вывода звука). От Документация разработчика Apple :

… обратные вызовы рендеринга имеют строгие требования к производительности, которые вы должны придерживаться. Обратный вызов рендеринга живет в приоритетном потоке в реальном времени на какие последующие вызовы рендеринга поступают асинхронно. Работа, которую вы делаете в теле рендеринга обратного вызова происходит в этом ограниченном по времени среда. Если ваш обратный вызов все еще производит образцы кадров в ответ на предыдущий вызов рендеринга при следующем вызове рендеринга прибывает, вы получаете разрыв в звуке. По этой причине вы не должны принимать блокировки, выделение памяти, доступ к файловой системе или сети подключение или иным образом выполнять трудоемкие задачи в теле функция обратного вызова рендеринга

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

Единственный пример Я обнаружил, фактически сгенерировал данные PCM внутри метода рендеринга, чего я не могу сделать.

Это единственный способ использования AudioUnits (с асинхронным обратным вызовом рендеринга)?

Есть ли альтернатива воспроизведению данных PCM из памяти?

1 Ответ

4 голосов
/ 25 ноября 2011

Использование аудиоустройства RemoteIO может потребовать наличия отдельной очереди данных (fifo или циклический буфер) вне обратного вызова аудиоустройства, которая может предварительно буферизовать достаточное количество аудиоданных из файла, считанного перед обратным вызовом рендеринга аудиоустройства, для встречаются худшие задержки. Затем обратному вызову рендеринга нужно только быстро скопировать аудиоданные, а затем обновить флаг только для записи, который указывает, что аудиоданные были использованы.

Альтернативой, встроенной в iOS, является использование API Audio Queue, который выполняет предварительную буферизацию для вас. Это позволяет вашему приложению заблаговременно заполнить несколько больших звуковых буферов в главном цикле выполнения. Вам по-прежнему необходимо предварительно буферизовать достаточно данных, чтобы обеспечить максимальный размер файла, сети, блокировки или других задержек.

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

...