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)を作成することです。出力を入力にコピーし、このパススルーデバイスをデフォルトの出力として設定し、入力から記録するハードウェアに関連付けられています。私はBackgroundMusicやBlackHoleのようなオープンソースのAudioServerプラグインを使用してこれを行いました[TODO:もっと追加]。

その結果、デバイスからのタップ/記録するために、あなたは簡単に追加することができAudioDeviceIOProc、それにコールバックするか、などのデバイスを設定kAudioOutputUnitProperty_CurrentDeviceしますkAudioUnitSubType_HALOutput AudioUnit

上記の仮想パススルーデバイスアプローチには、2つの問題があります。

  1. パススルーデバイスによって消費されているため、出力を聞くことができなくなります
  2. デフォルトの出力デバイスを変更すると、デバイスから離れて切り替わり、タップは無音になります。

1.が問題の場合は、パススルーデバイスと実際の出力デバイス(スクリーンショットを参照)を含むマルチ出力デバイスを作成し、これをデフォルトの出力デバイスとして設定するだけです。ボリュームコントロールは機能しなくなりますが、実際の出力デバイスのボリュームはで変更できますAudio MIDI Setup.app

2.の場合、デフォルトの出力デバイスにリスナーを追加し、変更されたときに上記のマルチ出力デバイスを更新できます。

上記のほとんどは迅速に実行できますが、バッファ配信コールバックからリングバッファを取得するには、Cまたはリアルタイムオーディオルール(ロックなし、メモリ割り当てなしなど)を尊重できるその他の言語を使用する必要があります。AVAudioEngineタップを試みることもできますが、IIRCの入力デバイスの変更は涙の谷間です。