2012年7月29日日曜日

/mnt/sdcard/ディレクトリのアクセス権限

ウォークマン(Zシリーズ)で、SHOT04(NokogiRider)をデバッグしていて機種依存の盲点をひとつ発見。

SHOT04の場合、SDカード(/mnt/sdcard)の下に専用のディレクトリを掘って、そこにプレイデータ(スコアとか)やリプレイデータを保存する仕様にしていたのですが、Zシリーズの場合、/mnt/sdcardにアクセス権限が無いようでした。

確かに、Androidの仕様として、/mnt/sdcardの有無は機種依存に成り得ます。
Androidの仕様として、アプリケーションが(ストレージパーミッションで)読み書きが保障されているのは、基本的に 標準のアプリケーションディレクトリ(/data/data/パッケージ名) 配下のみのようです。

という訳で、/mnt/sdcardにアクセス権限が無い場合、標準のアプリケーションディレクトリ(/data/data/パッケージ名)にデータファイルを保存する仕様にしておきました。


なお、/mnt/sdcardにアクセス権限がある場合は、SDカードに保存するようにします。
一般的にSDカードの方が空き領域が大きいので、標準のアプリケーションディレクトリに配置するデータは可能な限り小さくする方が、ユーザにとって親切だと思うし、リプレイデータとかを独自にバックアップしたりするのも楽なので。(/data/dataディレクトリの場合、パス決めウチで打たないとファイルへアクセスできないという...)


これは、InvaderBlock2も同じ仕様にしておく必要がありそうです。
まぁ、このバグに気付けただけでも、Zシリーズを購入した甲斐がありました。
Zシリーズ設備投資分のペイバックは無いでしょうけど。

しかし、Androidの機種依存には困ったものです。
SHOT04は、かなりその辺を柔軟に作ってましたが、それでもこういう手落ちは出てくる・・・


追記(8/4):
Xアプリで、音楽データを転送したら/mnt/sdcardに書き込み権限ができたっぽい?
とりあえず、SHOT04は、/mnt/sdcardに書き込み権限があれば、/mnt/sdcardにデータ保存して、なければ/data/dataにデータ保存する仕様にしておきます。

エスプレッソ+ソーダ

サントリーのエスプレッソーダという商品があったので買ってみました。

[ニュースリリース]
http://www.suntory.co.jp/news/2012/11446.html

[販促サイト]
http://www.suntory.co.jp/softdrink/espressoda/product/index.html

発売は7/31~とのことですが。
ジャンプみたいなもんですかね?

まぁ、昔っからこういう商品はありました。
スパークリングカフェ(ネスカフェ)とか。
http://gigazine.net/news/20060605_sparklingcafe/

スパークリングカフェはもう製造してないようです。
理由は単純にマズイから。
まぁ、普通に考えてウゲェ~となる組み合わせです。
エスプレッソーダも、名前からして、一発狙いの臭いがプンプンします。
ペプシのシソとかスイカみたいな。
ですが、飲んでみると、結構ウマイ。

ただし、私の舌はかなりアテになりませんが。
試飲された方のブログを幾つか見た限り、肯定的な意見はあまり無かった感じでしたし。

恐らく、「コーヒー」という先入観を持って飲むとマズイのかも。
得体の知れない液体を飲む感じで飲めば、普通にウマイです。
味を表現するのは難いのですが、疲れた時に飲むと疲労感がメキメキと回復する感じでしょうか。

Z1050導入

SonyのZシリーズ(Z1050)を購入。
手持ちのスマホをAndroid4.0へアップしてしまったので、2.3スマホのデバッグ機として。
今年に入ってもう3台目のAndroid機。(iPodTouchを含めれば4台目か)


使ってみた感じでは、かなりの良品です。
附属のヘッドフォンがかなり良いです。
ノイズキャンセルがついているのに、イヤホン側に電源不要。
内蔵型ですかね。

あと、保護シールが最初っから貼ってあるのも良いです。
なかなか滑らかにスライドができる素材のものなので、張替え等は不要だと思います。

ネックは値段とSDカード非対応ということぐらい。
iPodTouchと戦うには戦力不足。
iPodTouchと同価格でSDカードを装備していれば・・・という感じ。

海外で発表されているZシリーズの後継機(NWZ-F800)もSDカードは付かないようです。
ただ、ノイズキャンセルは後継機ではついていないから、その分、価格は安くなるかも。
個人的には、値段よりもSDカード対応の方が重要だと思いますが。

2012年7月28日土曜日

Windows版の扱い

現在開発中のSTG(SHOT04)ですが、Android版については無料のLITE版を配布&有料(100~200円程度の予定)の製品版を販売する予定ですが、Windows版の扱いをどうしようか、全然決めてなかったな。。。

LITE版相当の無料版は適当に(ベクターとかで)配るつもりですが。
せっかくなので、アレンジ付きのサウンドトラックと製品版相当のWindows版をセットで同人ショップあたりで販売しようかという案があります。
DL販売ではなく物理媒体の販売で。

ただし、そうなると赤字の可能性が・・・まぁ、一種の道楽なので、多少の赤字は問題無いですが。
とりあえず、適当なプレス屋さんで値段を調べてみました。

Pケース:3week
枚数300枚500枚700枚1000枚1500枚2000枚
料金89,70095,000100,100105,000157,500206,000
1枚当たりの単価299190143105104103
枚数2500枚3000枚3500枚4000枚4500枚5000枚
料金247,500294,000339,500384,000427,500470,000
1枚当たりの単価999897969594
[参考] http://www.inv.co.jp/~popls/

コストパフォーマンスで見ると、1,000枚~が概ね最低ラインですかね。
Android版でちゃんと原価分の利益が出てくれれば、何も躊躇することなくトライできますが。
仮に、Android版を150円で販売した場合、Googleの手数料(30%=45円)を差し引いて、1,000本ぐらい売れればトライできる感じですかね。(1,000本も売れる気がしませんが)

2012年7月27日金曜日

デバッグ機の選定

Android2.3のデバッグ機(スマホ)を探していますが、Sonyのウォークマン(Zシリーズ)が良いかも。
http://www.sony.jp/walkman/products/NW-Z1000_series/index.html

白ロムで買ってもどうせ3Gは不要(3Gは手持ちのスマホだけで十分)なので。

昔これを買おうと思っていた時期があったのですが、デバッグ用途としては不向きと判断して断念。
店頭で「PCからアプリ転送できませんよ」という張り紙がしてあったことが致命傷。
あと、SDカードが付いていないこと等がネック。

ですが、これを選定していた当時は、色々と知識不足でした。(Android端末を持ってなかったので)
スマホで実機デバッグする時、SDカードはまず使いません。
店頭表示の意味はイマイチよく分かりませんが、2ch情報だとadbでapkを転送するのは普通にできるようです。
ちなみに、私の場合、FTPでPCからapkを内部ストレージへ転送して、インストールしてます。
なので、仮に2ch情報がガセだったとしても問題なし。

概ね、Zシリーズ導入の方向で確定しつつあります。
ただ、仮に白ロムで買うとすれば、SonyEricssonのMiniProあたりが(値段+サイズが)手ごろで良い感じ

2012年7月26日木曜日

3ボス完成

3面のボスがとりあえず完成。
デカめのレーザー。
発射前にはちゃんと集気的な感じの前振り+効果音で知らせるので、初見殺しではないです。
3面はステージの難易度が高めだったので、ボスの難易度は緩くしておきました。

しかし、現時点では最高難度(Ninja)で私が3面を越せないという状況。
このままではマズイので、調整が必要です。
ただ、全体バランスというのもあるので、とりあえず完成を優先する方が吉な気がしてきました。

あと、ボス戦でグダグダと稼ぐゲームにはしたくないので、タイムボーナスを高くする方向で調整中。
スコアシステムは、体験版(公開中)から大分弄ったかも。
あまりにも弄りすぎてしまい、私自信が細かい要素を忘れつつあります。

だいたい、ソースコードが10ks(10,000行)を超えだすと、自分自身でも全体を把握し切れない|-)
全体規模で10ksは余裕で超えていますが、そろそろゲーム本編処理のみで10ksを超えそうな感じ。

2012年7月25日水曜日

開発状況(3面ボス作成中)

3面ボスを作成中。
怒首領蜂(無印)の2面ボスあたりをオマージュした感じでしょうか。
珍しく、DoGAに殆ど頼らずドット絵を自分で描いてみました。
(DoGAで描いているのは、左右の副砲のみ)

色々と予定が遅延方向になる事由があったので、進捗は悪いです。
夏中に完成は厳しいかも。
というより、難易度の調整が厄介です。
3面のボスが一通り完成したら、ちょっとやり込んで調整する必要があります。
無理ゲーというほどではないのですが、現行の3面の難易度が鬼畜すぎるので、易しくする方向で。2面は、殆ど調整不要で良い感じにできたのですが、3面は色々と自重しなかった所為で、色々と吹っ切れ過ぎてしまいました。


今にして思えば、全5面というのがオーバースペックだったかも。。。
まぁ、音楽も作ってしまったので、全5面で作りますが。
ただ、次回作からは全3面で良いかも・・・と、思いつつあります。
次回作を作る予定は、今のところありませんが。
構想めいたものはありますが、どの程度売れるかが疑心暗鬼なので。
(SHOT04が想定よりも売れたら作る予定)

とりあえず、調整し易いように残機MAXでデバッグしてますが、Practiceはこのままで良いかも。
あと、画面構成を少し変えました。
例の問題のこともあるので、FPS表示をする方向で。

2012年7月24日火曜日

効果音の作り方

アマチュアがゲームを作るとき、効果音を自作している人はどれぐらい居るのでしょうか?
ふと、疑問に思いました。
割と有名なフリー素材があり、そこから拝借・・・という手があります。
しかし、私の経験上、自分で作った方が楽です。
素材だと、気に入った音を探すのが大変だし、ライセンス(使用許諾)の縛りも発生するので。
つまり、技術的にも権利云々(著作権とか)でも、自作した方が楽です。

(0)必要な機材

必要なのは、PCと波形エディタソフトだけです。
マイクとかは不要です。
自然音を加工して使いたいのであれば別ですが、ゲームの場合、自然音を使うと逆に不自然。

私は、3種類の波形エディタを使っています。(全部フリーウェア)
効果音エディタ_D
wavy
③Tiny Wave Editor


(1)音を作る


一番大事なことは、「効果音エディタ_Dで目的の音を自在に作れること」だと思います。
適当に弄っていても作れますが、音色の仕組みを理解すれば、ある程度狙って作れます。

a) サイン波
最も基本的な音色はサイン波(下図)です。

効果音エディタ_Dで波形(音色)のところに上図のような線を描き、再生してみてください。
たぶん、「ぽーーー」という感じの丸い音が鳴ると思います。
笛系の楽器の音がだいたいサイン波です。
マイクを持っている人は、笛の音を録音して、1周期(凸と凹の1セット)を見れば分かります。



b) 三角波

サイン波を少し変化させた感じの音色に三角波(下図)があります。
三角波は、概ねサイン波と同じような感じの音です。
ただ、ちょっと鋭い感じになります。
「ぺーーー」という感じでしょうか。
ちなみに、ファミコンのベース音でよく使われるのが、この三角波です。


c) 矩形派

嘗て、電子音といえば矩形派でした。
理由は波形を作るための計算が物凄く簡単なので。
つまり、安価なマイクロチップで処理できます。
AY-3-8190とかのPSG(Programmable Sound Generator)は矩形派ですね。

「ピーーー」という感じの音が鳴ります。
楽器でいうとクラリネットとかよく言われますが、個人的には「?」です。

ポイントは、
・サイン波=ポーーー
・三角波=ペーーー
・矩形波=ピーーー
です。

相違(図では黒線の位置)の変化が大きいと、音が鋭くなるという感じでしょうか。
それだけ抑えておけば、だいたいどんな音でも狙って作れます。
あとは、デューティー比(プラスの相違とマイナスの相違の比率)を調整したり、合成したり等々。


d) ノコギリ波
メロディーとしてよく使われる音色がノコギリ波ですね。
ちょっと、分かり易くするために2周期分のノコギリ波を描いてみました。
サイン波や三角波との決定的な違いは、1周期終わった後の変化量です。
上から下まで一気に降下しているのが分かると思います。
この大きな変化量が、非常に心地よい違和感を与えてくれます。
楽器でいうと、ストリングスとかの音になります。

上図だと、2周期分のノコギリ派を鳴らしますが、単位時間あたりの波の周期の数(周波数)が多くなると、音が高くなります。1秒間に440周期で鳴らせば、オクターブ4のラの音になります。
880周期鳴らせば、オクターブ5のラですね。

効果音エディタ_Dでは、音色と同様、周波数の波(時系列での変化)も編集できます。
あとは、音量の波も編集できます。
そして、これらを弄って目的の音を作ります。
左右の出力バランスも調整できますが、私は効果音は全てモノラルで作るので使いません。

e) ノイズ
あとは、相違をランダムに変化させれば、ノイズになります。
ちなみに、ファミコンで使えるプリセット波形は、三角波、矩形波、ノコギリ派、ノイズの4種類です。

(2)音を加工する

wavyなどのフィルターツールを使い、適当な加工をします。
加工のコツですが、「加工し過ぎないこと」です。
実はこれは結構重要です。
だから、私の場合、加工フェーズで使うフィルターは概ねエコーのみです。


(3)周波数などの調整


私の場合、ゲームで使う効果音は、22050Hzのモノラルと決めています。
そういった周波数の調整をするのに、Tiny Wave Editorが役立ちます。
Tiny Wave Editorは、かつてヤマハのサイトで無料で入手できました。
ただ、最近は配っていないようです。

海外のヤマハサイトを巡回すれば見つかるかもしれません。
ちなみに、私は3年ぐらい前にカナダのヤマハサイトで見つけました。
(一応、まだ無いかチェックしてみましたが、もう無いようです)


(4)効果音を入れるコツ

細かい全ての動作に対して効果音を入れると良いです。
過剰に設定するぐらいがちょうど良いです。
ちょっと邪魔っぽい感じだったら、音を鳴らさなくする前に、音を小さくしてみると良いかも。
ちなみに、SHOT04(NokogiRider)の体験版で使っている効果音は、34種類。
現段階(3面途中)では40種類。
完成版では、少なくとも50種類ぐらいになると思います。

2012年7月19日木曜日

今後の対応について

今後のアプリ開発の方向性について、Androidの扱いをどうするか真剣に考える必要がありそうです。
とりあえず、前の記事に書いたパフォーマンス劣化の問題が酷すぎるので。
最初から、iPhoneをメインを据えるべきだったか。。。

ただ、この問題が私の使った端末(Razr)固有のものだったら、まだ救いはあります。
たぶん、2.3から4.0へアップデートできる端末はそんなにはないので、そのケースの地雷を踏んだだけかも。
そうであれば、まだAndroidを切るという判断は早い。

更に、SHOT04(NokogiRider)の体験版を既にAndroidMarketで無料配布していて、尚且つ1,000本近いダウンロードもして頂いたので、ここで頓挫してしまったら楽しみにして頂いている方たちに申し訳ないです。まだ、日本の方からは感想は貰ってませんが、海外の方からはメールで感想を貰っていて、楽しみにしているとのことでしたし。


でも、私のメイン端末でデバッグができないのは痛すぎますが。
その点は、2.3系のスマホを別途(白ロムで)入手して、何とかしようと思います。
一応、2.3系のタブレットは持ってますが、やはりメインターゲットはスマホなので、スマホのデバッグ機は1台は欲しい。

まさか、1年で3台買うハメになるとはね。。。orz
開発環境のコストはタダ同然(最初に25$必要なだけ)だから、最初は(iPhoneではなく)Androidにしたのですが、もしかすると裏目だったかも。

2012年7月16日月曜日

Android 4.0で発生するパフォーマンス劣化の問題について

下記の記事で記載している性能劣化の問題ですが、Razrに対して2012年9月に提供されたシステムアップデートを適用することで、だいぶ改善されることを確認しました。ただし、まだまだ不安定です。概ね60fps程度で動くようになったのですが、バラツキが非常に激しいため、Android2.3の頃のような安定度はまだありません。
2012年9月7日・記

前の記事に書いている内容と重なる部分があるかと思いますが、Android4.0(3.0を含む?)で発生する、アプリケーションのパフォーマンス劣化に関する問題について、今、私が把握している情報を纏めておきます。

(1)どんな問題?

Android4.0(4.0.4)では、SurfaceViewCanvasを使って画面描画を行っているアプリケーションの動作性能(パフォーマンス)が極端に劣化する問題が発生します。
私はこの現象を、Motorola社のRazrという機種で確認しました。

SurfaceViewCanvasとは、2Dゲームなどでよく使われる「高速な描画」を行うための機能です。
私(SuzukiPlan)が開発しているアプリの場合、次のようなロジックでこれを利用しています。
/*
 *============================================================================
 * サーフェース・ビュー
 *============================================================================
 */
class VgeSurfaceView extends SurfaceView implements SurfaceHolder.Callback,Runnable {
    public Thread thread;
    public boolean isAttached;
    private final int XSIZE=240;
    private final int YSIZE=320;
    private Bitmap vram;
    private Rect vramRect;
    private Rect screenRect;
    private Paint screenPaint;
    /*
     *------------------------------------------------------------------------
     * コンストラクタ
     *------------------------------------------------------------------------
     */
    public VgeSurfaceView(Context context) {
        super(context);
        vram=Bitmap.createBitmap(XSIZE,YSIZE,Bitmap.Config.RGB_565);
        vramRect=new Rect(0,0,XSIZE,YSIZE);
        getHolder().addCallback(this);
    }
    /*
     *------------------------------------------------------------------------
     * サーフェース変更の検出
     *------------------------------------------------------------------------
     */
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        int xPos=0;
        int yPos=0;
        float wX=(float)width;
        float wY=(float)height;
        if((float)YSIZE*(wX/XSIZE)<wY) {
            wY=YSIZE*(wX/XSIZE);
            yPos=0;
            height=(int)wY;
        } else {
            wX=XSIZE*(wY/YSIZE);
            xPos=(width-(int)wX)/2;
            width=(int)wX;
        }
        Log.i("SHOT04-J","Width="+width);
        Log.i("SHOT04-J","Height="+height);
        screenRect=new Rect(xPos,yPos,width+xPos,height+yPos);
        screenPaint=new Paint();
    }
    /*
     *------------------------------------------------------------------------
     * サーフェース作成の検出 (スレッド起動)
     *------------------------------------------------------------------------
     */
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        isAttached=true;
        thread = new Thread(this);
        thread.start();
    }
    /*
     *------------------------------------------------------------------------
     * サーフェース破棄の検出 (スレッド停止)
     *------------------------------------------------------------------------
     */
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        isAttached = false;
        while (thread.isAlive());
    }
    /*
     *------------------------------------------------------------------------
     * メインループ (スレッド)
     *------------------------------------------------------------------------
     */
    @Override
    public void run() {
        SurfaceHolder holder=getHolder();
        Canvas canvas;
        int rc=0;
        while (isAttached) {
            rc=SHOT04.setVram2(vram);
            canvas=holder.lockCanvas();
            if(null!=canvas) {
                canvas.drawBitmap(vram,vramRect,screenRect,screenPaint);
                holder.unlockCanvasAndPost(canvas);
            }
            if(rc!=0) break;
        }
        if(0!=rc) {
            System.exit(0);
        }
    }
}

上記の青色の部分が問題が発生する箇所です。
問題の処理は、
 1. 240x320(QVGA)サイズのBitmap(AndroidBitmap)を更新(SHOT04.setVram2
 2. そのBitmapを表示(lockCanvasdrawBitmapunlockCanvasAndPost
という単純な処理を繰り返し実行しています。
Android2.3では、この処理では60fpsの性能を(かなりの余裕をもって)キープできていました。
しかし、Android4.0では、40fps~50fps程度の性能しか出なくなります。(※Razrの場合)

(2)原因は何?

推測ですが、Android2.3の場合、上記の描画処理でハードウェアアクセラレーション(GPU)が作用してました。
※なお、GPUを搭載していない端末の場合を除きます。(Android2.3を搭載しているスマホのほぼ全てに搭載していますが、ただし、一部の端末では搭載していない場合があるようです。GPUを搭載しているかどうかについては、あなたが所有する端末の公式サイトなどに掲載されているスペック表で確認できます)

しかし、Android4.0の場合、上記の描画処理でGPUが作用せず、ソフトウェア描画になったものと思われます。
その結果、遅延が発生したものと考えています。
その原因について調査した結果、下記のフォーラムを発見しました。
https://groups.google.com/forum/?fromgroups#!topic/android-developers/CK_jkHEQoOM

なお、上記フォーラムはAndroid3.0に関するものなので、本件とは同件では無いかもしれません。
ただし、質問者のコンディションと上記の実装が一致するので、私は同じ問題だと考えています。
上記の回答にあるGoogleのAndroid開発者、Romain Guy氏曰く、
In this case you won't get hardware acceleration.
この場合(SurfaceViewとlockCanvasを使用する場合)、ハードウェアアクセラレーションは作用しません。
We couldn't add this feature on time for Android 3.0. Sorry about this.
我々(Google)は、この機能をAndroid3.0で実装する時間がありませんでした。申し訳ありません。
とのことです。
私の和訳は若干怪しい部分があります。具体的には、on time forのところ。
Google翻訳の場合、「Android3.0の時」という風になりました。
ただ、「could not X on time Y」って「XがYに間に合わなかった」って意味では?(※カンです)
という訳で、上記のような翻訳にしておきました。

ただ、上記の記事は1年半ぐらい前のものです。
そして、Android4.0ではなくAndroid3.0に関するものです。
なので、不良ではなく仕様の可能性が高いと思っています。

追記:あと、そもそもAndroid2.3の時もこのケースではGPUは働いていなかった可能性もあります。
つまり、ソフトウェア描画だったけど、極端に性能が劣化してしまったということ。
劣化の度合いが大きいので、その可能性は低いと想定していますが。
まぁ、結局のところ、本当の原因はAndroidのソースコードを追いかけなければ分からない・・・ということ。

(3)アプリ利用者が問題を回避する手段は?

ありません。
Android4.0の場合、「設定」の「開発」で「全ての2D描画処理をGPUで行う」というモードがあります。
しかし、そのモードを設定しても、上記問題を回避することはできません。

(4)アプリ開発者が問題を回避する手段は?

■マニフェストによる回避は不可能
しばしば、android:hardwareAccelerated="trueをマニフェストに定義すれば良いんでない?」という意見を見ますが、その方法での回避は不可能です。
まず、この設定項目のデフォルト値は、"true"です。
そもそも、この設定項目は、GPUの使用を抑制するために定義するものです。
(そして、上記(3)の設定(強制GPUモード)は、falseを強制的にtrueにするものです)
なので、マニフェストの定義で、問題を解決することはできません。

[訂正]
上記については、若干間違いがありました。(マニフェストで回避不可能な点は正しいです)
デフォルト値はfalseでした。
ただし、実機確認した限り、SurfaceView+lockCanvasではtrueにしてもハードウェアアクセラレーションは作用しません。性能劣化があまりにも極端だったので、GPUが作用していたものがしなくなったものと実動作から判断しましたが、Android3.0以降(4.0以降を含む)は、有り得ないレベルで性能がデグっているだけという可能性もあります。(これについては、Androidのソースコードを追いかけて調べるしかないですが、未だ調べてません)

■GLSurfaceView(OpenGL/ES)へ移行による回避
この回避方法を用いれば、大半のアプリケーションは問題を回避できます。

しかし、(私が開発しているアプリのように)ピクセル単位で描画内容を更新するアプリの場合、この方式での問題回避は不可能です。ピクセル単位で描画内容を更新するアプリとは、例えば、エミュレータ(SNES,NES,MAME)などが該当します。

ピクセル単位で描画内容を更新するアプリがOpenGL/ESで目的とする処理を実現しようとする場合、テクスチャのフレーム単位での更新が必要になります。しかし、画像情報をテクスチャに変換する処理は(GPUがやっていますが)メチャクチャ遅い欠点があります。Android(やiPhone)のテクスチャは、GPUの内部では「PVRTC」という圧縮形式で保持する必要があるのですが、この圧縮方式への変換に極めて大きなオーバヘッドを要するため、240x320もの大きなサイズのテクスチャを60fpsで変換することはRazrで検証した限り不可能でした。(これについての詳しい検証内容は、前の記事を参照してください)

■RSSurfaceViewへの移行による回避
この方式については検証していません。
しかし、私の場合、そもそもこの方式を採用することが不可能です。
というのも、RSSurfaceViewはAPI level 11以降でないと使えません。
API level 11以降の場合、Android2.3以前での動作が不可能になります。
API level 11以降は、Android3.0以降で動作するアプリケーション専用

現在、世の中で最も普及しているAndroid2.3を切るという選択肢は、当面ありえません。
今のところ、Android3以降の機能を使いたいアプリ限定で利用可能な選択肢といえます。
少なくとも、ゲーム開発者でそれを考えている人はほぼ居ないと思います。

■結論
大半のアプリは、GLSurfaceViewへの移行で問題を解決できます。
私が検証してみた限り、けっこう大変な作業になると思いますが。。。
ガッツがある方は、がんばって移行してください。
しかし、ピクセル単位で描画内容を更新するアプリの場合、アプリ開発者でも問題の回避は不可能です。

つまり、Android4.0(or3.0)でデグってます。
Googleが修正しない限り、何ともなりません。
「Googleが修正しない限り」というのは、必ずしも正しくはないかもしれません。今では、Motorola側の作りこみ部分の不具合の可能性の方が高いかも・・・と、思っていたりします。
2012年9月7日・記
なお、この結論は、私なりにちゃんと実機で検証した上で得たものです。
しかし、私が技術的に至らないだけで、別に良い回避手段があるかもしれません。
私は、その可能性について、探り続けるしかありません。
(ですが、全然見つからないので、開発自体を投げ出しそうです...)

もちろん、Googleが本件を不良と認めて、修正するのがベストですが。
ただ、私の英語力では、Googleと交渉する自信が全くありません。
他力本願でアレですが、そこは英語が得意な人or米国のデベロッパーにお任せで。
たぶん、4.0がもっと普及すれば、米国でもすぐに叩かれる筈。

なお、この記事を英訳して、blogへ記事を転載してくれる方が居るとすれば、有り難いです...
この記事の内容の転載はご自由にどうぞ。
ただし、転載先で発生したトラブル等についての責任ついて、私が取ることはできません。
その点はご了承ください。

2012年7月14日土曜日

OpenGL/ESによる2D描画の高速化 (update-6)

VG-EngineのJava部分の描画処理をSurfaceView+CanvasからOpenGL(GLSurfaceView+GL10)に変更したところ、処理性能が大分落ちてしまった問題が直りつつあります・・・ですが、今一歩。。。

ポイントとなるonDrawFrameの処理は以下のような感じ。
public void onDrawFrame(GL10 gl10) {
// VG-Engineの描画処理を呼び出す
int rc=SHOT04.setVram(vram);
if(0!=rc) {
System.exit(0);
}

// VRAMの内容をテクスチャ領域へ転送
// GLUtils.texSubImage2D(GL10.GL_TEXTURE_2D,0,0,0,vram);
gl10.glTexSubImage2D(GL10.GL_TEXTURE_2D,0,0,0
,TXSIZE
,YSIZE
,GL10.GL_RGB
,GL10.GL_UNSIGNED_SHORT_5_6_5
,vbuf
);

// 描画
drawUv.put(vramPositions);

drawUv.position(0);
gl10.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl10.glVertexPointer(3, GL10.GL_FLOAT, 0, drawUv);
gl10.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);

}

最初のSHOT04.setVramというのは、VG-Engine(エミュレータ)の中核描画ルーチンです。
従来、引数に渡しているvramはBitmapクラス(AndroidBitmap)でしたが、byte配列に変更。
この部分で、仮想VRAM(240x320pixel)の描画処理を行います。
AndroidBitmapのlock/unlockが無くなった分、高速になったかも。
ただ、ポイントはそこではないです。

ポイントは、「VRAMの内容をテクスチャ領域へ転送」というコメントのところです。
この部分を、GLUtils.texSubImage2DからGL10.glTexSubImage2Dに変更しました。
GLUtils.texSubImage2Dの場合、AndroidBitmapを引数に渡します。
しかし、転送するバッファサイズを指定できないから、常に全体を転送する無駄が生じます。
OpenGLの仕様上、テクスチャ画像の辺の長さが2のn乗でなければならないので、VG-EngineのVRAM仕様(QVGA=240x320)の場合、AndroidBitmapのサイズは256x512pixelという具合になり、無駄なデータ転送が発生する訳です。

GL10.glTexSubImage2Dの場合、テクスチャバッファに転送するバッファの幅と高さ情報を指定できるので、転送量を256x320にすることが可能になります。(ちなみに横方向は240にすると危なそうなので、256のままにしておきました)

これにより、転送量を262,144byteから、163,840byteに削減できます。
ほぼ半分程度の削減になりますね。(47.5%の削減
OpenGL内部でのバッファ⇒テクスチの変換処理が恐ろしく遅いので、この削減効果は極めて大きいです。

ちなみに、テクスチャやテクスチャの表示位置を設定する処理は、全てonSurfaceChangedで纏めてやってます。
つまり、変換イベントを検出しない限り、1回ポッキリ。
こうすることで、バッファリング演算の処理回数を大幅に削減できます。
大幅っていっても1テクスチャのみだから高が知れてますが。



描画時の頂点バッファ演算(2ポリゴン分)は削れませんが。(この部分も最適化の余地があります)
なお、サーフェースのクリア処理(glClearとか)は大して重くないけど、やる意味が無いから、やってません。
(テクスチャは画面全体のVRAMが1枚のみだから、こういうやり方でOK)

しかし、このやり方でやっても52~58fps程度しか出ない。(IdeaPadA1の場合)
やはり、常識的に考えて、テクスチャの書き換えというのは重過ぎる。。。
(当然ながら、ボトルネックはglTexSubImage2Dです)

ちなみに、上記はBVQ(Basic Vert Quads)という、割とオーソドックスな手法です。
DTE(Draw Texture Extension)の方が高速という噂があるので、DTEも試したのですが、結果は同程度。
(性能が同程度なら、オーソドックスな手法の方が良かろうと思います)

やはり、テクスチャの書き換えによる描画という手法自体が鬼門ですねぇ・・・。
まぁ、最初から知っていたことですが。(知っていたから、当初Canvasを使っていた訳で)
surface lockをサポートしている分、OpenGLよりはDirect3Dの方が2D向きです。
何故、OpenGLはsurface lockをサポートしていないのやら・・・
3D onlyのゲームでも普通に要ると思うのですが。

半分、諦めの境地です。
ですが、諦めるのはまだ早い。
「思い切って、フルネイティブ(NativeActivity)にしてしまえばどうだろう?」というのも、無くは無いです。
当初、Android特有の拡張機能を取り込むのに不便だから避けてましたが、必要になるとすれば広告(アフィリエイト)や何らかの通信サービスを入れる時ぐらいだろうし、そういうものを実装するつもりは今の所無いので。(でも、後からやりたくなったら困るから、中々踏み切れない)





追記

上記のonDrawFrameの処理時間を測定してみたところ、だいたい平均で9ms~10msぐらい。

個別に測定してみたところ、
・仮想VRAM作成(setVram)が3~6msぐらい(ゲーム本編の処理量による)
・テクスチャ作成’(glTexSubImage2D)が5~15msぐらい(平均すると7ぐらい)
・描画が1~2msぐらい

たぶん、これが限界性能なのかも。
もうちょっと最適化余地を探ってみますが。

あとは、JavaVM(ダルビッシュでしたっけ?)とかAndroid側の制御や、VGSの処理(OpenSL)の制御やらが色々絡んでって感じかなぁ・・・ただ、VGSは別スレッドの筈だから、そんな大したものではないです。なので、やはりNativeActivity化が一番優良の策なのかも。。。


キツイなぁ。


追記2

とりあえず、NativeActivity化する前に、onDrawFrameの処理(全部)をJNIで実行する形に改造。

↓こんな感じ
@Override
public void onDrawFrame(GL10 gl10) {
// VG-Engineの処理を呼び出す
if(0!=SHOT04.setVram(gl10)) {
System.exit(0); // Exitボタンが押された
}
}

まぁ、Javaで書く意味は無いですからねぇ。
頂点座標についても、onSurfaceChangedで、Cのバッファへコピーし、Cで作成。
ループ処理中のJavaからのデータ受け渡しは一切無いです。

こうすれば、NativeActivityで実装するのとほぼ同等性能だと思います。
たしかに、少しばかり速くなりました。
遅いタブレットマシンでだいたい55~58fpsぐらい。
Razrならほぼ60fps。

う~ん・・・今一歩です。
やっぱり、NativeActivityにするしか無いかなぁ・・・



追記3

まぁ、追記2のコードでダメだったということは、このままNativeActivity化しても効果はほぼ無いでしょう。
Javaコードは、タッチ等のイベント処理とonDrawFrameしか走らないので。
なので、圧縮テクスチャを利用してみようと思います。

一般論で、「圧縮」というと遅そうなイメージですが。
ただ、OpenGLの世界では、圧縮=色のビットレートを落とすことという意味らしい。
まぁ、圧縮であることには違いません。
データ転送量が減るから、圧縮した方が高速だということです。

16bitカラーから8bitカラーに変更した場合、glTexSubImage2Dの転送量が次のようになります。
・16bitカラーの場合 = 240×320×2 = 153,600byte
・8bitカラーの場合 = 256色×3byte+240×320×1byte = 77,568byte


VGEの仮想ハードウェアの色表示性能は8bit(256色)なので、表現性に劣化は生じません。
(VGEのハードスペックを設計した時、8bitカラーを採用しておいて本当に良かった・・・)
表現性に劣化が生じずに転送量を1/2にできるというのは美味しすぎる。
つまり、これをやらない手はないです!



追記4

ほぼ、チェックメイトになりました・・・
圧縮したテクスチャ情報を送信する場合
glCompressedTexImage2D または
glCompressedTexSubImage2D を使います。

glCompressedTexImage2Dの場合、転送する画像サイズが、テクスチャサイズと同値でないと失敗します。
・VRAMサイズ = 240x320pixel(QVGA)
・テクスチャサイズ = 256x512pixel
という差異があり、テクスチャサイズでしか転送できない場合、倍程度の無駄領域が発生してしまいます。
なので、折角圧縮して転送量が半分になるのに、無駄領域の転送により転送量が倍になる・・・
・・・要するに、完全なる無意味状態。

glCompressedTexSubImage2Dの場合、圧縮形式が通常のGL_PALETTE8_R5_G6_B5_OESとかではなく、PVRTC方式というGPU内部のアルゴリズムで圧縮しなければなりません。
一応、glext.hに以下の4種類が#defineされています。

#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG                      0x8C00
#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG                      0x8C01
#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG                     0x8C02
#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG                     0x8C03

で、この圧縮方式ですが、けっこう複雑です。
要するに、GPU内部でこのアルゴリズムでテクスチャ情報を変換して保持しているから、テクスチャイメージの書き換えには膨大な処理時間を持っていかれてしまう訳ですね。
なので、仮に自前のCPU演算で同じ圧縮演算をしたとしても、GPU任せの変換と比較して膨大な処理時間を食う訳です。


という訳で、ほぼチェックメイトです。
「ほぼ」というのは、まだ2つほど別のアイディアがあるという意味です。

【アイディア1:ベースロジックの改造】
テクスチャ変換処理を完全に別スレッド(非同期)にして、onDrawFrameのサイクルが呼ばれる時点で完成した前フレームのテクスチャを画面に出力する(毎回1フレームの遅延が発生するけど、かなり軽くなる筈)


【アイディア2:総転送量を減らす】
テクスチャを2枚(256x256と256x64にして、組み合わせて256x320にする。
この方式はかなり危険です。
・つなぎ目の境界がボンヤリ見えてしまう可能性がある。
・2回glCompressedTexImage2Dを呼び出す必要がある。





追記5


とりあえず、【アイディア2:総転送量を減らす】を実装してみました。
つなぎ目は割りと気になりません。
しかし、やはり、2回glCompressedTexImage2Dを呼び出すオーバーヘッドが思ったよりも大きい。
一応速くなりましたがね。


IdeaPadA1で、55~56fpsで安定していたものが57~58fpsで安定する程度に。。。
もはや、ギブアップ寸前。。。

やっぱり、OpenGL/ESは使い物にならない。。。

そもそも、ポリゴンのテクスチャとは、頻繁な書き換えを想定したものではないので。
OpenGL/ESで性能を出そうと思えば、パターンデータは完全に固定化する必要があるというのが、結論かな。
しかし、2Dゲームの場合、そんなんだと使い物になりません。。。
ピクセル単位での書き込みや、スプライトのマスキング表示などが必須なので。
それらはパターンデータの加工が必須。
テスクチャを書き換えずに利用する方式だと、パターンデータの加工はできない。
よって、チェックメイト・・・。


ちなみに、onFrameDrawのC側の関数の入口と出口にログ出力処理を入れてみたところ、
I/SHOT04  (16557): 2012/07/15 19:01:37.562 start
I/SHOT04  (16557): 2012/07/15 19:01:37.578 end (4ms)
I/SHOT04  (16557): 2012/07/15 19:01:37.579 start
I/SHOT04  (16557): 2012/07/15 19:01:37.595 end (16ms)
I/SHOT04  (16557): 2012/07/15 19:01:37.597 start
I/SHOT04  (16557): 2012/07/15 19:01:37.612 end (15ms)
I/SHOT04  (16557): 2012/07/15 19:01:37.613 start
I/SHOT04  (16557): 2012/07/15 19:01:37.629 end (16ms)
I/SHOT04  (16557): 2012/07/15 19:01:37.630 start
I/SHOT04  (16557): 2012/07/15 19:01:37.646 end (16ms)
I/SHOT04  (16557): 2012/07/15 19:01:37.647 start
I/SHOT04  (16557): 2012/07/15 19:01:37.662 end (15ms)
I/SHOT04  (16557): 2012/07/15 19:01:37.664 start
I/SHOT04  (16557): 2012/07/15 19:01:37.671 end (7ms)
I/SHOT04  (16557): 2012/07/15 19:01:37.686 start
I/SHOT04  (16557): 2012/07/15 19:01:37.694 end (8ms)
という具合。

絶望的な遅さです。
何よりバラツキが激しい。
やっぱり、PVRTCが相当なクセモノです。
完全なソフトウェアレンダリングの方が高速に処理できる気がしてきたので、そっちの方向で探ってみるか。。。



追記6


そもそも、今回の問題の発端になったCanvasがICS(Android4)で劇的に性能劣化するようになった原因のGoogle公式回答が見つかりました。
https://groups.google.com/forum/?fromgroups#!topic/android-developers/CK_jkHEQoOM


Google「すまんね、lockCanvasはAndroid3以降、ハードウェアアクセラレーションしないよ。

えっ?
それだけ?

質問している方は、代替策を聞いているのに、代替策に関しては無策ということはバグですね。
ICSからのバグならまだしも、Android3の頃からのバグ(仕様欠陥)ってことは、直す気ナシか?
Googleみたいなスカタンな連中にOSを作らせた結果がコレです。

完全に推測ですが、ICS開発中のGoogle内部でのやりとりは、大方
・電池持ちについて検討
・SurfaceView+CanvasのH/Wアクセラレーションを切れば電池持ちが良くなる
・ゲームが遅くなる可能性については黙認 (デグっても問題なしと判断)
といった感じですかね。

さて、どうしたものか。
Android 2.3専用にして作り続けるか、開発自体をドロップするかの二択?
厳しいなぁ。。。

とりあえず、やる気が大分削げました。
Windowsでゲーム本編の開発を進めることはできるから、作りながら待つべきか。

OpenGL化に苦戦中

とりあえず、SurfaceView + Canvasで描画していたVRAM転送処理を、OpenGL化。
VRAM情報(AndroidBitmap)はそのまま使える筈なので、骨組みを変更するだけ・・・・
・・・なんですがね。

Java部分というかAndroid固有部分の実装は、正直かなり面倒です。
とりあえず、本屋でOpenGL/ES関連の書籍を入手。
http://www.amazon.co.jp/%E5%88%9D%E3%82%81%E3%81%A6%E3%81%AEOpenGL-ES-%E5%B1%B1%E4%B8%8B-%E6%AD%A6%E5%BF%97/dp/4873114969

とりあえず、OpenGL/ESの1.0で実装してみました。
しかし、Android2.3の検証機で動かしてみたのですが、重い。。。
Android2.3で遅くなるのはアウト過ぎます。
私自身のスマホは4.0にアップしましたが、やはり、メインターゲットは2.3なので。

まぁ、まだかなり改善余地がありそうなので、頑張ってみます。
AndroidBitmapで作成したVRAM情報を、毎フレームtexSubImage2Dで転送しているのが無駄に思えてしょうがない。

OpenGL側で管理しているテクスチャ原本のメモリポインタを取得できれば、一気に解決なんですが。

2012年7月13日金曜日

Android4大幅性能劣化

Android4で、自作アプリの処理性能が大幅に劣化する問題が発生。
たぶん、CanvasがGPUを介さずに動いているのかも。

私のアプリは、Cで仮想ビデオメモリ(240x320pixel )の情報をAndroidBitmapとして作成し、それをSurfaceViewでCanvasを使って、画面サイズにあわせて拡大描画するという処理方式。
スプライト描画などは、Cで実装している完全に自前のロジックです。
その部分では問題が出る筈が無いので、問題の原因はほぼ100%、SurfaceView or Canvasのどちらか。

実は、Canvasが相当重い処理であろうことは想定済みです。
ただ、手元にあるシングルコアの陳腐なAndroid2.3機(Lenovo製)でもそのCanvas方式で60fpsを出せていたから、「問題ないのかな?」と、思っていたのですが、どうやらAndroid4だと、問題が出てしまったという訳です。

もちろん、Android4がバグっているだけという可能性も否定できません。
しかし、改善の余地はあるから、この部分の処理方式を大幅に変えてみようと思います。
とりあえず、OpenGLでテクスチャを使う方式に変更してみようか・・・。
OpenGLは苦手ですが....


しかし、こんなショボイ性能デグを起こすあたり、流石、Googleさん。
やはり、Java脳の人々は、性能に無頓着すぎる。

2012年7月12日木曜日

Android4へアップデート

電話機(Razr)のOSをAndroid4.0.4へアップデートしました。
ちなみに、自作アプリの動作保障バージョンは、2.3.3以降です。
デバッグ専用のタブレットは2.3系なので、検証環境は問題ありません。

アップデートの主目的は、自作アプリの動作検証のため。
まぁ、私のアプリの場合、設計上OSのバージョン固有の問題は出る可能性が極めて低いので、早急にやる必要は無いと思っていましたが、それでも一応、実機で動作を確認した方が良いのは確かな筈。
あと、ホーム画面のフォルダ表示とかが便利そうだったというのもあります。
ザックリと使ってみた感じでは、

ダメなところ

(1) 描画パフォーマンスが大幅に劣化
描画処理の仕様変更により、相当パフォーマンスが劣化してます。
ゲームの動作がモッサリした感じになります。
あと、動画とかも2.3の頃よりも粗い感じで表示される気がしないでもないです。
(これは、気のせいかも)

微妙なところ

(1) 標準ブラウザのお気に入りがワンタッチで表示できなくなった?
(2) ホーム画面でWi-FiのON/OFFができなくなった?
(3) ロック画面で最初に鍵ボタンを押してからパターンやpin入力になるのが意味不明
(4) アプリ画面やホーム画面のスライド時に誤反応みたいな感じになることがある

(5) フラッシュ実質非対応

フラッシュは、4.0からプリインストールから外れるけど、インストールは可能でサポートもされる・・・
・・・とのことですが、現状、真っ当に動きません。
たぶん、Adobeもやる気は全然無いはずなので、今後の改善も期待できないと思います。
なお、Android4.0からはフラッシュではニコニコ動画とかを見ることが出来なくなりました。
ただし、ニコニコ動画については、非公式のニコニコブラウザを入れて、Chromeからそれを起動させれば、Android2.3の時とほぼ同じ感じで見れるので、問題無いっぽいです。


良いところ

(1) ホーム画面にフォルダを作れる

結構便利です。
使用するアプリの種類が多い人にとっては嬉しいと思います。

(2) 電池持ちが若干良くなったかも

描画処理の仕様変更によるプラスの影響かも。


(3) Chromeが使える


パソコンのブックマークと共有できます。
あと、個人的には標準のブラウザよりも使い易い。



概ね想定通りです。
微妙なところは、使っていくうちに慣れるかも。

ただ、総合していえることは、「通常のユーザは現時点では2.3にしておいた方が良い」です。
総合的に見て、Android2.3からAndroid4.0にすると損するケースの方が多いかもしれません。
どちらかといえば、デベロッパに叩いて貰うためのリリースだと思います。
ゲームや動画は見ない人にとっては、電池持ちが良くなったメリットは大きいので、アップしても良いかも。

なお、フラッシュが使えなくなったことで、当初色々とデメリットがありそうだと思ってましたが、そうでもなさそうです。ニコニコ動画については、今のところChrome+非公式ツールの方が標準ブラウザ+フラッシュの頃よりも見易くなった気がします。

2012年7月9日月曜日

3面進捗が・・・

結局、NHKがらみの対応(参照)で、殆ど開発が着手できず・・・
実際にやったことといえば、テレビの処分と解約の手続きだけで昨日(7/7)全て完了していたのですが、主に法律関係の調査と理論武装などに若干の時間が掛かりました。法律は難しいですねぇ。でも、法律を勉強するのは楽しいので、あまり入れ込みすぎないように注意する必要があります。(私の場合、下手をするとネタで司法試験予備試験でも受けてみようかという発想になりかねない)

本当は、今日、3面が完成する予定だったんですが、当然ながら完成せず。
9月公開という線については、若干暗雲が立ち込めてきましたが、まだ焦るような時期じゃない。
平日が割りと暇になる頃合なので、平日にチャージできそうですし。

2012年7月7日土曜日

NHKを合法的に解約する。(update-11)

NHKの営業が「契約のことで・・・」と尋ねてきました。
ちなみに、私は真面目にNHK受信料を収めているので、「はて?何事?」と思いながら応対。
どうも、ウチのマンションが共同のBS受信アンテナを設置したようで、テレビ本体にBS受信機能が備わっている場合、BS契約(月額だいたい+1,000円ぐらいup)に切り替える必要があるとのこと。

「えっ?スクランブルとかしてないの!?」と聞いたら、「スクランブルはしてません」とのこと。
つまり、ケーブルを接続すれば、NHKのBS放送が見れる状態だった模様。
地デジ対応のテレビなんて、BS機能が無いものの方が珍しいので、当然、ウチのテレビもアウト。
内心、「ふざけんな!」と思っていましたが、冷静さを欠くと判断を誤る恐れがあるので、グッと我慢。

という訳で、しぶしぶBS契約を締結・・・なんて、する筈もなく、
「テレビ自体見てないから、処分します」
と宣言し、通常のNHK契約を含めて解約することにしました。

ちなみに、私の携帯電話(MotorolaのRazr)は、テレビを見る機能が付いていないので、交換不要な筈。
テレビだけ処分すれば、完全にテレビとの縁が切れる訳です。
つまり、通常のNHK契約も解約可能です。

まぁ、インターネットをやっている家庭から強制的にNHK契約をさせられる方向になれば、再契約が必要かもしれませんが。インターネットでNHK契約なんてふざけた話し(NHKのWEBサイトなんて、今回解約する手続きを調べるために見るのが初)ですが、有り得ない話しでは無いと思います。当然、普通の会社だったら有り得ないこと(普通、契約というのは同意が取れて初めて締結するものなので、NHK契約自体が契約の原則に反しているから、ありえないこと)ですが、NHKの体質を勘案すれば、十分に有り得る話しだと思うので。
※「NHK契約自体が契約の原則に反している」とはいっても、NHKが違法か合法かでいえば、合法です。NHKは特別法により守られているので、一般法における契約の概念には反していますが、合法です。こんな詐欺まがいのものを特別法で保護するのは、如何なものかと思いますが。
①受信機を設置していてもNHKを見なければNHK契約は不要
②NHKは、NHK契約をしない限り閲覧を不可能とする(契約者に限り、閲覧可能とする)処置(スクランブル等)を行う
というのが、本来あるべき姿です。実は、技術的に②は簡単にできます。技術的な詳しい話しは知りませんが、スカパーとかでは出来ているので、NHKに出来ない筈がありません。っていうか、地上ディジタル化しているのだから、技術的なハードルなんて無いに等しい気がします(カンですが)しかし、NHKはそれをやっていません。恐らく、それをやってしまうと既得権益を失うことになるので。

一応、現行の制度では契約を切って問題無いから、正式に解約する手続きとテレビを処分する作業を実施中。
っていうか、NHK契約自体は続けても良かったんですがねぇ。
災害時とかはそこそこ役立つと思っていたので。

割高だとは思っていましたが。
災害時以外には、朝のニュースを見たり、暇な時に相撲を見るぐらい。
朝のニュースは、必要な情報だけ伝えてくれれば良いのに、無駄情報が多いから、無くても問題なし。
たぶん、月額300円(税抜き)ぐらいが適正価格です。

ちなみに民放についてはここ数年間、見たことがありません。


7-Jul 追記(1) (以下、解約に至るまでの軌跡を書き綴っておきます)
なお、かなりバカ正直な方法でNHKと応対して解約することにします。
かなり、攻撃的な対応をされている方が多いようですが、別にNHKに喧嘩を売る気は無いので。
あくまでも法律に則り且つ紳士的に、尚且つNHKから有無を言わせずに解約してみようと思っています。

先ずは、NHKの解約手続きを確認。
NHKの解約手続きは、日本放送協会放送受信規約の第9条に定められています。

以下、現時点の規約から引用。
(放送受信契約の解約)

第9条 放送受信契約者が受信機を廃止すること等により、放送受信契約を要しないこととなったときは、直ちに、次の事項を放送局に届け出なければならない。
1
放送受信契約者の氏名および住所
2
放送受信契約を要しないこととなる受信機の数
3
受信機を住所以外の場所に設置していた場合はその場所
4
放送受信契約を要しないこととなった事由
2 NHKにおいて前項各号に掲げる事項に該当する事実を確認できたときは、放送受信契約は、前項の届け出があった日に解約されたものとする。ただし、放送受信契約者が非常災害により前項の届け出をすることができなかったものと認めるときは、当該非常災害の発生の日に解約されたものとすることがある。
3 NHKは、第1項の届け出の内容に虚偽があることが判明した場合、届け出時に遡り、放送受信契約は解約されないものとすることができる。

先ずは、届けを出すよりも先に受信機の処分を完了させる必要がありそうですね。
それからすぐに届けを出し、届けを出した日以降、解約されたものとなるようです。
ただし、NHKの担当者が、受信機未設置(=処分したこと)の確認をするようで、そこで引っ掛かった場合、解約は無効になるようです。テレビ本体は当然ながら、チューナー類が一切無い状態にしておかないと、このチェックにより「解約無効」となる場合がある点に注意が必要そうです。(ガサ入れでもするつもりなんですかね?勿論、入室して調べる法的な権限など、NHKには無いから、それは有り得ませんが)

届けを出すのと、受信機の処分を平行でやっても問題無いとは思いますが、安全のため、機器の物理的な処分作業を優先した方が良いと思います。

割と面倒。
まぁ、仕方が無い。


7-Jul 追記(2)

ふぅ・・・テレビを処分しました。
購入した小売店が自宅から徒歩3分のところにあるので、直接持ち込みました。
20型とはいえ、重かった...
一応、購入証明として保証書と購入時のレシートを持っていったけど、不要っぽかったです。

リサイクル料金は、収集運搬料金2,625円、テレビリサイクル料2,835円。計5,460円也。
ちなみに、リサイクル手続きの控えは絶対に必要なので、忘れずに貰っておきましょう。
電気屋のおばちゃんは、「要らないと思うけど・・・」と言ってましたが。
ですが、現行の制度を確認する限り、処分の証明は必須な筈なので、絶対に必要になります。
リサイクルが完了したら、次に解約の意思表示です。

意思表示の方法については規定が無いので、どのような手段でもOK(有効)だと思います。
ですが、コールセンターに直接連絡してするのが一番確実なので、電話をしましょう。
電話した際に聞かれた項目は下記。

①契約者情報
・契約番号
・氏名
・住所
・電話番号
を聞かれる。
契約番号は、たまにNHKから届く通知みたいなものに書いてありますので、それを参照。
ちなみに、「BS契約への切り替えのお願い」みたいな通知を発見。(埋もれてました)
それに契約番号が書かれていました。
まぁ、契約番号は無くても問題無いという情報がありますが、有った方がスムースに対応できます。

②解約する経緯
 ⇒ 上述のBS料金の支払いに応じたくないので、テレビを処分したためと回答。

③処分方法(いつ、どのように処分したのか)
 ⇒ 本日、受信機を購入した小売店に持ち込み、家電リサイクルにより処分した旨を回答。
  解約書にその時の控えの写しを添えて欲しいとのことだったので、承諾。
 ※つまり、これが実質的には9条第三項で掲げる項目の対応に相当するという意味で解釈できます。
  だから、リサイクルした時の控えが絶対に必要になる訳です。

④テレビ以外の受信機の所有について
 ・ワンセグ対応の携帯電話機
 ・テレビチューナーを備えたパソコン
 ・テレビチューナーを備えたカーナビ
 などを所有していないか?と聞かれる。
 ⇒ 携帯電話は、ワンセグ機能に対応していないものを所有、
  パソコンには、テレビチューナーを付けていない、
  カーナビはそもそも持っていない、と回答。

要するに、9条一項の1号から4号の内容そのものです。
ポイントは②の回答だと思います。
「既にリサイクル処分した」と伝えておけば、無理な引き止めはされません。
なお、処分方法としては、リサイクル以外に知人へ譲渡などの手段もあるかもしれませんが、証明書付きの売却やリサイクルなどの証拠が残る形にしておいた方が楽だと思います。要するに、客観的に見て処分したことが事実であることを証明できる状態にしておかないと、職員がお宅訪問とか面倒なことになるかも。彼らにとっても死活問題なので、それぐらいはしてくると想定した方が良いと思います。なお、リサイクル費用は、運搬費込みでも受信契約料3ヵ月分で償却できるから、安いものです。

ですが、ウソは絶対についてはいけません。
本当にお金を払ってリサイクル済みだからこそ、毅然と対応できる訳です。
ウソをついたら、矛盾を付かれて解約を引き止められたり、後々係争になるケースも有るので。
ちなみに、NHKとの通話内容は、NHK側で記録&保持しています。(事前にそういう案内をしてます)
NHKは、不正な未契約者を見せしめとして訴訟する魔女狩りみたいなことを稀にやっているのですが、仮に訴訟を受けて法廷で争うことになる場合、この通話記録は有効な証拠となります。
まぁ、訴訟を受けるケースは稀だと思うので、あまり神経質になる必要はありませんが。
ただし、訴訟云々を抜きにして、常識的に考えてウソはダメです。
あくまでも、合法的にNHKとの縁を断ち切りましょう。

その後、1週間程度で解約書を送るから、上記で回答した内容を書き、リサイクル控えの写しを添えて返送すれば、晴れて解約完了になるとのことでした。ただし、期限以内に返送が無かった場合、解約手続き自体が一旦無効になるとのこと。

あと、過払い分の払戻し手段などを確認するやりとりをしました。
(※私は1年毎に一括で料金を支払っていたので)


7-Jul 追記(3)

まぁ、当たり前のことなんですが、解約した場合の今後の注意点など。

①受信機を設置しないこと
現行制度では、受信機を設置した場合、NHKを見るか見ないかに関わらず、契約する必要があります。
なので、受信機を設置しないように気をつける必要があります。

②携帯電話のワンセグもダメ
もちろん、携帯電話のワンセグもダメです。
だから、意識してノンセグ携帯を持つようにする必要があります。
そうなると、選べる機種が限られてきます。

現在、私が使用している、Motorola社のRazrという端末は、ワンセグやお財布ケータイなどの日本国内仕様の機能は実装していないから問題ありませんが、国産メーカーのものだと「ワンセグが付いてて当たり前」なので、気をつける必要があります。

ガラケーの場合、だいたいアウトです。(ほぼ全ての機種にワンセグがついてます)
iPhoneは、ワンセグチューナー(外付け)を買わなければOKです。
Androidは、国産メーカーのものはだいたい付いているから海外メーカーに絞る必要があります。

Androidに関しては、Motorola一択ですかね。
ちなみに、私がMotorolaを選んだのは、「ワンセグが付いていないから」という訳ではないです。
敢えて、Motorola製(マニアックな機種)を選んだのは、単純にMotorolaに思いいれがあるため。
ただ、Motorolaは、将来的にはお財布ケータイやワンセグに対応したものも出すとかなんとか・・・
まぁ、そうなったら今のRazrを使い続けるしかない。


7-Jul 追記(4)

「受信機を設置するが、NHK契約を締結しなくても良い」というパターンを念のため調べました。
どうやら、事実上できそうなのは、回線をケーブルテレビにしてアンテナを取っ払うぐらいですかね。
まぁ、しませんけど。
そもそも、借家住まいだから出来ないですし、そこまでしてテレビを見たい欲求は無いです。

最もリーガルな解決策は、(上の方でも書いてますが)NHKが放送をスクランブル化すること。
まぁ、それは無理でしょう。
「NHK自身がやらないといけない⇒NHKが自らの首を絞めなければいけない」ということになるので。
別にNHKの肩を持つ訳ではないですが、それは商売人として当然な行為だと思います。

NHKを商売人というのは語弊がありますが。
実際、彼らの言い分はそんなストレートなものではなく、
「全国どこでも放送を分けへだてなく視聴できるようにする、という公共放送の理念と矛盾する」
「特定の利益や視聴率に左右されず、視聴者の視点にたって、多様で良質な番組を放送するべき」
という、感じです。

ちなみに、上記(青字)の主張が、真っ当な主張に見えますか?
私の目には、以下のように映って見えます。
「誰でもいつでも見れるようにしてやってるんだから、全員漏れなく受信料払えよ!」
 - 日本国内の何処であっても、NHKが必ず見れるように努めているのだから、テレビを設置する以上、
  契約締結は必須という、NHKにおける放送法の解釈に関する主調(アピール)だと解釈できます。
「俺達の番組サイコー!異論は認めない!」
 - NHKが視聴者の視点にたって(=自分達の視点で)良質と評価俺達サイコー と解釈できます。
 - 利益や視聴率に左右されず = 異論は認めない と解釈できます。

ひねくれ過ぎかも。
大人はイヤですねぇ。。
ちなみに、NHK(日本放送協会)というのは普通の民間企業(会社法に基づく株式会社)ではなく、社団法人(旧民法に基づく公益法人 又は 現在の一般社団法人及び一般財団法人に関する法律に基づく一般社団法人)だったと思うので、建前上、「利益追求」とは言えないという事情があるのだろうと、思います。なお、誤解しがちかもしれませんが、公益法人というのは、ボランティアではありません。つまり、営利活動をする事は法律上問題ありません。法人が目的とする活動をするのに必要な資金を得る程度の営利活動は、認められます。ただし、余剰利益の分配(株式会社でいうところの配当のようなもの)は違法だった気がします。要するに、「必要以上の利益を得てはいけない」という縛りがあります。彼らの目的(存在の意義)は活動を継続することであって、利益を追求することであってはなりません。職員の平均年収1,000万以上あって平然と「過剰な利益を得ていない」とドヤ顔で言える神経は、全く理解できません。平均年収を500~600万程度に調整し、余剰金は過払い金として、契約者に返還すべきではないでしょうか?まぁ、NHKの法人としての存在意義に関する意見は、私にとっては過去のものになります。少なくとも、私は晴れてNHKとは無関係になるので、意見をいう立場の人間ではありません。ただ、現状契約が完全に切れていないので、今の内に意見を言っておきたかっただけです。気にしないでください。後のことは、NHKと利害関係者が有る方々で頑張ってください。

別のリーガルな解決策としては、NHKを受信できない仕様のテレビを作ること
技術的には、テレビに組み込んでいるコンピュータのプログラムを少し弄るだけで、簡単にできます。
要するに、「家電業界がそういうテレビを作ろうと思えば、簡単に作れる」ということです。
ただし、市販品でそういうテレビが出ることが無いのは、既にネマワシ済みという意味だと思います。
あまり深く首を突っ込まない方が良さ気な話題っぽいので、考えない方が幸せになれます。
考えすぎかな?
ホント、大人はイヤですねぇ。。。


8-Jul 追記(5)

さて、万が一、私の手続きになんらかの不備があり、解約後に解約が無効(9条第三項を適用)となった場合、「幾らぐらいの料金を遡及的に取られ得るか?」という点について、整理しておこうと思います。
ちなみに、私は法律に関しては(今回少しだけ勉強したけど)基本的に素人です。
なので、色々と違ってるかも。
まぁ、私が理解した範囲で書きます。

私が解約に至るまでに実施した手順について、私には一切の落ち度は無いと思います。
そして、一切の虚偽をしていません。
この場合、何らかの抜けがあったとすると、無過失善意ということになります。
果たして、無過失善意の相手から、遡及的に料金を請求できるのか?

答えは、否です。
ビタ一文たりと、払う必要はない筈です。

私の法律解釈では、無過失善意ということは、NHKが提供する役務(サーヴィス)の提供を現に受けていないことにもなります。現に提供を受けていない役務に対する対価を支払う必要は無い筈なので、ビタ一文たりと、払う必要はない筈と解釈しました。

過失(履行して然るべき義務の不履行)があった場合(善意過失)、若干微妙です。
ですが、役務の提供を受けていないので、料金を支払う謂れは無いと思います。
そもそも、9条第三項でも、無効の条件を「虚偽があった場合」に限定してますし。
なので、その場合も解約は無効にはならない筈です。

それでは、仮に「故意に受信装置導入するが再契約をしない(=悪意)」又は「虚偽」があった場合、どうなるか?
もちろん、私にはそういうことをする意思は無いです。
私は、信義に従い誠実に義務を履行している清く正しい人間なので。
(まぁ、自分のことを「清く正しい」とか言ってしまっている人は、だいたいドス黒い訳ですが)

悪意で受信装置を設置した場合、受信装置を設置した時点から、料金の支払い義務が発生します。
虚偽があった場合、解約自体が不成立となります。
それらが、遡及される始点となります。

原則的には、遡及される始点から現在に至るまでの期間の料金を支払う義務が生じる筈です。
ただし、日本の法律には「時効」というものがあります。
時効が成立する分の料金については、支払う必要がありません。
役務(商品)の対価の支払いに対する時効は、2年で成立します。
なので、私の法律解釈では、支払うべき料金は最大で2年分という結論になりました。

・・・しかし、判例によると最大5年分支払わされているようです。
どうやら、税金とか家賃の時効と同じく、民法169条の規定により時効が設定さている模様。

NHKの契約料って役務の提供に対する対価じゃないという判断?
「放送」とは、常識的に考えて役務の提供だと私は思いますが。
でも、専門家がそう判断したのなら、それが正しいのでしょう・・・俄かには信じ難いですが。

まぁ、法律のことはよく分からんです。

ちなみに、時効の適用については、自動ではないので注意が必要です。
例えば、10年間NHK受信料を払っていなかった人に対して、NHKが「10年分払ってください」と言ってきて、それに応じた場合は払う必要があります。つまり、「時効が成立している分については払いませんよ」と明確に断らない限り、時効が適用されることはありません。(つまり、主張が無ければ時効を適用しなくても良いということです)

■私の法律解釈(念のため)
債権一般の時効は10年です。(民法167条1項)
年又はこれより短い時期によって定めた金銭その他の物の給付を目的とする債権は5年です。(民法169条)
そして、民法173条では次のように規定しています。

第百七十三条  次に掲げる債権は、二年間行使しないときは、消滅する。
  生産者、卸売商人又は小売商人が売却した産物又は商品の代価に係る債権
  自己の技能を用い、注文を受けて、物を製作し又は自己の仕事場で他人のために仕事をすることを業とする者の仕事に関する債権
  学芸又は技能の教育を行う者が生徒の教育、衣食又は寄宿の代価について有する債権


私の解釈では、NHKが提供する役務(それを商品と解釈)に対する対価に関する債権は、173条1項に該当します。
つまり、NHK受信料とは、NHK(役務商品の生産者)が売却した商品に対する対価だと思っています。
だから、時効は2年の筈です。
しかし、判例は169条と判断。
173条1項を適用しないとする根拠は不明です。

裁判の記録を調べれば何か分かるかもしれませんが、そこまで調べるのは面倒くさい。
そもそも、時効に該当する期間について、不正に役務を受けてた可能性はある訳なので支払うべき・・・という理屈に、正当性があるようにも思いますし。

あと、173条ではなく174条2項に該当するという意見もあります。
174条2項 = 自己の労力の提供又は演芸を業とする者の報酬又はその供給した物の代価に係る債権
174条2項に該当する場合の時効は1年です。
ですが、これの適用は無理がありそうな気がします。
174条2項で規定している債権は、例えば歌舞伎の演技などに対する対価とかを指すと思うので。



8-Jul 追記(6)

放送法64条の解釈について、割と微妙な解釈をしているところが見受けられました。
放送法64条は、受信契約が必要な場合を規定した法律で、次のように規定しています。
第六十四条  協会の放送を受信することのできる受信設備を設置した者は、協会とその放送の受信についての契約をしなければならない。ただし、放送の受信を目的としない受信設備又はラジオ放送(音声その他の音響を送る放送であつて、テレビジョン放送及び多重放送に該当しないものをいう。第百二十六条第一項において同じ。)若しくは多重放送に限り受信することのできる受信設備のみを設置した者については、この限りでない。
  協会は、あらかじめ、総務大臣の認可を受けた基準によるのでなければ、前項本文の規定により契約を締結した者から徴収する受信料を免除してはならない。
  協会は、第一項の契約の条項については、あらかじめ、総務大臣の認可を受けなければならない。これを変更しようとするときも、同様とする。
  協会の放送を受信し、その内容に変更を加えないで同時にその再放送をする放送は、これを協会の放送とみなして前三項の規定を適用する。

私の言う「微妙な解釈」というのは「受信料の支払い義務についての解釈について」です。
放送法64条では、「条件に該当する場合、受信についての契約をしなければならない」としています。
それについて、「契約は必要だが受信料の支払いは不要」とか「受信料の支払いは任意である」という解釈をされている方が結構います。しかし、その解釈は明らかにオカシイです。契約した以上、原則的には受信料を支払わなければなりません。

一般論ですが、契約というのは「権利の取得と義務の履行に関する約束」です。
例えば、AさんとNHKの間で契約を締結した場合、次の権利と義務が同時に発生します。
・Aさんは、放送を受信する権利を得て、NHKは、放送を発信する義務を負う。
・Aさんは、受信料を支払う義務(債務)を負い、NHKは、受信料を受け取る権利(債権)を得る。

そして、契約書では受信料を2,690円(2ヶ月)、7,650円(6ヶ月)又は14,910円(1年)と規定しています。放送法で規定する「放送の受信についての契約」がこの契約を指すものだとすれば、契約締結=債務を負うことについて同意となります。
という訳で、「契約はするが受信料は支払わないぜ!」という理屈は成立しません。
その理屈を成立させるには、放送の受信についての契約」が債務と債権が発生しない形態の契約でなければなりません。(もしかして、「契約は必要だが受信料の支払いは不要」というのは、そういう形態の受信契約が実は存在するという意味?)

たぶん、条文をそのまま読むと「放送の受信について」だけしか規定していないように見えるから勘違いし易いのだろうと思いますが。 「放送の受信についての契約」 で債務と債権の規定がある以上、放送法64条で規定する契約と受信料の支払いはワンセットと解釈するのが普通だと思います。


8-Jul 追記(7)

テレビを処分した状態で丸一日過ごしましたが、不便だと思ったのは、朝起きた時の1回のみ。
私は、習慣的に朝起きてとりあえずテレビを点けてから、食事をしていたようです。
脳の働きが鈍い状態だと、受動的に情報を受信する方式の方が楽。

ラジオでも設置しようか。
上述の放送法64条でも規定されていますが、ラジオについては受信料を支払う義務は無いものとしてます。

ただ、ソレは結構微妙です。
ラジオ放送にも当然コストは掛かっている訳で、そのコストは受信料で賄っている訳なので。
つまり、謂れの無い施しを受けることになります。
生活保護の不正受給みたいな感じ?

なので、ラジオも設置しない方向で。
まぁ、ちゃっちゃと脳をフル稼働状態にすれば問題ありません。

割とオススメなのは、従来テレビを見ていた時間、テレビの代わりに部屋の掃除をすること。
そうすれば、手持ち無沙汰みたいな感じにならないし、目も覚めます。
ついでに、部屋もキレイになります。
いわゆる代償行為というやつですかね。


11-Jul 追記(8)

まだ、解約通知は届かず。
「1週間以内に送る」といっていて、それについては了承したので、1週間は待ちますが。
今週の土曜日に届かなかった場合、再度コールセンターに連絡して、「独自形式で9条一項の規定を満たす文書を送るがそれで良いですか?」と聞いてみるつもり。

NHKに解約通知が到達した日が見做し解約日になるので、到着タイミング+到着有無についての避けるため、解約通知は配達記録郵便で送るべきかな。


14-Jul 追記(9)

昨日(13日)か一昨日(12日)に、通知が届いていました。
内容物は準備完了。
あとは送るだけです。

ちなみに、配達記録って2009年ごろに廃止になっていたようです。知らなかった。
特定記録とか、簡易書留とかいうのが代わりにあるようです。
まぁ、普通郵便で出しておきますが。

これで、無事到着してくれれば、晴れて解約完了となります。
しかし、やっぱりテレビが無いのは(特に朝の時間に)不便ですね。
ニュース等は携帯電話(スマホ)だけで十分仕入れることができますが、やはり、受動的に情報が入ってくる方が楽といえば楽なので。その内慣れると思いますが。

ちなみに、会社の人にテレビを捨ててNHKを解約したことを話したら、驚かれました。
テレビを捨てる(家電リサイクルに出す)ことを即日で決断&決行したことについて。
「別に捨てる必要は無かったんじゃない?」
「誰かにあげたことにすれば良かったのでは?」
というような反応。
これは至極真っ当な反応だと思います。

なお、処分方法については譲渡ということでも全く問題ありません。
コチラが「譲渡して処分した」と言い張れば、NHKはそれを信じるしかないので。
何らかの証明を求めてくる可能性はありますが、それに応じる義務はありません。
そもそも、NHKに対して処分を証明する義務も無いです。

そもそも、NHKが詐欺まがいのこと(スクランブル非対応)をやっていることが悪いです。
例えば、大道芸人が街中で大道芸を披露して、それを偶然目にした人に対して閲覧料金を請求しているようなものなので。
だからといって、悪に対抗する手段が悪であってはいけません。
真面目に受信料を支払っている方も居る訳で、ウソをついてテレビを持ったまま解約したり、テレビを持っているのに契約しないのは、受信料を支払っている方々から謂れのない施しを受ける事になるので。

謂れの無い施しを受けた場合、別の形でそれを返さなければいけない時が来る・・・かどうかは定かではありませんが、私は、「少なからずそういうことは有る」と思っておくようにしています。
それがプラスになることは何もありません。
マイナスになることもありません。
プラマイ0です。
それが理想形。



10-Aug 追記(Last)

今日、口座の取引履歴を確認していたら、過払い分の受信料(※年払いで契約していたので8月以降の支払い分)の払戻しがされていたので、無事、解約できたことの確認ができました。という訳で、ここに書いてある内容通りに手続きを踏めば、トラブル無くNHKの受信契約を解約できるので、ご参考まで。

あと、緊急時用に情報が得られないのはやっぱり不安だったので、ラジオ(1,000円ぐらいのやつ)は設置しました。(現行の)放送法の規定では、ラジオ設置の場合には受信料は発生しないので問題ありません。ただし、ラジオ放送のコストはテレビの受信料で賄っているものなので、テレビ受信料を納めている方々に感謝しつつ、使う事にします。

合理的ではないものを作りたい

ここ最近、実機版の東方VGSの開発が忙しくて、東方VGSの曲追加が滞っています。 東方VGS(実機版)のデザインを作りながら検討中。基本レトロUIベースですがシークバーはモダンに倣おうかな…とか pic.twitter.com/YOYprlDsYD — SUZUKI PLAN (...