Introduction
仕事の絡みで音響認識をすることになったのですが、画像処理なら OpenCV 使うなりして、それなりに対応できますが、音声となるとまったく…です。
それで、自分の引き出しを増やすために、音声処理系のライブラリを試してみました。
今回は Microsoft Public License で開発が進められている NAudio を試しました。
NAudioはマイクからの入力やスピーカーへの出力をキャプチャしてファイルに出力したりできます。
そうです。録音ソフトを作成できます。
今回は、ヘッドフォンやスピーカーへの出力をファイルに書き出すサンプルを作りました。
ソースは下記になります
Explanation
いつも通り、MVVMを利用します。
MainWindow に対応する MainViewModel、音声の出力デバイスを取得する AudioService、デバイスからの音声データをファイルに書き込む AudioOutputWriter から成り立ちます。
AudioService
1 | using System; |
GetActiveRender は、PCに接続されているアクティブな出力デバイス一覧を取得します。
NAudioの用語で、Render は出力、Capture は入力を表します。
MMDeviceEnumerator は、Multimedia Device であり、IMMDeviceEnumerator のラッパーでしょう。
AudioOutputWriter
今回の肝です。
1 | using System; |
コンストラクタが全ての重要なことを行っています。
WasapiLoopbackCapture は、WASAPI、つまり Windows Audio Session API のオーディオ処理をループバックさせキャプチャするためのクラスです。つまり、MMDeviceで指定したデバイスをキャプチャします。
WASAPI については、Wikipediaを見てください。といっても、日本語の記事は情報がないですが。
次は、DataAvailable イベントをサブスクライブします。
これは、キャプチャした生のバイトデータを処理できます。
このイベントでファイルへの出力を実行しています。
このファイルへの出力は、WaveFileWriter クラスが担っています。
今回は、同一ファイルが存在したら上書きする形でストリームを生成し、第一引数に渡しています。
第二引数は、出力する WAVE ファイルのフォーマットを指定します。
これは、ループバックからキャプチャされる形式と同一にしています。
あとは、任意のタイミングで、WasapiLoopbackCapture.StartRecording メソッドで録音を開始し、WasapiLoopbackCapture.StopRecording メソッドで録音を停止するだけです。
テスト
実行するアプリは、左側に出力デバイス一覧、右側には出力先ファイルを指定するテキストボックス、録音の開始ボタン、録音の停止ボタン、キャプチャデータのキャプチャタイミングのログを表示するリストから成り立っています。
ファイルを指定して、Startボタンを押下するとPCで再生される音声をファイルに書き出し始めます。
Stopを押下して録音を停止し、出力されたファイルをメディアプレイヤーで再生すると、録音された音声が再生されるのがわかるはずです。
また、録音中、音声データが細切れになってファイルに書き込まれていくことがログからわかります。
Conclusion
長くなりましたが、それなりに簡単にできました。
NAudio の音声処理の向き等、理解することは多いですが、基本さえつかめれば、入力データの加工等もできるのでしょう。
Source Code
https://github.com/takuya-takeuchi/Demo/tree/master/AudioSignalProcessing/NAudio/NAudio1