トップ 最新 追記

SewiGの日記

2004|01|04|05|06|07|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|

2006-06-01 [木] [長年日記]

[Other] WebMoney買ってきた

クレジットカード決済でもよかったんだけど、なんとなくカードを使いたいサイトと使いたくないサイトがあって、今回はWebMoneyで払ってみました。手数料とか関係ない1回きりの登録関係の支払いだったしね。

本日のツッコミ(全2件) [ツッコミを入れる]

JOUF2330Sun [某コンビニで買おうとしたら店員が分かっていなくて買えませんでした。別の店で買ってきますorz]

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-03 [土] [長年日記]

[Other] オープンキャンパス

オープンキャンパスでした。高校生や大学生や一般の方などたくさん人がいました。

パネル展示とデモで、こんな研究やってるのかと驚かされるとともに、この研究室はダメぽみたいなことも分かってなかなかおもしろい1日でした。


2006-06-04 [日] [長年日記]

[Music] ヤマハのプレイヤーズ王国もオリジナル曲を有料配信

ブログなんかのおかげで、個人のコンテンツが大きな価値を持つことが分かってきたわけですが、音楽もオンラインで1曲単位での販売が主流になったので、個人のインディーズ音楽を販売したくなります。

今までもmuzieなんかが着メロの販売をやってたりしましたが、ここでヤマハも参戦。面白くなってきました。

Vectorがブログの有料購読を開始したりと、今個人のコンテンツ配信が熱い!


2006-06-05 [月] [長年日記]

[PC] ディスプレイをBTOする時代

いいなコレ。しかもナナオ。

液晶サイズは当然として、VAパネル/TNパネルの選択、スピーカの削除、本体色の選択など細かい選択ができるみたい。これは面白そう。

本日のツッコミ(全1件) [ツッコミを入れる]

Ethan [In awe of that anwser! Really cool!]


2006-06-06 [火] [長年日記]

[Other] 家計簿データ吹っ飛んだ

とりあえず、2006年から入力しなおすも項目多すぎで、しかもレシートの無い買い物は再現できず。

別に完全な記録は必要なくて、どれくらい買い物したか把握できればいいのでなんとかして入力しないといけないけど時間が無い。

最近、変な買い物ばかりするから、先月と比べてどれくらい消費してるか知りたいのに、入力だけで1ヶ月かかりそう。


2006-06-07 [水] [長年日記]

[Book] 変身 - 東野圭吾 著

不慮の事故で重体だった青年、成瀬純一に世界初の脳移植手術が行われた。温厚な性格だった純一が、徐々に壊れていくという話。

「変身」を読む上でのポイントは、純一の恋人である葉村恵の存在、脳手術を執刀した堂元博士の観察日記、そして人格が侵食されるのを自覚する純一の苦悩。恵は、画家を目指していて自分に一途だった温厚な性格の頃の純一に戻ることを願い、他人のように変わった純一であっても傍に居ようとした。堂元は世界初の試みを行い純一がどのように変化するかに興味があった。そして、純一は自分に純一の人格が存在するうちに真相を素人ドナーを探そうとした。

内臓移植で、ドナーの性格が表層化するといった話は現実の世界で起こっているけど、もし将来脳移植が現実のものとなったら人体はドナーの脳に乗っ取られてしまうのだろうか。自己を構成するものは何だろうか。脳移植されてもこの体は自分のものだと言えるのだろうか。

いつ我々の身に降りかかるか分からない脳移植の恐怖に怯える前に、元気なうちに自分の証を残していこう。


2006-06-08 [木] [長年日記]

[Book] 萌えるSE 業界ノベルズ お兄ちゃんはプログラマ

プログラミングやってない人には面白くない話かもしれない。

いい加減な仕様書、仕様変更、など様々な困難に立ち向かうプログラマの話。新人君の大町はプログラマのアニオタぶりに圧倒される。さすがに萌え関係は脚色しすぎな気もするが、概ねこんな感じにのプログラマばっかだと思う。そして、納期に追われる開発現場に美少女あずみが現れる。しかもテスターやってるし。あー雑用やってくれるかわいい女の子ほしいなぁ。

とりあえず、萌えを期待して買うと後悔する。かわいい女の子が開発に居ればいいなーと思ってる人が、ああ、こんなやつ俺の回りにいるぜとか、ああ、やっぱマならそうするよな、と納得しながら読む本。あんまりオススメするほど面白い本でもないけど。


2006-06-09 [金] [長年日記]

[Book] 絶対音感 - 最相葉月 著

絶対音感を持つ人、持たない音楽家、様々な人の体験談が載っているノンフィクション小説。概要から科学的な話まであり、1,2章は世界の音楽教育と比較した過去から現代までの日本における音楽教育の違い、特徴が載っている資料価値の高い作品に仕上がっている。

単純に絶対音感を身につけたいと考えている人が読む本ではない。必ずしも絶対音感が良いとは言えないことが本書から伝わってくる。アカデミックな分野と義務教育の違い。具体的には、固定ドと移動ドの問題。それにともなう絶対音感の弊害。

絶対音感に興味がある人は、1〜4章まではぜひ読んで欲しい内容。


2006-06-10 [土] [長年日記]

[Other] 鶴来街道はやはり田舎だった

今日も金沢へチャリで向かっていたら、四十万付近でチャリがパンクしました。修理に出して夕方に引き取ることにして、電車に乗ろうとしたら目の前で発車しやがりました。1時間に2本しか来ないのに。

バスに乗ろうとバス停に行ったら1時間に0.5本しか来ないし、しかもこれもさっき出発したばかり。

チャリがなかったらなにもできないよー。

北陸鉄道さんにお願い。鉄道線でICa全種類使用可能にして運行本数を増やして、香林坊まで路線を延ばしてください。そしてバス路線はせめて1時間に1本以上運行してください。


2006-06-11 [日] [長年日記]

[Lifestyle] ブログを使ったレポート提出があるみたい

情報の科目でHTMLを作成して提出、というのは昔から良くある内容ですが、最近はブログを作成してトラックバックしないと単位がもらえないらしいです。

とある友人の出題ページを見ると、自分でサーバを立ち上げてブログを開設するのではなく、既存のブログサービスを利用するというもの。猫も杓子もブログの時代とはまさにこのことか。ろくに更新されないブログが増えて無駄なスペースが増えるだけのような気もします。いや、利用者数増加で開設される側はうれしいのか。んー。なんともふしぎな現象です。


2006-06-12 [月] [長年日記]

[Programming] Direct X + C#

最近、C#がJavaぽいくて移行は楽チンで、Direct Xも使えるとなるとゲームなど用途によってはC#がいいかも、と思います。

Formのインスタンスを作るだけでウィンドウが作られ、わずか数行でDirect Xの初期化できたりして、C++ Win32の苦労はありません。

これは生産性が上がる。


2006-06-13 [火] [長年日記]

[Network] Google Earth 4

2005/06/29の日記で紹介して1年。バージョン4では、かなり情報量が増えてて家一軒確認できます。しかも漢字で検索できます。

しかし、漢字で検索すると山の中にポインタが出てきて、その近辺は詳細な地形が表示されるのに、肝心の市街地が荒い地図になったりする地域も多々ありました。

しかし、これは便利になりました。いろいろ遊べそう。


2006-06-14 [水] [長年日記]

[Other] 突然音楽が

ヘッドホンしてるのにいきなりPCから音楽が鳴り出したので何事かと思ったら、ビープ音で音楽がなってました。いまどき珍しいなあ、としみじみ。

なつかしい。なんかアナログ音源で打ち込みしたくなりますね。


2006-06-15 [木] [長年日記]

[Other] 梅雨到来

北海道以外は梅雨入りみたいです。湿度が高くて暑いと作業効率が上がらないのが嫌ですね。

天気に左右されない強い心が必要。


2006-06-16 [金] [長年日記]

[Programming][C#] C#で2D Programming on Direct3D (1)

Managed DirectXを使えばC#でもDirectXが扱えます。.NET Frameworkのおいしい仕様とDirectXの豊富な機能が使えるのは便利。

環境構築

  1. VisualStudio 2005や.NET Frameworkといった開発環境をインストール
  2. DirectX SDKの最新版をインストール
  3. PATHを通す

DirectX SDKをインストールするときにVisualStudioの設定も行われるので順番は間違えないようにしましょう。PATHは例えば、「C:\Program Files\Microsoft Visual Studio 8\VC\bin」を追加しておくと、コマンドプロンプトでvcvars32を実行するだけで、いろいろと設定できます。

C#でDirectXの初期化

→ ソースコード (csmdx_init.zip)

まず、上記のソースコードをコンパイルして実行してみましょう。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-19 [月] [長年日記]

[Software] Google Earth 4はすごい

噂には聞いていたけど、「35 37' 59.96"N, 139 47' 57.49"E」は凄かったです。Google Mapsのサテライトマップで見ても何の変哲も無い東京ビビッグサイトだけど、Google Earth 4で見ると凄い光景が見れた。

てかこれ最初に見つけた人すごいね。衛星写真の解像度もココまで来るとおもしろいね。

本日のツッコミ(全56件) [ツッコミを入れる]

Before...

compra viagra italia [tyujotgr oqsqxdhc rjgkexms]

acquisto cialis in farmacia [oxxekbxt lvtwcnvn flpwzkyq]

comprare cialis in italia [mvpcwtlr zzopctbf uatnezuy]


2006-06-20 [火] [長年日記]

[Software] Opera 9リリース & Windows Live Messengerリリース

Opera 9正式版にもBitTorrent搭載で、MacOS Xみたいなウィジェットもあります。そしてRSSアイコンがFirefoxと一緒のオレンジのやつに。しばらく使ってみないと細かなバグが直ったかどうかわからないなぁ。

そして、Windows Live Messenger。見た目はかっこよくなったんだけど、細かな変更がちょっと気になりました。それより、通話機能の追加や共有フォルダは便利。マイコンピュータに表示されるとデータの受け渡しが楽になりますね。前の1対1の送受信は大変でしたからね。

本日のツッコミ(全1件) [ツッコミを入れる]

Nazri [What a pleasure to find someone who iditeefins the issues ..]


2006-06-21 [水] [長年日記]

[C#][Programming] C#でサウンド(1)

C# + .NETでサウンドを扱う方法はいくつかあります。順番に紹介します。

  1. .NET 2.0のSystem.Media.SoundPlayerを使う
  2. MCIを使う
  3. DirectShowを使う
  4. Win32APIのwaveOutやPlaySoundを使う
  5. 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);
		}
	}
}
本日のツッコミ(全55件) [ツッコミを入れる]

Before...

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()で閉じます。基本は、オープンしたら、データのセット→バッファの準備→バッファの書き込みの繰り返しです。このウェーブバッファの循環によって途切れなく再生が可能になり、また動的な制御に強い理由です。

本日のツッコミ(全57件) [ツッコミを入れる]

Before...

cialis 20mg [kxhlzcam uypjeckx pywrettq]

viagra online [mlajgntv xmdvpeov onqwdqaj]

Nuroaoqk [We believe open discussion and finding a spiral staircase ..]


2006-06-25 [日] [長年日記]

[Other] 休息

研究室の仲間と遊びに行きました。最近レポートに追われる日が続いていたのでちょうどいい息抜きになりました。騒いだり、買い物したり、食事したり。こういう穏やかな日も必要です。

それはそうと、今月は私の周りで誕生日の方が多いのです。どういうサプライズを仕掛ければ面白いだろうかとたくらんでる時間もまたいとをかし。

頭を空にできる時間。

それは、次に来る頭脳戦に向けた準備期間。


2006-06-26 [月] [長年日記]

[Hardware] アーキテクチャ刷新

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-28 [水] [長年日記]

[Other] いろいろショック

今日は、研究室で飲み会がありました。待ち合わせまで時間があったので片町付近をぼぉーと歩いていたら、私服姿の綺麗な女性が通り過ぎていきました。どこかで見たことある顔だなぁと思っていたら、いつものメイドカフェのメイドさんでした。

うわー、なぜこう今日は大した用事も無いからといい加減な服装したときに限って目撃されるかなぁ…

そして、飲み会で数千円消えてしまいました…


2006-06-29 [木] [長年日記]

[Software] Flash Player 9 と Flex 2

従来版よりも最大で約10倍高速といった点もすごいのですが、SDKが無償配布されるといった点が開発者としてはありがたいところ。やはり手の込んだオーサリングツールとしては製品版がいいのは事実なんですが、コードで制御できるのはなんともうれしい。


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();
	}
}
}
本日のツッコミ(全57件) [ツッコミを入れる]

Before...

cialis [ygwjfwxz fntxgdsi fostqmcz]

viagra [eomkevnv zildabfi jlpbtyvl]

Tvpyaxna [With silibinin, kills skin cells mutated by UVA radiation,..]


Copyright © 2004-2008 SewiG All rights reserved.