C#は電気羊の夢を見るか?(引っ越し中)

dtiブログが閉鎖とのことでhttp://tanocs.blog.fc2.com/へ引っ越します。

SlimDXでXAudio2をつかってサイン波を再生する

XAudio2のいろんなサンプルを継ぎ接ぎしてSlimDXに対応させた。


一番困ったのは、転送してるのはByteのくせに、
その中身はShortにしておく必要があるとか、
よく分からない事になってたのに気がつかなくて苦労した。

[2011/11/27追記]
format.BitsPerSample = 16; なんだから当然でした。
24とか32Fによって対応方法を変えてくりゃれ。

32Fはfloatに一旦突っ込んで中身が1.0〜-1.0って表記になる
そいつを、int32に放り込むなら32bitの最大値で掛けて、整数型に直してやればいい。

この方法だと、厳密にはプラス側と、マイナス側で最大1の誤差が出るが、
どう頑張っても聞き分けられないので、無視していいと思う。
[追記終わり]


byte[] byteArray = new byte[waveData.Length * 2]; //バッファ
Buffer.BlockCopy(waveData , 0, byteArray, 0, byteArray.Length);

↑このへん。

それ以外はWaveを扱ったことがある人なら、それほど苦労することはないと思う。
若干クセがあるものの、全体的に簡単な使い心地。
というか、他の音関係のライブラリが難しすぎるんだと思う・・・

そんなわけで、以下サンプル。


XAudio2 device = new XAudio2();
MasteringVoice masteringVoice = new MasteringVoice(device);

WaveFormat format = new WaveFormat();
format.Channels = 1;
format.SamplesPerSecond = 44100;
format.BitsPerSample = 16;
format.BlockAlignment = (short)(format.BitsPerSample / 8 * format.Channels);
format.AverageBytesPerSecond = format.SamplesPerSecond * format.BlockAlignment;
format.FormatTag = WaveFormatTag.Pcm;

// Create the sample data into memory
short[] waveData = new short[format.AverageBytesPerSecond];

//「ラ」を表すsin波(440Hz、1秒)
for (int i = 0; i < waveData.Length; i++)
{
waveData[i] = (short)(32767.0 * Math.Sin(2.0 * Math.PI * 440.0 * i / (double)format.SamplesPerSecond));
}

byte[] byteArray = new byte[waveData.Length * 2]; //バッファ
Buffer.BlockCopy(waveData , 0, byteArray, 0, byteArray.Length);

MemoryStream ms = new MemoryStream(byteArray);
AudioBuffer buffer = new AudioBuffer();
buffer.AudioData = ms;
buffer.AudioBytes = (int)ms.Length;
buffer.LoopCount = XAudio2.LoopInfinite; // 永久にループ
buffer.LoopBegin = 0; // ループ開始位置
buffer.LoopLength = 0; // 再生する長さ。0だと全部。
buffer.Flags = BufferFlags.EndOfStream;

SourceVoice sourceVoice = new SourceVoice(device, format);
sourceVoice.SubmitSourceBuffer(buffer);
sourceVoice.Start(); //再生

MessageBox.Show("終了");

// cleanup the voice
buffer.Dispose();
sourceVoice.Dispose();
ms.Close();
ms.Dispose();

masteringVoice.Dispose();
device.Dispose();
このエントリーをはてなブックマークに追加
LINEで送る

DirectShowLib-2005をWin7で使えるようにする

DirectShowLib-2005をWindows7の64bitで使おうとしたところ
『接続に必要な中間フィルターの組み合わせが見つかりませんでした。』
とかってエラーがでて動作しない。


Windows7ではDirectShowフィルターは
強制的にMicrosoft製の物が優先になるとか何とか(うろ覚え)

まぁ、そのあたりの絡みなのかなぁと思いつつ、
どうせ使わないのでDirectShowフィルターを無効にしてやることで、
とりあえずこの問題をクリアした。


修正はたった1行で
ソース『Capture.cs』内の SetupGraph メソッド中にある、
以下の一行をコメントアウトすればよい。

m_pinStill = DsFindPin.ByCategory(capFilter, PinCategory.Still, 0);
このエントリーをはてなブックマークに追加
LINEで送る

シェーダー高速化の肝

今まではXNAのサンプルそのままに
ガウシアンブラーで右方向と下方向をサンプリングしていたのだが、
これを右下、左上に変更するだけで、なぜか高速化されたので覚書き。

TexCoordのサンプラオフセット値の指定を
texcoord + float2(x,0);
texcoord + float2(0,y);
から
texcoord + float2(x,y);
texcoord - float2(x,y);
と変えるだけで780->920fpsという、となかなか大き変化があった。

時間に直せば0.0002秒の差だが、
低速なマシンではボチボチ効果がある差なのではないかと思う。

一体何がどうしてこの速度の差に現れたのか、すごく気になる。
そこで、あれこれ試してみたところ、
少しコードの書き方を変えるだけで30fpsくらいは、ぴょこぴょこと簡単に変化が出る。

シェーダにおいてはコンパイラさんが気に入るコードを書くことが、
高速化の肝なのだなぁと身を持って感じた。
このエントリーをはてなブックマークに追加
LINEで送る

 | HOME | 

PAGE TOP ▲

Appendix

■春条

■春条

生息地は愛知
車と甘い物が好きな31歳
特技は無限昼寝

MONOからSharpDXを使う
変態的な手法で、
.NET Frameworkを使わずに
ゲーム作りやってます。

Search

Calender

« | 2011-11 | »
S M T W T F S
- - 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 - - -

Twitter

Recent Entries

DTIブログポータルへ
このブログを通報
Report Abuse

利用規約