2013/09/30

Eclipse CDT 上で Android NDK を使った JNI 作成環境を構築する

昔はコマンドラインから ndk-build を叩かないといけなかった Android NDK ですが、 いつの頃からか、Eclipse CDT 上でビルド出来るようになりました。
せっかくの統合開発環境ですから、これを使わない手はありません。
というわけで、環境構築方法を書いておこうと思います。

以下、前提条件です。
  • ADT インストール済みで Java アプリケーションが作れる
  • CDT がインストール済み
  • Android Native Development Tools がインストール済み

Preprocessor Include Paths を無効にする

Eclipse 4.2 (JUNO) 以上を使用している場合は、以下の作業をしておかないと include path が適切に処理されません。
Android Native Development Tools が新しい CDT の機能に対応していないのが原因のようなので、そのうち必要なくなるかもしれません。

Window → Preferences → C/C++ → Property Pages Settings

Display "Preprocessor Include Paths" page のチェックを外す。
この作業は Workspace 毎に一度行えば大丈夫です。


既存のAndroidプロジェクトに JNI を追加する

まず、普通に Android アプリケーションプロジェクトを作成します。
その後、
プロジェクトを右クリック → Android Tools → Add Native Support...

jni ディレクトリが作成され、Android.mk 等が作成されているはずです。

ビルドする

Project → Build Project
libs 以下に soファイルが作成されます。

あとは、普通のJNI プロジェクトとして作成すればOKです。

2013/09/27

Android NDK で出力ディレクトリを libs 以外にする方法

Android NDK でデフォルトディレクトリを jni 以外にしてみたのは良いのですが、実行ファイルなのに libs ディレクトリに出力されるのはいかがなものかと名は体を表すべきなのです。
というわけで、libs ディレクトリ以外に出力する方法も書いておきます。

方法は簡単で、以下のように NDK_APP_DST_DIR に出力先のディレクトリを指定してやるだけです。

$ ndk-build NDK_APP_DST_DIR="${PWD}/out/\$(TARGET_ARCH_ABI)"

デフォルトだと、out/armeabi 以下に成果物が出力されます。

TARGET_ARCH_ABI の前の $ がエスケープされていることに注意してください。
TARGET_ARCH_ABI はターゲットアーキテクチャで、ビルドターゲットによって変わります。
つまり、このコマンドを実行した段階では展開してはいけません。
後展開するように、$ をエスケープしているわけです。

Windows の場合は以下のようになります。
> ndk-build.cmd NDK_APP_DST_DIR="%cd%/out/$(TARGET_ARCH_ABI)"

Windows の場合は $ が環境変数として展開されませんので、エスケープする必要はありません。


Android NDK でデフォルトディレクトリを jni 以外にする方法

Android NDK のビルドツール ndk-build はデフォルトでプロジェクト直下の jni ディレクトリを見に行き、その Application.mk もしくは Android.mk から処理を開始します。
JNI 製作時は便利なのですが、実行ファイルを作りたい時などは、「jni というディレクトリ名はどうなのよ?」って思いますJNI じゃなくても、jni ディレクトリ以下に作っておけば良いという考え方もあるかもしれませんが、やはり名は体を表すべきです。
他人(未来の自分)が混乱するものは極力避けるべきでしょう。


というわけで、任意のプロジェクト構成で ndk-build する方法を探ってみました。
例として、以下のような構成のプロジェクトで Android 用の実行ファイルを作成してみます。

$(NDK_PROJECT_PATH)/
                   |-src/
                   |    |-HelloWorld.c
                   |    |-Android.mk
                   |
                   |-Application.mk

Application.mk を作成する

正確には、Application.mk を作成しなくても良いのですが、柔軟なプロジェクト構成のためにはあったほうが良いでしょう。
基本的には、プロジェクトディレクトリの直下に配置します。

Application.mk
APP_PROJECT_PATH := $(NDK_PROJECT_PATH)

# ターゲットの Android.mk を指定する
APP_BUILD_SCRIPT := $(APP_PROJECT_PATH)/src/Android.mk

プロジェクト作成

プロジェクトの作成は、jni 以下に作成するのと同様に行います。
例えば、以下のような感じです。

src/Android.mk
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := a.out
LOCAL_SRC_FILES := HelloWorld.c

include $(BUILD_EXECUTABLE)

本筋とは関係ないですが、一応ソースコードも載せておきます。

src/HelloWorld.c
#include <stdio.h>

int main(int argc, char *argv[]) {
 printf("Hello world.");
 return 0;
}

ビルド

プロジェクト直下で、ndk-build を実行します。
この時、以下のようにオプションを追加するところがポイント。

$ ndk-build NDK_PROJECT_PATH=${PWD} NDK_APPLICATION_MK="\$(NDK_PROJECT_PATH)/Application.mk"
Compile thumb  : a.out <= HelloWorld.c
Executable     : a.out
Install        : a.out => libs/armeabi/a.out

NDK_PROJECT_PATH にプロジェクトのルートディレクトリ。
NDK_APPLICATION_MK に Application.mk ファイル。
上記2点を適切に指定する必要があります。

実行すると、無事 libs/armeabi/a.out が作成されました。

また、Windows の場合は以下で同様の処理が可能です。
> ndk-build.cmd NDK_PROJECT_PATH=%cd% NDK_APPLICATION_MK="$(NDK_PROJECT_PATH)/Application.mk"
"Compile thumb : a.out <= HelloWorld.c
Executable     : a.out
Install        : a.out => libs/armeabi/a.out

Windows の場合は $(PWD) が定義されていませんので、同様の環境変数 %cd% を使用してやる必要があるわけです。

参考
作成した実行ファイルをエミュレータ等に送って実行したりできます。
Android NDK で .so ではなく、実行ファイルをつくる - Hacking My Way ~ itogのhack日記


2013/09/17

ミュージックサーバ用に SONY SRS-D5 を買ってみた

BeagleBoard-xM でミュージックサーバを構築したので、新たにスピーカーを買ってみました。

最初は、以前から持っている audio-technica AT-SP92を使いまわそうと思っていたのです。

このスピーカー、小さい割には良い音なので BeagleBoard-xM にはピッタリなのですが、既に別の用途で使ってたので、別のものも検討してみようかなと。
古い AT-SP92

で、検討した結果、SONY SRS-D5を買ってみました。
決め手は、5000円を切る値段とオートパワーオン/オフ機能です。
BeagleBoard-xM がせっかく低消費電力なのに、スピーカーがつきっぱなしというのは残念ですから。

で、買ってみてどうかというと、今のところ、かなり満足しています。
少し大きいのが玉にキズですかね。
音響に関しては素人なので、音質云々は語れないのですが、結構良い音なのではないかと思います。
オートパワーオン/オフ機能もうまく動いています。
サブウーファーがコンポの本体みたい
本物の本体は普段は後ろに隠しておきます

今回はリビングに設置するので、大きめでも良いという結論になって買ってみました。
とはいえ、BeagleBoard-xM と比べるとその大きさが際立ちます。
まー、どうせ本体は見えない所にあるわけですから、別に構わないんですけど。

しかし、MPDは便利です。
家中に設置したら面白いだろうなー。狭い家なんで全く意味ないですけどね…。



ちなみに、他にもオートパワーオン/オフ機能がついたスピーカーを探したのですが、そんなに数は無さそうです。
今回の用途に使えそうなのは、以下くらいでしょうか。

2013/09/16

MPDroid の使い方

BeagleBoard-xM 上にミュージックサーバを構築してみたので、手元の Android 端末 (Xperia acro HD) でコントロールしてみたいと思います。
Android 用のクライアントはいくつかありますが、その中でも評判の良い MPDroid を使ってみることにしました。
参考
その他の MPD クライアント
Clients - Music Player Daemon Community Wiki

2013/09/15

BeagleBoard-xM 上で MPD を動かし、ミュージックサーバを構築する

我が家では NAS を設置して、その中に音楽ファイルを入れています。
PC間で音楽をシェアして便利に使っているのですが、一つ問題が。

私の持っているノートPCは音がひどいのです。
音楽を聴くのにはとても使えません。
リビングなどで作業する時には、小さなスピーカーも一緒に持って行くのですが、これがとても面倒臭い。

そこで、リビングに MPD (Music Player Daemon) サーバを設置してみることにしました。
MPD はリモートで音楽を再生するためのサーバで、スマホなどから遠隔操作で音楽再生を行うことが出来ます。

しかし、リビングに新しいPCを設置するなんて本末転倒ですリビングで作業するときにはそのPCを使えば良い訳ですから
そんな時こそ、BeagleBoard-xM の出番以前、購入したもの。
新規購入の場合は BeagleBone BlackRaspberry PiCubox 等も候補に上がりそうです。

小さいし、低消費電力なので、MPDサーバにはぴったりと言えます。
5W 以下のようなので、電気代は100円/月以下で抑えられそう。

というわけで、実際にやってみました。
構成の簡略図は以下のような感じ。

NAS に入っている音楽ファイルを、BeagleBoard-xM にネットワークマウントし、それをスピーカーから鳴らすわけです。
音楽の再生・停止や音量のコントロールはスマホ等、同一ネットワーク内にある MPD クライアントから行います。

以降は、BeagleBoard-xM に Ubuntu 13.04 がインストールされていて、 ディスプレイ、キーボード、スピーカーが接続されている状態を前提としています。

2013/09/12

BeagleBoard-xM 上に Ubuntu 環境を構築する

BeagleBoard-xM で MPD サーバを構築しようと思い立ちまして、やってみました。
OS の選択はいくつかあるのですが、今回は扱いやすい Ubuntu 13.04 にしてみました。
参考
http://elinux.org/BeagleBoardUbuntu
Method 1: Download a Complete Pre-Configured Image

以下は、デスクトップマシン(Ubuntu 12.04 LTS)での作業です。
2014/2/22 追記
Raw Image を直接書き込む方法を書きました。
この方法ならば Windows でも大丈夫です。
穀風: BeagleBoard-xM 上に Ubuntu 環境を構築する (Windows 編)

Raw Image を用意

まずは、イメージをダウンロードして解凍。
その後、チェックサムを確認します。
$ wget https://rcn-ee.net/deb/rootfs/raring/ubuntu-13.04-console-armhf-2013-08-24.tar.xz
$ echo "026d8809821c9b6438f1d8ec4991aa58  ubuntu-13.04-console-armhf-2013-08-24.tar.xz" | md5sum -c - 
ubuntu-13.04-console-armhf-2013-08-24.tar.xz: OK
$ tar xJf ubuntu-13.04-console-armhf-2013-08-24.tar.xz

micro SD カードスロットの確認

カードリーダに micro SD card を入れ、以下のコマンドを実行。
$ cd ubuntu-13.04-console-armhf-2013-08-24/
$ sudo ./setup_sdcard.sh --probe-mmc
Are you sure? I Don't see [/dev/idontknow], here is what I do see...

fdisk -l:
Disk /dev/sda: 120.0 GB, 120033041920 bytes
Disk /dev/sdb: 1000.2 GB, 1000203804160 bytes
Disk /dev/sdc: 2000.4 GB, 2000398934016 bytes
Disk /dev/sdd: 1000.2 GB, 1000203804160 bytes
Disk /dev/sde: 3951 MB, 3951034368 bytes
Disk /dev/mapper/isw_ecbcbgbcii_Volume0: 1000.2 GB, 1000201129984 bytes
Disk /dev/mapper/isw_ecbcbgbcii_Volume0p1: 1000.2 GB, 1000199946240 bytes

# 以下略
今回は 4GB の micro SD Card を用意したので、/dev/sde が対象であることがわかります。

イメージの書き込み

以下のコマンドでイメージを micro SD Card に書き込みます。
注意:/dev/sde はご自分のデバイスと読み替えてください。誤ったデバイスを指定すると、その内容を全消去してしまいます!
$ sudo ./setup_sdcard.sh --mmc /dev/sde --uboot beagle_xm --swap_file 512

確認のメッセージが表示されます。
くどいようですが、間違ったデバイスを指定していないことを確認の上、y を入力します。
Are you 100% sure, on selecting [/dev/sde] (y/n)?

書き込みが始まります。
少々、時間がかかります。
以下のようなメッセージが表示されたら終了です。
Finished populating rootfs Partition
-----------------------------
setup_sdcard.sh script complete
-----------------------------
The default user:password for this image:
ubuntu:temppwd
-----------------------------
デフォルトのユーザ名とパスワードが表示されているので覚えておきます。
ユーザ名: ubuntu
パスワード: temppwd

起動

micro SD Card を BeagleBoard-xM に挿入し、電源をつなぎます。
この時、ディスプレイ、キーボード、イーサネットはつないでおいた方がよいです。

ディスプレイに起動画面が表示され、数秒でログイン画面になりました。
先ほどの ubuntu:temppwd でログインします。

パスワード変更

必須ではないですが、セキュリティ的にはパスワードを変更しておいた方が良いでしょう。
$ passwd
Changing password for ubuntu.
(current) UNIX password: 
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully

以上でOSのインストール終了です。