Получите аудио буферы устройства вывода macOS в реальном времени

Dec 14 2020

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

Я хочу скопировать эти данные в кольцевой буфер в реальном времени, чтобы работать с ними отдельно.

Комбинация документов Apple и (устаревших?) Ответов SO сбивает с толку, нужно ли мне писать хакерское расширение ядра, можно ли использовать CoreAudio для этого или нужно взаимодействовать с HAL?

Я хотел бы по возможности работать в Swift.

Большое спасибо

(PS. Я смотрел на то и это )

Ответы

3 RhythmicFistman Dec 14 2020 at 23:07

Я не знаю о расширениях ядра - использование ими специальных сертификатов для подписи «позвоните нам» или необходимость выключения SIP препятствует случайному исследованию.

Однако вы можете использовать комбинацию плагинов CoreAudio и HAL AudioServer, чтобы делать то, что вы хотите, и вам даже не нужно писать плагин самостоятельно, есть несколько версий с открытым исходным кодом на выбор.

CoreAudio не дает вам возможности записывать с (или «касаться») устройств вывода - вы можете записывать только с устройств ввода, поэтому способ обойти это - создать виртуальное «сквозное» устройство (AudioServerPlugin), а не связанный с любым оборудованием, которое копирует вывод на ввод, а затем устанавливает это проходное устройство в качестве вывода по умолчанию и записывает с его ввода. Я сделал это, используя плагины AudioServer с открытым исходным кодом, такие как BackgroundMusic и BlackHole [TODO: добавить больше].

Для крана / записи из полученного устройства вы можете просто добавить функцию AudioDeviceIOProcобратного вызова к нему , или установить устройство как kAudioOutputUnitProperty_CurrentDeviceизkAudioUnitSubType_HALOutput AudioUnit

У описанного выше подхода виртуального сквозного подключения есть две проблемы:

  1. вы больше не можете слышать звук, потому что он потребляется проходным устройством
  2. при изменении устройства вывода по умолчанию ваше устройство будет отключено, и нажатие прекратится.

Если 1. является проблемой, то проще всего создать устройство с несколькими выходами, содержащее сквозное устройство и реальное устройство вывода (см. Снимок экрана), и установить его в качестве устройства вывода по умолчанию. Регуляторы громкости перестают работать, но вы все равно можете изменить громкость реального устройства вывода Audio MIDI Setup.app.

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

Вы можете сделать большую часть вышеперечисленного быстро, хотя для загрузки кольцевого буфера из обратных вызовов доставки буфера вам придется использовать C или какой-либо другой язык, который может соблюдать правила звука в реальном времени (без блокировок, без выделения памяти и т. Д.). Возможно, вы могли бы попытаться AVAudioEngineсделать кран, но изменение устройства ввода IIRC - это юдоль слез .