NAudio ライブラリでオーディオを再生する(1)


soundPlayer で wav ファイルを再生したり、MemoryStream で信号発生器を作ってみたりしましたが、やはりちょっと力不足を感じますね。そこで、NAudio 1.6 (Fri Oct 26, 2012 at 5:00 PM) というオーディオライブラリを試してみましょう。

 

NAudioをダウンロードする

NAudio-Release.zip を CodePlex からダウンロードして展開すると、こんなファイル構成です。

license.txt
Microsoft Public License (Ms-PL) である。高橋忍さんの説明を読めば十分でしょう http://blogs.msdn.com/b/shintak/archive/2012/09/09/10347542.aspx
NAudio.dll
ライブラリのアセンブリDLL
NAudio.WindowsMediaFormat.dll
ライブラリのメディア形式を扱うアセンブリDLL
NAudio.xml
Visual Studio(MSVS) でアセンブリを使うときに必要な定義をまとめたファイル
readme.txt
Mark Heathさんのよんでね.txt。主に謝辞。

ソースやデモもありますので、今度は NAudio-1.6-DemoApps.zip をダウンロードしてみましょう。

展開したら、NAudioDemo.exe を実行します。画面がこれ。

naudiodemo1

左側のパネルから実行したいデモをダブルクリックすると、右側にパネルが表示され、オーディオファイルの再生や録音、MIDI や MP3 のストリーミングも試せます。この画面は Audio File Playback のものですが、レベルメーターに、dB(デシベル)表示のボリューム、再生時間表示、波形表示と欲しかったものがすべてそろっています。

Output Driver は2段階の選択になっていて、まず Windows で扱える 4 つのオーディオAPIが選択できます。

WaveOut
Windows Multimedia API(古い)
DirectSound
DirectXの音部分(ちょっと古いけど、互換性はいいやつ)
WasapiOut
Windows Audio Session API(Vista/7/8 の最新サウンドAPI)
AsioOUT
Steinberg社のサウンドドライバで、Windowsの音管理をパスして遅延を小さくできる

こんな感じです。その後、そのAPIに対応したデバイスを選びます。

Kernel Streaming って手法もあるらしいけど、詳しくないので参考資料のほうをどうぞ。

音を出してみよう

簡単なプログラムで音を出してみましょう。Vista 以降は、WASAPI がお勧めということですが、まずは waveOut からいくのが筋ですよね。いつも通り Windows フォームアプリケーションのプロジェクトを Visual Studio 2010 C# で作ります。そして、さっき展開した、NAudio.dll を「プロジェクト」「参照の追加」で参照に加えておきましょう。まず、using を次のように追加して入力の手間を減らします。

using NAudio;
using NAudio.Wave;

次に、出力可能なデバイスを列挙する関数 EnumulateDevices() を書きます。WaveOut は呼び出せばいきなりデバイスが得られます。列挙したら、コンボボックス comboBoxAudioIf に入れておきます。

private void EnumulateDevices()
{
	for (int id = 0; id < WaveOut.DeviceCount; id++)
	{
	WaveOutCapabilities capabilities = WaveOut.GetCapabilities(id);
	comboBoxAudioIf.Items.Add(String.Format("{0}:{1}", id, capabilities.ProductName));
	}
comboBoxAudioIf.SelectedIndex = 0;
}

さていよいよ本題です。mp3ファイル等を考えるといろいろと面倒なので、シンプルに wav ファイルだけを扱います。2つの変数を定義します。

private IWavePlayer WaveOutDevice=null;
private WaveStream wavStream=null;

IWavePlayer は再生デバイス、WaveStream はオーディオファイルを読みこむ Stream です。Stream は soundPlay のサンプルでも出てきました。ここで、デバイス側を初期化する関数、CreateDevice() を書きましょう。waveOutDeviceNumber(デバイス番号)と DesiredLatency(ミリ秒単位) を指定して、デバイスを初期化しています。最後の as IWavePlayer あたりが不思議な感じですがいいことにしてください。

private IWavePlayer CreateDevice(int id, int latency)
{
	WaveOut outputDevice = new WaveOut();
	outputDevice.DeviceNumber = id;
	outputDevice.DesiredLatency = latency;
	return outputDevice as IWavePlayer;
}

準備はできました。再生ボタンの関数を書きましょう。

private void buttonPlay_Click(object sender, EventArgs e)
{
	WaveOutDevice = CreateDevice(comboBoxAudioIf.SelectedIndex, 250);
	wavStream = new WaveFileReader(textBoxSoundFile.Text);
	WaveOutDevice.Init(wavStream);
	WaveOutDevice.Play();
}

最初にさっき書いた CreateDevice() を呼び出して、デバイスを初期化します。DesiredLatency はミリ秒単位とのことなので、余裕を持って 250 にしてみました。id は偶然(もちろん偶然ではない)コンボボックスのIndexと一致しているはずなのでそれを使います。次の行で、WaveFileReader という wav ファイルを読み込んで Stream を返すNAudioの関数を呼び出し、そのストリームをデバイスに結び付けています。Play() を呼ぶと選んだデバイスから音が出ます。WaveFileReader Mp3FileReaderに変えたりするといいことが起こります。

naudiodemo3
以前作った soundPlay に比べてすこし分かりにくいところはありましたが、それほどではないですね。違いは、出力デバイスを選択できるところだけです。もう少し工夫すると、音量調節、レベルメーター表示、MP3ファイルの再生、ミキサー機能の追加なども簡単にできます。機会があれば紹介しましょう。なお、ソースのほうはエラー処理などを若干加えてあります。

load_downloadNAudioWavePlayTest ソースダウンロード

参考

  • The NAudio Documentation Wiki
    http://naudio.codeplex.com/documentation
  • Audio Output Modes
    http://wiki.jriver.com/index.php/Audio_Output_Modes
  • WASAPI
    http://ja.wikipedia.org/wiki/WASAPI
  • WASAPI vs ASIO vs DirectSound
    http://www.hydrogenaudio.org/forums/index.php?showtopic=92280
印刷
You can skip to the end and leave a response. Pinging is currently not allowed.
Subscribe to RSS Feed Twitter は Ume108 だよ