#include <xtl.h>
#include <xaudio2.h>

extern "C"{
	#include "psemuxa.h"
};

#define printf

//-------------------------------------------------------------------------------------
// Audio
//-------------------------------------------------------------------------------------
static IXAudio2* g_pXAudio2 = NULL;
static IXAudio2MasteringVoice* g_pMasteringVoice = NULL;
static IXAudio2SourceVoice* g_pSourceVoice = NULL;
static WAVEFORMATEXTENSIBLE wfx;

unsigned int m_BufferSize = 0;

#define SOUND_FRENCENCY	44100

extern "C" void SetupSound(void)
{
//-------------------------------------------------------------------------------------
// Initialise Audio
//-------------------------------------------------------------------------------------	
	HRESULT hr;
	if( FAILED( hr = XAudio2Create( &g_pXAudio2, 0 ) ) )
    {
        printf( "Failed to init XAudio2 engine: %#X\n", hr );
		DebugBreak();
        return;
    }

//-------------------------------------------------------------------------------------
// Create a mastering voice
//-------------------------------------------------------------------------------------	
    if( FAILED( hr = g_pXAudio2->CreateMasteringVoice( &g_pMasteringVoice ) ) )
    {
		printf( "Failed creating mastering voice: %#X\n", hr );
        DebugBreak();
        return;
    }

//-------------------------------------------------------------------------------------
// Create source voice
//-------------------------------------------------------------------------------------	
	WAVEFORMATEXTENSIBLE wfx;
	XMemSet(&wfx, 0, sizeof(WAVEFORMATEXTENSIBLE));
	wfx.Format.wFormatTag           = WAVE_FORMAT_EXTENSIBLE;
	wfx.Format.nSamplesPerSec       = SOUND_FRENCENCY;
	wfx.Format.nChannels            = 2;
	wfx.Format.wBitsPerSample       = 16;
	wfx.Format.nBlockAlign          = wfx.Format.nChannels*wfx.Format.wBitsPerSample/8;
	wfx.Format.nAvgBytesPerSec      = SOUND_FRENCENCY * wfx.Format.nBlockAlign;
	wfx.Format.cbSize               = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX);
	wfx.Samples.wValidBitsPerSample = 16;
	wfx.dwChannelMask               = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
	wfx.SubFormat                   = KSDATAFORMAT_SUBTYPE_PCM;

	if(FAILED( g_pXAudio2->CreateSourceVoice(&g_pSourceVoice,(WAVEFORMATEX*)&wfx,0)	))
	{
		printf("CreateSourceVoice failed\n");
		DebugBreak();
        return;
	}

//-------------------------------------------------------------------------------------
// Start sound
//-------------------------------------------------------------------------------------	
	if ( FAILED(g_pSourceVoice->Start( 0 ) ) )
	{
		printf("g_pSourceVoice failed\n");
		DebugBreak();
        return;
	}
	return;
};

//At Exit
extern "C" void RemoveSound()
{
	g_pSourceVoice->FlushSourceBuffers();
	g_pSourceVoice->DestroyVoice();
	g_pSourceVoice=NULL;
};

extern "C" unsigned long SoundGetBytesBuffered(void){
	XAUDIO2_VOICE_STATE voiceState;
	g_pSourceVoice->GetState(&voiceState);
	return voiceState.SamplesPlayed & (m_BufferSize-1);
	/*
	unsigned long l = voiceState.SamplesPlayed;
	if((voiceState.SamplesPlayed-m_BufferSize)<0)
		return 1;
	else
		return voiceState.SamplesPlayed-m_BufferSize;
		*/
};

//play
extern "C" void SoundFeedStreamData(unsigned char* pSound,long lBytes)
{
	m_BufferSize = lBytes * sizeof(signed short);
	unsigned char* Sound = (unsigned char*)malloc(lBytes);
	XMemCpy(Sound, pSound, lBytes);

	XAUDIO2_BUFFER g_SoundBuffer = {0};
	g_SoundBuffer.AudioBytes = lBytes;//len*2;	//size of the audio buffer in bytes
	g_SoundBuffer.pAudioData = (BYTE*)(Sound);		//buffer containing audio data

//-------------------------------------------------------------------------------------
// Send sound stream
//-------------------------------------------------------------------------------------	
	g_pSourceVoice->FlushSourceBuffers();
	if( FAILED(g_pSourceVoice->SubmitSourceBuffer( &g_SoundBuffer ) ) )
	{
		printf("SubmitSourceBuffer failed\n");
		DebugBreak();
		return ;
	}
};


extern "C" void usleep(int x)
{
	Sleep(x);
};