Unityでビデオキャプチャデバイス(GV-USB2)から受け取った音声入力をリアルタイム再生しようとした話1 デバイス検出処理検証

この記事を書き始めてからだいぶ時間が経過してしまい、

元々書いていたブログサービスが終了して、

やや入力や表示のフォーマットずれが起きている事、

当時の記憶が曖昧になった事、

テストプロジェクトの衛生状態が情報を整理しにくい事、

整理していくに連れて記事内の記述の区分分けが不適切である事等が分かったので、

おそらくそのうちまた書き直すと思います。

 

 

まずは各ライブラリの音声入力デバイスを検出する処理について検証します。
GV-USB2が音声入力デバイスとして検出されない事には
性能の検証やリアルタイム再生の技術検証をしても意味が無いからです。

始めに

筆者はあんまりネイティブやデバイスやライブラリの規格や仕様の事は詳しくないので、
手当たり師団検証して結果をつらつら書いていくような内容になります。

おそらく、もっと最適な解や途中解を用いた効率的な検証方法等あると思うので、
技術的な知見を広める為の記事では無く、
主に同じく
基礎知識が無く手探りで検証をしていこう
と思っている人向けの記事になるかと思います。

検証環境に関しても疎いながら思い浮かぶ事を一応書いておきます。
マシン:BTOのミニタワーデスクトップ
OS:Windows10(64bit)
CPU:i3-6100
メモリ:12GB
グラボ:マザーボード標準
Unity:2019.4.5f1

注意点としては検証過程のライブラリのインポート等に関する説明は省略する場合があります
自分も今回初めてやった事も多かったですが、
調べると出てその通りやったら出来たと思うので、
全般的な作業手順については書いてなかったら自己補完して対応して頂ければと思います。

また、元々ここでの答えの通り対応したい人も居るかも知れないので
先に結果だけ書いておきますが、
見る限りGV-USB2が音声入力デバイスとして検出されるライブラリはありませんでした。

なので、本来GV-USB2に接続する赤端子と黄色端子をステレオミニプラグに変換して
ライン入力に繋ぐアプローチを取る予定です。


それでは検証本文に入ります。

1.Unity標準

1-1.UnityEngine.Microphone
正常動作
GV-USB2の検出 ×

UnityEngineにはMicrophoneと言う標準APIがあります。

UnityEngine.Microphone.devicesMicrophone.devices
にUnityEngineで使用出来るサウンド入力デバイス名が列挙されます。

ただ、どうもGV-USB2はオーディオインプットデバイスとして列挙されません。

ちなみに確か、
同じくビデオ入力デバイス名が取得出来、
GV-USB2の名前が確認出来る
UnityEngine.WebCamTexture.devices[x].name
を指定したり、
他のソフトから見た名前を指定して
UnityEngine.Microphone.Start()
してやってもうまく行かなかったと思います。


2.DirectShow(C#)

2-1..NET
正常動作 ×
GV-USB2の検出 ×

http://blog.livedoor.jp/cogorou/DSLab/TestVarious.html
Unity5系の時にビデオ入力を撮ろうとした時にやった事があるが正しく動かなかったもの。

多分5系のDLLは持ってくる方法が調べればいっぱい出てくるし、
間違いにくい構造をしていたと思うので、
多分間違っていないんじゃないかなと思うが、
当時果たしてその時に正しいDLLを引っ張って来れていたのかは分からない。

ただし、今回改めて必要なDLLをPluginsに引っ張って来て、
UnityEngine.MonoBehaviour系アダプタを作って動かしてみたがやはり動かなかった。

Api Compatibility Levelが
.Net Standard 2.0の時は
System.Type.GetTypeFromCLSID()
にて以下のエラー
System.NotImplementedException: The requested feature is not implemented.
が、
.Net 4.xの時は
System.Activator.CreateInstance ()
にて以下のエラー
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.MethodAccessException: Method `System.__ComObject..ctor()' is inaccessible from method `System.__ComObject..ctor()'
at (wrapper managed-to-native)
が出力される。

.Net Standard 2.0時のエラーは.Net 4.xに変更する事で解決し、
.Net 4.x時のエラーはCOMオブジェクトを作れないようだが、
これを追及するのは気が引けるので、
このアプローチは断念することにした。

2019系では5系などに比べてDLLの場所がややこしくなっている。
これに関しては多分別の機会に紹介すると思うので、
今回は正しいDLLの場所に関しては省略する。


3.ラッパー

この辺りからは主にDirectShowラッパー系の検証です。

3-1.アレンジ系ラッパー

オリジナル書式で書かれているので他のラッパーと処理フローに互換性が無いと思われるもの。

3-1-1.DirectShowNet
正常動作 ×
GV-USB2の検出 ×

基本的にはここ
https://blog.ishitoya.info/entry/20080524/1211598985
に書いてある通りに進める。

CodeProjectのリンクは消失していて、
ざっくりは探したが見つからず、
そもそもこの技術がポンと使えそうかどうかが分からないと、
その辺りを追求する意味も無いので、
取り敢えずはリンク先で更に参考にしたと書かれているページの
サンプル内に入っているDirectShowNetを摘まみ食いする事にする。

他にも微調整等したかも知れないが忘れたので省略。
基本的には2に同じく必要なDLLをPluginsに引っ張って来て実行。
すると
DsDev.GetDevicesOfCat()
が成功せず
outパラメータへの出力も確認出来ない為以後の処理を実行出来ない。

これも追及するのは気が引けるので、
このアプローチは断念することにした。


3-2.ラッパー

元のフローに沿ってラップしていると思われるので他のラッパーと処理フローに互換性が有るもの。

3-2-1.NAudio1.10

NAudioはNuGetが必要そうなので、
UnityでNuGetを使えるようにする奴を入れる。

NuGetはApi Compatibility Levelを参照した上で
適切なライブラリをダウンロードするので、
NuGetでダウンロードする前に設定する。

もし先にダウンロードしてしまったら、
アンインストールしてApi Compatibility Levelを変えて再びインストールする。

3-2-1-1.NAudio1.10 Wave名前空間
正常動作
GV-USB2の検出 ×

Unityに入れてみた先駆者が居たので、こちら
https://qiita.com/nise_aoi/items/7923ab29a678aa5a9b14
に沿って進める。

ちなみにApi Compatibility Levelどちらでも変わらなかった気がするけれど、
この記事を書いている段階の設定は.Net4.xが設定されている。

記事元を追っていくとUnityがハングする理由に依存DLLが上がっているが、
そちらに関する検証はもっと先の内容に当たるので、
一旦ハングしてもデバイス列挙の挙動を見る事を優先、
NAudioの検証にはDLLは一旦必要ないものとする。

他にも微調整等したかも知れないが忘れたので省略。
実行すると特にエラー出ず。
ただし
NAudio.WaveIn.GetCapabilities(x).ProductName
をログ出力してもGV-USB2の列挙は見当たらなかった。


3-2-1-2.NAudio1.10 CoreAudioApi名前空間
正常動作 ×
GV-USB2の検出 ×

3-2-1-1の結果を元に調べていたところ、以下
https://teratail.com/questions/53571
のようなQ&Aを見つけた。

Q&Aには別の関数を使ったと書かれていたので調べていくと、
別のデバイス列挙処理が出てきたのでこちらも検証。

https://ja.ojit.com/so/c%23/3223207
をMonoBehaviour化し実行。

すると
new NAudio.CoreAudioApi.MMDeviceEnumerator().EnumerateAudioEndPoints ()
にて以下のエラーが発生した。

Object reference not set to an instance of an object

正しく動いているかどうかは分からないが厳密には
new NAudio.CoreAudioApi.MMDeviceEnumerator()
まではコール上は成功している。

コピペだとアンリーチではあるものの、
ソースコード上は存在している
new NAudio.CoreAudioApi.MMDeviceEnumerator().GetDefaultAudioEndpoint()
をリーチさせても同じようなエラーが出る。

これも追及するのは気が引けるので、
このアプローチは断念することにした。


3-2-1-3.NAudio1.10 XAudio2名前空間

無さそう。未検証。


3-2-2.NAudio2.00

NAudioに関しては、
他のライブラリの検証をやってるうちにバージョンアップしていました。

 

3-2-2-1.NAudio2.00 Wave名前空間
正常動作
GV-USB2の検出 ×

https://teratail.com/questions/186223
WaveはWaveInEventに変わってるようです。
構文エラーにインテリセンスを順番に決めて正常動作。

ただし変わらずGV-USB2に関する列挙は見当たらない。


3-2-2-2.NAudio2.00 CoreAudioApi名前空間
正常動作 ×
GV-USB2の検出 ×

NAudio.CoreAudioApi.MMDeviceEnumerator.EnumerateAudioEndPoints ()
が変わらず動かないようだ。
残念。

一応DLLの構成が変わっていて、
参照DLL名自体は変わっているようには見える。


3-2-2-3.NAudio2.00 XAudio2名前空間

無さそう。未検証。


3-2-3.CSCore(NuGet)

3-2-1-2に関してQ&Aを投げていた人を発見した。
https://stackoverflow.com/questions/48217715/c-sharp-unity-3d-naudio-throws-nullreferenceexception-while-checking-for-default
この人はCSCoreと言う上位互換を発見したと言っているので、
NuGetからCSCoreを入れてお手並みを拝見することにした。

ただしNuGetからダウンロードしようとしても
.nupkgはダウンロードされているがDLLが生成されない。

https://www.atmarkit.co.jp/fdotnet/chushin/nuget_02/nuget_02_02.html
.nupkgはzipらしいので、
複製を.zipにリネームし展開してみる。
ディレクトリ名がマッチの範囲外なのか、
net35-client
と言うディレクトリがあるので、
これを他のNuGetでダウンロードしたものと同じ形になるように
プロジェクトに配置する。

3-2-3-1.CSCore(NuGet) Wave名前空間
正常動作 ×
GV-USB2の検出 ×

インテリセンスを漁って行くとCSCore.SoundIn名前空間に互換のある処理が見つかる。

CSCore.SoundIn.WaveInDevice.EnumerateDevices().ToList().Count
からデバイス数は取得出来るが,
CSCore.SoundIn.WaveInDevice.EnumerateDevices().ToList()[x].Name
が常にNullでデバイスを識別出来ない。


3-2-3-2.CSCore(NuGet) CoreAudioApi名前空間
正常動作
GV-USB2の検出 ×

https://github.com/filoe/cscore/blob/master/Samples/AudioPlayerSample/MusicPlayer.cs
この辺をヒントに置換していく。
型に関する定義やパラメータフォーマット等は違うようだが、
基本的な処理フローは大体同じようだ。

パラメータを
DataFlow.All, DeviceState.All
とすると40近いデバイスが列挙されるが、
GV-USB2と思われる名前は確認出来なかった。

ちなみにステートをAllにしているが、
これはどうやら認識された事はあるが
現在接続されていないものまで検出しているようだ。


3-2-3-3.CSCore(NuGet) XAudio2名前空間
正常動作 ×
GV-USB2の検出 ×

https://github.com/filoe/cscore/blob/master/CSCore.Test/XAudio2/XAudio2Tests.cs
詳しくは知らないが、
CSCore.XAudio2.XAudio2.CreateXAudio2()
の実態が
CSCore.XAudio2.XAudio2_7
の場合は
CSCore.XAudio2.GetDeviceDetails()
でデバイスを列挙出来るらしい。

自分の環境は
System.Object.GetType()
を取ると
CSCore.XAudio2.XAudio2_8
だった。
勿論強引に
CSCore.XAudio2.XAudio2_7
キャストしようとしても正しく動かない。


3-2-4.CSCore(NuGet)

 

ダウンロードはしてみたものの、
どうやらDirectShow関連のものとは全く別の
C#の標準的な機能のラッパーのようだ。

 

3-2-5.SharpDX

多分NuGetでXAudio2とかで検索して出てきたんだと思う。

3-2-5-1.SharpDX Wave名前空間

不明。未検証。


3-2-5-2.SharpDX CoreAudioApi名前空間

不明。未検証。


3-2-5-3.SharpDX XAudio2名前空間
正常動作 ×
GV-USB2の検出 ×

多分名前空間を差し替えるだけでXAudio2_7のコードが動いたが、
内部でXAudio2_7とXAudio2_8のアダプタをしているわけではなく、
InvalidOperationException: This method is only valid on the XAudio 2.7 requestedVersion [Current is: Version28]
SharpDX.XAudio2.XAudio2.CheckVersion27 ()
と出る。

 

 

3-2-6.MFLib

確か3-2-5までやってMediaFoundationと言う名前空間を見つける。(確か。
今までの書式に互換性が無くて諦めたんだった気がするが
このページを見ながらやった記憶があまり無いので一応置いておく。
https://github.com/sharpdx/SharpDX-Samples/blob/master/Desktop/MediaFoundation/MediaEngineAppVideo/Program.cs

 

3-2-6-1.MFLib Wave名前空間

無さそう。未検証。


3-2-6-2.MFLib CoreAudioApi名前空間

無さそう。未検証。


3-2-6-3.MFLib XAudio2名前空間

無さそう。未検証。



3-2-6-4.MFLib ___名前空間

https://qiita.com/kenjiuno/items/fa8ff3483dfc2b48c466
MF.EnumVideoDeviceSources()
でUnityがハングする。


 

メモ

なんかNuGetでDirectShowLibをインストールしてるがこれテストしてなくない?
↑結構日を跨ぎながら色んな事検証してたので
こう言うのがある気がするのもあって文書に起こしてみようと思ってたんですよね。
記事書いていくうちでこれを使ってるテストプロジェクトがあれば
ここの記述は消しますが、
DirectShowNetのラッピングの形とDirectShowLibのラッピングの形で
外からコールに互換性を見出せなくて辞めたんだった気がしますが、
それにしても他のサンプルと互換性が無いか確認したり、
ここ
https://qiita.com/tera1707/items/df751cae4cec4e6da0db
のサンプルの検証したりしてないとおかしい気はします。
一旦保留。

 

 


まとめてると検証漏れだったりまだ簡単に検証出来そうな事が幾つかあったのと、
思ったより自分がやっている検証とそれを元に書いている文章のまとまりが無さ過ぎるので、
この記事を元にそのうちもう一回検証して同じ内容の記事を作ると思います。

まあ何を参考にして何をやったかが全然分からなくなっているわけですが、
社会人なんですからログとドキュメント化くらいはやっておきましょう。

最低でも一発目の検証でうまく行かなかった事はちゃんとログ付けた方が良いですね、
あまり技術検証とか得意じゃ無いんで今回は良い経験になりました。

多分やり残してる検証をやってから、実際に使うライブラリの検証をやっていくと思います。

余談ですが、AudioClipに変換したりOnAudioFilterReadを使ったりするより
そのままどこかにあるだろうサンプル通りデバイスに直接音を流してしまおうかと思っていたりします。
AudioClipはバッファをAddしていくような構造があるか怪しいと言うか
ぱっと検索した限りサンプルが見当たらなかったのと、
OnAudioFilterReadはAudioListenerに流れてきた波形を上書きするものなので、
ジャックして上書きするか混ぜる計算をやる必要がありそうですが、
前者はUnityのサウンド機能が動かなくなるのと、
後者は専門的な知識が必要そうだからです。

では、またそのうち。

Unityでビデオキャプチャデバイス(GV-USB2)から音声を録音、リアルタイム再生しようとした話

UnityEngineにはMicrophoneと言うAPI?があります。
ただ、どうも少なくともGV-USB2はオーディオインプットデバイスとして列挙されないんですよね。
そこでデバイスを列挙する処理に関して色々検証してみた事を
記事にしてみようと思います。

一応現状の結果としては物理的な対応をする事にしようとは思っているのですが、
自分としても実際に遅延検証に入る前段階として
現状を整理したいなと思ったので綴っていきます。

始めに

筆者はあんまりネイティブやデバイスやライブラリの規格や仕様の事は詳しくないので、
論理的と言うよりは検証をつらつら書いていくような内容になります。
おそらく、もっと最適な解や途中解を用いた効率的な検証方法等あると思うのですが、
同じく基礎知識が無くて手探りで検証をしていこうと思っている人に向けての記事になるかと思います。

あと、そう言う前提で、思い浮かぶ環境を書いておきます。
マシン:BTOのミニタワーデスクトップ
OS:Windows10(64bit)
CPU:i3-6100
メモリ:12GB
グラボ:マザーボード標準
Unity:2019.4.5f1

検証作業の途中にあるライブラリのインポート等に関しては語ったり語らなかったりすると思います。
自分も今回初めてやった事も多かったですが、調べると出て、
その通りやったら出来たと思うので、
全般的な作業手順については書いてなかったら自己補完して対応して頂ければと思います。

1.UnityEngine.Microphone

前述になりますが、UnityEngineにはMicrophoneと言うAPI?があります。
UnityEngine.Microphone.devicesMicrophone.devices
にUnityEngineで使用出来るサウンド入力デバイス名が列挙されていて、
UnityEngine.Microphone.Start()の引数で指定してやることで
UnityEngine.AudioClipにリアルタイム出力させてやるように出来るのですが、
UnityEngine.Microphone.devicesMicrophone.devices
にはGV-USB2が列挙されません。

ちなみに確か、
同じくビデオ入力デバイス名が取得出来、
GV-USB2の名前が確認出来る
UnityEngine.WebCamTexture.devices[x].name
を指定したり、
他のソフトから見た名前を指定してStartしてやってもうまく行かなかったと思います。

2..NET

正直何やってるのかあまり分かってないですが、取り敢えずここ
http://blog.livedoor.jp/cogorou/DSLab/TestVarious.html
の内容をUnityにぶっ込んで
必要なDLLをPluginsに引っ張って来て、
UnityEngine.MonoBehaviour系アダプタを作って動かしてみるアプローチ。

この検証はUnity5系の時にビデオ入力を撮ろうとした時にやった事があって、
果たしてその時に正しいDLLを引っ張って来れていたのかは怪しいが、
多分5系のDLLは持ってくる方法が調べればいっぱい出てくるし、
間違いにくい構造をしていたと思うので、
多分間違っていないんじゃないかなと思う。

それを改めて動かすと
System.Type.GetTypeFromCLSID()
にて以下のエラーが出る。
System.NotImplementedException: The requested feature is not implemented.

当時はこれで諦めたし、これに関して更に追及してみる予定は無いのだが、
取り敢えず現在のバージョンでどのような挙動になるかは確認する事にした。

2019系ではDLLの場所がややこしくなっているが、
結論から言うとこの案は現状使う予定が無く、
掘り下げる予定も無ければ、
多分別の機会に紹介すると思うので、
今回は正しいDLLの場所に関しては省略する。

また、これもその時にも説明すると思うが、
.Net Standard 2.0
はDLLの構成の都合、
依存関係で再生時だかビルド時だかにエラーを吐くのと、
そもそも.Netのバージョンも上げないと多分あんまり意味がないので、
PlayerSettingsからApi Compatibility Levelを
.Net 4.x
に変更する。

諸々整えた後、改めて動かすと先程の
System.Type.GetTypeFromCLSID()
は通過するようだが、直後の
System.Activator.CreateInstance ()
にて
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.MethodAccessException: Method `System.__ComObject..ctor()' is inaccessible from method `System.__ComObject..ctor()'
at (wrapper managed-to-native)
...
と言うエラーが出力される。
見る感じCOMオブジェクトを作れないようだが、
これも追及するのは気が引けるので、
このアプローチは断念することにした。


この辺りからは主にDirectShowラッパー系の検証です。

3.DirectShowNet

基本的にはここ
https://blog.ishitoya.info/entry/20080524/1211598985
に書いてある通りに進める。

CodeProjectのリンクは消失していて、
ざっくりは探したが見つからず、
そもそもこの技術がポンと使えそうかどうかが分からないと、
その辺りを追求する意味も無いので、
取り敢えずはリンク先で更に参考にしたと書かれているページの
サンプル内に入っているDirectShowNetを摘まみ食いする事にする。

他にも微調整等したかも知れないが忘れたので省略。
基本的には2に同じく必要なDLLをPluginsに引っ張って来て実行。
すると
DsDev.GetDevicesOfCat()
が成功せず
outパラメータへの出力も確認出来ない為以後の処理を実行出来ない。

これも追及するのは気が引けるので、
このアプローチは断念することにした。

なんかNuGetでDirectShowLibをインストールしてるがこれテストしてなくない?
↑結構日を跨ぎながら色んな事検証してたので
こう言うのがある気がするのもあって文書に起こしてみようと思ってたんですよね。
記事書いていくうちでこれを使ってるテストプロジェクトがあれば
ここの記述は消しますが、
DirectShowNetのラッピングの形とDirectShowLibのラッピングの形で
外からコールに互換性を見出せなくて辞めたんだった気がしますが、
それにしても他のサンプルと互換性が無いか確認したり、
ここ
https://qiita.com/tera1707/items/df751cae4cec4e6da0db
のサンプルの検証したりしてないとおかしい気はします。
一旦保留。


NAudioに関しては掘ったり検証していくに連れて、
途中でバージョンが上がったり複数のデバイス列挙機構を内包していたりしたので、
一個一個大項目を区切って行く。

NAudioはNuGetが必要そうなので、
UnityでNuGetを使えるようにする奴を入れる。
NuGetはApi Compatibility Levelを参照した上で
適切なライブラリをダウンロードするので、
NuGetでダウンロードする前に設定する。
もし先にダウンロードしてしまったら、
アンインストールしてApi Compatibility Levelを変えて再びインストールする。

4.NAudio(1.10/NAudio.Wave名前空間)

Unityに入れてみた先駆者が居たので、こちら
https://qiita.com/nise_aoi/items/7923ab29a678aa5a9b14
に沿って進める。

ちなみにApi Compatibility Levelどちらでも変わらなかった気がするけれど、
この記事を書いている段階の設定は.Net4.xが設定されている。

記事元を追っていくとUnityがハングする理由に依存DLLが上がっているが、
そちらに関する検証はもっと先の内容に当たるので、
一旦ハングしてもデバイス列挙の挙動を見る事を優先、
NAudioの検証にはDLLは一旦必要ないものとする。

他にも微調整等したかも知れないが忘れたので省略。
実行すると特にエラー出ず。
ただし
NAudio.WaveIn.GetCapabilities(x).ProductName
をログ出力してもGV-USB2の列挙は見当たらなかった。
つまり、
処理自体は正常動作するが期待する結果は得られなかった。

5.NAudio(1.10/NAudio.CoreAudioApi名前空間)

4の結果を元に調べていたところ、以下
https://teratail.com/questions/53571
のようなQ&Aを見つけた。

Q&Aには別の関数を使ったと書かれていたので調べていくと、
別の別のデバイス列挙処理が出てきたのでこちらも検証。

https://ja.ojit.com/so/c%23/3223207
をMonoBehaviour化し実行。

すると
new NAudio.CoreAudioApi.MMDeviceEnumerator().EnumerateAudioEndPoints ()
にて以下のエラーが発生した。

Object reference not set to an instance of an object

厳密には
new NAudio.CoreAudioApi.MMDeviceEnumerator()
までは正しく動いているかどうかは分からないがコール上は成功している。

コピペだとアンリーチではあるものの、
ソースコード上は存在している
new NAudio.CoreAudioApi.MMDeviceEnumerator().GetDefaultAudioEndpoint()
をリーチさせても同じようなエラーが出る。

これも追及するのは気が引けるので、
このアプローチは断念することにした。

6.3のNAudio(1.10)化

3のDirectShowNetDLLをNAudioDLLに置換して
正常動作しなかった
DsDev.GetDevicesOfCat()
をNAudioの互換処理に置換するアプローチ。

ヒエラルキ等を漁ったものの
NAudioではDirectShowNetの書式に互換のある書式は無さそうだった。

後にも似たような事をやっていくが、
見る限りDirectShowNet側がカスタマイズ書式の印象。

NAudioはマイクロソフトが出してるとかだった気がするし、
他言語のマイクロソフトテクノロジを忠実にラップしているだけだとすると
辻褄も合うような気はする。


NAudioに関しては、
他のライブラリの検証をやってるうちにバージョンアップしていました。

既にバージョンアップは過去の事象で、
どちらとも既存のテクノロジには変わりなく、
記事上でライブラリを往復したくないので、
先に同じNAudioの2.00の検証内容を書きます。

7.NAudio(2.00/NAudio.Wave名前空間)

WaveIn系の処理に互換があるものが見つからなかった。
元々1.10でデバイスが列挙されていて、
列挙して欲しいデバイスは列挙されていなかった事は確認していたので、
こちらは省略する事にした。

なんか手掛かりらしきものを見つけたので一応コピペ。
https://teratail.com/questions/186223
実際にインテリセンスで見たりしたわけではないので
自分の問題に一致するヒントかは分からない。
2.00は暫くベータリリースだったようなので、
このアンサーが2.00に関する情報の可能性はあり。

8.NAudio(2.00/NAudio.CoreAudioApi名前空間)

Object reference not set to an instance of an object
at NAudio.CoreAudioApi.MMDeviceEnumerator.EnumerateAudioEndPoints ()

変わらず動かないようだ。
残念。

一応DLLの構成が変わっていて、
参照DLL名自体は変わっているようには見える。

5に同じくこのアプローチは断念。


5に関してQ&Aを投げていた人を発見した。
https://stackoverflow.com/questions/48217715/c-sharp-unity-3d-naudio-throws-nullreferenceexception-while-checking-for-default
この人はCSCoreと言う上位互換を発見したと言っているので、
NuGetからCSCoreを入れてお手並みを拝見することにした。

ただしNuGetからダウンロードしようとしても
.nupkgはダウンロードされているがDLLが生成されない。

どこかで見たが、.nupkgはzipらしいので、
複製を.zipにリネームし展開してみる。
ディレクトリ名がマッチの範囲外なのか、
net35-client
と言うディレクトリがあるので、
これを他のNuGetでダウンロードしたものと同じ形になるように
プロジェクトに配置する。

9.5のCSCore化

7に同じくWaveIn系の処理に互換があるものが見つからなかった。
元々1.10でデバイスが列挙されていて、
列挙して欲しいデバイスは列挙されていなかった事は確認していたので、
こちらは省略する事にした。

10.6のCSCore化

https://github.com/filoe/cscore/blob/master/Samples/AudioPlayerSample/MusicPlayer.cs
この辺をヒントに置換していく。
型に関する定義やパラメータフォーマット等は違うようだが、
基本的な処理フローは大体同じようだ。

パラメータを
DataFlow.All, DeviceState.All
とすると40近いデバイスが列挙されるが、
GV-USB2と思われる名前は確認出来なかった。

ちなみにステートをAllにしているが、
これはどうやら認識された事はあるが
現在接続されていないものまで検出しているようだ。

これも
処理自体は正常動作するが期待する結果は得られなかった。

11.CSCore.XAudio2名前空間

https://github.com/filoe/cscore/blob/master/CSCore.Test/XAudio2/XAudio2Tests.cs
詳しくは知らないが、
CSCore.XAudio2.XAudio2.CreateXAudio2()
の実態が
CSCore.XAudio2.XAudio2_7
の場合は
CSCore.XAudio2.GetDeviceDetails()
でデバイスを列挙出来るらしい。

自分の環境は
System.Object.GetType()
を取ると
CSCore.XAudio2.XAudio2_8
だった。
勿論強引に
CSCore.XAudio2.XAudio2_7
キャストしようとしても正しく動かない。

12.AssetStoreのCSCore

ダウンロードはしてみたものの、
どうやらDirectShow関連のものとは全く別の
C#の標準的な機能のラッパーのようだ。

13.11のSharpDX化

多分NuGetでXAudio2とかで検索して出てきたんだと思う。
多分名前空間を差し替えるだけでXAudio2_7のコードが動いたが、
内部でXAudio2_7とXAudio2_8のアダプタをしているわけではなく、
InvalidOperationException: This method is only valid on the XAudio 2.7 requestedVersion [Current is: Version28]
SharpDX.XAudio2.XAudio2.CheckVersion27 ()
と出る。


ここでMediaFoundationと言う名前空間を見つける。(確か。
今までの書式に互換性が無くて諦めたんだった気がするが
このページを見ながらやった記憶があまり無いので一応置いておく。
https://github.com/sharpdx/SharpDX-Samples/blob/master/Desktop/MediaFoundation/MediaEngineAppVideo/Program.cs

14.MFLib

https://qiita.com/kenjiuno/items/fa8ff3483dfc2b48c466
MF.EnumVideoDeviceSources()
でUnityがハングする。


一旦途中経過まで。
まとめてると検証漏れだったりまだ簡単に検証出来そうな事が幾つかあったのと、
思ったより自分がやっている検証とそれを元に書いている文章のまとまりが無さ過ぎるので、
この記事を元にそのうちもう一回検証して同じ内容の記事を作ると思います。

まあ何を参考にして何をやったかが全然分からなくなっているわけですが、
社会人なんですからログとドキュメント化くらいはやっておきましょう。

最低でも一発目の検証でうまく行かなかった事はちゃんとログ付けた方が良いですね、
あまり技術検証とか得意じゃ無いんで今回は良い経験になりました。

多分やり残してる検証をやってから、実際に使うライブラリの検証をやっていくと思います。

余談ですが、AudioClipに変換したりOnAudioFilterReadを使ったりするより
そのままどこかにあるだろうサンプル通りデバイスに直接音を流してしまおうかと思っていたりします。
AudioClipはバッファをAddしていくような構造があるか怪しいと言うか
ぱっと検索した限りサンプルが見当たらなかったのと、
OnAudioFilterReadはAudioListenerに流れてきた波形を上書きするものなので、
ジャックして上書きするか混ぜる計算をやる必要がありそうですが、
前者はUnityのサウンド機能が動かなくなるのと、
後者は専門的な知識が必要そうだからです。

では、またそのうち。