/****************************************************************************
* Initialize:
* Creates and initializes the XACT engine
*****************************************************************************/
void SoundController::Init()
{
	CoInitializeEx(NULL, COINIT_MULTITHREADED);

	XACT3CreateEngine( /*XACT_FLAG_API_DEBUG_MODE*/  0, &pXACT3Engine );

// Load the global settings file and pass it into XACTInitialize
    VOID* pGlobalSettingsData = NULL;
    DWORD dwGlobalSettingsFileSize = 0;
    bool bSuccess = false;
    DWORD dwBytesRead;
    HANDLE hFile;
	DWORD dwFileSize;
    HANDLE hMapFile;


    hFile = CreateFile( gsPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
    if( hFile )
    {
        dwGlobalSettingsFileSize = GetFileSize( hFile, NULL );
        if( dwGlobalSettingsFileSize != INVALID_FILE_SIZE )
        {
            // Using CoTaskMemAlloc so that XACT can clean up this data when its done
            pGlobalSettingsData = CoTaskMemAlloc( dwGlobalSettingsFileSize );
            if( pGlobalSettingsData )
            {
                if( 0 != ReadFile( hFile, pGlobalSettingsData, dwGlobalSettingsFileSize, &dwBytesRead, NULL ) )
                {
                    bSuccess = true;
                }
            }
        }
        CloseHandle( hFile );
    }
    if( !bSuccess )
    {
        if( pGlobalSettingsData )
            CoTaskMemFree( pGlobalSettingsData );
        pGlobalSettingsData = NULL;
        dwGlobalSettingsFileSize = 0;
    }


    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.fnNotificationCallback = XACTNotificationCallback;
    xrParams.lookAheadTime = XACT_ENGINE_LOOKAHEAD_DEFAULT;

	pXACT3Engine->Initialize( &xrParams );


	// Setup 3D audio structs
    ZeroMemory( &listener, sizeof( X3DAUDIO_LISTENER ) );
    listener.OrientFront = D3DXVECTOR3( 0, 0, 1 );
    listener.OrientTop = D3DXVECTOR3( 0, 1, 0 );
    listener.Position = D3DXVECTOR3( 0, 5, 0 );
    listener.Velocity = D3DXVECTOR3( 0, 0, 0 );

    ZeroMemory( &emitter, sizeof( X3DAUDIO_EMITTER ) );
    emitter.pCone = NULL;
    emitter.OrientFront = D3DXVECTOR3( 0, 0, 1 );
    emitter.OrientTop = D3DXVECTOR3( 0, 1, 0 );
    emitter.Position = D3DXVECTOR3( 0, 0, 0 );
    emitter.Velocity = D3DXVECTOR3( 0, 0, 0 );
    emitter.ChannelCount = 2;
    emitter.ChannelRadius = 1.0f;
    emitter.pChannelAzimuths = NULL;
    emitter.pVolumeCurve = NULL;
    emitter.pLFECurve = NULL;
    emitter.pLPFDirectCurve = NULL;
    emitter.pLPFReverbCurve = NULL;
    emitter.pReverbCurve = NULL;
    emitter.CurveDistanceScaler = 1.0f;
    emitter.DopplerScaler = NULL;

    DelayTimes[0] = 0.0f;
    DelayTimes[1] = 0.0f;

    // Init MatrixCoefficients. XACT will fill in the values
    ZeroMemory( &MatrixCoefficients, sizeof( FLOAT32 ) * 8 * 2 );

    // query number of channels on the final mix
    WAVEFORMATEXTENSIBLE wfxFinalMixFormat;
    pXACT3Engine->GetFinalMixFormat( &wfxFinalMixFormat );
	WORD nDstChannelCount = wfxFinalMixFormat.Format.nChannels;

    ZeroMemory( &dspSettings, sizeof( X3DAUDIO_DSP_SETTINGS ) );
    dspSettings.pMatrixCoefficients = MatrixCoefficients;
    dspSettings.pDelayTimes = DelayTimes;
    dspSettings.SrcChannelCount = 2;
    dspSettings.DstChannelCount = nDstChannelCount;

    // Initialize 3D settings
    XACT3DInitialize( pXACT3Engine, x3DInstance );


	// Read and register the wave bank file with XACT 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
    hFile = CreateFile( wbPath, 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 )
            {
                pbWaveBank = MapViewOfFile( hMapFile, FILE_MAP_READ, 0, 0, 0 );
                if( pbWaveBank )
                {
                    pXACT3Engine->CreateInMemoryWaveBank( pbWaveBank, dwFileSize, 0,
                                                                       0, &pWaveBank );
                }
                CloseHandle( hMapFile ); // pbWaveBank is maintains a handle on the file so close this unneeded handle
            }
        }
        CloseHandle( hFile ); // pbWaveBank is maintains a handle on the file so close this unneeded handle
    }
    
    // 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.
    hFile = CreateFile( sbPath, 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
            pbSoundBank = new BYTE[dwFileSize];
            if( pbSoundBank )
            {
                if( 0 != ReadFile( hFile, pbSoundBank, dwFileSize, &dwBytesRead, NULL ) )
                {
                    pXACT3Engine->CreateSoundBank( pbSoundBank, dwFileSize, 0,
                                                                0, &pSoundBank );
                }
            }
        }
        CloseHandle( hFile );
    }

	bInitialized = true;

	iBackgroundMusic = pSoundBank->GetCueIndex( "Test" );
	iHCIdle = pSoundBank->GetCueIndex( "HC_Idle" );
}
Пример #2
0
bool CSoundComponent::InitXACT(const char* engine_xgs)
{
	HRESULT hr;
	CoInitializeEx( NULL, COINIT_MULTITHREADED );  // COINIT_APARTMENTTHREADED will work too
	//TODO("Create the XACT engine");
	hr=XACT3CreateEngine(0, &mpXEngine);

	if( FAILED( hr ) || mpXEngine == NULL )
	{
		FAIL("Problems creating XACT engine","InitXACT Failed");
		return false;
	}

	// Load the global settings file and pass it into XACTInitialize
	VOID* pGlobalSettingsData = NULL;
	DWORD dwGlobalSettingsFileSize = 0;
	bool bSuccess = false;
	HANDLE hFile = CreateFile( engine_xgs, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
	if( hFile!=INVALID_HANDLE_VALUE )
	{
		dwGlobalSettingsFileSize = GetFileSize( hFile, NULL );
		if( dwGlobalSettingsFileSize != INVALID_FILE_SIZE )
		{
			pGlobalSettingsData = CoTaskMemAlloc( dwGlobalSettingsFileSize );
			if( pGlobalSettingsData )
			{
				DWORD dwBytesRead;
				if( 0 != ReadFile( hFile, pGlobalSettingsData, dwGlobalSettingsFileSize, &dwBytesRead, NULL ) )
				{
					bSuccess = true;
				}
			}
		}
		CloseHandle( hFile );
	}
	if( !bSuccess )
	{
		if( pGlobalSettingsData )
			CoTaskMemFree( pGlobalSettingsData );
		pGlobalSettingsData = NULL;
		dwGlobalSettingsFileSize = 0;
		FAIL(engine_xgs,"Problems opening engine file");
		return false;
	}

	// Initialize & create the XACT runtime 
	XACT_RUNTIME_PARAMETERS xrParams = {0};
	xrParams.lookAheadTime = XACT_ENGINE_LOOKAHEAD_DEFAULT;
	xrParams.pGlobalSettingsBuffer = pGlobalSettingsData;
	xrParams.globalSettingsBufferSize = dwGlobalSettingsFileSize;
	xrParams.globalSettingsFlags = XACT_FLAG_GLOBAL_SETTINGS_MANAGEDATA; // this will tell XACT to delete[] the buffer when its unneeded
	//TODO(Initalise the XACT engine);
	hr=mpXEngine->Initialize(&xrParams);
	if( FAILED( hr ) )
	{
		FAIL(engine_xgs,"Problems Initalising XACT engine");
		return false;
	}

	X3DAUDIO_EMITTER emitter = {0};
	X3DAUDIO_LISTENER listener = {0};

	listener.OrientFront = D3DXVECTOR3( 0, 0, 1 );
	listener.OrientTop = D3DXVECTOR3( 0, 1, 0 );
	listener.Position = D3DXVECTOR3( 0, 0, 0 );
	listener.Velocity = D3DXVECTOR3( 0, 0, 0 );

	// the following need to be orthonormal
	emitter.OrientFront = D3DXVECTOR3( 0, 0, 1 );
	emitter.OrientTop = D3DXVECTOR3( 0, 1, 0 );
	emitter.Position = D3DXVECTOR3( 0, 0, 0 );
	emitter.Velocity = D3DXVECTOR3( 0, 0, 0 ); // needs to not be zero if you want to hear Doppler effect

	// emitter ChannelCount and DSP Setting's SrcChannelCount must match
	emitter.ChannelCount = 2;   

	// this will be set by XACT3DCalculate if ChannelCount > 1.
	emitter.ChannelRadius = 1.0f;   

	// will be set by XACT3DCalculate
	emitter.pChannelAzimuths = NULL;

	// will be set by XACT3DCalculate
	emitter.pVolumeCurve = emitter.pLFECurve
		= emitter.pLPFDirectCurve
		= emitter.pLPFReverbCurve
		= emitter.pReverbCurve
		= NULL;

	emitter.CurveDistanceScaler = 1.0;
	emitter.DopplerScaler = 1.0f;

	hr = XACT3DInitialize(mpXEngine, xact3dInstance);

	if( FAILED( hr ) )
	{
		FAIL(engine_xgs,"Problems Initalising XACT 3D engine");
		return false;
	}

	// check how many output channels are supported
	WAVEFORMATEXTENSIBLE format;
	hr = mpXEngine->GetFinalMixFormat(&format);
	if(FAILED(hr))
	{
		FAIL("BLABLBA");
	}
	// fill the DSP
	ZeroMemory(&dspSettings,sizeof(dspSettings));
	// different code's seem to suggest 1 or 2 channels for the emitter
	dspSettings.SrcChannelCount = 1;
	dspSettings.DstChannelCount = format.Format.nChannels;  // as supported 
	dspSettings.pMatrixCoefficients = new FLOAT32[dspSettings.SrcChannelCount * dspSettings.DstChannelCount];
	ZeroMemory(dspSettings.pMatrixCoefficients ,sizeof(FLOAT32)*dspSettings.SrcChannelCount * dspSettings.DstChannelCount);

	return true;
}