2011年8月27日土曜日

[AV] コンポーネント端子がついてないテレビにPS2や古いDVDプレイヤーを接続する

How to connect component terminal to D terminal?

テレビも液晶ディスプレイも故障したため新しいテレビを買を買ったのですが、このテレビにはコンポーネント端子がついていません。(承知の上で買いました)
今までのテレビが10年以上前に買った製品だったので、ゲーム機もDVDプレイヤーもコンポーネント端子でつなげていました。

テレビ背面の端子。コンポーネント端子やS端子がありません。


左がプレステ2用、左が汎用
綺麗な映像を見たいのでコンポジット端子は使いたくありません。
このテレビにはD端子がついてるのでD端子ケーブルを買えばいいのですが、機器に合わせて全部そろえるとしたら大きな出費です。
HDMIの時代に、アナログ規格のケーブルに投資するのは気が引けてしまいます。

そこで、1780円前後で売られているコンポーネント端子をD端子に変換するケーブルを買いました。
富士パーツD端子コンポーネント変換ケーブル AD-513 0.1m(D端子・オス-コンポーネント端子・メス)
AVケーブルD端子⇔コンポーネント端子変...

AVケーブルD端子⇔コンポーネント端子変...
価格:1,785円(税込、送料別)

これで綺麗に映りました。

私事ですが、プレステ用のAVケーブルはコンポーネント端子ケーブルの他、21ピンアナログRGBケーブルやS端子ケーブルも持ってます。
過去にいろいろなAV規格があったのに、デジタル時代の今ではHDMI、DisplayPort、Thunderboltといった異なる規格が乱立してます。
日本のメーカーのノートパソコンにはHDMIがついてますが、HP製にDisplayPort、アップル製にThunderboltといった別の規格がついてます。
ノートパソコンの映像を外部出力するにはそれぞれの規格に対応した装置が必要になってしまいます。
規格争いはいい加減にして欲しいですね。

2011年8月20日土曜日

[Android] ThumbモードとARMモード、どちらが速いのか?

Which is faster, Thumb or ARM?

多くのAndroid端末に使われているARM系CPUは16ビットのThumbモードと32ビットのARMモードとがあります。
「ARMモードの方が速い」という意見がある一方、「Thumbモードはプログラムサイズが小さい分メモリーアクセスが少ない」という意見があり、どちらが効率がいいのかよくわかりません。
そこで、ThumbモードとARMモードを比較してみました。

Activityのソース(Main.java)
jni/nck.cpp
Android.mk(Thumbモードの場合)
Android.mk(ARMモードの場合)
結果
(1)int型(32ビット)の検証
エミュレーター・実機(IS01)とも、Thumbモードの方が速い。

(2)float型(64ビット)の検証
エミュレーターではARMモードの方が速く、実機(IS01)ではthumbモードの方が速い。

(3)atan2関数(複雑な計算)の検証
エミュレーターではARMモードの方が速く、実機(IS01)ではthumbモードの方が速い。

結論
Thumbモードの方が速い場合がある。
ARMモードが常に速いとは限らないようです。Android-NDKを使ったアプリケーションを公開する時は機種ごと・アプリごとにベンチマークを取って比較した方がいいようです。

以上、参考になれば幸いです。

2011年8月13日土曜日

[Android] 自身をタスクキルするアプリケーションを作るには

How to kill the application's own self

Androidアプリケーションは終了すると、何の処理をしなくてもRAM(メモリー)に残ります。
(終了してもバックグランドで処理を続けるプリケーションもあります)
他のアプリケーションが起動するなど、空きメモリーが必要になったときにOSがRAMから消します。
アプリケーションがRAMに残っていた方が速く起動できるし、バッテリーやフラッシュROMの寿命も長持ちします。

ただ、アプリケーションが終了後もRAMに残ることに不安を覚えるユーザーも少なからずいらっしゃるようです。
そこでActivityを終了したらRAMから消える(タスクキル)サンプルを作ってみました。

ソースです。
Activityのソース用(Main.java) ※パーミッション不要のため、マニフェストは省略

onDestroyメソッドの最後に Process.killProcess(Process.myPid()); を書くだけです。

アプリケーションを起動するとタスクリスト(※)にパッケージ名が表示されます。
(※正式名称は不明ですがここでは「タスクリスト」と呼びます)
一度起動したアプリケーションは、RAMに十分な空き容量があれば終了してもタスクリストから消えないのが普通です。

Process.killProcess(Process.myPid()); が実行されると直ちにタスクリストから消えます。

ちなみにタスクキルすると
INFO/ActivityManager(**): Process jp.fujiu.AndroidApp.ProcessKiller (pid ***) has died.
というログが残ります。異常終了したときと同じ内容なので、あまりいい気分ではありません。
タスクキルのメリットを強いて上げるならメモリーリークを解放してくれるようですが、メモリーリークを起こしているならタスクキルに頼らずコードを直すべきです。
本当にタスクキルするかどうかをユーザーに確認する画面を用意した方がいいと思います。

以上、参考になれば幸いです。

2011年8月6日土曜日

[Android] Android-NDKでテクスチャを表示するには

How to draw textures in Android-NDK

Havaは大きいソースが扱えないので、[Android] 頂点の多いポリゴンを扱うには では頂点数の多いポリゴンをAndroid-NDKを使ってJNIからJavaに大きい配列を渡す方法でバナナを表示しました。この方法はFloatBufferの作成に時間がかかるという問題がありました。
今回は、頂点とテクスチャの機能もJNIで書いてみます。

JNIで画像を扱うには?
テクスチャを表示するためglTexImage2Dを使います。
glTexImage2Dで表示できるテクスチャ画像はunsigned char型配列のビットマップデータです。配列の内容は1ピクセルごとにRGBAの順に1バイトずつです。
このブログを作成している時点ではJNIからres/drawableフォルダーやassetsフォルダーのファイルを扱う方法が見当たりませんでした。
そこで、JNIで画像データを扱うために次のようにしました。
  1. Javaでres/drawableフォルダーの画像をint型配列に変換してJNIに渡す
  2. JNIでJavaから渡されたint型配列をunsigned char型配列に変換しテクスチャ表示する
以下ソースです。
ndk.cpp
glu.h (Android-NDKのsampleの com.example.SanAngeles から抜粋しました)
Android.mk
これら ndk.cpp、glu.h、Android.mk と、HBehrens-obj2opengl-a0f123e.zipのbanana.h をプロジェクトのjniフォルダーにインポートし、カレントフォルダーをjniに移してndk-buildを実行します。
HBehrens-obj2opengl-a0f123e.zipののbanana.jpgをres/drawableフォルダーにインポートします。

Activityのソース(Main.java)
画面をフリックするとバナナが回転するようにしました。
これをエミュレーターで実行したら一瞬でバナナが表示されました。JavaでFloatBufferを作成する方法(エミュレーターで2分くらい)とは大違いの速さです。
テスト環境では、Heapを見比べたらJavaでFloatBufferを作成する方法に比べて1MBほどメモリーの節約になりました。
Android-NDKでビルドしたアプリケーションはARMの端末でしか動作しないのが玉に瑕です。

以上、参考になれば幸いです。

2011年7月30日土曜日

[Android] Androidエミュレーターが起動しなくなった

How to solve a problem that Android-NDK dose not launch
android-sdk_r12-windowsをインストールしたらエミュレーターが起動しなくなりました。

エラーメッセージ
invalid command-line parameter: Files\android-sdk-windows\android-sdk_r12-windows\tools/emulator-arm.exe.
Hint: use '@foo' to launch a virtual device named 'foo'.
please use -help for more information

どうやらパスにスペースが含まれていることが原因のようです。
保存場所を
D:\Program Files\android-sdk-windows から
D:\android-sdk-windows に変更したら起動するようになりました。

android-sdk_r11-windowsまではパスにスペースが含まれていてもちゃんと動いたのでびっくりしました。
ちなみにAndroid-NDK(ndk-build)もパスにスペースがあるとコンパイルできませんでした。

以上、参考になれば幸いです。

2011年7月23日土曜日

[Windows7] メモリーを増設したら起動しなくなった (Kernel-power イベントID41)

Windows7 had been unstable since I added memory.

安くて有名だったサーバーHP ProLiant ML115 G5にWindows7-64bitをインストールしてパソコンとして使っているのですが、メモリー(RAMモジュール)を5GB(2GB×2 + 1GB)から8GB(2GB×4)に増やしたら起動が不安定になりました。
過去に故障のためメインボードを交換してます。
CPUはAthlon X2に交換済みです。

電源が切れた状態から起動(コールドスタート)すると
「ファイルを読み込んでいます」と表示した後に勝手に再起動し、修復セットアップを要求する(無視すると正常に起動する)
「このファイルのデジタル署名を検証できません」と表示される(再起動すると正常に起動する)
のどちらかの現象が起こります。
たまに正常に起動しますが復元ポイントに戻されます。再起動した場合はこの症状は起きません。
イベントビューアーをみるとKernel-power イベントID41が記録されています。

※この問題は
起動しなくなったHP ProLiant ML115 G5が直った
にて完全に解決しました。
以下の解決方法は2011年7月時点の内容ですのでご了承ください。

結論
BIOS設定の
Advanced
 - CPU Configuration
  - Memory Channel Mode を
Independent から Combined に変更したら解決しました。

しかもメモリーのWindowsエクスペリエンスインデックスが7.1から7.2に上がりました。
容量もこの通り8GB(8MB×1024)と認識されてます。

試してみたけど解決に至らなかったこと
  • 修復セットアップ
    →復元ポイントに戻されるだけ、Windows Updateが台無しです
  • CドライブをフォーマットしてOSをクリーンインストール
    →効果無し
  • ハードディスクのSATAケーブルを交換
    →変化無し
  • BIOSのPowerNow!をDisableに設定する
    →効果無し
  • グラフィックボードをRADEON HD5450(VRAM 512MB)からNVIDIA GeForce 8400GS(VRAM 256MB)に変更
    →効果無し、ただし発熱量が下がりました
  • MEMTEST86+でRAMの不良確認
    →異常なし
  • デバイスマネージャーのPCI標準PCI-to-PCIブリッジ デバイス13(オンボードのグラフィック機能)を無効にする
    →効果無し
  • システムエラーの「自動的に再起動する」の無効化
    →エラーが起きた後に再起動するかしないかの設定なので意味がない

気休め1・デバイス13の無効化

気休め2・システムエラーの「自動的に再起動する」の無効化

最近のWindowsは不具合が起きたらOSよりハードウェアを疑うべきです。
ただし今回の症状はハードウェアは正常で、しかもコールドスタートするとたまに発症する内容でなので対処方法がわかるまで時間がかかりました。

以上、参考になれば幸いです。

2011年7月16日土曜日

[Android] OpenGLで頂点の多いポリゴンを扱うには

How to draw many vertrics on GLSurfaceView

前回のブログobj2opengl.plをJava用に改造する では
obj2opengl: convert obj 3D models to arrays compatible with iPhone OpenGL ES « Heiko Behrens (Blog):
http://heikobehrens.net/2009/08/27/obj2opengl/
で公開されているバナナのオブジェクトは頂点が多くてJavaでは扱えないことがわかりました。

原因は
定数プールは65536エントリー以内
コンストラクターやメソッドのソースは65536バイト以内
というJavaの仕様によるものでした。

Javaは大きいソースをビルドできないので、外部ファイルに持たせる方法をいくつか試してみましたがどれも無理でした。

1.assetsフォルダーに頂点データをテキストファイルに保存する
→AssetManagerは256行以上のテキストファイルを読み込めない(IOException例外が発生)

2.頂点データをvalues/strings.xmlに保存する
→strings.xmlは65536行以上のデータを扱えない

試行錯誤の結果、obj2opengl.plが出力したbanana.hをAndroid-NDKで使うことでバナナを表示できました
HBehrens-obj2opengl-a0f123e.zipに含まれるbanana.jpgとbanana.hをAndroidプロジェクトに取り込みます。
jniフォルダーを作ってbanana.hを保存します。
drawableフォルダーを作ってbanana.jpgを保存します。
jniフォルダーにはさらにAndroid.mkとbanan.cppを保存します。

Android.mk
banana.cpp
Activityのソースです。
Main.java(Activity) これでカレントフォルダーをプロジェクトのjniフォルダーに移動し、ndk-buildを実行します。

起動するとこうなります。
画面をドラッグすると視点が動くようにしました。
バナナとバナナの中心点がかなり離れてるようで(気のせいでした)、大きく動かすと画面から消えてしまいます。

今回は頂点の配列をAndroid-NDK、それ以外をJavaで書いたのでエミュレーターで実行するとすごく遅いです
FloatBufferの作成にすごく時間がかかります。バナナが表示されるまで2分くらいかかりました。
FloatBufferをシリアライズできればもっとスマートになるんですが。

Blenderモンキーの頂点+法線ベクトルの組み合わせもソースが大きくてJavaではビルドできませんでした。objファイルをobj2opengl.plでhファイルに変換し、バナナと同じようにAndroid-NDKでビルドしました。光源で照らしてます。こちらはテクスチャがないのでエミュレーターに表示されるまで30秒くらいでした。

Android-NDKを使うデメリットはARMプラットフォームの端末しかサポートきなくなることです。x86版Android端末にはインストールすらできなくなります。
ただし、今のところ国内のAndroid端末はほとんどがARMベース(Qualcomm、Tegraなど)なので大きなデメリットではないと思います。

以上、参考になれば幸いです。