Exemplo n.º 1
0
//--------------------------------------------------------------------------------------
// Initialize XACT engine
//--------------------------------------------------------------------------------------
HRESULT InitXACT( IXACT3Engine** ppXACTEngine )
{
    // Init COM and create XACT engine
    HRESULT hr;
    hr = CoInitializeEx( NULL, COINIT_MULTITHREADED );
    if( SUCCEEDED( hr ) )
    {
        // Switch to auditioning mode based on command line.  Change if desired
        bool bAuditionMode = DoesCommandLineContainAuditionSwitch();
        bool bDebugMode = false;

        DWORD dwCreationFlags = 0;
        if( bAuditionMode ) dwCreationFlags |= XACT_FLAG_API_AUDITION_MODE;
        if( bDebugMode ) dwCreationFlags |= XACT_FLAG_API_DEBUG_MODE;

        hr = XACT3CreateEngine( dwCreationFlags, ppXACTEngine );
    }
    if( FAILED( hr ) || *ppXACTEngine == NULL )
        return E_FAIL;

    XACT_RENDERER_DETAILS rendererDetails = {0};
    if( FAILED( hr = ( *ppXACTEngine )->GetRendererDetails( 0, &rendererDetails ) ) )
        return hr;

    XACT_RUNTIME_PARAMETERS xrParams = {0};
    xrParams.fnNotificationCallback = NULL;
    xrParams.lookAheadTime = XACT_ENGINE_LOOKAHEAD_DEFAULT;
    xrParams.pRendererID = rendererDetails.rendererID;

    if( FAILED( hr = ( *ppXACTEngine )->Initialize( &xrParams ) ) )
        return hr;

    return S_OK;
}
Exemplo n.º 2
0
HRESULT Sound::init()
{
	ZeroMemory( &audioState, sizeof( AUDIO_STATE ) );
	InitializeCriticalSection( &audioState.cs );

	audioState.nCurSongPlaying = -1;
	audioState.nCurWorld = -1;

	audioState.bInBattle = false;
	
	audioState.bGlobalPaused = false;
	audioState.bMusicPaused = false;
	audioState.bBGMPaused = false;

	audioState.bBGMStopped = false;
	audioState.bBGMFade = false;

	audioState.fGlobalVolume = 1.0f;
	audioState.fMusicVolume = 1.0f;
	audioState.fBGMVolume = 1.0f;

	hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );  // COINIT_APARTMENTTHREADED will work too
    if( SUCCEEDED( hr ) )
    {
        // Switch to auditioning mode based on command line.  Change if desired
        bool bAuditionMode = DoesCommandLineContainAuditionSwitch();
        bool bDebugMode = false;

        DWORD dwCreationFlags = 0;
        if( bAuditionMode ) dwCreationFlags |= XACT_FLAG_API_AUDITION_MODE;
        if( bDebugMode ) dwCreationFlags |= XACT_FLAG_API_DEBUG_MODE;

#ifdef USE_XACT3
        hr = XACT3CreateEngine( dwCreationFlags, &audioState.pEngine );
#else
		hr = XACTCreateEngine( dwCreationFlags, &audioState.pEngine );
#endif

    }
    if( FAILED( hr ) || audioState.pEngine == NULL )
        return E_FAIL;

    // Load the global settings file and pass it into XACTInitialize
    VOID* pGlobalSettingsData = NULL;
    DWORD dwGlobalSettingsFileSize = 0;
    bool bSuccess = false;
    hFile = CreateFile( L"Sounds.xgs", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
    if( hFile )
    {
		dwGlobalSettingsFileSize = GetFileSize( hFile, NULL );
		if( dwGlobalSettingsFileSize != INVALID_FILE_SIZE )
		{
			pGlobalSettingsData = CoTaskMemAlloc( dwGlobalSettingsFileSize );
			if( pGlobalSettingsData )
			{
				if( 0 != ReadFile( hFile, pGlobalSettingsData, dwGlobalSettingsFileSize, reinterpret_cast<LPDWORD>(&dwBytesRead), NULL ) )
				{
					bSuccess = true;
				}
			}
		}
		CloseHandle( hFile );
	}
   
    if( !bSuccess )
    {
        if( pGlobalSettingsData )
            CoTaskMemFree( pGlobalSettingsData );
        pGlobalSettingsData = NULL;
        dwGlobalSettingsFileSize = 0;
    }

    // Initialize & create the XACT runtime 
    XACT_RUNTIME_PARAMETERS xrParams = {0};
    xrParams.pGlobalSettingsBuffer = pGlobalSettingsData;
    xrParams.globalSettingsBufferSize = dwGlobalSettingsFileSize;
    xrParams.globalSettingsFlags = XACT_FLAG_GLOBAL_SETTINGS_MANAGEDATA; // this will tell XACT to delete[] the buffer when its unneeded
    xrParams.lookAheadTime = 250;
	xrParams.fnNotificationCallback = XACTNotificationCallback;
    hr = audioState.pEngine->Initialize( &xrParams );
    if( FAILED( hr ) )
        return hr;

	//-----------------------------------------------------------------------------------------
    // Register for XACT notifications
    //-----------------------------------------------------------------------------------------

    // The "wave bank prepared" notification will let the app know when it is save to use
    // play cues that reference streaming wave data.
    XACT_NOTIFICATION_DESCRIPTION desc = {0};
    desc.flags = XACT_FLAG_NOTIFICATION_PERSIST;
    desc.type = XACTNOTIFICATIONTYPE_WAVEBANKPREPARED;
    audioState.pEngine->RegisterNotification( &desc );

    // The "sound bank destroyed" notification will let the app know when it is save to use
    // play cues that reference streaming wave data.
    desc.flags = XACT_FLAG_NOTIFICATION_PERSIST;
    desc.type = XACTNOTIFICATIONTYPE_SOUNDBANKDESTROYED;
    audioState.pEngine->RegisterNotification( &desc );

    // The "cue stop" notification will let the app know when it a song stops so a new one 
    // can be played
    desc.flags = XACT_FLAG_NOTIFICATION_PERSIST;
    desc.type = XACTNOTIFICATIONTYPE_CUESTOP;
    desc.cueIndex = XACTINDEX_INVALID;
    audioState.pEngine->RegisterNotification( &desc );

    // The "cue prepared" notification will let the app know when it a a cue that uses 
    // streaming data has been prepared so it is ready to be used for zero latency streaming
    desc.flags = XACT_FLAG_NOTIFICATION_PERSIST;
    desc.type = XACTNOTIFICATIONTYPE_CUEPREPARED;
    desc.cueIndex = XACTINDEX_INVALID;
    audioState.pEngine->RegisterNotification( &desc );

    // Create an "in memory" XACT wave bank file using memory mapped file IO
    // Memory mapped files tend to be the fastest for most situations assuming you 
    // have enough virtual address space for a full map of the file
    hr = E_FAIL; // assume failure
    hFile = CreateFile( L"InMemory.xwb", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
    if( hFile != INVALID_HANDLE_VALUE )
    {
        dwFileSize = GetFileSize( hFile, NULL );
        if( dwFileSize != -1 )
        {
            hMapFile = CreateFileMapping( hFile, NULL, PAGE_READONLY, 0, dwFileSize, NULL );
            if( hMapFile )
            {
                audioState.pbInMemoryWaveBank = MapViewOfFile( hMapFile, FILE_MAP_READ, 0, 0, 0 );
                if( audioState.pbInMemoryWaveBank )
                {
                    hr = audioState.pEngine->CreateInMemoryWaveBank( audioState.pbInMemoryWaveBank, dwFileSize, 0,
                                                                       0, &audioState.pInMemoryWaveBank );
                }
                CloseHandle( hMapFile ); // pbInMemoryWaveBank maintains a handle on the file so close this unneeded handle
            }
        }
        CloseHandle( hFile ); // pbInMemoryWaveBank maintains a handle on the file so close this unneeded handle
    }
    if( FAILED( hr ) )
        return E_FAIL; // CleanupXACT() will cleanup state before exiting

	//-----------------------------------------------------------------------------------------
    // Create a streaming XACT wave bank file.  
    // Take note of the following:
    // 1) This wave bank in the XACT project file must marked as a streaming wave bank 
    //    This is set inside the XACT authoring tool)
    // 2) Use FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING flags when opening the file 
    // 3) To use cues that reference this streaming wave bank, you must wait for the 
    //    wave bank to prepared first or the playing the cue will fail
    //-----------------------------------------------------------------------------------------
    hr = E_FAIL; // assume failure
    audioState.hStreamingWaveBankFile = CreateFile( L"Stream.xwb",
                                                      GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
                                                      FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, NULL );
    if( audioState.hStreamingWaveBankFile != INVALID_HANDLE_VALUE )
    {
        XACT_WAVEBANK_STREAMING_PARAMETERS wsParams;
        ZeroMemory( &wsParams, sizeof( XACT_WAVEBANK_STREAMING_PARAMETERS ) );
        wsParams.file = audioState.hStreamingWaveBankFile;
        wsParams.offset = 0;

        // 64 means to allocate a 64 * 2k buffer for streaming.  
        // This is a good size for DVD streaming and takes good advantage of the read ahead cache
        wsParams.packetSize = 64;

        hr = audioState.pEngine->CreateStreamingWaveBank( &wsParams, &audioState.pStreamingWaveBank );
    }
    if( FAILED( hr ) )
        return E_FAIL; // CleanupXACT() will cleanup state before exiting

    // Read and register the sound bank file with XACT.  Do not use memory mapped file IO because the 
    // memory needs to be read/write and the working set of sound banks are small.
    hr = E_FAIL; // assume failure
    hFile = CreateFile( L"Sounds.xsb", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
    if( hFile != INVALID_HANDLE_VALUE )
    {
        dwFileSize = GetFileSize( hFile, NULL );
        if( dwFileSize != -1 )
        {
            // Allocate the data here and free the data when recieving the sound bank destroyed notification
            audioState.pbSoundBank = new BYTE[dwFileSize];
            if( audioState.pbSoundBank )
            {
                if( 0 != ReadFile( hFile, audioState.pbSoundBank, dwFileSize, reinterpret_cast<LPDWORD>(&dwBytesRead), NULL ) )
                {
                    hr = audioState.pEngine->CreateSoundBank( audioState.pbSoundBank, dwFileSize, 0,
                                                                0, &audioState.pSoundBank );
                }
            }
        }
        CloseHandle( hFile );
    }
    if( FAILED( hr ) )
        return E_FAIL; // CleanupXACT() will cleanup state before exiting

    // Get the sound cue index from the sound bank
    //
    // Note that if the cue does not exist in the sound bank, the index will be XACTINDEX_INVALID
    // however this is ok especially during development.  The Play or Prepare call will just fail.
    audioState.iSE = audioState.pSoundBank->GetCueIndex( "se" );
	for( int i = 0; i < 2; i++ )
    {
		for( int j = 0; j < 2; j++)
		{
	        CHAR sz[256];
	        StringCchPrintfA( sz, 256, "stage%d-%d", i + 1, j + 1 );
		    audioState.iStage[i][j] = audioState.pSoundBank->GetCueIndex( sz );
		}
    }

	for( int i = 0; i < 2; i++ )
	{
		CHAR sz[256];
		StringCchPrintfA( sz, 256, "battle%d", i + 1 );
		audioState.iBattle[i] = audioState.pSoundBank->GetCueIndex( sz );
	}
	audioState.iOpening = audioState.pSoundBank->GetCueIndex( "opening" );
	audioState.iBoss = audioState.pSoundBank->GetCueIndex( "boss" );
	audioState.iCeiling = audioState.pSoundBank->GetCueIndex( "ceiling" );
	audioState.iAttack = audioState.pSoundBank->GetCueIndex( "attack" );
	audioState.iBomb = audioState.pSoundBank->GetCueIndex( "bomb" );
	audioState.iHit = audioState.pSoundBank->GetCueIndex( "hit" );
	audioState.iPuzzleClear = audioState.pSoundBank->GetCueIndex( "puzzleclear" );
	audioState.iWalk = audioState.pSoundBank->GetCueIndex( "walk" );


	audioState.iGlobalCategory = audioState.pEngine->GetCategory( "Global" );
	audioState.iMusicCategory = audioState.pEngine->GetCategory( "Music" );
	audioState.iBGMCategory = audioState.pEngine->GetCategory( "BGM" );

    return S_OK;
}
Exemplo n.º 3
0
//-----------------------------------------------------------------------------------------
// This function does the following steps:
//
//      1. Initialize XACT by calling pEngine->Initialize 
//      2. Register for the XACT notification desired
//      3. Create the in memory XACT wave bank(s) you want to use
//      4. Create the streaming XACT wave bank(s) you want to use
//      5. Create the XACT sound bank(s) you want to use
//      6. Store indices to the XACT cue(s) your game uses
//-----------------------------------------------------------------------------------------
HRESULT PrepareXACT()
{
    HRESULT hr;
    WCHAR str[MAX_PATH];
    HANDLE hFile;
    DWORD dwFileSize;
    DWORD dwBytesRead;
    HANDLE hMapFile;

    // Clear struct
    ZeroMemory( &g_audioState, sizeof( AUDIO_STATE ) );
    InitializeCriticalSection( &g_audioState.cs );

    hr = CoInitializeEx( NULL, COINIT_MULTITHREADED );  // COINIT_APARTMENTTHREADED will work too
    if( SUCCEEDED( hr ) )
    {
        // Switch to auditioning mode based on command line.  Change if desired
        bool bAuditionMode = DoesCommandLineContainAuditionSwitch();
        bool bDebugMode = false;

        DWORD dwCreationFlags = 0;
        if( bAuditionMode ) dwCreationFlags |= XACT_FLAG_API_AUDITION_MODE;
        if( bDebugMode ) dwCreationFlags |= XACT_FLAG_API_DEBUG_MODE;

        hr = XACT3CreateEngine( dwCreationFlags, &g_audioState.pEngine );
    }
    if( FAILED( hr ) || g_audioState.pEngine == NULL )
        return E_FAIL;

    // Initialize & create the XACT runtime 
    XACT_RUNTIME_PARAMETERS xrParams = {0};
    xrParams.lookAheadTime = XACT_ENGINE_LOOKAHEAD_DEFAULT;
    xrParams.fnNotificationCallback = XACTNotificationCallback;
    hr = g_audioState.pEngine->Initialize( &xrParams );
    if( FAILED( hr ) )
        return hr;

    //-----------------------------------------------------------------------------------------
    // Register for XACT notifications
    //-----------------------------------------------------------------------------------------

    // The "wave bank prepared" notification will let the app know when it is save to use
    // play cues that reference streaming wave data.
    XACT_NOTIFICATION_DESCRIPTION desc = {0};
    desc.flags = XACT_FLAG_NOTIFICATION_PERSIST;
    desc.type = XACTNOTIFICATIONTYPE_WAVEBANKPREPARED;
    g_audioState.pEngine->RegisterNotification( &desc );

    // The "sound bank destroyed" notification will let the app know when it is save to use
    // play cues that reference streaming wave data.
    desc.flags = XACT_FLAG_NOTIFICATION_PERSIST;
    desc.type = XACTNOTIFICATIONTYPE_SOUNDBANKDESTROYED;
    g_audioState.pEngine->RegisterNotification( &desc );

    // The "cue stop" notification will let the app know when it a song stops so a new one 
    // can be played
    desc.flags = XACT_FLAG_NOTIFICATION_PERSIST;
    desc.type = XACTNOTIFICATIONTYPE_CUESTOP;
    desc.cueIndex = XACTINDEX_INVALID;
    g_audioState.pEngine->RegisterNotification( &desc );

    // The "cue prepared" notification will let the app know when it a a cue that uses 
    // streaming data has been prepared so it is ready to be used for zero latency streaming
    desc.flags = XACT_FLAG_NOTIFICATION_PERSIST;
    desc.type = XACTNOTIFICATIONTYPE_CUEPREPARED;
    desc.cueIndex = XACTINDEX_INVALID;
    g_audioState.pEngine->RegisterNotification( &desc );


    if( FAILED( hr = FindMediaFileCch( str, MAX_PATH, L"InMemoryWaveBank.xwb" ) ) )
        return hr;

    // Create an "in memory" XACT wave bank file using memory mapped file IO
    hr = E_FAIL; // assume failure
    hFile = CreateFile( str, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
    if( hFile != INVALID_HANDLE_VALUE )
    {
        dwFileSize = GetFileSize( hFile, NULL );
        if( dwFileSize != -1 )
        {
            hMapFile = CreateFileMapping( hFile, NULL, PAGE_READONLY, 0, dwFileSize, NULL );
            if( hMapFile )
            {
                g_audioState.pbInMemoryWaveBank = MapViewOfFile( hMapFile, FILE_MAP_READ, 0, 0, 0 );
                if( g_audioState.pbInMemoryWaveBank )
                {
                    hr = g_audioState.pEngine->CreateInMemoryWaveBank( g_audioState.pbInMemoryWaveBank, dwFileSize, 0,
                                                                       0, &g_audioState.pInMemoryWaveBank );
                }
                CloseHandle( hMapFile ); // pbInMemoryWaveBank maintains a handle on the file so close this unneeded handle
            }
        }
        CloseHandle( hFile ); // pbInMemoryWaveBank maintains a handle on the file so close this unneeded handle
    }
    if( FAILED( hr ) )
        return E_FAIL; // CleanupXACT() will cleanup state before exiting

    //-----------------------------------------------------------------------------------------
    // Create a streaming XACT wave bank file.  
    // Take note of the following:
    // 1) This wave bank in the XACT project file must marked as a streaming wave bank 
    //    This is set inside the XACT authoring tool)
    // 2) Use FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING flags when opening the file 
    // 3) To use cues that reference this streaming wave bank, you must wait for the 
    //    wave bank to prepared first or the playing the cue will fail
    //-----------------------------------------------------------------------------------------
    if( FAILED( hr = FindMediaFileCch( str, MAX_PATH, L"StreamingWaveBank.xwb" ) ) )
        return hr;
    hr = E_FAIL; // assume failure
    g_audioState.hStreamingWaveBankFile = CreateFile( str,
                                                      GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
                                                      FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, NULL );
    if( g_audioState.hStreamingWaveBankFile != INVALID_HANDLE_VALUE )
    {
        XACT_WAVEBANK_STREAMING_PARAMETERS wsParams;
        ZeroMemory( &wsParams, sizeof( XACT_WAVEBANK_STREAMING_PARAMETERS ) );
        wsParams.file = g_audioState.hStreamingWaveBankFile;
        wsParams.offset = 0;

        // 64 means to allocate a 64 * 2k buffer for streaming.  
        // This is a good size for DVD streaming and takes good advantage of the read ahead cache
        wsParams.packetSize = 64;

        hr = g_audioState.pEngine->CreateStreamingWaveBank( &wsParams, &g_audioState.pStreamingWaveBank );
    }
    if( FAILED( hr ) )
        return E_FAIL; // CleanupXACT() will cleanup state before exiting

    // Create the XACT sound bank file with using memory mapped file IO
    if( FAILED( hr = FindMediaFileCch( str, MAX_PATH, L"sounds.xsb" ) ) )
        return hr;
    hr = E_FAIL; // assume failure
    hFile = CreateFile( str, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
    if( hFile != INVALID_HANDLE_VALUE )
    {
        dwFileSize = GetFileSize( hFile, NULL );
        if( dwFileSize != -1 )
        {
            // Allocate the data here and free the data when recieving the sound bank destroyed notification
            g_audioState.pbSoundBank = new BYTE[dwFileSize];
            if( g_audioState.pbSoundBank )
            {
                if( 0 != ReadFile( hFile, g_audioState.pbSoundBank, dwFileSize, &dwBytesRead, NULL ) )
                {
                    hr = g_audioState.pEngine->CreateSoundBank( g_audioState.pbSoundBank, dwFileSize, 0,
                                                                0, &g_audioState.pSoundBank );
                }
            }
        }
        CloseHandle( hFile ); // pbInMemoryWaveBank maintains a handle on the file so close this unneeded handle
    }
    if( FAILED( hr ) )
        return E_FAIL; // CleanupXACT() will cleanup state before exiting

    // Get the cue indices from the sound bank
    g_audioState.iZap = g_audioState.pSoundBank->GetCueIndex( "zap" );
    g_audioState.iRev = g_audioState.pSoundBank->GetCueIndex( "rev" );
    for( int i = 0; i < 3; i++ )
    {
        CHAR sz[256];
        StringCchPrintfA( sz, 256, "song%d", i + 1 );
        g_audioState.iSong[i] = g_audioState.pSoundBank->GetCueIndex( sz );
    }

    return S_OK;
}