ホーム < ゲームつくろー! < Ogg Vorbis入門編

Ogg Vorbis入門編
その7 OggVorbisクラスのリファクタリング:サンプルプログラム


 Ogg Vorbis入門編その7「OggVorbisクラスのリファクタリング」で説明した内容を踏まえたサンプルプログラムです。実行するとコンソール画面が現れて、指定のOggファイルがストリーム再生されます。


サンプルスクリーンショット。見た目は相変わらず変わらないんですよねぇ…

 このサンプルは1つのOggファイルをオープンし、デコーダがそこから音声情報をデコードし、さらに再生機がそれを再生します。機能的には前章までと全く一緒ですが、クラスの構成が変わっています。


○ サンプルの動かし方

 サンプルを動かすために必要なファイルはこちらからダウンロードできます(OGGSmp_No7_v101.lzh)。空のコンソールアプリケーションを作成し、アーカイブに入っているクラスをすべて追加し、Ogg Vorbisライブラリを環境に設定するとビルドできます。実行して音楽を聴くにはプロジェクトフォルダ下に「Test.Ogg」というOggファイルが必要です。お手元の音楽をOggファイルに変換して試してみてください。

 PCMDecoderオブジェクトはスマートポインタに包む必要があります。またIDirectSound8インターフェイスはCOMポインタに包みます。これはポインタ先のアクセスを保障するためです。使用の際はご注意下さい。

○ Ogg Vorbisライブラリについて

 このサンプルを動かすには別途Ogg Vorbisライブラリを組み込む必要があります。組み込み方についてはOgg Vorbis入門編その1「Ogg Vorbisライブラリのインストール」に詳しく記載しておりますのでご参照ください。うまくいかない場合は掲示板にご報告下さい。

○ バージョン情報

・ v1.00 -> v1.01
 OggVorbisMemory::cloneメソッドでクローンを作成して重複再生すると落ちるバグを修正。

// Ogg Vorbisストリーム再生クラステストプログラム
//
//  製作者 : IKD
//  HP     : http://marupeke296.com
//


#pragma comment ( lib, "dxguid.lib" )
#pragma comment ( lib, "dsound.lib" )

#include <dsound.h>
#include <tchar.h>
#include "OggDecoder.h"
#include "OggVorbisMemory.h"
#include "OggVorbisFile.h"
#include "PCMPlayer.h"
#include "DixSmartPtr.h"
#include "DixComPtr.h"

// コンソールのウィンドウハンドル取得
HWND GetConsoleHwnd(void)
{
    TCHAR pszWindowTitle[ 1024 ];
    GetConsoleTitle( pszWindowTitle, 1024 );
    return FindWindow( NULL, pszWindowTitle );
}

// 一時停止関数
void StopProc() {
    while ( 1 ) {
        Sleep( 200 );
        // Escapeキーを押したら抜ける
        if ( GetAsyncKeyState( VK_ESCAPE ) )
            break;
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    // DirectSoundの作成
    IDirectSound8 *pDS8;
    DirectSoundCreate8( NULL, &pDS8, NULL );
    Dix::Com_ptr< IDirectSound8 > cpDS8( pDS8 );
    pDS8->SetCooperativeLevel( GetConsoleHwnd(), DSSCL_PRIORITY );

    // Oggオブジェクト作成
//    Dix::sp< Dix::OggVorbisMemory > spOggResource( new Dix::OggVorbisMemory( "test.ogg" ) );
    Dix::sp< Dix::OggVorbisFile > spOggResource( new Dix::OggVorbisFile( "test.ogg" ) );
    Dix::sp< Dix::OggDecoder > spOggDecoder( new Dix::OggDecoder( spOggResource ) );
    Dix::PCMPlayer player[ 2 ];
    for ( int i = 0 ; i < 2; ++i ) {
        player[ i ].setDevice( cpDS8 );
        player[ i ].setDecoder( spOggDecoder );
    }

    bool isLoop = true;
    for ( int i = 0; i < 2; ++i ) {
        if( player[ i ].play( isLoop ) == false ) {
            printf( "ファイル準備に失敗しています" );
            return 0;
        }
        Sleep( 100 );    // わざとずらします
    }

    // 再生
    printf( "ただ今再生中\n" );
    StopProc();

    // 停止
    for ( int i = 0; i < 2; ++i ) {
        player[ i ].stop();
    }
    printf( "\n停止しました\n" );

    return 0;
}