SewiGの日記
2006-06-02 [金] [長年日記]
■ [Programming] pthread
以前、Win32でCreateThreadを使うときは注意しようなんてことを書いたので、今度はUnixのスレッドについて書いてみます。幸い、pthread.hにPOSIXなスレッドが用意されているのでこれを使いましょう。
pthread_create()でスレッドを作成します。このとき引数に作成されたスレッドが処理する関数を渡しておきます。あるスレッドの同期を取りたければ、pthread_join()で処理を待ちます。そしてコンパイルするときは、マルチスレッドなコードであることをコンパイラに教えます。
cc -D_REENTRANT -o thread thread.c -lpthread
これは、マルチスレッドだと動かない処理が含まれると困るからです。再入可能か否か。
例えば以下のような感じでマルチスレッドなコードが書けます。
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> int counter = 0; void *increment() { int i; for (i = 0; i < 10000000; i++) { counter++; } } int main(void) { pthread_t tid1, tid2; pthread_create(&tid1, NULL, increment, NULL); pthread_create(&tid2, NULL, increment, NULL); pthread_join(tid1, NULL); pthread_join(tid2, NULL); printf("%d\n", counter); }
しかし、上記のコードは正常に動作しません。2つのスレッド間で同期が取れていないからです。片方のスレッドで変数を参照して、スレッドが切り替わってもう一方のスレッドが変数を参照してから値をインクリメントして演算結果を変数に書き戻す。そしてスレッドが切り替わって先ほどのスレッドが変数を更新したら、一方の更新が無くなりますよね。lost updateです。
そこでセマフォを利用します。変数をあるスレッドが変数にアクセスしているときはロックしてブロックします。具体的には以下のようにします。
struct { pthread_mutex_t mutex; int value; } counter = {PTHREAD_MUTEX_INITIALIZER, 0}; pthread_key_t private_key; void *increment() { int i; int *privp; pthread_setspecific(private_key, malloc(sizeof(int))); privp = pthread_getspecific(private_key); *privp = 0; for (i = 0; i < 10000000; i++) { pthread_mutex_lock(&counter.mutex); counter.value++; pthread_mutex_unlock(&counter.mutex); privp = pthread_getspecific(private_key); (*privp)++; } printf("%d\n", *privp); } int main(void) { pthread_t tid1, tid2; pthread_key_create(&private_key, NULL); pthread_create(&tid1, NULL, increment, NULL); pthread_create(&tid2, NULL, increment, NULL); pthread_join(tid1, NULL); pthread_join(tid2, NULL); printf("%d\n", counter.value); }
private_keyはセマフォとは直接関係ありませんが一応。
2006-06-04 [日] [長年日記]
■ [Music] ヤマハのプレイヤーズ王国もオリジナル曲を有料配信
- 自作曲を有料配信できるヤマハ「ミュージックマーケット」 (ITmedia)
ブログなんかのおかげで、個人のコンテンツが大きな価値を持つことが分かってきたわけですが、音楽もオンラインで1曲単位での販売が主流になったので、個人のインディーズ音楽を販売したくなります。
今までもmuzieなんかが着メロの販売をやってたりしましたが、ここでヤマハも参戦。面白くなってきました。
Vectorがブログの有料購読を開始したりと、今個人のコンテンツ配信が熱い!
2006-06-05 [月] [長年日記]
● Ethan [In awe of that anwser! Really cool!]
2006-06-07 [水] [長年日記]
■ [Book] 変身 - 東野圭吾 著
不慮の事故で重体だった青年、成瀬純一に世界初の脳移植手術が行われた。温厚な性格だった純一が、徐々に壊れていくという話。
「変身」を読む上でのポイントは、純一の恋人である葉村恵の存在、脳手術を執刀した堂元博士の観察日記、そして人格が侵食されるのを自覚する純一の苦悩。恵は、画家を目指していて自分に一途だった温厚な性格の頃の純一に戻ることを願い、他人のように変わった純一であっても傍に居ようとした。堂元は世界初の試みを行い純一がどのように変化するかに興味があった。そして、純一は自分に純一の人格が存在するうちに真相を素人ドナーを探そうとした。
内臓移植で、ドナーの性格が表層化するといった話は現実の世界で起こっているけど、もし将来脳移植が現実のものとなったら人体はドナーの脳に乗っ取られてしまうのだろうか。自己を構成するものは何だろうか。脳移植されてもこの体は自分のものだと言えるのだろうか。
いつ我々の身に降りかかるか分からない脳移植の恐怖に怯える前に、元気なうちに自分の証を残していこう。
2006-06-08 [木] [長年日記]
■ [Book] 萌えるSE 業界ノベルズ お兄ちゃんはプログラマ
プログラミングやってない人には面白くない話かもしれない。
いい加減な仕様書、仕様変更、など様々な困難に立ち向かうプログラマの話。新人君の大町はプログラマのアニオタぶりに圧倒される。さすがに萌え関係は脚色しすぎな気もするが、概ねこんな感じにのプログラマばっかだと思う。そして、納期に追われる開発現場に美少女あずみが現れる。しかもテスターやってるし。あー雑用やってくれるかわいい女の子ほしいなぁ。
とりあえず、萌えを期待して買うと後悔する。かわいい女の子が開発に居ればいいなーと思ってる人が、ああ、こんなやつ俺の回りにいるぜとか、ああ、やっぱマならそうするよな、と納得しながら読む本。あんまりオススメするほど面白い本でもないけど。
2006-06-09 [金] [長年日記]
■ [Book] 絶対音感 - 最相葉月 著
絶対音感を持つ人、持たない音楽家、様々な人の体験談が載っているノンフィクション小説。概要から科学的な話まであり、1,2章は世界の音楽教育と比較した過去から現代までの日本における音楽教育の違い、特徴が載っている資料価値の高い作品に仕上がっている。
単純に絶対音感を身につけたいと考えている人が読む本ではない。必ずしも絶対音感が良いとは言えないことが本書から伝わってくる。アカデミックな分野と義務教育の違い。具体的には、固定ドと移動ドの問題。それにともなう絶対音感の弊害。
絶対音感に興味がある人は、1〜4章まではぜひ読んで欲しい内容。
2006-06-12 [月] [長年日記]
■ [Programming] Direct X + C#
最近、C#がJavaぽいくて移行は楽チンで、Direct Xも使えるとなるとゲームなど用途によってはC#がいいかも、と思います。
Formのインスタンスを作るだけでウィンドウが作られ、わずか数行でDirect Xの初期化できたりして、C++ Win32の苦労はありません。
これは生産性が上がる。
2006-06-13 [火] [長年日記]
■ [Network] Google Earth 4
- Google Earthのメジャーアップデート公開 (ITmedia)
2005/06/29の日記で紹介して1年。バージョン4では、かなり情報量が増えてて家一軒確認できます。しかも漢字で検索できます。
しかし、漢字で検索すると山の中にポインタが出てきて、その近辺は詳細な地形が表示されるのに、肝心の市街地が荒い地図になったりする地域も多々ありました。
しかし、これは便利になりました。いろいろ遊べそう。
2006-06-16 [金] [長年日記]
■ [Programming][C#] C#で2D Programming on Direct3D (1)
Managed DirectXを使えばC#でもDirectXが扱えます。.NET Frameworkのおいしい仕様とDirectXの豊富な機能が使えるのは便利。
環境構築
- VisualStudio 2005や.NET Frameworkといった開発環境をインストール
- DirectX SDKの最新版をインストール
- PATHを通す
DirectX SDKをインストールするときにVisualStudioの設定も行われるので順番は間違えないようにしましょう。PATHは例えば、「C:\Program Files\Microsoft Visual Studio 8\VC\bin」を追加しておくと、コマンドプロンプトでvcvars32を実行するだけで、いろいろと設定できます。
C#でDirectXの初期化
まず、上記のソースコードをコンパイルして実行してみましょう。C#でManaged DirectXのコンパイルをする方法は次の通りです。
- コマンドラインでコンパイルする場合
> csc /t:winexe /lib:"C:\WINDOWS\Microsoft.NET\DirectX for Managed Code\1.0.2902.0" /r:Microsoft.DirectX.Direct3D.dll,Microsoft.DirectX.dll MainApplication.cs Window.cs
"C:\WINDOWS\Microsoft.NET\DirectX for Managed Code\1.0.2902.0"の部分は各自の環境に書き換えてください。「/t:winexe」でコンパイルしたら、GUIプログラミングでコマンドプロンプトが出ません。
- VisualStudio 2005の場合
プロジェクトの「参照の追加」で、「.NET」タブから「Microsoft.DirectX.Direct3D.dll」と「Microsoft.DirectX.dll」を選択します。それからプロジェクトをビルドします。
実行ファイルを起動して、白いウィンドウが表示されれば成功です。
解説
まずは、名前空間に以下を追加。
using Microsoft.DirectX; using Microsoft.DirectX.Direct3D;
それから、Deviceオブジェクトの生成に必要なパラメータはPresentParametersです。PresentParameters.Windowedをfalseにするとフルスクリーンモードになります。PresentParameters.SwapEffectはいろいろな表示アルゴリズムから最適なものが選択されます。PresentParameters.BackBuffer〜でバックバッファのパラメータが設定できます。
パラメータが用意できたら、Deviceオブジェクトの生成。グラフィックカードの種類によってモードが変わります。ハードウェアを利用する方法から順に生成を試みます。
あとは、OnPaint()で描画を行います。次回、画像を描画する方法について考えます。
Deviceオブジェクトは使い終わったらDisposeで破棄します。
2006-06-17 [土] [長年日記]
■ [Programming][C#] C#で2D Programming on Direct3D (2)
次は、画像を表示する方法。DirectDrawを使用すれば、2D描画は可能ですが、Direct3Dの使用が推奨されているので、Direct3Dを使用しましょう。
考え方としては、ポリゴンにテクスチャを貼り付けたものディスプレイの四角形にあわせて表示することで二次元を表現します。
→ ソースコード (csmdx_3dpc.zip, 2006/06/20 微修正)
前回とのソースコードとは、TextureImageクラスが増えている点、Windowクラスが以下のようになっている点が異なります。
フルスクリーンにしてカーソルを消してみました。
pp.Windowed = false; System.Windows.Forms.Cursor.Hide();
画像の描画関連。
Bitmap bitmap = new Bitmap("hello.bmp"); image = new TextureImage(device, width, height, bitmap); image.drawTexture();
TextureImageは、画像を読み込んで描画するクラスです。コンストラクタの以下の部分ではポリゴンの頂点情報を管理する頂点バッファを作成しています。頂点が6個あるのは、三角形を2枚あわせて四角形を表現しているからです。
vertex = new VertexBuffer(typeof(CustomVertex.TransformedTextured), 6, device, Usage.None, CustomVertex.TransformedTextured.Format, Pool.Managed); Array array = vertex.Lock(0, LockFlags.None); array.SetValue(new CustomVertex.TransformedTextured(0, 0, 0, 1, 0, 0), 0); array.SetValue(new CustomVertex.TransformedTextured(width, 0, 0, 1, 1, 0), 1); array.SetValue(new CustomVertex.TransformedTextured(0, height, 0, 1, 0, 1), 2); array.SetValue(new CustomVertex.TransformedTextured(width, 0, 0, 1, 1, 0), 3); array.SetValue(new CustomVertex.TransformedTextured(width, height, 0, 1, 1, 1), 4); array.SetValue(new CustomVertex.TransformedTextured(0, height, 0, 1, 0, 1), 5); vertex.Unlock();
インスタンスを作成したら、あとはDrawTexture()で描画するだけ。
device.SetTexture(0, texture); device.SetStreamSource(0, vertex, 0); device.VertexFormat = CustomVertex.TransformedTextured.Format; device.DrawPrimitives(PrimitiveType.TriangleList, 0, 2);
サンプルプログラムは、hello.bmpを読み込んで表示する単純なものです。萌え画像でも何でもいいのでお気に入りの画像を用意して表示されれば成功です。
2006-06-18 [日] [長年日記]
■ [Programming][C#] C#で2D Programming on Direct3D (3)
今度はスプライトを使用した例。Microsoft.DirectX.Direct3D.Spriteです。スプライトを使用すれば、頂点情報を利用することなく、テクスチャと座標から2次元サーフェイスに画像を描画できます。
→ ソースコード (csmdx_sprt.zip, 2006/06/20 微修正)
スプライトオブジェクトを生成。
Sprite sprite = new Sprite(device);
これだけ。
あとは、device.BeginScene()のあとでスプライトを描画。
sprite.Begin(SpriteFlags.AlphaBlend); sprite.Draw2D(texture, center, 0, new Point(x, y), Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF)); sprite.End();
スプライトも、3Dに似たようなBeginとEndがあって、この間で描画していきます。Draw2Dの第1引数はテクスチャ、第4引数は描画する座標、第5引数はスプライトの透過色。第2、3引数は回転に関するものです。無駄に多機能w 第2引数は回転軸の座標、第3引数は回転角度(ラジアン)を指定します。回転しない場合は0ですね。
2D描画はこんな感じですかね。間違ってもテクスチャを秒間何フレームも書き換えないでください。テクスチャの張替えはコストが掛かります。実際fpsも出ません。
2006-06-20 [火] [長年日記]
■ [Software] Opera 9リリース & Windows Live Messengerリリース
Opera 9正式版にもBitTorrent搭載で、MacOS Xみたいなウィジェットもあります。そしてRSSアイコンがFirefoxと一緒のオレンジのやつに。しばらく使ってみないと細かなバグが直ったかどうかわからないなぁ。
そして、Windows Live Messenger。見た目はかっこよくなったんだけど、細かな変更がちょっと気になりました。それより、通話機能の追加や共有フォルダは便利。マイコンピュータに表示されるとデータの受け渡しが楽になりますね。前の1対1の送受信は大変でしたからね。
● Nazri [What a pleasure to find someone who iditeefins the issues ..]
2006-06-21 [水] [長年日記]
■ [C#][Programming] C#でサウンド(1)
C# + .NETでサウンドを扱う方法はいくつかあります。順番に紹介します。
- .NET 2.0のSystem.Media.SoundPlayerを使う
- MCIを使う
- DirectShowを使う
- Win32APIのwaveOutやPlaySoundを使う
- DirectSoundを使う
.NET 2.0のSystem.Media.SoundPlayerを使う
標準で使える安心感がありますし、使い方も簡単です。
using System.Media; SoundPlayer player = new SoundPlayer("hoge.wav");
これだけ。あとはPlayで再生。
player.Play();
もし読み込みを待たずに非同期にしたかったら
player.LoadAsync();
ループ再生もできます。
player.PlayLooping();
欠点としてはWaveファイルしか扱えず、細かい制御ができないことです。
2006-06-22 [木] [長年日記]
■ [C#][Programming] C#でサウンド(2)
MCIを使う
Win32のwinmm.dllを呼び出すので、System.Runtime.InteropServicesを利用します。
using System.Runtime.InteropServices;
で、フィールド部分は以下のように記述します。
[DllImport("winmm.dll")] extern static int mciSendString(string command, StringBuilder ret, int length, int cb); private StringBuilder builder = new StringBuilder(32);
特に重要なのは、commandはMCIコマンド、再生や停止のコマンドを入れます。retは戻り値の文字列。lengthは文字列の長さ。
ファイルを開いて
mciSendString("open \"" + filename + "\" alias currentItem", null, 0, 0);
再生して
mciSendString("play currentItem", null, 0, 0);
停止して
mciSendString("stop currentItem", null, 0, 0);
閉じる
mciSendString("close currentItem", null, 0, 0);
MCIを使えば、Waveだけでなく音楽CDやMIDI、MP3なども再生できて便利です。MCIコマンドはほかにもいろいろあるのでぜひ調べてみてください。
2006-06-23 [金] [長年日記]
■ [C#][Programming] C#でサウンド(3)
DirectShowを使う
今回はCOMを使用します。なので、DLLを作ります。
> vcvars32 > tlbimp C:\WINDOWS\System32\quartz.dll
↑「C:\WINDOWS」の部分は各自の環境に読み替えてください。カレントディレクトリにQuartzTypeLib.dllができます。コレを参照設定に追加すればOKです。
次に再生。
using System.Runtime.InteropServices; QuartzTypeLib.IMediaControl mc; QuartzTypeLib.IMediaEvent e; int b; try { mc = new QuartzTypeLib.FilgraphManagerClass(); mc.RenderFile("hoge.mp3"); mc.Run(); e = (QuartzTypeLib.IMediaEvent)mc; e.WaitForCompletion(-1, out b); mc.Stop(); if (mc != null) { Marshal.ReleaseComObject(mc); } if (e != null) { Marshal.ReleaseComObject(e); } } catch(Exception) { }
同様の方法で、DirectShowが対応できる形式ならいけます。動画だと新規ウィンドウができてしまうので、Panelに表示させて、Formに貼り付けるといいでしょう。
class DShow : Form { QuartzTypeLib.IMediaControl mc; QuartzTypeLib.IVideoWindow vw; QuartzTypeLib.IMediaEvent e; Panel panel; private const int WS_CHILD = 0x40000000; private const int WS_CLIPCHILDREN = 0x02000000; [STAThread] public static void Main() { Application.Run(new DShow()); } public DShow() { ClientSize = new Size(640, 480); panel = new Panel(); panel.Location = new Point(0, 0); panel.Size = new Size(640, 480); Controls.Add(panel); try { mc = new QuartzTypeLib.FilgraphManagerClass(); mc.RenderFile("hoge.wmv"); vw = mc as QuartzTypeLib.IVideoWindow; vw.Owner = (int)panel.Handle; vw.WindowStyle = WS_CHILD | WS_CLIPCHILDREN; vw.SetWindowPosition(ClientRectangle.Left, ClientRectangle.Top, ClientRectangle.Width, ClientRectangle.Height); Show(); Play(); } catch(Exception) { } } public void Play() { int b = 0; mc.Run(); e = (QuartzTypeLib.IMediaEvent)mc; e.WaitForCompletion(-1, out b); mc.Stop(); vw.Visible = 0; if (vw != null) { Marshal.ReleaseComObject(vw); } if (mc != null) { Marshal.ReleaseComObject(mc); } if (e != null) { Marshal.ReleaseComObject(e); } } }
● acquistare cialis senza ricetta [xxfdwqnl ahwstkkp hzfjmvwy]
● viagra generico [bytahfzm hjgqldae iypotlsb]
● excellent site thanks utlqusotem <a href="http://www.zmkhmyffaoye.com">click here</a> :3 erkvecjb, :[ djosmprxyv [url="http://www.zmkhmyffaoye.net"]or here[/url] :|] uzpjmnddelsdjun, 3:) rqyitzpblx http://zmkhmyffaoye.info 8-| wibgy, 8-| dzriwllekt [url=http://zmkhmyffaoye.ru]gqsqxvmjdy[/url] O:) vmnvjyupnobg, B-| ugayetwnhh [link=http://zmkhmyffaoye.se]taejaosygq[/link] 8| wibgy, <3 [lajewuddbcat]
2006-06-24 [土] [長年日記]
■ [C#][Programming] C#でサウンド(4)
Win32APIのwaveOutやPlaySoundを使う
まず、PlaySound。音関連はwinmm.dllにあるので、DllImportを使います。
[DllImport("winmm.dll")] extern static int PlaySound(string str, IntPtr ip1, int ip2);
このextern〜で使いたいメソッドが外部に定義されているよ、と教えておきます。
それから、使いそうな定数もあらかじめ調べておきます。
private const int SND_SYNC = 0x00000; private const int SND_ASYNC = 0x00001; private const int SND_LOOP = 0x00008; private const int SND_FILENAME = 0x20000; private const int SND_RESOURCE = 0x40004;
まとめると、以下のような感じでしょうか。
using System; using System.Runtime.InteropServices; namespace Sample { public class SndPlay { [DllImport("winmm.dll")] extern static int PlaySound(string str, IntPtr ip1, int i2); private const int SND_SYNC = 0x00000; private const int SND_ASYNC = 0x00001; private const int SND_LOOP = 0x00008; private const int SND_FILENAME = 0x20000; private const int SND_RESOURCE = 0x40004; public void play(string filename) { PlaySound(filename, IntPtr.Zero, SND_FILENAME|SND_ASYNC); } public void stop() { PlaySound(null, IntPtr.Zero, 0); } } }
で、waveOutですが、これが面倒。面倒だけど音をミックスして出力したり、ストリーム再生できたりと便利。そこで、Interop Declarations for Windows.hを利用することで、Win32プログラミングっぽいことをC#で可能にします。しかし、ポインタを使わざるをえません。そしてそれに伴ってunsafeの指定が必要になります。とりあえず、サイン波でも鳴らしてみましょう。こちらのページは今現在日本語で書いてある数少ない参考ページです。
というか、ほとんど一緒。
using System; using System.Runtime.InteropServices; using System.Windows.Forms; namespace Sample { public class WavePlay { unsafe public void play() { // 波形生成 short *wave_data = stackalloc short[44100]; double dr = 2 * Math.PI / (44100.0 / 440.0); for (int t = 0; t < 44100; t++) { *(wave_data + t) = (short)(Math.Sin(dr * t) * 32767); } // WAVEデバイス設定 WAVEFORMATEX wf = new WAVEFORMATEX(); wf.wFormatTag = 0x0001; // PCM wf.nChannels = 1; // モノラル wf.nSamplesPerSec = 44100; // 周波数 wf.wBitsPerSample = 16; // 16bit wf.nBlockAlign = (ushort)(wf.nChannels * wf.wBitsPerSample / 8); wf.nAvgBytesPerSec = wf.nSamplesPerSec * wf.nBlockAlign; wf.cbSize = 0; HWAVEOUT__ hwo = new HWAVEOUT__(); HWAVEOUT__ *hWOut = &hwo; windows.waveOutOpen(&hWOut, 0x0000, &wf, 0, 0, 0x0000); // WAVE情報設定 wavehdr_tag wt = new wavehdr_tag(); wt.lpData = (sbyte *)wave_data; wt.dwBufferLength = sizeof(short) * 44100; wt.dwFlags = 0; //バッファの追加情報 wt.dwLoops = 1; //1回再生 wt.dwBytesRecorded = 0; //録音用 wt.dwUser = 0; //オプションのユーザ領域 wt.lpNext = null; //使用しない wt.reserved = 0; //使用しない windows.waveOutPrepareHeader(hWOut, &wt, (uint)sizeof(wavehdr_tag)); windows.waveOutWrite(hWOut, &wt, (uint)sizeof(wavehdr_tag)); MessageBox.Show("OK", "確認", MessageBoxButtons.OK); windows.waveOutClose(hWOut); } } }
何か、もうC#じゃないみたい。
簡単に動作説明すると、waveOutOpen()で再生デバイスを開きます。ウェーブの情報はWAVEHDRに書き込みます。生のウェーブデータは適当な配列を用意します。waveOutWrite()で出力します。使い終わったらwaveOutClose()で閉じます。基本は、オープンしたら、データのセット→バッファの準備→バッファの書き込みの繰り返しです。このウェーブバッファの循環によって途切れなく再生が可能になり、また動的な制御に強い理由です。
2006-06-26 [月] [長年日記]
■ [Hardware] アーキテクチャ刷新
- 初のCoreマイクロアーキテクチャ採用「Xeon 5100」国内発表 (ITmedia)
XeonもFSBが1GHzにアップしてますね。消費電力も軽減されますね。予想価格も安い。ついにAMDへの抗戦が始まりますね。
これでサーバ分野だけでなく、デスクトップ分野にも影響がきそうですね。Pentium4の時代は、あまりのショックで使ってなくて今はAthlon64 FXを使用中なので、ここでアノもっさり感がなくなれば。なくなればまたインテルの時代が来るのでは、と思います。
2006-06-27 [火] [長年日記]
■ [C#][Programming] C#でサウンド(5)
DirectSoundを使う
C#でDirectXを利用する場合はDirectX9が前提になります。しかし、DirectXなら複数のサウンドも勝手にミックスしてくれたりしますし、もし描画にDirect3Dを使ってるならぜひあわせて使うといいでしょう。
まず、初期化。
Microsoft.DirectX.DirectSound.Deviceがデバイスのオブジェクトです。この辺はDirect3Dなんかと設計が統一されているので分かりやすいですね。それから、SecondaryBuffer。SetCooperativeLevelは強調レベルという優先度みたいな設定があるのですが、なぜか、引数にSystem.Windows.Forms.Controlを要求してきます。new Form()でも与えれば良さそうだけど、ここは真面目に親フォームを指定しておきましょう。SecondaryBufferがあるのだからPrimaryBufferも当然あるのですが、PrimaryBufferは意識する必要がありません。SecondaryBufferに書き込んだデータがしかるべきタイミングでPrimaryBufferに書き込まれこれが再生されます。
using Microsoft.DirectX.DirectSound; Device device; SecondaryBuffer buffer; device = new Device(); device.SetCooperativeLevel(owner, CooperativeLevel.Normal); BufferDescription desc = new BufferDescription(); buffer = new SecondaryBuffer(filename, desc, device);
なんか、SecondaryBufferのコンストラクタにファイル名を書き込むあたりに抽象度の高さを感じざるを得ませんが変更しないオーディオを再生させるだけならこれでもOK。もちろんメモリをオーディオの大きさだけ消費します。
再生は
buffer.Play(0, BufferPlayFlags.Default);
ループ再生なら
buffer.Play(0, BufferPlayFlags.Looping);
停止は
buffer.Stop();
ただし、停止後の再生箇所は停止位置からとなるので、もし最初から再生したければ、再生位置を変更します。
buffer.SetCurrentPosition(0);
使い終わったら解放します。解放するのはSecondaryBufferとDeviceの両方です。
まとめると以下のようになります。
using System; using System.Windows.Forms; using Microsoft.DirectX.DirectSound; namespace Sample { public class DSPlay { private Device device; private SecondaryBuffer buffer; public DSPlay(Control owner, string filename) { device = new Device(); device.SetCooperativeLevel(owner, CooperativeLevel.Normal); BufferDescription desc = new BufferDescription(); buffer = new SecondaryBuffer(filename, desc, device); } public void close() { if (buffer != null) { buffer.Stop(); buffer.SetCurrentPosition(0); buffer.Dispose(); } if (device != null) { device.Dispose(); } } public void play() { buffer.Play(0, BufferPlayFlags.Default); // buffer.Play(0, BufferPlayFlags.Looping); } public void stop() { buffer.Stop(); } } }
2006-06-30 [金] [長年日記]
■ [C#][Programming] C#でサウンド オマケ
ブザーで音楽。
using System; using System.Runtime.InteropServices; namespace Sample { public class BeepSound { [DllImport("kernel32.dll")] private extern static bool Beep(uint dwFreq, uint dwDuration); private const int C4 = 262; private const int Cs4 = 277; private const int D4 = 294; private const int Ds4 = 311; private const int E4 = 330; private const int F4 = 349; private const int Fs4 = 370; private const int G4 = 392; private const int Gs4 = 415; private const int A4 = 440; private const int As4 = 466; private const int B4 = 494; private const int C5 = 523; private const int Cs5 = 554; private const int D5 = 588; private const int Ds5 = 622; private const int E5 = 660; private const int F5 = 698; private const int Fs5 = 740; private const int G5 = 784; private const int Gs5 = 830; private const int A5 = 880; private const int As5 = 932; private const int B5 = 988; private const int b = 3000; private const int n1 = b; private const int n2 = b/2; private const int n4 = b/4; private const int n8 = b/8; private const int n16 = b/16; private const int n32 = b/32; private const int n64 = b/64; public BeepSound() { Beep(F4, n8); Beep(Ds4, n16); Beep(F4, n8); Beep(C5, n16); Beep(As4, n4); } static void Main() { new BeepSound(); } } }
● JOUF2330Sun [某コンビニで買おうとしたら店員が分かっていなくて買えませんでした。別の店で買ってきますorz]
● SewiG [バイト暦の浅い店員だとそうなるんですかねぇ。 ローソンならロッピーで手続きしてレシートを レジに持っていくだけですの..]