サウンドレコーダー/サウンドプレーヤーの代替としての StreamRelay.NET.exe(NAudio)

### NAudio 利用版

Win32/Win64 併用の [NAudio](https://github.com/naudio/NAudio)という.NET Framework でサウンド関係のライブラリを利用してStreamRelay.NET.exeの標準入出力のリダイレクト先として使えるようにしたプラグインを作った

- Plugins\stdioSoundRecordNAudio.dll

開発時期が異なることもあり、ManagedDX(MDX)やSlinDX版とは引数などはかぶっていなかったりする。

NAudio経由で、StreamRelay.NET.exeの標準入出力をリダイレクトして、マイクから録音(Wav/Aiff/Mp3/CUE)、スピーカーへの音声再生、サウンドファイル(Wav/Aiff/Mp3/CUE/Vorbis)の再生ができるようになっていると思う。

### NAudioのプラグインがアクセスしているDLL

- libmp3lame.32.dll
- libmp3lame.64.dll
- NAudio.Asio.dll
- NAudio.Core.dll
- NAudio.dll
- NAudio.Lame.dll
- NAudio.Vorbis.dll
- NAudio.Wasapi.dll
- NAudio.WinForms.dll
- NAudio.WinMM.dll
- NVorbis.dll

### NAudioと.NET Frameworkのバージョン

NAudio.WinForms 2.0.x.x が .NET Framework 4.7.2 以降なので、.NET Framework 4.7.2 以降でないと動作しないかと思います。

### NAudioプラグインと引数

stdioSoundRecordNAudio.dllのプラグインと関係する引数は以下

- -ListNAudioDevices
- -RemoteNAudioSoundIn デバイスID
- -LocalNAudioSoundIn デバイスID
- -RemoteNAudioSoundOut デバイスID
- -LocalNAudioSoundOut デバイスID
- -RemoteNAudioSoundInWave サウンドファイル
- -RemoteNAudioSoundInMP3 サウンドファイル
- -RemoteNAudioSoundInCue サウンドファイル
- -RemoteNAudioSoundInAiff サウンドファイル
- -LocalNAudioSoundInWave サウンドファイル
- -LocalNAudioSoundInMP3 サウンドファイル
- -LocalNAudioSoundInCue サウンドファイル
- -LocalNAudioSoundInAiff サウンドファイル
- -RemoteNAudioSoundOutWave サウンドファイル
- -RemoteNAudioSoundOutMP3 サウンドファイル
- -RemoteNAudioSoundOutCue サウンドファイル
- -RemoteNAudioSoundOutAiff サウンドファイル
- -LocalNAudioSoundOutWave サウンドファイル
- -LocalNAudioSoundOutMP3 サウンドファイル
- -LocalNAudioSoundOutCue サウンドファイル
- -LocalNAudioSoundOutAiff サウンドファイル
- -RemoteNAudioSoundInVorbis サウンドファイル
- -LocalNAudioSoundInVorbis サウンドファイル
- -RemoteNAudioSoundInBit (default:16)
- -LocalNAudioSoundInBit (default:16)
- -RemoteNAudioSoundOutBit (default:16)
- -LocalNAudioSoundOutBit (default:16)
- -RemoteNAudioSoundInRate (default:44100)
- -LocalNAudioSoundInRate (default:44100)
- -RemoteNAudioSoundOutRate (default:44100)
- -LocalNAudioSoundOutRate (default:44100)
- -RemoteNAudioSoundInChannel <<1|2>>
- -LocalNAudioSoundInChannel <<1|2>>
- -RemoteNAudioSoundOutChannel <<1|2>>
- -LocalNAudioSoundOutChannel <<1|2>>
- -RemoteNAudioSoundInRecordSecond 秒数
- -LocalNAudioSoundInRecordSecond 秒数
- -RemoteNAudioSoundOutBitRate (default:128kbps) (only MP3)
- -LocalNAudioSoundOutBitRate (default:128kbps) (only MP3)

あたり。

...多いな...入力と出力、橋渡し側の両方(ローカルとかリモートと故障しているデバイスとの接合点)と、各オプションの掛け算なので、、、

### まずはマイクやスピーカーのデバイス一覧

`StreamRelay.NET.exe -ListNAudioDevices`

で、マイクとスピーカーの一覧(とデバイスID)が表示されると思う。
デバイスIDは0から始まって、1,2,3...という感じ

### サウンドプレーヤーの代替としての StreamRelay.NET.exe (音声再生)

Localと呼称する側から読み取り、Remoteと呼称する側にスピーカーを割り当てるとこんな感じ。

MP3ファイルを `test.mp3` として、デバイスID「0」のスピーカー(大抵は既定のスピーカーだと思う)

`StreamRelay.NET.exe -LocalPort 0 -RemotePort 0 -LocalNAudioSoundInMP3 test.mp3 -RemoteNAudioSoundOut 0`

#### 音声ファイルの音質などの設定

サウンドファイルの場合は、音質(ビット数とか・・・)は、NAudio自体が自動的に判断してくれる。

#### 全デバイスで再生

スピーカーの指定がない場合、接続している全てのスピーカーが対象(デバイスID=65535と仮指定)となっている

`StreamRelay.NET.exe -LocalPort 0 -RemotePort 0 -LocalNAudioSoundInMP3 test.mp3 -RemoteNAudioSoundOut`

とすると接続している全てのスピーカーで音が鳴ると思う

### サウンドレコーダーの代替としての StreamRelay.NET.exe (録音)

Localと呼称する側にマイクと接続して、Remoteと呼称する側で、ファイルに保存するとこんな感じ。

デバイスID「0」のマイク(大抵は既定のマイクとなっていると思う)から、10秒間だけ、録音しつつMP3ファイル `test.mp3` として保存する。

`StreamRelay.NET.exe -LocalPort 0 -RemotePort 0 -LocalNAudioSoundIn 0 -RemoteNAudioSoundOutMP3 test.mp3 -LocalNAudioSoundInRecordSecond 10`

#### 既定のマイクから録音

マイクの指定がない場合は、既定のマイク(デバイスID=0)が対象になる

なので、

`StreamRelay.NET.exe -LocalPort 0 -RemotePort 0 -LocalNAudioSoundIn 0 -RemoteNAudioSoundOutMP3 test.mp3 -LocalNAudioSoundInRecordSecond 10`

と

`StreamRelay.NET.exe -LocalPort 0 -RemotePort 0 -LocalNAudioSoundIn -RemoteNAudioSoundOutMP3 test.mp3 -LocalNAudioSoundInRecordSecond 10`

は同じ。

#### 録音(入力側)の音質設定を、保存時(出力側)の設定へ自動引き継ぎについて

マイクtoファイルの場合、入力側のセッティングを出力側は拾うようにしている。

上記の場合は、Localと呼称する側のセッティング(量子化ビット/サンプリング周波数/チャンネル数)を、Remoteと呼称する側の出力時に共有されているので、出力側のセッティングの明示は不要となっているが、ネットワーク越とか、入力側からセッティングがコピーできない場合は、(既定でない設定については)出力時にセッティングを明示する必要があるよ。

#### 録音時の既定の音質

音質は、既定では、

- 量子化ビット : 16Bit
- サンプリング周波数 44.1kHz
- MP3ビットレート : 128kBPS

という感じ

チャンネル数の既定値は、入力デバイス(マイク)の既定値を使うようにしている

#### 録音(入力)/保存(出力)時の既定の音質

設定を替えたい場合は、以下のオプションを使う

入力側の設定

- -LocalNAudioSoundInBit (default:16)
- -LocalNAudioSoundInRate (default:44100)
- -LocalNAudioSoundInChannel <<1|2>>
- -RemoteNAudioSoundInBit (default:16)
- -RemoteNAudioSoundInRate (default:44100)
- -RemoteNAudioSoundInChannel <<1|2>>

出力側の設定

- -RemoteNAudioSoundOutBit (default:16)
- -RemoteNAudioSoundOutRate (default:44100)
- -RemoteNAudioSoundOutChannel <<1|2>>
- -RemoteNAudioSoundOutBitRate (default:128kbps) (only MP3)
- -LocalNAudioSoundOutBit (default:16)
- -LocalNAudioSoundOutRate (default:44100)
- -LocalNAudioSoundOutChannel <<1|2>>
- -LocalNAudioSoundOutBitRate (default:128kbps) (only MP3)

ここで、一つポイントなのだが、MP3のビットレートについては、出力側の設定ということ。

なので、
8Bit/22000Hz/2Chで、168kBpsでMp3録音したい場合は、

`StreamRelay.NET.exe -LocalPort 0 -RemotePort 0 -LocalNAudioSoundIn 0 -RemoteNAudioSoundOutMP3 test.mp3 -LocalNAudioSoundInRecordSecond 10 -LocalNAudioSoundInBit 8 -LocalNAudioSoundInRate 22000 -LocalNAudioSoundInChannel 2 -RemoteNAudioSoundOutBitRate 168`

こんな感じ。
MP3のビットレートの設定(168の部分)だけ、Remoteと子使用される側の出力側の設定となっている点に**注意**

#### 録音時間について

録音時間についてのオプションは、入力側の設定

--LocalNAudioSoundInRecordSecond
--RemoteNAudioSoundInRecordSecond

この録音時間を指定しないと、終了時はCtrl+Zの強制終了となるわけで、そうなるとStreamオブジェクトのCloseメソッドが呼ばれないということになる。

MP3などは大丈夫かもしれないけど、Wave形式の場合は、CloseメソッドでWave形式のヘッダ更新を実施ているので、録音ファイルは壊れるかもしれない。

### 参考

ManagedDirectX(MDX)、SlimDX 版は[こちら](https://qiita.com/tomoki0sanaki/items/7b5260b09803ceee074b)

[音声を再生したり、さらには録音したりするプログラムを何本か作った](https://qiita.com/tomoki0sanaki/items/98ec5cc02f82512736c4)

---
### 目次へ戻る

[目次というか最初の一歩](http://qiita.com/tomoki0sanaki/items/85f20cbe18378e33cd6f)