Androidスマートフォン購入。10年くらいDocomo-NECだったのでN-04C。CASIOの電子手帳-初代ZAURUS-Palm-Windows Mobileと15年以上乗り換えてきたけどここまできてるんですね。Windows Phoneが日本で出たらまた乗り換えるかも知れないけど。

でAndroidなんだけど,要はりなざう(Linux ZAURUS)に電話機能が付いただけみたいな,SHARPの目の付け所がシャープすぎたみたいな。でも性能とかアプリとかは昔のPDAの比じゃないですね。

ということで何か面白いことができないか考え中。


最初にかけた電話はウィルコムへの解約申込み。8年間AirEdgeにお世話になったが,自分のところも実家も光,モバイルもスマートフォンになってついに使うことはなくなった。丁度2年契約も来月中旬までだし丁度いい。

帰りの駅は入場制限ですごい状態。始発駅で1番線にたくさん並んでるので2番線に並んだのだが,その後来た電車が2番線。駅員の放送で「2番線が先に来ちゃった。2番線に待ってる人はそのままで1番線の人が先に乗ってね。テヘ」みたいな。この混雑っぷりでそんなことを要求する駅員もスゴイが,何の混乱もなくそれに従う人々もスゴイ。その後1番線に電車が来て1番線側の人を乗せてたのはさすがに文句が出てたけど。

えっと,何がプログラマ日記かというと,待ち行列理論?

なるほど,場所を言わないとなんだか被災地にいるみたいに見えますね。私は神奈川,ぱじさんは掲示板で言ってるように千葉,サーバ管理者は東京ですので,謎の物資不足以外は何の問題もありません,ていうか野菜と肉買うだけだから不足してないけど。サーバは計画停電には入ってないと思いますが,止まってたら3時間くらい待って下さい。


ここまで書いていて,そういえば! とプロバイダのページに行ってみると,「震災に伴う計画停電等による影響で、一時的にサービスが停止したり、サービス更新が遅延する可能性があります。」と書いてあった。Denasuのページが一時的に見えなかったりするかも知れませんが,3時間もすれば見えるようになるでしょう。っていうか3時間くらい非常電源あるよね。

更新も掲示板への発言もないとアレなので一応書いておこう。私とぱじ氏は無事です。サーバも無事なので管理者も無事なのだろうか。そして5日目は分かりません。

で,今日も会社へ行ったのだが,普段使っている電車が止まってて会社からも「無理してまで来るな的」な連絡があったのに,やっぱりどうにかして仕事に行くというのはすごいと思った。こういうのはすごい冷静なのに何故か買いだめに群がるのは不思議な気もするけど。なかなかパニックにはならないけどパニックになり始めると止まらないってことなのだろうか。


追記。原発の話。報道見てて謎がたくさんあったので技術的な情報を探してたら「Fukushima Nuclear Accident a simple and accurate explanation」がリンクされてて読んでみた。なんかいろいろ納得いった感じ。テレビのフリップと実際のイメージにものすごい隔たりがあるというか,テレビいい加減すぎというか,この通りだとしたら全て織り込み済みってことか。


プログラマ日記になってないですね。そういえばVisual Studio 2010 SP1が出ていた。ダウンロードはしたけどなかなか当てる気にならない。

ActiveMonitorを自分で使っていて問題があったところを更新。しばらく動作していると輝度が変わらなくなる問題とマウスをはじっこより外に移動させると不安定になる問題を修正。VMWareでモニタ4台とかやってみようと思ったけどWmiMonitorIDが取れなくて例外をはく。まあいいか。

Windows 7 SP1が公開されていたのでインストール。とりあえずdenasu公開ソフトは起動はした。

しばらくノート+外付けのマルチディスプレイにしているが,使わないときはサブディスプレイの輝度を落とせたらなあ,とか思った。つまりマウスがあるディスプレイだけ明るくて他のディスプレイは暗いという。で検索してみたけどそんなソフトは皆無だったので作ってみた。

最初,Win32 APIのSetMonitorBrightnessでできると思ってC++で作ってみたのだが,外付けのナナオはOKなもののDELLノートのディスプレイがGetMonitorCapabilitiesで失敗を返す。ヘルプだとDDC/CIに対応してないとダメって書いてあるので多分ダメなんだろう。

次にWMIのWmiMonitorBrightnessでできそうなのでC#で作ってみた。こっちだとDELLノートのディスプレイはコントロールできるが逆に外付けのナナオは不可。WmiMonitorIDはちゃんと2台分返してくるのだがWmiMonitorBrightnessは1つしか返ってこない。

結局,外付けの方は暗くならなくてもいいや的な感じでマウスのフックとかタスクトレイアイコンとか作って完成。まともなテストはしてないけど一応公開。ActiveMonitor

掲示板に出ている文字化けの話。12/14に出たWindows UpdateKB2467659で,JISコードの自動判定がなくなったため。インターネット初期の時代,8bitコードを処理できないサーバがあるため文字コードは必ずJISにせよとの暗黙の了解があった。わけだが,このUpdateによってそれは崩壊し,インターネット初期からあるページは軒並み文字化けするようになっているはず。とりあえずUTF-8にするとして,全ページ修正が必要なのでついでにXHTML化するか。

サポート掲示板の「new」表記がおかしくなった。いろいろ調べてみるとCokkieがきいていないようなので見直してみると,有効期限が「Fri, 31-Dec-2010 00:00:00 GMT」になっている。2000年くらいに適当に決めたんだろうけどこんなところで問題が出てくるとは。あれから10年もたってるのか。

ちょっと前までVector+MicrosoftでWindows 7 アプリ投稿キャンペーンというのをやっていた。Windows 7の機能を使ったアプリケーションを登録するとMSのページで紹介されるというもので,そんなの開発者しかチェックしないよね的な気がしながらPurentroをポチっておいた。最終的に150件という多いのか少ないのか分からない件数が集まってますね。でキャンペーンプレゼント当選のお知らせが届いていたのだが,既にプレゼントのページが消されているので何がもらえるのか分からない。

Android調査。NDKを使うとネイティブアプリケーションを作れるのだが,その中にSocketも含まれていたのでWeatherTyping移植できるかも? とか思ったのだが,やってみるとPermission Denied。どうやらルートっぽい権限がないと動かせないらしい。ルート化して動かして下さいなんてアプリ怪しすぎるし。Windows Phoneもそうだけど,PDAのときと違って一般人を対象にしているせいか制約がきつい。

ぱじ氏が飽きたとのことなのでロビー第1サーバは終了。そろそろウェザタイロビーの役割も終わってきた感じだし第2サーバだけでいいかな。

CNETのdownload.comに登録したら他のサイトからも「登録しましたが何か?」的なメールが届いた。日本でもVectorに登録するといろいろ登録されるのでこの辺は同じか。

Softpedia。Purentro。紹介用にコメントとかスクリーンショットもちゃんと書いてる。なんかついでにWorld Testerも登録されてた。わざわざDenasuページからひろってきてるのか。

Brothersoft。Purentro。これはCNETそのままパクってる感じ。

他にアラビア語のサイトとかあったけどよく分からない。

Purentro。折角英語版を作ったので海外サイトに登録しよう! てなわけでググってみるとCNETのdownload.comが最大手らしい。登録方法が非常に分かりにくいが,upload.comという別サイトで登録するようだ。適当に英語で説明を書いて申請したところ,アカウント登録に1日,作者登録に1日,ソフト登録に1日で完了。CNETのPurentroページ。とりあえずサポート掲示板を英語対応しておいた。

なんか気が向いたのでWPF練習用にファイル検索ツールを作り始めた。これ公開していいんだろうか。

大学のOB会。某シェアウェアで生計を立てている先輩といろいろ話せて興味深かった。ウェザタイでiPhone vs Android対戦できたら面白いかもみたいな話をしたり。作るのは簡単なんだろうけど,多分P2Pじゃできなくてサーバクライアント方式になるから,今のサーバでは無理だろうなあ。どうしても赤字前提でレンタルサーバになってしまう。

開発が終わって日記に書くネタがないので適当な話を。掲示板へのSPAM投稿をサポート掲示板(保留)にコレクションしているのだが,投稿数Top10を発表。

順位 ホスト名 投稿数
1 oska.nt.fttd4.ppp.infoweb.ne.jp 1984
2 starnet.md 397
3 osaknt01.ap.so-net.ne.jp 288
4 sweb.ru 36
5 locaweb.com.br 33
6 lxa.perfora.net 29
7 kasserver.com 23
8 pipni.cz 22
9 maxim.net 21
10 in-solve.ru 20

一時期starnetさんをよく見かけたのだが,最近は完全にoska.ntさんのペース。これからの追い上げに期待。あと意外にロシアが多い。

長かった開発も一段落で次は何しよう。まずはWindows Phone 7の開発について調査。Silverlightならロビーくらいすぐ移植できるかな,と思ってたけど,実は現状Socketが未サポートらしく,簡単には実現できなさそう。Webサービスならいけそうだけどわざわざそんなことしないといけないのか? 次にXNAも触ってみようとしたが,Windows Phone 7用のXNA開発はDirectX10対応カードが必須。普通にWindows用ならできそうだけど…。先は長い。

「MIDI プレイヤー & 練習ソフト Purentro Ver.1.0」を公開。新作キーボード練習ソフト! といってもMIDIキーボードだけど・・・。

今回はマニュアルにおまけ情報を書けなかったのでここに書いてしまおう。


このプロジェクトは,元々10年前に某鳥の名前のファミレスでMIDIキーボード練習ソフト作ろーみたいな話があって,いつの間にか立ち消えになったもの。1年くらい前からひっそり再開して作っていたのだが,とりあえず作りたかったものができたので公開してみた。

内容としては,.midファイルを読み込んで楽譜を表示し,MIDIキーボードがあれば練習にも使えるというソフト。ということでこれを使う人はだいぶ限られそうなので環境とか何も考えずに作っている。XPは動くけど非サポート扱いにしたし,.NET 4.0必須だし,ディスプレイの解像度は1920×1200以上じゃないと厳しいし。要は自分の環境に最適化したという話。


技術的な話も。まず,マニュアルにも言い訳を書いているが,MIDIファイルは楽譜ファイルじゃないのでちょっと複雑なMIDIファイルだとお手上げ。発音のタイミングが音符の位置からずれまくるし,1つのトラックに複数のパートがあると見分けが付かないし,世にある楽譜化ソフトも相当苦労しているはずだけど,完璧なものはないですね。この辺の苦労をはっぱさんと語れたのが今回最大の収穫。そういえばはっぱさんからはiPadでやったらいいよとかメモ書き機能があるといいよとかアドバイスをもらった。次バージョンがあれば考えてみよう。音楽は何も知らないのでそういう人が近くにいると心強いですね。

あとはWPFですかね。最初はC++ Direct Drawで作ってたけど,斜め線が引けなくてDirect3Dに切り替えて,その後きれいに拡大縮小をしたくてC# WPFに切り替えた。以前Silverlightを少し触っていたときはあまり感じなかったけど,WPFを本格的にやってみるとかなり面白い。これだけの開発環境が揃っているといろいろ作りたくなってくる。Windows PhoneはSilverlight(=WPFの軽量版みたいなもの)なので,いろいろやってみたいかも。


ところでPurentroって未だに意味がわからないんですけど,どういう意味ですか?>ぱじ

いろいろあってスマートフォン開発環境を構築。Windows PhoneとAndroidとiPhone/iPad。とりあえず日本だとこの3つを押さえればいいのかな。

Windows PhoneはWindows Phone SDKを入れるとVisual StudioでSilverlight for Windows PhoneとXNA Game Studio 4.0プロジェクトを作成できるようになる。Silverlightで作ればいいのでものすごく簡単。

AndroidはWindowsにAndroid SDKを入れるとJavaで開発ができる。Eclipseを使うと割と楽に開発できる。さらにCygwinとNDKを入れると,CのソースをARM用にクロスコンパイルし,JNIで呼び出すことが可能。

iPhone/iPadはMac必須。iOS SDKをダウンロードしようとするとComing soonみたいなページにとばされてなかなかダウンロードできなかったが,なんとか構築環境。iOS SDKを入れてXcode上で開発ができる。Objective-Cなんだけど,普通のC言語でも動くのか,なあ。

結局C#/Java/Objective-Cなので共通で動くものを作ろうとするとPure C言語で作っておいてC#に移植/JNI/C言語でやることになるのかな。


ここまできて,問題は何を作るか,なんだけど。とりあえず練習として,Windows Phone 7が日本で発売されるまでにWeather Typingロビークライアントを作ってみるのもいいかな。今作っているMIDIプレイヤーはマニュアル作ったら完成なのでその間に何を作るか決めよう。

WPFで使っている自作DLLの名称を変更したのだが,どうしてもリソースファイルを旧名称でアクセスしてしまい,Not Foundになる。GrepしてみるとPropertiesResources.Designer.csとSettings.Designer.csの中に旧名称が残っている。この2つはTool Generatedで変更するなと書いてあるのだが,生成元のソースはどこにもない。確かにこのファイルを消してプロジェクトを開き直すと再生成されるのだが・・・。

てことで悩んだ結果,VSSからとってきていることが判明。いつのVisual Studioからか知らないけど,ファイルが足りなかったら勝手にVSSからとってくるようになってたのか。VSSに接続しないようにするとResources.Designer.csもSettings.Designer.csも生成されずにビルドエラーになるので,とりあえず再生成はされないと断定して直接いじることにした。

WPFで7セグメントLED(時計とかのデジタル数字)を表示したい箇所があっていろいろ調べていたのだが,なかなかいい案が見つからない。今使用しているPCにはAscenderFonts製Quartz MSってフォントが入っているけどどこでも入っているのか,どこに何を払えばプログラムに同梱できるのかよく分からないし,カスタムコントロールで画像を表示するのもつまらない。ってことでフォント自作。フリーではfontforgeってのが有名らしく,使ってみた。キーボードショートカット使うと落ちまくりつつもなんとか「0~9:/」だけを含むフォントが完成。WPFのプロジェクトにつっこんでおけばそのままリソースとして使える。フォントのインストールは不要。

たいしたものではないので公開しておこう。何にどう使ってもOKですが,何か問題があってもサポートはしません。

2010092301

ダウンロード

MIDIキーボードタイピングソフトができてきたところでそろそろテスト工程に入る。まずはXP実機で試してみる。以前VMWareで実験したときはエラーが出て実行できなかったが,実機というか.NET4.0にしたおかげか実行はできた。ただ,設定ファイルにハッシュアルゴリズムSHA256を使っていたのがXPではサポートされていないらしく設定ファイルを読むところでエラーになった。とりあえずセキュリティ的に重要なわけではないのでSHA1で我慢しておくか。

C#でMIDIキーボード入力をやってみる。midiInOpenにコールバックを登録しておけば,midiInStart/midiInStopでメッセージを受け取れる。

{
    [DllImport("winmm.dll")]
    public static extern uint midiOutOpen(
        ref IntPtr phmo,
        uint uDeviceID,
        IntPtr dwCallback,
        IntPtr dwInstance,
        uint fdwOpen);

    public delegate void CallBackDelegate(
        IntPtr hdrvr,
        uint uMsg,
        uint dwUser,
        uint dw1,
        uint dw2);
}

public class MIDIIn
{
    private Win32MIDI.CallBackDelegate _callback = null;

    public void Open()
    {
        _callback = new Win32MIDI.CallBackDelegate(CallBack);

        Win32MIDI.midiInOpen(
            ref _midiin,
            _mididevice,
            (IntPtr)Marshal.GetFunctionPointerForDelegate(_callback),
            (IntPtr)0,
            Win32MIDI.CALLBACK_FUNCTION);
    }

    private void CallBack(IntPtr hdrvr, uint uMsg, uint dwUser, uint dw1, uint dw2)
    {
        int state = (int)dw1 & 0xff;
        int data1 = (int)dw1 >> 8 & 0xff;
        int data2 = (int)dw1 >> 16 & 0xff;
    }
}

最初,C++で実装するときと同じようにCallBackをstaticメソッドにしていたのだが,インスタンスのメンバ変数を使いたくて,midiInOpenのdwInstanceにthisを渡すことを考えていた。でもthisをIntPtrに変換する方法というか変換していいのかを調べても何も情報は見つからない。最終的に「GetFunctionPointerForDelegateはthisポインタをうまいこと扱ってくれる」というような記述を見つけて,思いきってstaticを取ったらそのまま動いた。C++の発想だとstaticにしないと動かないのでメンバ関数をそのまま渡すというのは思いつきもしなかった。こんな感じで半日を無駄にしてしまった。

その後は順調に進んで,キーボード練習ソフトっぽいものはできあがった。そろそろもばもば(?)に投げてみよう。

Visual Studio 2010でWPF(というか.NET)のソースコードレベルデバッグをする方法。MSのブログに載っている2008の方法と同じだが,Tools-OptionsでDebugging-GeneralからEnable source server supportをONにし,Symbolsの一番上に「http://referencesource.microsoft.com/symbols」を追加する。なお,「http://msdl.microsoft.com/download/symbols」とは違うPDBファイルらしいので,既に設定している場合はダウンロード済みのシンボルを一旦削除する必要があるっぽい。

ちなみにWPFのソースコード自体はAvailable Source Code Componentsから落とせる。

Google マップなんかでホイールを回すとズームする機能。あれって現在マウスが指している位置はそのままで拡大率だけが変わるのだが,同じことを実装しようとすると意外に難しい。忘れそうなのでメモ。

2010090801

図は拡大率R1から拡大率R2に変更したときの例。大きな四角はマップ全体で,中の四角はビューポート。拡大率R1でマウスカーソルが絶対座標(Ax, Ay) 相対座標(Rx,Ry)にいるとき,拡大率をR2にした場合を考える。このとき,ビューのスクロール位置(Sx, Sy)をうまくいじってやれば,ビューからの相対座標(Rx,Ry)を変えずに拡大をすることができる。(Sx, Sy)の求め方は以下の通り。

(Sx', Sy') = (Ax', Ay') - (Rx, Ry)
           = (Ax, Ay) * R2 / R1 - (Rx, Ry)

でここからがWPFの場合だが,OnMouseWheelの中で以下のように実装してみた。_view(ScrollViewerなど)の中に_map(Canvasなど)を入れている前提。_viewへのGetPositionとスクロール位置はR1倍した値になり,_viewの中身へのGetPositionは拡大する前の値になるので上の式と若干異なっている。

private void OnMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
{
    double a_x = e.GetPosition(_map).X;
    double a_y = e.GetPosition(_map).Y;
    double r_x = e.GetPosition(_view).X;
    double r_y = e.GetPosition(_view).Y;

    R_2 = R1 + e.Delta;

    _view.ScrollToHorizontalOffset(a_x * R_2 - r_x);
    _view.ScrollToVerticalOffset(a_y * R_2 - r_y);
}

シャドールームさんのところでいくつかタイピングゲームの複数入力の方法について話題が出ていたのでWeather Typingのやり方を少しだけ書いてみる。 Weather Tytpingの自動ローマ字入力はオートマトンを使っている。シャドールームさんで紹介されてたHow To Become A Typerさんが「Tsuikyo 2.0 – 鎚鏡弐」で書いているのと同じ方法ですかね。以下の絵は,いつかタイピングソフトの作り方ページを作るときのために作ったネタだけど,多分今後も作らないだろうし,丁度良いので載せてみる。 2010090401

図は「しゃ」という問題文があったときの例。まず「しゃ」という問題がきたら,あらかじめ上のようなオートマトンを作成しておく。作り方はなんでもいいけど「しゃ」と上のオートマトンをテーブルで用意しておいてもいい。で画面に表示する文字列を作るときは,現在の設定に従ってオートマトンを処理する。例えば「CよりはSを使う」「SHよりはSYを使う」「LYAやXYAは使わない」設定であればS→1→7→Eを通って「SHA」を表示する。次にゲーム中ユーザ入力がきた場合,設定と画面表示を更新しながらオートマトンを処理していく。例えば「CILYA」と入力したときは2へ行って「SよりはCを使う」設定に変更。3→5へ行って「LYAやXYAを使う」設定に変更。最後に9→Eへ行って完了。上の矢印以外の入力が来たらミス扱い。 上の例は「しゃ」だが,問題文が長くなったらオートマトンをつなげていくだけ。例えば「しゃしゃ」だったら上のを2個つなぐだけでOK。「ん」「っ」が入ってくるとだいぶややこしくなるが,基本的には上のやり方でやればいい感じの自動入力ができる。 なお,TODでは多分「SHよりはSYを使う」のような系統立てた入力設定ではなく「SHAよりはSYAを使う」「SHUよりはSYUを使う」みたいな細かい入力設定になっているっぽい。「ん」の扱いも変。Weather TypingはTODを超えることを目指して作っていたので,この辺はTODより改善できているはず。

楽譜表示のUI部分が完成。だいぶWPFに詳しくなった気がする。あとは楽譜表示に戻って8vaとか未実装な部分を実装すればとりあえずは完成か。


てことでWPF関連。プロジェクトを.NET 3.5ベースにしているとうまくいかないけど.NET 4.0ベースにしたらうまくいったケースがあったのでメモ。.NET 4.0はWindows 7デフォルトで入っていないが,Windows Updateに重要な更新で出てくるし,大丈夫でしょう。


1つ目。CheckBoxにbool型のプロパティをtwoway Bindingしている状況で,ある条件のときはsetterで何もせずに返すようなコードを書いた。チェック操作をしたけどチェックできませんでした,みたいなことをしたいのである。

XAML
<CheckBox IsChecked="{Binding IsDisplay, Mode=twoway}">
C#
 bool IsDisplay
 {
     set
     {
         if(xxx)
         {
             return;
         }
         _isdisplay = value;
         PropertyChanged(this, new PropertyChangedEventArgs("IsDisplay"));
     }
     get
     {
         return _isdisplay;
     }
 }

この状態でチェックボックスをオフからオンに変えようとすると,プロパティはfalseのままなのにUIはtrueになってしまって状態が食い違う感じになってしまう。で結局プロジェクトを.NET 4.0ベースにするとうまくチェックがキャンセルされた。


2つ目。以下のようにListBoxでテキストラベルとそれ以外を配置しているようなケースで,テキストラベルを可変長(Width=”100*”とか)にしている場合,ウィンドウを1度でも広げていれば問題はないのだが,ウィンドウ表示時に画面を狭くしていると,レイアウトが崩れてしまう。

2010082501

2010082502

これも結局プロジェクトを.NET 4.0ベースにするとレイアウトが崩れなくなった。

BS11で3D放送をやっていて普通のモニタで見てみたのだが,画面が左右に分割されていたので裸眼立体視で3Dに見えた。いくつか放送の形式があるらしいのだが,この方式だと普通のモニタで立体に見えますね。水平解像度が半分なのでアスペクト比が崩れて3D具合がきつくなるけど。

掲示板。ログを一度に100しか見られないように制限したので,左上に過去ログとして1000発言ずつアーカイブしたものを置くようにした。トップページのカウンタも少しだけ軽くしておいた。これでCoreファイルができなくなるといいんだけど,無理そう。ウェザタイのランキングもどうにかしないと・・・。


ぱじさんが3日目のストレスでついに・・・。

最近掲示板とランキングがCoreを吐いて落ちまくっている。一度に表示する数を増やすと表示に時間がかかってしまい落とされるっぽいのは分かっているのだが,データが大きくなってきてどうしようもない感じ。プロバイダに何か言われる前に対策を打ちたいんだけど,根本的にはCGIを作り直すしか手はなさそう。とりあえず一度に表示できる数を制限しておいた。