CoreAudio AudioQueue | Как выполнить потоковую передачу из сети на указанное c подключаемое устройство Audio Server в macOS? - PullRequest
0 голосов
/ 20 марта 2020

Я относительно новичок в программировании на macOS, но не программирую вообще. Я бы предпочел работать на (Objective) C / C ++, а не на Swift. Мне нужно открыть указанное c аудиоустройство для вывода и выполнить потоковую передачу аудиоданных в реальном времени из сети на устройство вывода. Устройство имеет собственный драйвер плагина Audio Server, источник которого у нас есть. Я чувствую себя очень глупо, пытаясь выяснить из документации Apple, что мне нужно сделать, чтобы сделать это. Может ли кто-нибудь помочь ответить на следующие вопросы:

1) Какие соответствующие API-интерфейсы используются для этого? Я думаю, что мне нужны CoreAudio и AudioQueue, но я слишком невежественен, чтобы быть уверенным. Любые ссылки на аналогичные примеры приложений будут оценены. Рекомендации книги также приветствуются.

2) Как мне открыть мой специфический c, специальный драйвер для вывода? Это как-то связано с UUID, который я вижу в коде драйвера, или драйвер определяется другим способом? Мне нужна моя программа, чтобы найти пользовательский драйвер без какой-либо помощи человека, например, выбора из списка выбора.

3) Тупой вопрос, потому что я не видел четкого примера в примерах приложений, на которые я смотрел: I скачал приложение CAPlayThrough (https://developer.apple.com/library/archive/samplecode/CAPlayThrough/Introduction/Intro.html) и вроде как понял, но что-то конкретно не понимаю. Как мне записать мои «проталкиваемые» данные в памяти из сети на устройство вывода? Нужно ли мне использовать какой-то обратный вызов, который читает из кольцевого буфера, в который записан сетевой поток в реальном времени?

ADDENDUM:

3/24/2020 Основываясь на дальнейших исследованиях, я ' Я ответил на мои основные вопросы, но все еще имею проблему, которая, по моему мнению, выходит за рамки. Я дам свой ответ ниже и напишу новый вопрос.

Ответы [ 2 ]

0 голосов
/ 24 марта 2020

1) Какие соответствующие API-интерфейсы используются для этого?

Я определил, что службы Audio Queue Services лучше всего соответствуют моим потребностям.

2) Как открыть мой специфицированный c, пользовательский драйвер для вывода?

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

  CFStringRef deviceUID = CFSTR("BlackHole_UID"); // For example
  status = AudioQueueSetProperty(queue, kAudioQueueProperty_CurrentDevice, &deviceUID, sizeof(deviceUID));

3) Как записать мои «проталкиваемые» данные в памяти из сети на устройство вывода?

Учитывая то, как работают AudioQueues, похоже, я должен сделать следующее: отправить декодированное потоковое аудио в кольцевой буфер, который извлекается из выходного обратного вызова AudioQueue.

0 голосов
/ 22 марта 2020

1) Какие соответствующие API-интерфейсы использовать для этого?

API Core Audio подойдет. См. AudioDeviceCreateIOProcID и AudioDeviceStart в CoreAudio/AudioHardware.h. По какой-то причине на сайте документации Apple нет документов для них, поэтому вы должны найти его в заголовочном файле.

Или вы можете использовать AVAudioEngine. (Но не AVAudioPlayer.)

В зависимости от ваших других требований, может быть проще использовать существующую программу, такую ​​как GStreamer или VL C.

Любые ссылки на аналогичные примеры приложений будут оценены.

CAPlayThrough может быть хорошим местом для начала, но он использует AUGraph, что устарело. Я не уверен, понадобится ли вам аудиоустройство с переменной скоростью, которое оно использует для настройки различий в частотах дискретизации, но вы, по крайней мере, можете начать без него. 1026 *: https://github.com/pje/WavTap/blob/master/App/AudioTee.cpp

Как открыть мой специфический c, настраиваемый драйвер для вывода?

Драйвер будет опубликован sh устройство вывода звука, и оно будет иметь свойство с именем kAudioDevicePropertyModelUID (см. AudioHardwareBase.h.) И должно иметь для него постоянное значение. Вы можете проверить это, дважды щелкнув по устройству в HALLab.

Ваша программа может использовать AudioObjectGetPropertyData, чтобы получить свойство kAudioHardwarePropertyDevices «объекта аудиосистемы» (kAudioObjectSystemObject), а затем получить kAudioDevicePropertyModelUID свойство каждого устройства.

Если вы используете C ++, вы можете использовать Publi c Utility классы , чтобы помочь с этим.

Имеет ли это какое-то отношение к UUID, который я вижу в коде драйвера, или драйвер идентифицирован как-то иначе?

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

Как записать мои «выдвинутые» данные в памяти из сети на устройство вывода? Нужно ли мне использовать какой-нибудь обратный вызов, который читает из кольцевого буфера, в который записан сетевой поток в реальном времени?

Функция, которую вы передаете AudioDeviceCreateIOProcID, будет вызываться каждый цикл ввода-вывода и получать буфер для заполнения сэмплами для этого цикла.

...