ホーム > デベロッパ > BREW プログラミング入門 > 音を出してみよう > - 3 / 3 -

音を出してみよう - 3 / 3 -

今回のサンプルアプリ

今回のサンプルアプリでは、前述の三通りの方法で MIDI ファイルを再生しています。

アプレット構造体は次のようになります。

// アプレット構造体
typedef struct _PlayMedia {
    AEEApplet     a;      // 最初のメンバは必ず AEEApplet にすること
    IMedia*       media;  // IMedia 派生インタフェース
    AEEMediaData  mdata;  // メディア データ
} PlayMedia;

IMedia インタフェースを使うためには、ソースコードに AEEMediaFormats.h をインクルードする必要がありますので、忘れないでください。

方法 1 の実装

IMediaUtil を使用して再生するコードを以下に示します。

//
//  IMediaUtil インタフェースを使用して、
//  MIDI ファイルを再生します。
//
static void PlayMedia_PlaySound1(PlayMedia* app)
{
    IShell* shell   = app->a.m_pIShell;
    IMediaUtil* mutil = NULL;
    const char* filename = "test.mid";

    ISHELL_CreateInstance(shell, AEECLSID_MEDIAUTIL, (void**) &mutil);
    if (mutil != NULL) {
        app->mdata.clsData  = MMD_FILE_NAME;
        app->mdata.pData    = STRDUP(filename);
        app->mdata.dwSize   = 0;

        IMEDIAUTIL_CreateMedia(mutil, &app->mdata, &app->media);
    }
    IMEDIAUTIL_Release(mutil);

    if (app->media != NULL) {
        IMEDIA_Play(app->media);
    }
}

※IMediaUtil インタフェースは BREW 2.1 ではじめて導入されたインタフェースです。このインタフェースは「BREW API リファレンス」では解説されていません。 BREW SDK 2.1 日本語版の「BREW 2.1 新インタフェースリファレンス」のほうに解説があります。

IMedieUtil インタフェースを使用するには、まず始めに ISHELL_CreateInstance() でオブジェクトを取得する必要があります。取得しましたら、 IMEDIAUTIL_CreateMedia() にファイル名を渡すだけでそのファイルを再生するための IMedia 派生インタフェースを作成して返してくれます。非常に簡単ですね。

今回のサンプルでは MIDI ファイルを指定していますが、 IMediaUtil を使用する場合は、端末がサポートしているメディア形式であれば、どのようなファイルを指定しても構いません。

IMediaUtil はファイルのメディア形式を自動的に判別して、その形式を再生するのにふさわしい IMedia 派生インタフェースを作成してくれます。

IMediaUtil を使い終わったら解放することを忘れないでください。それから、 IMedia 派生インタフェースを作成した後で IMEDIA_Play() を呼び出さないと、実際に音声が流れないので注意しましょう。

※IMediaUtil はファイルの拡張子によって形式を判別する、と「BREW API リファレンス」に記述があります。したがって、ファイルの拡張子は適切なものをつけてください。

方法 2 の実装

メディアのデータ形式が分かっている場合、 IMedia 派生インタフェースを明示的に作成して、メディア データをセットアップすることもできます。下記のコードでは、ファイル名を指定して MIDI データをセットアップしています。

//
//  IMediaMIDI インタフェースを作成して、
//  MIDI ファイルを再生します。
//
static void PlayMedia_PlaySound2(PlayMedia* app)
{
    IShell* shell   = app->a.m_pIShell;
    const char* filename = "test.mid";

    // IMediaMIDI インタフェースを取得して、再生データをセットする。
    ISHELL_CreateInstance(shell, AEECLSID_MEDIAMIDI, (void**) &app->media);
    if (app->media != NULL) {
        app->mdata.clsData  = MMD_FILE_NAME;
        app->mdata.pData    = STRDUP(filename);
        app->mdata.dwSize   = 0;

        IMEDIA_SetMediaData(app->media, &app->mdata);
        IMEDIA_Play(app->media);
    }
}

方法 3 の実装

メディア データは、必ずしもファイルで提供する必要はありません。下記のコードでは、メモリ上のメディア データを再生しています。

//
//  ファイルから独自に MIDI データを読み取り、
//  IMediaMIDI インタフェースを使用して再生します。
//
static void PlayMedia_PlaySound3(PlayMedia* app)
{
    IShell* shell   = app->a.m_pIShell;
    IFileMgr* filemgr;
    IFile* file;
    uint32 filesize;
    const char* filename = "test.mid";
    FileInfo fileinfo;

    // ファイルを開く
    ISHELL_CreateInstance(shell, AEECLSID_FILEMGR, &filemgr);
    file = IFILEMGR_OpenFile(filemgr, filename, _OFM_READ);
    if (file == NULL) {


        IFILEMGR_Release(filemgr);
        return;
    }

    // ファイル サイズを取得する
    IFILEMGR_GetInfo(filemgr, filename, &fileinfo);
    filesize = fileinfo.dwSize;
    
    // バッファを確保する
    app->mdata.pData = (byte*) MALLOC(filesize);

    // データをバッファに読み取る
    IFILE_Read(file, app->mdata.pData, filesize);

    // ファイルの解放
    IFILE_Release(file);
    IFILEMGR_Release(filemgr);

    // メディア データを準備する
    app->mdata.clsData = MMD_BUFFER;
    app->mdata.dwSize = filesize;
    
    // IMediaMIDI インタフェースを作成して、再生する。
    ISHELL_CreateInstance(shell, AEECLSID_MEDIAMIDI, &app->media);
    if (app->media != NULL) {
        IMEDIA_SetMediaData(app->media, &app->mdata);
        IMEDIA_Play(app->media);
    }
}

メディア再生の後始末

上記のようなコードでメディア データを再生しますと、アプリ終了時には IMedia 派生インタフェースを解放する必要がありますし、メディア データとして提供したファイル名やバッファも解放する必要があります。今回のサンプル アプリでは、アプリ終了時に次のように解放しています。

//
//  アプリ終了イベント
//
static boolean PlayMedia_OnAppStop(PlayMedia* app)
{
    // IMedia 派生インタフェースの解放
    if (app->media != NULL) {
        IMEDIA_Release(app->media);
    }

    // メディア データの解放
    if (app->mdata.pData != NULL) {
        FREE(app->mdata.pData);            
    }

    return TRUE;
}