2007年04月29日

宇宙葬って6万あればできるのか


宇宙葬って金持ちだけのものかと思ったら以外とリーズナブルなお値段になっているぢゃん。
遺灰1グラム当たり495ドル(約5万9200円)って安くないか。


ロケットは無重力空間に達した後、遺灰を積んだカプセルが地上に無事帰還。遺灰は遺族に手渡された。宇宙葬はスペース・サービシズ社が企画し、料金は遺灰1グラム当たり495ドル(約5万9200円)。
スタートレック機関長の「宇宙葬」=遺灰を無重力空間へ−米



坊さんのお経はありがたすぎて理解できないので、そんなもんやるぐらいだったら、宇宙葬にした方がマシだ、何より夢がある。

kakaku.comの相場 によると、通常の葬儀だけでも 50万以上はかかるみたいだ。
50万あれば 約10gも遺灰を宇宙に上げられるぢゃん。


それに、死亡すると健康保険から、埋葬料が出るわけだし。


社会保険か国民健康保険皆さんどちらかの保険には入っていると思います。
葬儀を挙げると健康保険から7万円とか10万円あまり大きな金額ではないですが
葬祭費(埋葬料)としての支給があります。
葬祭費(埋葬費)需給の手続き 葬儀・葬式・密葬の佐藤葬祭


7万円とか10万円が相場なら十分、宇宙にいけるね。
posted by rti at 13:53| Comment(0) | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

C# プロパティの憂鬱

C#のプロパティって便利なようで使えなくないか、微妙な感じ。
名前そのままで、読み込みは public だけど、値を書き換えるのは protected or private でって設定ができないんだよなぁ。
もうちょっと空気を読んで欲しい。。。


//プロパティを利用しない書き形
class Test
{
private int Otakara;

public int GetOtakara()
{
return this.Otakara;
}

public Test(int inOtakara)
{
this.Otakara = inOtakara;
}
};



//プロパティを使ってみよう!!
class Test
{
private int Otakara
{
//読み込みは public で
public get //エラー!!
{
return this.Otakara;
}
//書き込みは private で
set
{
this.Otakara = value;
}
}

public Test(int inOtakara)
{
this.Otakara = inOtakara;
}
};


ちなみに MSのサンプルだとこげな風に書いてある事が多い気がする。


//MS推奨??
class Test
{
//小文字でメンバを定義するよ.
private int otakara;
//外側には見栄えが良い大文字で定義するよ.
public int Otakara
{
get
{
return this.otakara;
}
}

public Test(int inOtakara)
{
//メンバの先頭を小文字にしたくないよね。。。
this.otakara = inOtakara;
}
};


外には見栄えの良い大文字で表現して内部は小文字って感じ。
内部は見えないところだから見栄を張らなくていいらしい。将軍様の国か、どっかの温泉街か。

やっぱ、メンバってクラスの中ではグローバルであって危険な変数だから先頭を大文字にして強調したいよ。


だからといって、

//昔のようなハンガリアン!
this.m_Otakara

ってのはイヤだなー。

そもそも、メンバに m_ をつける癖をつけるぐらいだったら、this. をつける癖をつけたほうが合理的だ。
ローカル変数に this. をつけたらコンパイラが怒ってくれる。
こっちの方が誰が見てもメンバとわかる。

話がズレたけど、つまり、

this.Aaaaaaaa ってな感じになればいいわけよ。

そんで、外からは読み込みのみで書き込みは内部だけって感じにできないかなぁ。

プロハティの発想はいいと思うんだよなぁ。
いちいち、 getXXX setXXX ってアクセッサを定義するのは面倒。
だから、楽チンにかけるようにしたよ!! ってところは十分評価できる。

だけど、実際使ってみると、なかなか思うようには行かないですよ。。。

ふつーアクセッサの大部分は getXXX であって、 setXXX はめったに使われないよね。
setXXX で設定するぐらいなら、初期化ならコンストラクタか初期化用のメソッド呼ぶし、計算したいなら普通にメソッドたたくし。

そう考えると、読み込みは public だけど、値を書き換えるのはprotected or private って設定ができるのが一番楽のような気がするんだが、
どーなんでしょうか。


はっ!!????????


そうか、、、もしかしてプロパティをアクセッサ代わりに使おうという考えが間違っているのかもしれない!

プロパティの起源をよくよく考えてみれば、



private void Form1_Load(object sender, EventArgs e)
{
this.Text = "うがー";
//Builder だと、 this.Cation = "うがー"; ね。
}


ってヤツをやりたかったために プロパティって作ったんぢゃないのかと。

this.Text の実装は WinAPI ベースで行けば、 setWindowText() で値の書き換え。
やっていることは、アクセッサってレベルぢゃねーぞ
立派なメソッドだね。


プロパティは、アクセッサとしても使えるかもしれないが、それはたまたま利用できただけで、本当の目的はメソッドをラップして自然に見せるための機能って考えれば、現在の実装も理解できる。
posted by rti at 08:28| Comment(1) | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2007年04月28日

skype + 音声認識

skype-in で電話を受けて、音声認識でなんかできないかなーと、
思っていたら、既にやっている人がいた。

音声認識でハンズフリーレストラン検索「声探」
音声認識でハンズフリーレストラン検索 「声探」


俺的にやりたかったのは、
ニワンゴのサービスのようなやつの音声化。
ケータイ世代ではないので、ケータイのキーが討ちづらくてしかたないため、電話口でしゃべれば結果を返してくれるって感じのサービスがほしい。
本人認証の仕組みとかがあれば、結果をメールで受信もありかなぁ。
音声読み上げだと長い文章は大変だしね。

たとえば、あらかじめ発信者番号(自分の電話番号)をサーバに登録しておけば、簡易本人確認ができるよね。


ついでに、PCの制御とかもできるようになれば、
ラピュタのあのシーンを再現できるかもしれない。

コマンド バルス。

さっと、ケータイを取り出して、バルスってシャウトするとPCが勝手にシャットダウンするって感じかな。
すげーかっこよくないか。

PCをメールで遠隔操作するソフトがあるんだから、ケータイの音声で操作するソフトもありでしょう。
posted by rti at 04:34| Comment(0) | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2007年04月23日

自分に火の粉が降りかかるまでは傍観

トリビアの泉でアキバの人たちは電車男のように助けてくれるのか?
って実験で、アキバでは、被験者の約半分の人たちが助けに入ったという結果が出たが、特急にのっている人はそうではないらしい。
アキバが異常なだけか??


大阪府警淀川署は21日、JR北陸線の富山発大阪行きの特急「サンダーバード」の車内で昨年8月、大阪市内の会社員の女性(当時21歳)に暴行したとして、滋賀県湖南市石部南、解体工、植園貴光被告(36)を強姦(ごうかん)容疑で再逮捕した。当時、同じ車両には約40人の乗客がおり、一部の乗客は異変に気付いたものの、植園容疑者にすごまれ、制止できなかったという。
強姦:特急内で暴行、容疑の36歳再逮捕 乗客沈黙



俺様が同じ常態に居たらどうなんだろう、、、やっぱ助けないのかなぁ。
だめぢゃん。


人は自分に火の粉がふりかかってくるまで動かないものだ。
なんで強引に当事者にして火の粉を振り掛けるってのがもっとも簡単な解決法というのを聞いたことがある。

例えば、夜、暴漢に襲われたときに、助けを呼ぶ一番良い方法は、

「助けて!」と叫ぶ

ではなく、

「火事だ!」と叫ぶ

ことらしい。
「助けて!」だと逆に怖がって家から出てこない場合があるそうだ。
しかし、火事の場合は逃げないと自分に危害が加わるために家から出ずにはいられないわけだ。
奴らは目撃者を恐れるから、これで撃退できるということらしい。
#銀河英雄伝説でも似たようなシーンがあったなぁ

実際に効果があるのか? といわれると、幸いなことに一度も試す機会に恵まれなかったので、効果があるか謎。


ついでに、、、この記事のように暴漢に襲われたときも、

「誰か助けて」

ではなくて、

「そこのxx色の服を着ている人、助けを呼んで!」

ってな感じに指名するといいらしい。
ようするに、強引に関係者にしてしまう。
関係者になったからには、もう傍観は出来ない、と。
今まで傍観者Aだったのがいっせいにギャラリーの視線を浴び、関係者になるわけで、
この状態で見殺し(?)にできますか?ってわけだね。

まぁ、指名されたほうは迷惑だろうが(w 、これが一番らしい。

実際に効果があるのか? といわれると、
これも、幸いなことに一度も試す機会に恵まれなかったので、効果があるか謎。

俺様的には、かなり効果があるような気がするんだけどね。


昔、大夜逃げ学ってサイトがあって、
ゴネたり、居留守を利用して借金をなかなか支払ってくれない人に対して、効果的な取立ての方法として、
家を差し押さえるって方法をあげていた。

どんだけくらりくらりと借金取りから逃げる人も自分の住処を追われるのだけ容認できないらしい。
すぐに向こうから怒りの電話がかかってきてコンタクトを取ることが出来るそうな。
恐ろしい。


結局は、人は自分に害が加わるまで問題を先送りするものらしい。
マーチン神父の教えをほとんどの人は、守れていない。

逆にいえば、
他人になんかやって欲しいときは、強引に関係者にして火の粉を振り掛ければOKってことだね。
黙ってて欲しいときには、火の粉を振り掛けないようにするってことかなぁ。
これにかかわってもあなたに得はありませんよって感じに思わせるって感じか。
posted by rti at 17:50| Comment(0) | TrackBack(3) | 日記 | このブログの読者になる | 更新情報をチェックする

2007年04月22日

メモ 為替の過去のデータ

過去のデータがダウンロードできる。

Export of MARKET DATA to CSV

過去のデータを検証したいときに便利かも。
posted by rti at 18:16| Comment(0) | TrackBack(1) | 日記 | このブログの読者になる | 更新情報をチェックする

C# メモ System.XML の憂鬱、というか空気を呼んでくれないところ

System.XML(XmlDocument) でノードから行番号が取得できない。
特定のノードが xml ファイルのどこにあるのか取得できない。

XMLの文法エラーのときだけは 行番号を取得できるんだけどねぇ。


例えば、エロゲ屋の顧客リスト管理プログラムがあったとして、


<data>
<name>上上下下</name>
<age>15</age>
</data>


なんてデータが来たら、15才の未成年に売れないので、データがおかしいよってエラーを出してあげたい。
「ファイル xxx.xml の 128行目 name 上上下下の年齢がおかしいよ」ぐらいは表示してあげたい。

ついでに言えば、 128行目にスクロールしてあげるとかすれば空気を読めているだろう。

だけど、行番号を取得する方法がないのだ。

「name 上上下下の年齢がおかしいよ」ぐらいしか表示できない。
後は、上上下下で全文検索でもして該当データを直すって感じか。
めんどくさ。

もうちょっとMSFTのアーキテクトさんが空気読んで設計してくれていたら良かったのにね。設計は大切だ。

ライブラリに依存すると、ライブラリの手のひらで遊んでいるうちはいいんだけど、それを外れるとどうしようもなくなるところが困ったものだ。

一応、別解して次の方法があるらしいが、、、
面倒だなぁ。。。

Line number information in XmlDocument? - .NET XML
TopXML : Using LINQ to XML Annotations - tracking line numbers, in .NET XML, System.XML
posted by rti at 18:10| Comment(0) | TrackBack(1) | 日記 | このブログの読者になる | 更新情報をチェックする

2007年04月20日

スカイジャガー

うわー懐かしい。

SKYJAGUAR [MSX]


コナミから発売された縦シューですね。

めっちゃいきこんで攻略していたのに、途中で挫折してしまったヨ。
まさか、ループゲームなんて思ってもなかったよ。

俺の記憶が確かなら、デモ画面に背景が黒の宇宙みたいなところで戦っているでもシーンがあって、いつかこのシーンが登場するものだと思っていた。

SCENE8 のハンマーみたいなボスを倒すともう一度最初に戻されるわけ。
でも、 SCENE3 をクリアしても SCENE1 のような市街地に戻されるから、 もう一度ハンマーを倒せば、宇宙にいけるんぢゃねぇ? って淡い期待を抱いて、プレーしていた。

俺が操縦して弟が玉を打つとかやって、分担作業とかやったりして何とか攻略を試みていた。
ゲームセンターCX「高橋名人の冒険島」の課長と東島みたいな感じだ。
それでも、結局2度目のハンマーを撃墜することが出来なかったけどね。

紅白帽 頭にウルトラマン、ウルトラマンな感じに懐かしい思い出です。
posted by rti at 11:04| Comment(0) | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

俺のプログラムの師匠を見つけた

BASIC入門

俺様にプログラムってやつを教えてくれたソフトだった。
テラナツカシス。

発売はカシオだったのか。。。
ドット絵で飛行機飛ばしたり、mmlを記述して音楽鳴らしたりしていたもんだ。

基本はファミコンで遊んでいて、親からファミコンを取り上げられたら、「ゲームが無いければ作ればいいんぢゃね?」って感じでMSXで遊んでいた。
posted by rti at 10:39| Comment(0) | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2007年04月18日

SAPI Windows音声認識

何か、音声認識ネタが/.に出ていたので、昔書いた SAPI周りのやつでも上げとくか。
数年前に書いたやつなので、もう時代遅れになっている個所もあるかもしれんが何か役に立つといいかもね。




マイクから自由単語で認識するには?


USES_CONVERSION;

HRESULT hr;
CComPtr Engine; // 認識エンジンオブジェクト
CComPtr RecoCtxt; // 認識エンジンオブジェクトの作成

// CLSID_SpSharedRecognizer マイクから録音するとき?
// CLSID_SpInprocRecognizer Waveから変換するとき?
hr = Engine.CoCreateInstance(CLSID_SpSharedRecognizer);
if(FAILED(hr)) throw RComException(hr , "CLSID_SpSharedRecognizer 構築 に失敗");

// 認識コンテクストオブジェクトの作成

hr = Engine->CreateRecoContext(&RecoCtxt);

if(FAILED(hr)) throw RComException(hr , "CreateRecoContext に失敗");
hr = RecoCtxt->SetNotifyWin32Event();

if ( FAILED(hr) ) throw RComException(hr , "SetNotifyWin32Event に失敗");
hr = RecoCtxt->SetInterest(SPFEI(SPEI_RECOGNITION), SPFEI(SPEI_RECOGNITION));

if ( FAILED(hr) ) throw RComException(hr , "SetInterest に失敗");
hr = RecoCtxt->SetAudioOptions(SPAO_RETAIN_AUDIO, NULL, NULL);

if ( FAILED(hr) ) throw RComException(hr , "SetAudioOptions に失敗");
CComPtr dictationGrammar;

//メインとなる文法の作成
hr = RecoCtxt->CreateGrammar(0, &dictationGrammar);
if ( FAILED(hr) ) throw RComException(hr , "CreateGrammar に失敗");

hr = dictationGrammar->LoadDictation(NULL, SPLO_STATIC);
if ( FAILED(hr) ) throw RComException(hr , "LoadDictation に失敗");

//録音開始
hr = dictationGrammar->SetDictationState( SPRS_ACTIVE );
if ( FAILED(hr) ) throw RComException(hr , "SetDictationState に失敗");

puts("go!");
CSpEvent event;

//録音が終わるまで大待機
hr = RecoCtxt->WaitForNotifyEvent(INFINITE);
if ( FAILED(hr) ) throw RComException(hr , "WaitForNotifyEvent に失敗");

hr = event.GetFrom( RecoCtxt );
if ( FAILED(hr) ) throw RComException(hr , "GetFrom に失敗");

//認識した結果
ISpRecoResult* result;
result = event.RecoResult();

//認識した文字列の取得
CSpDynamicString dstrText;

hr = result->GetText(SP_GETWHOLEPHRASE, SP_GETWHOLEPHRASE, TRUE, &dstrText, NULL);
if ( FAILED(hr) ) throw RComException(hr , "録音したテキストの取得に失敗しました");
string ResultString = W2A(dstrText);

認識した結果が、ResultString に入ります。


wave から認識させるには?

CLSID_SpSharedRecognizer ではなくて、 CLSID_SpInprocRecognizer からオブジェクトを作成し、 BindToFileします。

USES_CONVERSION;
HRESULT hr;

CComPtr Engine; // 認識エンジンオブジェクト
CComPtr RecoCtxt;
// 認識エンジンオブジェクトの作成

// CLSID_SpSharedRecognizer マイクから録音するとき?
// CLSID_SpInprocRecognizer Waveから変換するとき?

/* これを
hr = Engine.CoCreateInstance(CLSID_SpSharedRecognizer);
if(FAILED(hr)) throw RComException(hr , "CLSID_SpSharedRecognizer 構築 に失敗");
*/
///こういう風に書き換える---------------------
CComPtr cpStream;
hr = Engine.CoCreateInstance(CLSID_SpInprocRecognizer); //CLSID_SpSharedRecognizerではないよ

if(FAILED(hr)) throw RComException(hr , "CLSID_SpInprocRecognizer 構築 に失敗");
hr = cpStream.CoCreateInstance(CLSID_SpStream);

if(FAILED(hr)) throw RComException(hr , "CoCreateInstance CLSID_SpStream に失敗");
hr = cpStream->BindToFile( L"c:\\test.wav" , SPFM_OPEN_READONLY , NULL , NULL, SPFEI_ALL_EVENTS);

if(FAILED(hr)) throw RComException(hr , "BindToFile に失敗");
hr = Engine->SetInput( cpStream, TRUE);

if(FAILED(hr)) throw RComException( Engine , CLSID_SpSharedRecognizer , hr , "SetInput に失敗");
/// ------------------------

// 認識コンテクストオブジェクトの作成

hr = Engine->CreateRecoContext(&RecoCtxt);

if(FAILED(hr)) throw RComException(hr , "CreateRecoContext に失敗");
hr = RecoCtxt->SetNotifyWin32Event();

if ( FAILED(hr) ) throw RComException(hr , "SetNotifyWin32Event に失敗");
hr = RecoCtxt->SetInterest(SPFEI(SPEI_RECOGNITION), SPFEI(SPEI_RECOGNITION));

if ( FAILED(hr) ) throw RComException(hr , "SetInterest に失敗");
hr = RecoCtxt->SetAudioOptions(SPAO_RETAIN_AUDIO, NULL, NULL);

if ( FAILED(hr) ) throw RComException(hr , "SetAudioOptions に失敗");


CComPtr dictationGrammar;
//メインとなる文法の作成

hr = RecoCtxt->CreateGrammar(0, &dictationGrammar);

if ( FAILED(hr) ) throw RComException(hr , "CreateGrammar に失敗");
hr = dictationGrammar->LoadDictation(NULL, SPLO_STATIC);

if ( FAILED(hr) ) throw RComException(hr , "LoadDictation に失敗");
//録音開始

hr = dictationGrammar->SetDictationState( SPRS_ACTIVE );

if ( FAILED(hr) ) throw RComException(hr , "SetDictationState に失敗");

puts("go!");
CSpEvent event;
//録音が終わるまで大待機

hr = RecoCtxt->WaitForNotifyEvent(INFINITE);

if ( FAILED(hr) ) throw RComException(hr , "WaitForNotifyEvent に失敗");
hr = event.GetFrom( RecoCtxt );

if ( FAILED(hr) ) throw RComException(hr , "GetFrom に失敗");
//認識した結果

ISpRecoResult* result;

result = event.RecoResult();
//認識した文字列の取得

CSpDynamicString dstrText;

hr = result->GetText(SP_GETWHOLEPHRASE, SP_GETWHOLEPHRASE, TRUE, &dstrText, NULL);

if ( FAILED(hr) ) throw RComException(hr , "録音したテキストの取得に失敗しました");

string ResultString = W2A(dstrText);



認識した結果が、ResultString に入ります。

音声認識のテストは、音がうるさいので、引きこもりが最も活動的になる夜にやりにいくですからねー。

録音した wav を使ってテストすれば、ご近所からも不審者と思われずに大丈夫です。



マイクからXMLで指定したルールにより認識するには?

USES_CONVERSION;
HRESULT hr;

CComPtr Engine; // 認識エンジンオブジェクト
CComPtr RecoCtxt;
// 認識エンジンオブジェクトの作成

// CLSID_SpSharedRecognizer マイクから録音するとき?
// CLSID_SpInprocRecognizer Waveから変換するとき?

hr = Engine.CoCreateInstance(CLSID_SpSharedRecognizer);

if(FAILED(hr)) throw RComException(hr , "CLSID_SpSharedRecognizer 構築 に失敗");

// 認識コンテクストオブジェクトの作成

hr = Engine->CreateRecoContext(&RecoCtxt);

if(FAILED(hr)) throw RComException(hr , "CreateRecoContext に失敗");
hr = RecoCtxt->SetNotifyWin32Event();

if ( FAILED(hr) ) throw RComException(hr , "SetNotifyWin32Event に失敗");
hr = RecoCtxt->SetInterest(SPFEI(SPEI_RECOGNITION), SPFEI(SPEI_RECOGNITION));

if ( FAILED(hr) ) throw RComException(hr , "SetInterest に失敗");
hr = RecoCtxt->SetAudioOptions(SPAO_RETAIN_AUDIO, NULL, NULL);

if ( FAILED(hr) ) throw RComException(hr , "SetAudioOptions に失敗");


CComPtr dictationGrammar;
//メインとなる文法の作成

hr = RecoCtxt->CreateGrammar(0, &dictationGrammar);

if ( FAILED(hr) ) throw RComException(hr , "CreateGrammar に失敗");
//録音開始

/*これを
hr = dictationGrammar->SetDictationState( SPRS_ACTIVE );
if ( FAILED(hr) ) throw RComException(hr , "SetDictationState に失敗");
*/

///こういう風に書き換える---------------------


//ユーザ指定ファイルからのロード

hr = dictationGrammar->LoadCmdFromFile( L"c:\\test.xml" ,SPLO_STATIC);

if ( FAILED(hr) ) throw RComException(hr , "LoadCmdFromFile に失敗");
//録音開始

hr = dictationGrammar->SetRuleState(NULL, NULL, SPRS_ACTIVE );

if ( FAILED(hr) ) throw RComException(hr , "SetRuleState に失敗");

////--------------------------------------




puts("go!");
CSpEvent event;
//録音が終わるまで大待機

hr = RecoCtxt->WaitForNotifyEvent(INFINITE);

if ( FAILED(hr) ) throw RComException(hr , "WaitForNotifyEvent に失敗");
hr = event.GetFrom( RecoCtxt );

if ( FAILED(hr) ) throw RComException(hr , "GetFrom に失敗");
//認識した結果

ISpRecoResult* result;

result = event.RecoResult();
//認識した文字列の取得

CSpDynamicString dstrText;

hr = result->GetText(SP_GETWHOLEPHRASE, SP_GETWHOLEPHRASE, TRUE, &dstrText, NULL);

if ( FAILED(hr) ) throw RComException(hr , "録音したテキストの取得に失敗しました");

string ResultString = W2A(dstrText);




//追加------------------------------

//認識に XMLを使用した場合、代入された結果を得る.

map
ResultMap; //これに結果を代入する

SPPHRASE *pPhrase;

event.RecoResult()->GetPhrase(&pPhrase);

const SPPHRASEPROPERTY *pProp;

for (pProp = pPhrase->pProperties; pProp; pProp = pProp->pNextSibling)

{

string a = W2A(pProp->pszName);

ResultMap[ W2A(pProp->pszName) ] = W2A(pProp->pszValue);

}

CoTaskMemFree(pPhrase);

///---------------------------------

認識した結果が、ResultString に入ります。
また、 XML で指定した名前と結果の配列が ResultMap に格納されます。
PHP でいう _POST みたいな感じで格納されるといえばわかりやすいでしょうか。

ここら辺は、http://julius.sourceforge.jp/sapi/index.html を参考にしました。
ありがとうございました。

マイクから自由単語で認識した結果を wav で保存するには?

USES_CONVERSION;
HRESULT hr;

CComPtr Engine; // 認識エンジンオブジェクト
CComPtr RecoCtxt;
// 認識エンジンオブジェクトの作成

// CLSID_SpSharedRecognizer マイクから録音するとき?
// CLSID_SpInprocRecognizer Waveから変換するとき?

hr = Engine.CoCreateInstance(CLSID_SpSharedRecognizer);

if(FAILED(hr)) throw RComException(hr , "CLSID_SpSharedRecognizer 構築 に失敗");

// 認識コンテクストオブジェクトの作成

hr = Engine->CreateRecoContext(&RecoCtxt);

if(FAILED(hr)) throw RComException(hr , "CreateRecoContext に失敗");
hr = RecoCtxt->SetNotifyWin32Event();

if ( FAILED(hr) ) throw RComException(hr , "SetNotifyWin32Event に失敗");
hr = RecoCtxt->SetInterest(SPFEI(SPEI_RECOGNITION), SPFEI(SPEI_RECOGNITION));

if ( FAILED(hr) ) throw RComException(hr , "SetInterest に失敗");
hr = RecoCtxt->SetAudioOptions(SPAO_RETAIN_AUDIO, NULL, NULL);

if ( FAILED(hr) ) throw RComException(hr , "SetAudioOptions に失敗");


CComPtr dictationGrammar;
//メインとなる文法の作成

hr = RecoCtxt->CreateGrammar(0, &dictationGrammar);
if ( FAILED(hr) ) throw RComException(hr , "CreateGrammar に失敗");

hr = dictationGrammar->LoadDictation(NULL, SPLO_STATIC);
if ( FAILED(hr) ) throw RComException(hr , "LoadDictation に失敗");

//録音開始
hr = dictationGrammar->SetDictationState( SPRS_ACTIVE );
if ( FAILED(hr) ) throw RComException(hr , "SetDictationState に失敗");

puts("go!");
CSpEvent event;

//録音が終わるまで大待機
hr = RecoCtxt->WaitForNotifyEvent(INFINITE);
if ( FAILED(hr) ) throw RComException(hr , "WaitForNotifyEvent に失敗");

hr = event.GetFrom( RecoCtxt );
if ( FAILED(hr) ) throw RComException(hr , "GetFrom に失敗");

//認識した結果

ISpRecoResult* result;

result = event.RecoResult();
//認識した文字列の取得

CSpDynamicString dstrText;
hr = result->GetText(SP_GETWHOLEPHRASE, SP_GETWHOLEPHRASE, TRUE, &dstrText, NULL);
if ( FAILED(hr) ) throw RComException(hr , "録音したテキストの取得に失敗しました");

string ResultString = W2A(dstrText);


//追加------------------------------

CComPtr ResultStream;
CComPtr voice;

hr = RecoCtxt->GetVoice(&voice);
if(FAILED(hr)) throw RComException(hr , "GetVoice に失敗");

hr = event.RecoResult()->GetAudio( 0, 0, &ResultStream );
if ( FAILED(hr) ) throw RComException(hr , "GetAudio に失敗しました");

CComPtr cpWavStream;
CComPtr cpOldStream;
CSpStreamFormat OriginalFmt;
voice->GetOutputStream( &cpOldStream );
OriginalFmt.AssignFormat(cpOldStream);

hr = SPBindToFile( L"C:\\output.wav",SPFM_CREATE_ALWAYS, &cpWavStream,&OriginalFmt.FormatId(), OriginalFmt.WaveFormatExPtr() )
voice->SetOutput(cpWavStream,TRUE);

hr = voice->SpeakStream( ResultStream , SPF_DEFAULT, 0 );
if ( FAILED(hr) ) throw RComException(hr , "SpeakStream に失敗しました");
///---------------------------------


あなたがコンピュータさまに、話し掛けたキモイ声が、 C:\output.wav に保存されます。




WindowsXPの人は SAPI 5.1 ぐらいが入っているから何もしなくてもいいけど、
Windows2Kの人は、 SAPIが入っていない?? っぽいんで、
http://www.microsoft.com/downloads/details.aspx?FamilyId=5E86EC97-40A7-453F-B0EE-6583171B4530&displaylang=en#filelist
からダウンロードして入れるといいよ。

上のドキュメント書いているときは、 SAPI4 で試しているので、5で動くかは謎。後で確認するかも。
posted by rti at 17:08| Comment(1) | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

C# eval先から自分の関数を呼び出させる

あんまりにも面白かったので作ってみた。

動的に 1+1+自分のクラスのAAAの値を求める。
サンプルでは、 AAA=13 なので、 1+1+13=15 と表示される。

自分

動的に作成したルーチン

自分の関数


これ使えば、簡易スクリプト言語なんて不要ぢゃねーの??

参考
文字列の計算式の計算結果を取得する
Evaluating Mathematical Expressions by Compiling C# Code at Runtime


using System;
using System.Collections.Generic;
using System.Text;

using System.CodeDom.Compiler;
using System.Reflection;

namespace @ref
{
//int AAA を保護するクラス
public class Himitsu
{
private int AAA;

public int getAAA()
{
return this.AAA;
}

public Himitsu(int inAAA)
{
this.AAA = inAAA;
}
};

public class Program
{
static private Himitsu HimitsuInstance;

public static int MyCallBack()
{
return HimitsuInstance.getAAA();
}
static void Main(string[] args)
{
//計算するためのコード
string source = @"
public class MainClass
{
public static double EVal()
{
int aaa = @ref.Program.MyCallBack(); //秘密の数字にアクセス
return 1+1+aaa;
}
}";

//秘密の数字13を渡す.
HimitsuInstance = new Himitsu(13);

//コンパイルするための準備
CodeDomProvider cp = new Microsoft.CSharp.CSharpCodeProvider();
ICodeCompiler icc = cp.CreateCompiler();
CompilerParameters cps = new CompilerParameters();
CompilerResults cres;
//メモリ内で出力を生成する
cps.GenerateInMemory = true;
cps.ReferencedAssemblies.Add("system.dll");
cps.ReferencedAssemblies.Add("ref.exe"); //自分自身のexe名
//コンパイルする
cres = icc.CompileAssemblyFromSource(cps, source);
if (cres.Errors.Count > 0)
{
string errors = "Compilation failed:\n";
foreach (CompilerError err in cres.Errors)
{
errors += err.ToString() + "\n";
}
Console.WriteLine(errors);
return;
}
//コンパイルしたアセンブリを取得
Assembly asm = cres.CompiledAssembly;
//MainClassクラスのTypeを取得
Type t = asm.GetType("MainClass");
//EValメソッドを実行し、結果を取得
double d = (double) t.InvokeMember("EVal",
BindingFlags.InvokeMethod,
null,
null,
null);

//結果を表示
Console.WriteLine(d);
}
}
}
posted by rti at 00:55 | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2007年04月17日

メモ プログラムの中でプログラムを実行する

文字列の計算式の計算結果を取得する

面白い。
Microsoft Script Controlを利用する方法については、サクラエディタが実装していると思う(たぶん)。
C++で書くと死ぬほど面倒くさくてまわりっくどい。

こーゆーのを見ていると、
Windows環境での自作スクリプトとか、Luaとかいらなくねぇ?って感じになるね。

自前スクリプトだと文法覚えるの面倒だし。
エラー処理がいい加減で、エラーメッセージが異常にわかりづらかったりするし。
スクリプト自体にバグがあったりしたら地獄だし。
何より、デバッカーがない!! っての最大の問題だ。


Windows環境で、何らかのスクリプトが欲しくて、自前で実装とかしているやつがいたら今すぐそのコードを破棄するべきだ。
その方が世の中平和になるし、何より楽で良い。
posted by rti at 23:26 | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

ロマサガ2 4000年プレー

ロマンシングサガ2 4000年プレーをやった。

イベントポイント 8ポイント + 字幕 + 250回(?)の戦闘をやれば、250年飛ぶ。
これを、14回繰り返せば 4000年代に飛ぶことが出来る。

目標


・4000年
・冥を取得する。
・サラマンダー以外のすべてを仲間にする。

参考


4000年裏マニュアル
ロマサガ2戦利品リスト/4000年考察

ルート



1000年代


・封印の地封印<1>
・クジンシータイプ1撃破<4> (ジュラールで撃破すること +1年)
・ゼラチナスマター退治<1>
・ルドン地方<4>(字幕)

この時点で分身剣まで覚えておくと楽。
絶対にゴブリンの穴をクリアしないこと!! (これのせいで一度やり直した)


1250年代


・東のダンジョン<1>
・カンバーランド<8>(字幕) トーマ88

この時点で乱れ雪月花等の最強技を覚えておくと後が楽。
魔女の祠で買物をすると、メルー砂漠を教えてくれる。
この時点で人魚と踊ってはいけない。


1500年代


・クィーン退治<3>
・サバンナ字幕<1>(字幕)
・コムルーン溶岩固め<3>
・コムルーン字幕<1>(字幕)


1750年代


・ディープワン退治<1>
・運河要塞<8>(字幕)


2000年代


・南のダンジョン<4>
・武装商船団問題<4>(字幕) (ラピスピがほしい)

運河要塞をクリアした次の年にクリアしないとギャロンが反乱を起こしてしまう。

ついでに、運河要塞をクリアした次の年でカンバーランドをクリアしないと滅亡する(?)。
だから、カンバーランドは運河要塞をクリアする前に、遠回りをしてクリアしておく。

全般的にだが、安全にレベルを上げるには、ワイリンガ湖が一番楽。
宿屋が近いし、戦場と宿屋間のワールドマップの切り替えが無い。
魚系の強敵が精神攻撃を使ってこないのも助かる。


2250年代


・人魚イベント (字幕)

人魚と踊った皇帝を死なせてはダメ。
皇帝継承をしてしまうと人魚イベントは消滅する。

サバンナ字幕を出さないと卵の殻を取得できない


2500年代


・ギャロン追放<4>
・ギャロン追放字幕<1>(字幕)
・詩人のどうくつ<1>
・ゴブリンの穴<1>
・ナゼール字幕<1>(字幕)

詩人のどうくつにダンタークがいる場合は、
詩人のどうくつのダンダークで全滅すると、通常のボスに変えることが出来る。


2750年代


・メルー地方<4>(字幕)(move)
・ギャロン亡霊退治<4>
・南ロンギット字幕<1>(字幕)

塔をクリアしてから、移動湖でノエルと和解して、デザートガードを仲間にする。
ここでギャロンを放置すると、スービエが出てきてしまうので注意。

3000年代


・ボクオーン打倒<8>(字幕)

良い仕事があるで撃破するとステップから敵が消える。
ボクオーンを先に撃破する理由は、ノーマッド女のツインテールに萌えるから、文句あっか。


3250年代


・ワグナス撃破<8>(字幕)

早めに雪の遺跡に行きたいし。


3500年代


・ロックブーケ撃破<8>(字幕)


3750年代


・ダンターグ撃破(子供と子ムー)<8>
・子供と子ムー字幕<1>(字幕)

ダンタークを倒した皇帝が子供を忘れる前に死亡してしまった場合、
子供が自力で戻ってしまい、字幕イベントが消滅するので注意すること。

最終皇帝のパーティー選抜をやるときには、
皇帝に魔石の指輪を装備させて宿に泊まりまくれば、仲間のLPを1に出来る。


4000年代


最終皇帝
・クィーン撃破
・クジンシー撃破
・ノエル撃破
・スービエ撃破


最終データ



最終年:4014年
ティセ最終皇帝剣:50槍:50斧:50弓:50体:50水:50土:50天:50
ユノーインペリアル女剣:50槍:50斧:50弓:0体:50火:50土:50天:50
ハンニバルインペリアル男剣:50槍:50斧:50弓:0体:50火:50土:50天:50
コウメイ軍師剣:50槍:0斧:50弓:0体:50火:50土:50天:50
ソウジイーストガード剣:50槍:50斧:50弓:0体:50火:50土:50天:50


軍師も筋トレしたので、千手観音で2000ぐらい出すよ。
冥をとったけどやっぱり使い道が無かった。

サラマンダーがいれば、アウ 腕24 を仲間にしているんだろうが、いないのでユノーで代理をさせます。
ソウジは腕力は弱いけど、素早さが高いので加えた。


735 名前: 腕力ベスト5 投稿日: 2000/07/28(金) 02:37

各クラスのトップを選んでみる。
同じクラスで同じ数値の場合は敏捷度の高いほうだけ。

1位 :インペリアルガード(M)、ハンニバル・腕25・敏11
2位 :サラマンダー     、アウ・腕24・敏11
3位 :インペリアルガード(F)、ユノー・腕23・敏11
同3位:格闘家        、ベイダー・腕23・敏10
5位 :イーストガード    、ソウジ・腕22・敏24
同5位:ホ−リーオーダー(M) 、バランタイン・腕22・敏12
【ロガサガ2を思い出でだけでクリアする】




744 名前: 魔力のベスト5 投稿日: 2000/07/29(土) 03:53

1位 :軍師・コウメイ         ・魔25・敏25
2位 :イーリス・スカイア       ・魔24・敏21
同2位:ホ−リーオーダー(F)・ソフィア・魔24・敏12
4位 :宮廷魔術師(M)・ライブラ   ・魔23・敏12
5位 :フリーメイジ(M)・ヴェガ   ・魔22・敏17
同5位:宮廷魔術師(F)・ルビー    ・魔22・敏16
同5位:フリーメイジ(F)・アイリス  ・魔22・敏15
【ロガサガ2を思い出でだけでクリアする】


ザコ戦は、ストーンシャワー連射でほぼ勝てる。(スライム系除く)
ボスクラスには、クリムゾンフレアと無名剣。

感想


大変でした。。。。
実は2回やり直してます。

一度目は、運河要塞→カンバーランドって進めて武装商戦を併合する前にギャロンが反乱をおこしたため。

二度目は、ゴブリンの穴を攻略してしまったため。
何とかリカバリーしようとあれこれプランを考えたんだけど、
サバンナ字幕を出さないと卵の殻が手に入らないためやり直し。

それを反省して上のプランを立てました。
無計画に進めて達成できるほど 4000年は甘くない!
posted by rti at 02:36 | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2007年04月16日

ファザーズ設立?

エープリルフールはもう終わったと思っていたんだけどなぁ。


4月15日(ブルームバーグ):15日付の毎日新聞は、日本証券業協会が、東京証券取引所やジャスダック市場などで上場廃止になった株式を売買する市場を創設する方針と報じた。日証協は近く作業部会を設けて検討に入る。
日証協:上場廃止株の市場創設へ−投資家保護でカネボウ株など取引も


ファザーズ市場がマジでできるのか。
上場廃止になるぐらいの株だから、そうとうなワケアリな会社なわけで、、、循環売買、粉飾決算、債務超過 etc...
いわくつきの株を飛び交う、投機家の戦場になりそうな。
それはそれで面白いか。

つーか、投資家保護とか言っているけど、
上場廃止まで最低一ヶ月ぐらい猶予あるでしょ。
そのときに売らなかったヤツが悪いだけなんぢゃないのかと。
整理ポストに移されてから、一回も寄らなかった銘柄であったっけ?

これからは、整理に移されてから、ファザーズに上場できるかどうかでリバが決まりそうだな。
余計にマネーゲームが加熱しそうな感じがする。
それと、インサイダーも。
posted by rti at 15:09 | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2007年04月14日

C# Double.IsNaN のベンチ

どれくらい遅いかベンチとって見ました。

結果
時間(速度)
Double <=00:00:10.0156250
Double IsNaN00:00:03.9062500
Double IsPositiveInfinity00:00:09.6250000
Int <=00:00:01.2968750
Int64 <=00:00:02.4687500


int は Double より3倍以上早い。赤くないのに3倍以上も早い。
整数型はやっぱ凄いな。

Double <= が意外に遅い。
Double.IsNaN は健闘している。
Double IsPositiveInfinity は微妙なところ。Double <= より数字は良いので責めるべきではないけどな。

Int64 は intより2倍ぐらい遅いけど、 Double よりマシなんで、 Double を Int64の固定少数で置き換えるテクニックはまだ有効らしい。ただ、面倒だからやらないけどさ。

結論。
Double が遅いのはあたりまえなんであきらめましょう。
大量に Double の演算をしなければならないルーチンを見直すべき。


検証に利用したコード

using System;
using System.Collections.Generic;
using System.Text;

namespace DoubleBench
{
class TimeWatcher : IDisposable
{
private string Message;
private DateTime StartTime;

public TimeWatcher(string inMessage)
{
this.Message = inMessage;
this.StartTime = DateTime.Now;
}
public void Dispose()
{
Console.WriteLine("{0}:{1}", this.Message, DateTime.Now - this.StartTime);
}
}

class Program
{
static void Main(string[] args)
{
int loopCount = 1000000000;
{
Double a = 0;
using( TimeWatcher t = new TimeWatcher("Double <=") )
{
for (int i = 0; i < loopCount; i++)
{
a += 1;
if (a <= -1)
{
Console.WriteLine("<=!"); //絶対成立しないけど最適化防止ぐらいにはなるかな?
}
}
}
}
{
Double a = 0;
using( TimeWatcher t = new TimeWatcher("Double IsNaN") )
{
for (int i = 0; i < loopCount; i++)
{
a += 1;
if (Double.IsNaN(a))
{
Console.WriteLine("NaN!"); //絶対成立しないけど最適化防止ぐらいにはなるかな?
}
}
}
}
{
Double a = 0;
using( TimeWatcher t = new TimeWatcher("Double IsPositiveInfinity") )
{
for (int i = 0; i < loopCount; i++)
{
a += 1;
if (Double.IsPositiveInfinity(a))
{
Console.WriteLine("IsPositiveInfinity!"); //絶対成立しないけど最適化防止ぐらいにはなるかな?
}
}
}
}
{
int a = 0;
using( TimeWatcher t = new TimeWatcher("Int <=") )
{
for (int i = 0; i < loopCount; i++)
{
a += 1;
if (a <= -1)
{
Console.WriteLine("<=!"); //絶対成立しないけど最適化防止ぐらいにはなるかな?
}
}
}
}
{
Int64 a = 0;
using( TimeWatcher t = new TimeWatcher("Int64 <=") )
{
for (int i = 0; i < loopCount; i++)
{
a += 1;
if (a <= -1)
{
Console.WriteLine("<=!"); //絶対成立しないけど最適化防止ぐらいにはなるかな?
}
}
}
}
}
}
}
posted by rti at 07:58 | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

Let's Trade!

Let's Trade!

ロマサガ3のミニゲームトレードを元に作られたフリーゲーム。
Let's Trade!.jpg

ロマサガ3はトレードと音楽がすべてで他は要らないと考えている俺様にとっては神のようなゲーム。

何で今までこのゲームのことを気がつかなかったんだろうか。
コニコニ動画にゲーム画像がアップロードされていて気が付いた。

昔は、フリーゲーム系ページを毎日のようにウォッチしていたのに、
ちょっと油断した好きにこれだ。

当然のように、サルのようにプレーしてNormal Mode クリアした。
大変だった。

資金力だけではなく、かけひきをうまく買わないと勝てない。
資金力だけと「ネマワシ」だけで勝てるロマサガのトレードとは違って難しい。

それと、やっぱ、買収は一気食いでしょう。
相手のグループを少しづつ引っぺがして弱体化させながらじわじわやるぐらいだったら、親会社と真正面からぶつかってグループ一気食い。伸るか反るかの大勝負って好きだ。現実世界でやると100%樹海行きなんだろうけどな。

次はハードモード?
posted by rti at 03:20 | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2007年04月11日

C# Double.IsNaN と Double.IsPositiveInfinity って重いの?

Omega Chartのプロファイルをフリーのプロファイラ NProf で取ってみた所、

Double.IsNaN
Double.IsPositiveInfinity

ってところが実行時間ででかくなっていた。
両者とも、Data.cs の TradeData.GetValueにある。
#自働売買シュミレーションをさせたときの結果

よく呼び出される、ネイティブの関数だから実行時間が大きくなったと考えることもできるけどな。

これらはネイティブコードなので、Double.IsNaN と Double.IsPositiveInfinity がどんな実装になっているかはわからない。
単純なビット比較で実装されていればいいんだけどな。
NaN フラグと、PositiveInfinityフラグを 論理和で見るぐらいであってほしい。
面倒な比較をやられると困るなぁ。

この関数の速度について説明している人や議論している人は今の所居なさそうなんだけど、どうなのかな。
浮動小数点計算なんてやる人たちが速度を気にするわけないか。
posted by rti at 22:48 | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

VT Trader API、、せっかくあってもログインできないんぢゃ意味ないよね

VT Trader API っていう大層なものがあるんだけど、
現在公開されるている 1.0.3 では日本語環境だとログインに失敗するらしい。
実際やってみたら、見事に失敗した。

んで、テスト版の 1.0.4 beta2 でも、治っているかーと思いきややっぱりダメらしい。

せっかくAPIって便利なものがあっても、これぢゃあ意味がない。
そもそも、なんで言語の環境で問題が出るんだ?

2バイト圏というってもログイン情報に2bytes使っていないし、
C#だったら、UNICODE ぢゃん。
謎杉。
posted by rti at 04:09 | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2007年04月10日

C# 俺にconstを使わせろ

何で C# は C++のコンストをまともに移植しなかったんだろうか。
変数にはreadonly とかへなちょこなヤツがあるみたいだが、
メソッドに const は付けられない。
このままでは、リファクタリングがやりにくくて仕方が無い。

これは、言語仕様の欠陥だ。
C#は大規模開発に向かない言語だと俺から烙印を押されても仕方あるまい。

思えば、C#を作ったと思われる元ボーランドビルダー開発陣は const の付け方がアホだったよな。
AnsiString の c_str() が const ついていなくて、失笑をかったのを忘れたか?
やつらは、const をまともに扱えないのではないだろうか。
posted by rti at 20:42 | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

誰が殺した

Microsoftを殺したのは誰?
俺様が思うに自壊のように思える。

1.
Vistaプロジェクトが迷走して開発者が愚痴をいうようになった。
エンジニアが誇れるような技術革新で楽しい企業ではなくなった。


2.
配当を出すようになった。
経営層も成長の鈍化を理解しているような。


3.
10年ぐらいの下位互換性のために動きが鈍った?
Windowsの資産であって同時にお荷物であるサードパーティのソフトとの互換性を取りつつ最新の機能を追加する苦労は想像を絶するものがありそう。
さらにバグ修正や多言語対応やらでバージョン間の互換性が取りにくくなって、テストは月単位の時間がかかるわけだ。

3は、Vista遅延の原因になったような気がする。
Windowsの歴史がWindowsに足かせをはめているんだろうな。
歴史が薄い新興やAppleのように切り捨てる所はそれがないから機動力がある。
スクラップ・アンド・スクラップビルドが出来るんならいいんだろうがなぁ。

Googleとかも山のように機能を追加しているので、
後数年後くらいにこの苦労を味わうんだろうか。
Webアプリだからそれほどでもないのかな。


ただ、マイクロソフトは、いまだに大量の現金も抱えているし、優秀な人もたくさんいるだろうから、舵取りをちゃんとやれば復活しそうな。
ラピュタみたいな感じ、何度でも蘇るさ。
posted by rti at 09:20 | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

音声検索


面白そう。


このサービスは、Googleが米国内に用意した無料通話番号に電話することによって利用できる。例えば「pizza」と電話に向かって話すと、地元のピザ屋に自動的に電話がつながるという具合だ。携帯電話から通話している場合には、検索結果をSMSで受け取ることもできる。その場合には音声で「text message」と話せばよい。
米Google、電話による音声認識検索サービスの実験を開始


同じくGoogleやニワンゴがやっているみたいに、多彩なキーワードに対応できれば面白いかな。
ケータイの貧弱なインターフェースで文字入力するのが大変な世代(俺含む)だと、文字ではなく、音声で検索してくれるサービスはありがたい。
googleに向かって「めしどこかたのむ」って聞けるようになる日も近いかも。
posted by rti at 08:42 | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする