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 件のコメント:
コメントを投稿