mioplay 概略
 

■ mioplay 概略

 MIO ファイルを再生するサンプルプログラムです。
 MIO ファイルは独自の音声圧縮フォーマットですので、MIO ファイルをお持ちでない方は、「恵理ちゃんclub」等からツール類をダウンロードすることが出来ます。
 又は、「開く」ボタンを押して直接 URL を入力してください。mioplay は HTTP を通じてファイルをダウンロードしながら再生することも出来ます。

 

■EWaveMixingServer クラスと MIOSoundStream クラス

 音声を再生するには音声出力デバイスオブジェクトと音声ストリームバッファオブジェクトを用意しなくてはなりません。
 mioplay では、音声出力デバイスオブジェクトに EWaveMixingServer クラスを利用しています。(通常はこのクラスを利用します)
 EWaveMixingServer クラスでは、入力された複数の音声ストリームバッファをリアルタイムでミキシング処理して出力します。このミキシング処理には専用のスレッドが自動的に作成され、そこで行われます。
 音声ストリームバッファは EWaveStreamBuffer クラスの派生クラスによって提供され、MIOSoundStream クラスでは MIO ファイルを再生することが出来ます。
 以下は、音声再生の概念図です。

 

■ EGLSThread クラス

 mioplay クラスでは EGLSThread クラスを用いてコマンドを処理するスレッドを実装しています。
 後で説明するように ESyncHttpFile クラスを用いない場合にはスレッドを作成する必要はありません。(ESyncHttpFile クラスを利用する場合でも、必ず必要だと言うわけではありません)
 このサンプルでは典型的なスレッドメッセージを処理するスレッドを実装しています。
 

■ ESyncHttpFile クラス

 ESyncHttpFile クラスは、ESyncStreamFile クラスと EHttpConnection クラスから派生したクラスで、EHttpConnection クラスは ESocket クラスから派生しています。
 このクラスを利用すると HTTP を通じてファイルを通常のファイルと同様に読み込むことが出来ます。

    EString strURL = pszURL ;
    if ( (strURL.Left(5) == "http:") && (strURL != "http://") )
    {
        ESLError    errResult ;
        ESyncHttpFile * pfile = new ESyncHttpFile ;
        errResult = pfile->OpenURL( strURL ) ;
        if ( errResult != eslErrSuccess )
        {
            MessageBox
                ( GetESLErrorMsg(errResult),
                    "エラー", MB_OK | MB_ICONERROR ) ;
            delete  pfile ;
        }
        else
        {
            m_pfile = pfile ;
        }
    }
    else
    {
        ERawFile *  pfile = new ERawFile ;
        if ( pfile->Open
            ( strURL, ESLFileObject::modeRead | ESLFileObject::shareRead ) )
        {
            MessageBox
                ( "ファイルを開けませんでした。",
                    "エラー", MB_OK | MB_ICONERROR ) ;
            delete  pfile ;
        }
        else
        {
            m_pfile = pfile ;
        }
    }

 上のコードはファイルを開いている処理です。
 ESyncHttpFile::OpenURL 関数では URL を指定すると HTTP を通じてファイルを開くことが出来ます。
 ERawFile::Open 関数では通常のローカルファイルを開きます。

 ESocket クラス、及び派生クラスを利用する際には、あらかじめ ESocket::InitSocket 関数を呼び出しておかなければならないことに注意してください。
 mioplay では CMioplayApp::InitInstance 関数内部で呼び出しています。
 ESocket::InitSocket 関数を呼び出すと、通信を行うためのスレッドが作成されます。
 以下の図は、ESyncHttpFile クラスの内部構造を模式化したものです。

 ESyncStreamFile クラスでは、Write 関数で書き出されたデータを Read 関数等を用いて通常のファイルのように読み込むことが出来ます。
 但し、Read 関数などで、まだ書き出されていないデータを読み込もうとした場合などには Write 関数で書き出されるか、FinishStream 関数でファイル全体が確定されるまで、読み込み関数は復帰しません。
 mioplay の例では、コマンドを処理するスレッドを作成していますが、このスレッドを作成しない場合、右下の「中止」ボタンを機能させることが出来なくなります。
 mioplay で、HTTP 上のファイルを開き、読み込みが終わらないうちにファイルの終端のほうまで再生位置を移動させ、再生ボタンを押してみてください。実際にその位置まで読み込まれるまで待機状態になるのが分かると思います。
 しかし、待機しているのは、コマンドを処理するバックグラウンドスレッドですので、ウィンドウのメッセージループは機能しており、「中止」ボタンを押すことが出来ます。待機状態で「中止」ボタンを押すと即座にコマンドが復帰しますが、ファイルが完全ではないのでファイルの先頭から再生を開始しても途中までしか再生できません。
 この動作については実際に試してみてください。
 このキャンセル処理のためのユーザーインターフェースが必要でない場合にはスレッドを作成する必要はありません。
 よく分からない場合には、スレッドを使用しないように書き換えて試してみてください。