XNAが開発終了って以外は、あんまり欠点のない方法、だと思う。
DynamicSoundEffectInstanceのコンストラクタでサンプリングレートとチャンネル(Mono/Stereo)を選択。最初のデータをSubmitBufferで設定してPlayで開始。データが無くなるとBufferNeededイベントが来るので、ハンドラ内でデータを生成してSubmitBufferで追加。たぶんStopとか使えば止められるんじゃないかなー。
Playは最初の1回だけでいいが、予めSubmitBufferでダミーデータでも追加しておかないと、ブツブツ途切れて再生してしまう。ちょっとしたダブルバッファみたいな感じになってるんだと思う。ということでPlayの前にBufferNeededを蹴っている。
あとFrameworkDispatcher.Update()のタイミングが結構シビア。場所を変えると例外が投げられる。とりあえず今は動いているが、いつ動かなくなるかはわからない。
それとFrameworkDispatcher.Updateを呼ぶタイミングは、SubmitBufferで設定した時間よりも短い間隔で呼ぶ必要がある。例えばBufferが50msec分なら、Updateは50msec以下のインターバルで呼ぶ必要がある。とはいえ、Thread.Sleepは往々にして設定時間の数割増しのインターバルとなるが、それでも正常に動いてるから、よほど大きく離れてない限りは問題ない様子。
C#は例外的にSerialPortがある程度で、ファイルアクセス以外はほとんどIOが無い(マウスやキーボードはFormの機能)。音声IOも例外ではなく、使いたいならWin32とかで工夫する必要がある。
XNAは前述の通り開発が終了しているが、ちょっとした音声IOで遊びたいなら有効なツールだと思う。
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using System; using System.Threading; using System.Windows.Forms; namespace WindowsFormsApplication9 { public partial class Form1 : Form { Thread t; bool loop; public Form1() { InitializeComponent(); loop = true; t = new Thread(new ThreadStart(hoge)); t.IsBackground = true; t.Start(); FormClosed += Form1_FormClosed; } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { loop = false; } void hoge() { using (DynamicSoundEffectInstance audio = new DynamicSoundEffectInstance(44100, AudioChannels.Mono)) { audio.BufferNeeded += Audio_BufferNeeded; Audio_BufferNeeded(audio, EventArgs.Empty); FrameworkDispatcher.Update(); audio.Play(); while (loop) { Thread.Sleep(10); FrameworkDispatcher.Update(); } } } private void Audio_BufferNeeded(object sender, EventArgs e) { DynamicSoundEffectInstance audio = sender as DynamicSoundEffectInstance; if (audio == null) { return; } byte[] buff = new byte[audio.GetSampleSizeInBytes(new TimeSpan(0, 0, 0, 0, 50))]; Random rand = new Random(); for (int i = 0; i < buff.Length;) { Int16 data = (Int16)rand.Next(-16384, +16383); byte[] datas = BitConverter.GetBytes(data); Array.Copy(datas, 0, buff, i, datas.Length); i += datas.Length; } audio.SubmitBuffer(buff); } } }
0 件のコメント:
コメントを投稿