1 2 3 次へ

Windows8なX220tでRawInputControlTestを動かす

Windows8にしてから動かなくなっている事に気づいていましたが、
小型BlueToothキーボードの活躍により利用する事がなくなっていたため調査せずスルーしていました。

しかし小型とはいえちょっとした作業をする場合にも持ち歩くのはちょっと面倒ですね。
よってRawInputControlTestにもまだ活躍の機会はありそうです。
という訳で腰痛を労わりつつ調査し、どうにか動くようになったので成果をここに上げておきます。

前回の記事ではタッチ座標の取得がうまくいっていなかったので修正しましたが、
今回はタッチされたかどうかの値の取得が上手くいっていませんでした。
そこで以下の部分を修正しています。

433行目
raw_stat := NumGet(RawInputData, RAWINPUTHEADER_Size + 8 + 1, "UChar") – 127

変更後
raw_stat := NumGet(RawInputData, RAWINPUTHEADER_Size + 8 + 3, "UChar")

少々やっつけな対応です。
タッチされていた場合0より大きな値が返り、
タッチされていない場合0が返ります。

元々どんなデータを受け取る前提なのかいまいち分かっていないので、
この対応は多分あまりいい方法じゃないと思います。

さらに、このままでは取得する値の結果が想定と違うので、
この修正に次いで以下の二か所も修正する必要があります。


455行目
ProcRawInput(wParam, lParam, msg, hwnd)

変更後
ProcRawInput(0, lParam, msg, hwnd)

463行目
ProcRawInput(wParam, lParam, msg, hwnd)

変更後
ProcRawInput(1, lParam, msg, hwnd)

本来は可変値ですが定数に置き換えます。
ProcRawInput関数内でタッチ番号などの判定に使われており、
この修正ではタッチ番号は常に1になります。
ただ、指一本でタッチする分にはなんら問題はないと思われるのでその辺はスルーしました。

※追記
ちょっと問題があったのでこっちの修正に変更です。
この場合一行だけの修正で済むので健全でもあります。

433行目
raw_stat := NumGet(RawInputData, RAWINPUTHEADER_Size + 8 + 1, "UChar") – 127

修正後
raw_stat := NumGet(RawInputData, RAWINPUTHEADER_Size + 8 + 3, "UChar") == 0

以上で動作するはずです。
タッチ位置の修正に関しては別記事を参照してください。

DFF⇒DSFに変換するツールを作ってみた

DSDファイルの変換ツールです。
縁のない人には聞き覚えのない単語だと思います。
故にニッチなツールです、まぁだからこそ製作したのですが…。

DSDというのはDirect Stream Digitalの略で、
簡潔に言えば高音質な音楽ファイル形式です。

音楽ファイルといえばmp3が主流ですね。
mp3は最高音質の320kbpsでも精々10MB程度だと思いますが、
DSDファイルは200MBを超えます。
実際に耳で体感できるほど高音質なのかはさておき、
それくらいの情報が入っているのです。

なぜ私がこんなものを作ったのかというと、
最近DSD対応のHP-A8を購入して必要になったからです。
HP-A8はDSDに対応していますが、読み込める形式が現状DSF限定なのです。

DSDには私が知る限り2つのファイル形式が存在します。
それがタイトルにあるDSDIFF(DFF)とDSFです。

DSDIFFは音楽業界で広く普及している形式のようです。
DSFはSONY独自の形式みたいですね。(DSDは元々SONYが提唱したもの)

この二つの形式の違いはデータ情報のみで、音声データ自体は同じです。(正確には少し違いますが)
(形式についての詳しい話はここではやめます)

さて、どうやってDSFを生成しましょう。

 

答えは簡単
無料のAudioGateを使えば簡単に作成できるんです!


※ただし変換時にツイートされる

 

煩わしさMAX!!

 

いやはや、タダほど怖いものはありませんわ。

AudioGate以外のツールもあるにはありますが、
Sony製は有料だし、無料ではWave to Dsdiff ConverterもありますがこれはDFF出力専用です。
isoからDSF変換するようなのもあるようですが、いちいちisoにするもの面倒なので却下(^^;

 

Wave to Dsdiff ConverterがDSF対応してくれれば最高なのに…。

DFF⇒DSF変換ツールはないものか。


検索をかけてみるも、
DSF⇒DFFに変換するツールはありますが逆はありませんでした。

しかし、変換ツールを製作していた人のブログにDSFとDFFの解析結果が載せてあります。


軽く見た感じ一日もあれば作れるレベルに感じます。

 


…神は私に”作れ”と言うのか…?

 

 

以上が製作までの経緯になります。

ダウンロード

dff2dsf_v0900.zip

注意

  • DSFにはメタ情報としてID3タグを付加できますが、このツールでは付加していません
    これはDFFがID3タグではなく独自形式(コメント)にしているので対応が面倒だったため除外しました。
    それに現状Wave to Dsdiff Converterが出力するDFFファイルにはコメント情報を付加していないので
    対応したところであまり意味はないです。
  • 2チャンネル(ステレオ)以外には対応していません
    対応できないわけじゃないけど面倒だった(ぁ
    気が向いたら対応するかもしれません。

参考にしたサイト

当初別のブログの方の解析結果を参考にして製作していたのですが、
途中でさらに詳しく解説しているブログを見つけました。ありがし。
http://blog.venetor-sound.com/?eid=27
http://blog.venetor-sound.com/?eid=28

Lua/PHP5/自作言語の速度測定

フィボナッチ数列で速度検証を行ってみた。
測定にはtimeコマンドを使用しています。

検証環境

  • MacBook Air 1600/11.6 MC969J/A
  • CPU: Core i5(Sandy Bridge) 1.6GHz
  • メモリ容量: 4GB
  • ストレージ: SSD

各言語のコード

Lua

function fibo(n) if 1 == n or 2 == n then return end fibo(n-1); fibo(n-2); end MAX_SIZE = 40 data = {} for idx = 1, MAX_SIZE do data[idx] = fibo(idx); end

PHP5

<?php function fibo($n) { if (1 == $n || 2 == $n) return; fibo($n - 1); fibo($n - 2); } for ($i = 1; $i <= 40; ++$i) { fibo($i); }

Ril(自作言語)

for文を実装していないので、whileで対応してます。

[macro name:"fibo" params:"n"] [if 1 == $n || 2 == $n][return][endif] [fibo $n-1] [fibo $n-2] [endmacro] [let $i = 1] [while $i <= 40] [fibo $i] [let $i++] [endwhile]

測定結果

./src/lua ./test/fibonacci.lua 68.67s user 0.02s system 99% cpu 1:08.69 total ./php fibonatti.php 175.76s user 0.29s system 99% cpu 2:56.15 total ./ril fibonacci.ril 270.05s user 0.22s system 99% cpu 4:30.34 total

検証回数は数回程度ですが、各言語の差はほぼ同じだったので問題ないでしょう。
Luaは噂通り速く、ダントツのトップです。
PHP5はLuaと比べて3倍程度遅い結果になっています。
自作言語の方はLuaと比べて4倍以上遅い結果となってしまいました。

自作言語は計算処理の部分を汎用的に扱えるように関数ポインタを用いて演算の分岐を行っています。
関数の呼び出しは比較的コストが高いので、計算処理のように何度も呼び出す箇所で使っていると結構な負担になります。
なので、switchを使用し関数の呼び出しを行わないようにすれば今よりいくらか速くなると思います。
他にも汎用性を重視した実装を行っているため、速度を犠牲にしている箇所があったりしますが、
それらの箇所は汎用性を重視するべき箇所で、これ以上の高速化は見込めません。
なので、この変更を行うことでどの程度の速度改善が図れるのかが今後の高速化のキーになりそうです。

Cの前置インクリメントの挙動がコンパイラによって違う

最近ゲーム制作の都合で、スクリプト言語を自作しています。
算術演算を一般的な言語の挙動と一致させるために、
インクリメントの挙動を確認していたら、面白い結果になったのでメモしておきます。

 

今回テストに使用したコード(jの値):

int i = 0, j = 0;
j = ++i + ++i + ++i;

Xcode(GCC)の結果: 7
VC++の結果: 9

 

一度の演算で同一の変数にインクリメントすると上記のように結果が変わってきます。
この原因は恐らく、
コンパイラが生成するアセンブリコードが違っているからではないかと勝手に解釈しています。
(残念なことに筆者はアセンブラを触った経験がないので、詳しくは分からないのですが)
コンパイラの演算の評価の仕方の違いでこのような差異が生まれるんだと思います。
具体的には以下のような評価をしているのではないかなぁと。

 

逆ポーランド記法による比較
GCCの評価 j,i,++,i,++,+,i,++,+,=
VC++の評価: j,i,++,i,++,i,++,+,+,=

 

VC++の場合、
インクリメントを演算子として評価しているので、こっちの方が実装が簡単です。
(GCCの挙動を見た段階で実装の判断をしてしまったので、結局難しい方で実装してしまいましたが)

まぁともあれ、どっちが一般的な挙動なんでしょうね。
本当にコンパイラによって結果が違うのであれば、
複数前置インクリメントを書くのはあまりおすすめできない方法と言えそうです。

ちなみに後置インクリメントの挙動は一致していました。

※追記
PHP5にて確認してみたところ、6というこれまた違う結果となりました。
恐らく評価順序はGCCと同様ですが、
iの加算処理を行った後スタックに積む際数値として処理しているんだと思います。

この結果から言語ごとに前置インクリメントの扱いは全く違うことが分かりましたので、
言語を自作する際は実装者の判断で決めてしまって問題ない、という事になりそうですね。

加速度センサーから画面の向きを変更するアプリを作ってみた

X220tabletを使っていて、画面の回転ボタンの挙動が気に食わなかったので、代替アプリを作ってみました。

 

標準の挙動は、押すたびに90度ずつ回転していく仕様なんですが、

この場合270度回転させるのに3回押さなければならず、非常に面倒です。

 

別のタブレットPCではdynabookM200を所持していますが、

こちらは優秀で、ボタンを押したときに傾きに合わせた方向で回転してくれます。

 

加速度センサー自体はX220tabletにも内臓されていますが、

ボタンを押した時ではなく、常に傾きを検知して自動的に回転する仕様でした。

ipadなどでもそうですが、ちょっと角度を変えた時に画面がいちいち回転してイライラします

せっかく専用ボタンがついているのなら、そこをトリガーにして回転させればいいのに。

(ipadはボタンがないからしょうがないとして)

 

幸いこの専用ボタンはWindows側で任意の動作を割り当てる事ができるので、

今回製作したアプリをこのボタンに割り当てる事で、

dynabookM200と同等の挙動を実現できるようになります。

(その際ActiveRotate機能は無効にしてください)

 

ダウンロード

SensorRotate.zip

 

加速度センサーの値を取得する方法を調べていると、

Windows7のAPIか、Thinkpad専用と思われるSensor.dllを使う方法がある事を知り、

実装が簡単な後者の方法で実装しました。

そのため、恐らくThinkpad以外では動かないと思います。

また、動作確認OSはWin7のみなので、他のOSで動く保障もありません。

 

タブレットモードの場合画面を180度回転させているので、

本来はその点も考慮して実装する必要があるんですが、

タブレットモードかどうかをチェックする方法が分からず、タブレットモード時専用として実装しています。

そのため、ラップトップモード時に実行した場合は向きが逆転しますのであしからず。

1 2 3 次へ

フィード

キーワード検索

最近の記事

最近のコメント

最近のトラックバック

カテゴリ

アーカイブ

ランキング