トップ «前の日(06-23) 最新 次の日(06-25)» 追記

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|

2005-06-24 [金]

[Network] Skypeの二重ログイン?

あるマシン(A)でSkypeにログインしている状態で、別のマシン(B)から同じアカウントでSkypeにログインすると、ログインできてしまいました。するとAが誰かとチャットで会話している様子がBで見れました。しかし、同じ状況を再現しようとするとうまくいきません。うーん。

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

Rxvxrahd [If it was more on Assignment on the main highlights is the..]


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

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

Before...

replique bracelet homme van cleef [It’s an iterative method. Say you have a pose (P, O) (posi..]

prezzo replica bracciale love cartier [The district in which I work does not have many ELL studen..]

rolex submariner replica [your tips on SWOT are briliant, I’ll try and apply them on..]


2007-06-24 [日]

[Other] 白もの家電

最近の若い人、というか自分の3歳下の5人いるなかで実に3人が「白もの家電」の意味が分かっていませんでした。ちなみに、冷蔵庫、洗濯機やエアコン、家庭用照明機器などのことを指します。うーん、たしかに最近白っぽい色の電化製品は減っていますけど、正直こんな人たちでも家電系の企業に就職できるほど今は人が足りないんだなぁと思いました。標本数が少ないですが、ここに3人いるってことは全国にはもっといるってことですよね…


Copyright © 2004-2008 SewiG All rights reserved.