//////////////////////////////////////////////////////////////////////////////
//
// Asura_Platform_Audio.cpp
//
// Copyright (c) 2008 Rebellion. All rights reserved.
//
//////////////////////////////////////////////////////////////////////////////

/******************************************************************************/
/* Included Files                                                             */
/******************************************************************************/

#include "Core/Asura.h"

#if defined ASURA_USE_AUDIO_SYSTEM

#include "Sound/Asura_Audio_System.h"

// Asura Platform-independent
#include "ChunkSystem/Asura_Chunk_Loaders.h"
#include "Debugging/Asura_Assert.h"
#include "Sound/Asura_Sound_Mixer.h"
#include "Sound/Asura_XAudio2.h"
#include "Sound/Asura_XAudio2_Buffer.h"

/******************************************************************************/
/* Asura_Audio_System Static Class Functions                                  */
/******************************************************************************/

void Asura_Audio_System::Platform_Initialise()
{
	Asura_XAudio2::Initialise();
}

void Asura_Audio_System::Platform_Reset()
{
	Asura_XAudio2::Reset();
}

void Asura_Audio_System::Platform_Shutdown()
{
	Asura_XAudio2::Shutdown();
}

void Asura_Audio_System::Platform_Update()
{
	Asura_XAudio2::Update();
}

void Asura_Audio_System::Platform_CreateDSPChain( const Asura_Hash_ID uHash,
	const Asura_Audio_DSPChain& xChain )
{
	//Asura_XAudio2::CreateDSPChain( uHash, xChain );
}

Asura_Handle Asura_Audio_System::Platform_CreateVoice( const Asura_Hash_ID uWave,
	const bool bFilter, const bool bMusic, const Asura_Hash_ID uDSPChain /* = ASURA_HASH_ID_UNSET*/ )
{
	return Asura_XAudio2::CreateVoice( uWave, bFilter, bMusic, uDSPChain );
}

Asura_Handle Asura_Audio_System::Platform_CreateStreamingVoice( const Asura_Hash_ID uStreamHash, const bool bFilter,
	const bool bMusic, const float fTimeOffset, const Asura_Hash_ID uDSPChain /* = ASURA_HASH_ID_UNSET*/ )
{
	return Asura_XAudio2::CreateStreamingVoice( uStreamHash, bFilter, bMusic, fTimeOffset, uDSPChain );
}

Asura_Handle Asura_Audio_System::Platform_CreateSubmixVoice( const bool bFilter, const bool bMusic,
															const Asura_Hash_ID uDSPChain /* = ASURA_HASH_ID_UNSET*/ )
{
	return Asura_XAudio2::CreateSubmixVoice( bFilter, bMusic, uDSPChain );
}

void Asura_Audio_System::Platform_DestroyVoice( const Asura_Handle iVoiceHandle )
{
	Asura_XAudio2::DestroyVoice( iVoiceHandle );
}

Asura_Audio_Voice* Asura_Audio_System::Platform_GetVoice( const Asura_Handle iVoiceHandle )
{
	return Asura_XAudio2::GetVoice( iVoiceHandle );
}

void Asura_Audio_System::Platform_SetMasterDSP( const Asura_Hash_ID uDSPChain, const float fFadeTime )
{
	Asura_XAudio2::SetMasterDSP( uDSPChain, fFadeTime );
}

bool Asura_Audio_System::Platform_LoadWave( Asura_Chunk_Stream& xStream, const u_int uFileSize,
	const u_int uSubType, const u_int uFlags, const char* const szFilename )
{
	bool bAlreadyExists;
	Asura_XAudio2_Buffer* const pxBuffer = Asura_XAudio2::CreateBuffer( szFilename, bAlreadyExists );
	if( pxBuffer && !bAlreadyExists)
	{
		if( !pxBuffer->LoadWave( xStream, uFileSize, uFlags ) )
		{
			Asura_Assertf( false, ("Failed to load wave file '%s'.", szFilename) );
		}
		return true;
	}
	else
	{
		return false;
	}
}

#if defined ASURA_AUDIO_STORE_FILENAMES

const char* Asura_Audio_System::Platform_GetWaveFilename( const Asura_Hash_ID uWave )
{
	return Asura_XAudio2::GetWaveFilename( uWave );
}

#endif // defined ASURA_AUDIO_STORE_FILENAMES

/******************************************************************************/
/* Asura_XAudio2 Static Class Functions                                       */
/******************************************************************************/

void* Asura_XAudio2::Platform_Allocate( const WORD usFormatTag, const u_int uSize )
{
	// XMA2 format data must be aligned on a 2048-byte boundary

	return usFormatTag == WAVE_FORMAT_XMA2
		? Asura_Xbox360_MemoryManagement::AllocatePhysical(Asura_Xbox360_MemoryManagement::MT_READ_WRITE, uSize, XALLOC_PHYSICAL_ALIGNMENT_2K)
		: Asura_Allocate( uSize );
}

void Asura_XAudio2::Platform_Deallocate( const WORD usFormatTag, void* const pBuffer )
{
	if( usFormatTag == WAVE_FORMAT_XMA2 )
	{
		Asura_Xbox360_MemoryManagement::FreePhysical(Asura_Xbox360_MemoryManagement::MT_READ_WRITE, pBuffer, XALLOC_PHYSICAL_ALIGNMENT_2K);
	}
	else
	{
		Asura_Deallocate( pBuffer );
	}
}

#endif // defined ASURA_USE_AUDIO_SYSTEM
