2013年8月30日金曜日

AndroidでのOpenSLの利用

AndroidでOpenSLを利用する際見ておくべき情報などメモ

1.公式ドキュメント

NDKインストール時に含まれているもの。
パスは<NDK-PATH>/docs/opensles/
で、内容は下記の2つ

- OpenSL_ES_Specification_1.0.1.pdf
     OpenSL ESの仕様書。これはAndroidに特化したものではない。
  なので、ここにあるもの全てが使えるわけではないので、その辺りは下記index.htmlを確認する必要がある。

 - index.html
     OpenSLのAndroid実装についての解説。
     webでも見ることができる→OpenSL ES for Android

    

2.サンプル

 - 上記OpenSL_ES_Specification_1.0.1.pdfの最後の方
   再生や録音の基本的なサンプルがある。

   →日本語訳
    これはサンプルというよりコードを交えた解説。日本語の情報としては一番内容が濃いと思う。

 PCMデータにデコードするコードが「動かないもの」として載ってる。
 読めばわかるように、バッファを2つEnqueueしてやれば動く
 こんな感じ↓
// enqueue a buffer and start playing
    CK_SL_VERIFY( (*g_playerBufferQueue)->Enqueue(g_playerBufferQueue, g_buf, k_bufSamples * sizeof(int16)) );
    CK_SL_VERIFY( (*g_playerPlay)->SetPlayState(g_playerPlay, SL_PLAYSTATE_PLAYING) );
// enqueue a buffer and start playing
    CK_SL_VERIFY( (*g_playerBufferQueue)->Enqueue(g_playerBufferQueue, g_buf, k_bufSamples * sizeof(int16)) );
    CK_SL_VERIFY( (*g_playerBufferQueue)->Enqueue(g_playerBufferQueue, g_buf, k_bufSamples * sizeof(int16)) );
    CK_SL_VERIFY( (*g_playerPlay)->SetPlayState(g_playerPlay, SL_PLAYSTATE_PLAYING) );

必要に応じてバッファを変えてあげて下さい。


エラー:Androidでのundefined reference to 'foo()'への対処

AndroidのNDKを使った開発で、undefined reference to 'foo()'が出た場合の対処例のメモ。

1.android.mkのLOCAL_SRC_FILESにfooを宣言しているファイル(例えばfoo.c)があることを確認

LOCAL_SRC_FILES := foo.c


2.(fooがcppファイルで宣言されていて、cファイルからの参照するときにエラーが出る場合のみ) foo()を宣言しているヘッダがextern "C"{}で囲われていることを確認(includeガードをしている場合は最初のincludeでこうなっていることを確認)

extern "C" {
#include "foo.h"
}

3.(別のライブラリとしてビルドしている場合のみ)android.mkのライブラリー関連の記述が正しいか確認

以下のようにfoo.cを含むライブラリーを静的ライブラリとしている場合は、
LOCAL_MODULE := bar
LOCAL_SRC_FILES := foo.c
include $(BUILD_STATIC_LIBRARY)

呼び出し側のライブラリの記述に以下を追加
LOCAL_STATIC_LIBRARIES := bar

共有ライブラリとしている場合( include $(BUILD_SHARED_LIBRARY) )は
LOCAL_SHARED_LIBRARIES := bar