2022年6月5日日曜日

サウンドデバイスの切り替え

結論:面倒臭くなったら SoundSwitch を使いましょう

https://soundswitch.aaflalo.me/


Windows 10 だと右下のタスクトレイのスピーカーアイコンを左クリックすると出てくるミニウィンドウにデバイス選択が出るので、それで切り替えたいデバイスにすれば良いです。



Windows 11 だと Wi-Fi などの機能設定と統合されたのですが、音量スライダーの右側の矢印がデバイス選択画面への切り替えボタンですので、選べば同様に変更が可能。


たまにであれば良いのですが、頻繁に発生すると案外面倒です。


これを解消するために調べてみたら先頭に書いてあるツールが紹介されているのを発見。


再掲:SoundSwitch / https://soundswitch.aaflalo.me/


とはいえ、別段大して手間ではなかろうて、という事で、自前で拵えることにしました。

すると案外面倒臭い案件。なんじゃこりゃ。


  • サウンドの再生デバイスにアクセスする API は Core Audio API にまとまってるが、 COM インターフェイス系のやつ
  • 更にこいつには標準の出力を設定するという機能はない
  • アンドキュメンテッドな IPolicyConfig にある SetDefaultEndpoint を使うのが鉄板


多分上記ツールもこれを触ってる。


とはいえ SetDefaultEndpoint に対象デバイスの ID を渡せば実現できる。

その ID はレジストリを漁れば分かったりする方法があるが、プログラム的には Core Audio API を使えば見つけられる。


  • IMMDeviceEnumerator : デバイス一覧をくれる奴。 mmdeviceapi.h を include すれば良い。
  • IMMDeviceCollection : 上記が検索した結果を突っ込んでくれる奴。
  • IMMDevice : デバイス毎の管理インターフェイス。
  • IPropertyStore : デバイスプロパティを握ってるやつ。


  1. IMMDeviceEnumerator::EnumAudioEndpoints に対して eRender ( 出力系 ) で DEVICE_STATE_ACTIVE ( 現状使える奴 ) を突っ込んでもらう。
  2. IMMDeviceCollection::GetCount でデバイス数が取れる。
  3. IMMDeviceCollection::Item でデバイスインターフェイスが取れる。
  4. IMMDevice::GetId でデバイスの ID が取れる ( これ重要 )
  5. IMMDevice::OpenPropertyStore に PKEY_Device_FriendlyName を渡すとフレンドリー名が取れる。所謂一般的な出力デバイス名称。


という訳で列挙するツールを作ってみた。

なお列挙できるということはデバイス ID を取得できている訳で、あとは IPolicyConfig::SetDefaultEndpoint に渡すだけ。


という訳で、ツールにデバイス名称を渡したら切り替えてくれる様に改造しました。

コマンドラインに渡された文字列を上記処理でフレンドリー名が取れたときに比較して、一致してたら切り替え処理を行って、以降スキップってやるだけ。

案外簡単に行ったけど、時間はちょいちょいかかってしまった悲しみ。

0 件のコメント:

コメントを投稿

LogiTune、おまえかい!

やっぱりそうやんなぁ、っていう。 前回に引き続き、OBSでの録画終了できない問題です。まことしやかに「GPU負荷高すぎで処理が終われない」とか書いてあるけど、どれだけ負荷下げた設定にしたって、ソース構成をシンプルにしたって駄目だったし。そもそもx264のソフトウェアエンコードにし...