オンラインゲームでボイスチャット標準化

MMOでもFPSでも ボイスチャットする場合、ゲームとは別のソフトウェアで、特定の人とコンタクトを取る場合がほとんど。
そうじゃなくて、ボイスチャットもゲームに組み込めば(組み込まない理由がある筈だけれど)、新しい雰囲気のゲーム作りが出来るんじゃないかと

オープンボイスチャットなら声の届く範囲や音の減衰を利用して、リアルな戦略が組めるんじゃないか
索敵で相手チームの話してる内容が聞こえるとか。面白そうじゃないか

Windowsで録音 再生

メモメモ。 音声を録音して再生するだけのプログラムです

MMSystem.h だけだと 動かないけど、Windows.hで、 うごく。。。不思議
Windowsマルチメディア系のAPIはここに書いてありました msdn WIN32API

参考にしたサイト一覧
WAVEデータの作成と再生
WAVE
WAVEファイルにリアルタイムで加工を施し再生する

リアルタイムに音声を録音し続けたいなら、コールバック関数を利用して、複数のバファを切り替えながら、waveInAddBuffer でおk。
録音と再生のレイテンシを小さくしたいなら、バッファの大きさを小さくすればok?
どちらにせよ、再生中のポインタと録音中のポインタの距離が近いほどレイテンシは抑えられそう。

ポインタが重なったりしたら、えらい雑音が入りそうだな@@

#include <Windows.h>
//#include <MMSystem.h>
//#pragma comment (lib, "winmm.lib")

#include <iostream>
using namespace std;

// waveInOpenが利用するコールバック関数
void CALLBACK waveInProc(
	HWAVEIN hwi,      
	UINT uMsg,        
	DWORD dwInstance, 
	DWORD dwParam1,   
	DWORD dwParam2    
	)
{
	switch(uMsg)
	{
	case WIM_OPEN:
		cout << "waveInOpen" << endl;
		break;
	case WIM_CLOSE:
		cout << "waveInClose" << endl;
		break;
	case WIM_DATA:
		cout << "バッファがいっぱいになりました" << endl;
		break;
	}
}

// waveOutOpenが利用するコールバック関数
void CALLBACK waveOutProc(
	HWAVEOUT hwo,
	UINT uMsg,        
	DWORD dwInstance, 
	DWORD dwParam1,   
	DWORD dwParam2    
	)
{
	switch(uMsg)
	{
	case WOM_OPEN:
		cout << "waveOutOpen" << endl;
		break;
	case WOM_CLOSE:
		cout << "waveOutClose" << endl;
		break;
	case WOM_DONE:
		cout << "バッファをすべて再生しました" << endl;
		break;
	}
}

int main()
{
	/*******************************************************************************
		録音
	********************************************************************************/
	HWAVEIN      hwi = NULL;				// WAVEハンドル
	LPBYTE       lpWaveData = NULL;			// バッファ本体のポインタ[ヒープ領域]
	WAVEFORMATEX wf = {0};					// デバイスオープン時に使う、設定構造体
	WAVEHDR      wh = {0};					// デバイスに与えるバッファの設定構造体

	// デバイスオープン時の設定
	wf.wFormatTag      = WAVE_FORMAT_PCM;	// PCM形式
	wf.nChannels       = 1;					// ステレオかモノラルか
	wf.nSamplesPerSec  = 22050;				// サンプリングレート 22.05KHz
	wf.wBitsPerSample  = 8;					// 量子化レベル
	wf.nBlockAlign     = wf.wBitsPerSample * wf.nChannels / 8;	// バイトあたりのビット数[PCMの仕様]
	wf.nAvgBytesPerSec = wf.nSamplesPerSec * wf.nBlockAlign;	// 1 秒あたりのバイト数
	// モノラル+サンプル22050+量子化8bitなので 一秒間に22050byteのデータが発生する
	// サンプル x nBlockAlign = 一秒間のデータ量なので nBlockAlignは1

	// デバイスオープン
	if(waveInOpen(
		&hwi,				// ハンドル
		WAVE_MAPPER,		// デバイスID。 WAVE_MAPPERデフォルトのデバイスを指定
		&wf,				// オープン時の設定
		(DWORD)waveInProc,	// コールバック関数
		0,					// しらん
		CALLBACK_FUNCTION	// コールバック関数の属性
		) != MMSYSERR_NOERROR)
		cout << "デバイスのオープンに失敗しました" << endl;

	DWORD dwRecordSecond = 10;		// 10秒
	DWORD dwDataSize;

	dwDataSize = wf.nAvgBytesPerSec * dwRecordSecond;	// 一秒間のデータ量 x 秒数
	lpWaveData = (LPBYTE)new BYTE[dwDataSize];

	// バッファ情報セット
	wh.lpData         = (LPSTR)lpWaveData;
	wh.dwBufferLength = dwDataSize;
	wh.dwFlags        = 0;

	// バッファの初期化
	waveInPrepareHeader(hwi, &wh, sizeof(WAVEHDR));

	// バッファの関連付け
	waveInAddBuffer(hwi, &wh, sizeof(WAVEHDR));

	// 録音開始
	waveInStart(hwi);

	rewind(stdin);
	getchar(); // 10秒待機すると、 "バッファがいっぱいになった" が表示されるはず

	// 録音終了
	waveInReset(hwi);
	waveInUnprepareHeader(hwi, &wh, sizeof(WAVEHDR));
	waveInClose(hwi);


	/*******************************************************************************
		再生
	********************************************************************************/
	
	HWAVEOUT hwo;	// ハンドル
	WAVEHDR whdr;		// 

	// デバイスを開く
	if(waveOutOpen(
		&hwo,			// ハンドル
		WAVE_MAPPER,		// デフォルトのデバイスを指定
		&wf,				// waveInOpenのとおなじでおk
		(DWORD)waveOutProc,	// コールバック関数
		0,					// しらん
		CALLBACK_FUNCTION	// コールバック関数の属性
		)
		!= MMSYSERR_NOERROR )
		cout << "Erroe" << endl;


	// 音声ファイルのパラメータを設定
	whdr.lpData =			(LPSTR)lpWaveData;			// 音声データの入ってるポインタ
	whdr.dwBufferLength =	dwDataSize;						// 音声データのサイズ
	whdr.dwFlags =			WHDR_BEGINLOOP | WHDR_ENDLOOP;	// 再生オプション
	whdr.dwLoops =			1;								// ループ回数

	// 初期化
	waveOutPrepareHeader(hwo,&whdr,sizeof(WAVEHDR));

	// 音声データブロックの書き込み
	waveOutWrite(hwo,&whdr,whdr.dwBufferLength);

	rewind(stdin);
	getchar();	// 再生中待機

	waveOutReset(hwo);
	waveOutUnprepareHeader(hwo, &whdr, sizeof(whdr));
	waveOutClose(hwo);
}

クリップカメラ -新しい写真撮影スタイル-「旅行」

旅行中カメラを両手で構えて風景をバシャバシャ撮っていて、ふと思ったことメモ

帽子にクリップみたいに付けられるカメラが有ったら面白そう。 時間を設定して、5秒ごとに自動で撮るとか。 ムービーでもよさそう

SDの大容量化と、HDカメラ小型化から カメラはクリップで帽子、電池&SDはポケットとか 首にかけるとか。

カメラと電池&SDはオシャレなワイヤーでつなげばいい

強力な “頭ブレ補正”が必要!

slmgr -プロダクトキーが不要??-

Windowsの試用期間が何回かリセットできる事を知ったのでメモメモ

slmgr.vbsっていう、MS純正スクリプトが最初からsystemフォルダにあるらしいです。
最初から環境パスに入っているので、プロンプトファイル名を指定して実行 slmgr.vbsと打てば起動できます。

間違えて、slmgrと打つと、フォルダが開くだけなので注意;;
試しにslmgr.vbs -dlv を実行すると、

slmgr.vbs -dlv

ちなみにEnterprise editionです。

リセット可能回数は3回までと、他のサイトで紹介されていましたが。

なぜか5回までリセット出来るようです。。

嬉しい! 有効期間は確か60日がリミットだったので

60日 x 5回 = 300日

だいたい300日もしないうちに、OSごとクリーン再インストールするので、つまりライセンス不要ってことですか??

追記: リセットされても8日ほどしか猶予は追加されませんでしたorz この数値もエディションごとに違うようなので注意です。

ちなみに、本題の有効期限をリセットするパラメータは-rearmです

slmgr.vbs -rearm


大喜びで、Serverの方で色々パラメータを試して遊んでいたら。

slmgr.vbs -upk

このコマンド試したら終わった。。

slmgr.vbs -dlv

え?

焦って、MSのヘルプへ行くと、

この問題を解決をするには、次の方法のいずれかを使用します。

方法 1

検索の開始 </a0>] コマンド プロンプト を入力する コマンド プロンプト を右クリックして [ 管理者として実行 </a0>] をクリックします。

管理者: コマンド プロンプト ] ウィンドウで、次のようなコマンドを入力して Enter キーを押します。

cscript c:\windows\system32\slmgr.vbs – ipk {ProductKey}

メモ 組織で MAK キーの代わりに、KMS キーを使用して、いる場合は、Pid.txt ファイルで提供されているジェネリック KMS キーを使用します。 このファイルは、Windows Vista インストール DVD 上の \sources フォルダーにあります。

種類コマンドを次のようなして Enter キーを押します。

cscript c:\windows\system32\slmgr.vbs – ato

方法 2

「現象」に記載されているエラー メッセージををクリックしてします。

製品キーを入力して、プロダクト キーをアクティブに指示に従います。

方法 3

コンピュータを再起動してください。

コンピュータにログオンします。 Windows のライセンス認証 ウィンドウが表示されます。

製品キーを入力して、プロダクト キーをアクティブに指示に従います。

まてまて、プロダクトキー無いですから!

もともと評価版だった上に、評価用ProductKeyのメモとかしてないですから!

また近いうちに入れなおしかー@@

Serverの有効期限は180日なので、もし5回リセット出来るなら

180日 x 5回 = 900日

十分すぎる!

追記: やっぱそんな甘くなかった! linuxへ移住がいいみたい

というわけで、 slmgr.vbs -upk に注意。

追記2: エディション毎の有効期限

時々追加します

エディション リセット残り回数 有効期限
Enterplise 0回 10日
Ultimate 3回 30日
Ultimate 0回 25日?
Professional 2回 30日
2008R2 5回 180日

悪用厳禁
悪用厳禁。
悪用厳禁。。