#include "Page1.h"

#include "PalmChip.h"
#include "Ac97.h"
#include "p_dsp.h"
#include "v_task.h"
#include "gdiconst.h"
#include "p_rtp.h"

BOOLEAN Ac97_bIVR = FALSE;

static BOOLEAN _bRing;
static volatile BOOLEAN _bWorking;
static volatile BOOLEAN _bNeedBuffer;

BOOLEAN _HandleFileData(BOOLEAN bPlay, BOOLEAN bSend)
{
	DCHAR iLen;
	XCHAR pBuf[G711_LEN];

	if (SoloFileRead(pBuf, Dsp_cFrameLen[Dsp_iType]))
	{
		iLen = Dsp_cRecordingLen[Dsp_iType];
		if (bPlay)
		{
			DspHandleDecodeData(iLen, pBuf);
		}
		if (bSend)
		{
#ifdef GUI_RTP
			RtpSend(iLen, pBuf);
#endif
		}
		return TRUE;
	}
	return FALSE;
}

void Ac97Startup()
{
	// Enable dma channel 6 (ac97 output) and dma channel 7 (ac97 input) 
//	XBYTE[SDRAM_DMA_EN1] = DMA_MASK_AC97_IN+DMA_MASK_AC97_OUT;	
//	XBYTE[SDRAM_DMA_EN1] = DMA_MASK_AC97_OUT;	

	Dsp_bFinished = TRUE;

	_bWorking = TRUE;
	Ac97StartCodec();
	Ac97Stop();

	Ac97SetInputSampleRate(TRUE);	// 8k input and 48k output

	// open handfree speaker
	Ac97WriteReg(AC97_HEADPHONE_VOL, AC97_RIGHTVOL_HI, AC97_SPK_VOL_MAX - Ac97_iHandfreeOutputVol);
#ifdef _USE_FXS
	Ac97WriteReg(AC97_MIC_VOL, AC97_MUTE_HI, AC97_MUTE_LO);            // MIC Input (mono)
#else
	Ac97WriteReg(AC97_MIC_VOL, AC97_MUTE_HI, AC97_MICBOOST_LO);            // MIC Input (mono)
#endif

	Ac97_bMuteInput = FALSE;
	Ac97OnHandsetChange();
}

void Ac97Stop()
{
	if (_bWorking)
	{
		_bWorking = FALSE;
		Ac97StopCodec();
		XBYTE[SDRAM_STATUS1] = 0x60;	// Stop previous SDRAM transfer, if any
	}
#ifdef LM386_CTRL
	Cam_LedOff(3);
#endif
	_bRing = FALSE;
	Ac97_bIVR = FALSE;
	while (!Dsp_bFinished);
//	SysNormalSpeed();
}

void Ac97StartIVR()
{
	DtmfStopAll();
	Ac97_bIVR = TRUE;
	Ac97Start();
}

void Ac97StopIVR()
{
	if (Ac97_bIVR)
	{
		Ac97_bIVR = FALSE;
		SoloFileCloseRead();
		if (IsInCall())
		{
			return;
		}
		Ac97Stop();
		OnCheckHandset();
	}
}

void Ac97StartRing()
{
//	Ac97StopIVR();

#ifdef _USE_FAKE_FXO
	SwitchToFXO(FALSE);
#endif
	_bRing = TRUE;
	Ac97Start();
	SysHighSpeed();

#ifdef _USE_FXS
	SlicStartRing();
#else
	if (Task_iRingType >= RING_TYPE_USER)
	{
		SdramRingFile();
	}
#endif	// _USE_FXS
	if (Task_iRingType <= RING_TYPE_USER)
	{
		DtmfRing();
	}
}

void Ac97StopRing()
{
	if (_bRing)
	{
		_bRing = FALSE;
		SoloFileCloseRead();
	}

#ifdef _USE_FXS
	SlicStopRing();
#endif

	DtmfStopAll();
}

void Ac97Start()
{
	if (_bWorking)	return;

#ifdef LM386_CTRL
	if (!PIO_bHandsetUp)
	{
		Cam_LedOn(3);
	}
#endif

#ifdef _USE_FXS
	Slic_iCidStatus = 0;
#endif

	if (Ac97_bIVR)
	{
		Dsp_iType = CODEC_G7231;
	}
	else
	{
		if (Sys_iAudioType == CODEC_NULL)
		{
			Dsp_iType = CODEC_G729;
		}
		else
		{
			Dsp_iType = Sys_iAudioType;
		}
	}

//	SysHighSpeed();

	DspStart();
	DtmfStopAll();
	_bWorking = TRUE;
	_bNeedBuffer = TRUE;

	Ac97InitBuffer();
}

void Ac97HandleInterrupt()
{
//	if (!Ac97CheckIrq())		return;
	XBYTE[SDRAM_DMA_INT1] = DMA_MASK_AC97_IN;
	if (!_bWorking)			return;

	Ac97SwapBuffer();
	DspCall();

	_bNeedBuffer = TRUE;

	Sys_iWholeSecond ++;
	Timer_bIndicated2 = TRUE;
	if (Dsp_iType == CODEC_G7231 || Dsp_iType == CODEC_ILBC)
	{
		if (Sys_iWholeSecond == 33 || Sys_iWholeSecond == 66)
		{
			Timer_bIndicated = TRUE;
		}
		else if (Sys_iWholeSecond >= 100)
		{
			Sys_iWholeSecond = 0;
			Timer_bIndicated = TRUE;
		}
#ifdef CALL_IAX2
		Sys_lTicker += 30;
#endif
	}
	else if (Dsp_iType == CODEC_GSM610)
	{
		if (Sys_iWholeSecond >= 50)
		{
			Sys_iWholeSecond = 0;
			Timer_bIndicated = TRUE;
		}
#ifdef CALL_IAX2
		Sys_lTicker += 20;
#endif
	}
	else
	{
		if (Sys_iWholeSecond >= 100)
		{
			Sys_iWholeSecond = 0;
			Timer_bIndicated = TRUE;
		}
#ifdef CALL_IAX2
		Sys_lTicker += 10;
#endif
	}
}

void Ac97Run()
{
	BOOLEAN bSend;

	if (!_bWorking)		return;

	while (DspHandleEncodeData());

	if (!_bNeedBuffer)	return;

	if (Ac97_bIVR)
	{
		if (!_HandleFileData(TRUE, FALSE))
		{
			Ac97StopIVR();
			Ac97SetOutputVol();
		}
	}
	else if (_bRing)
	{
		bSend = TRUE;
		// some MGCP IADs generate ringback tone locally and also play out the ringback peer send to it, 
		// which will corrupt the ringback tone, so here we don't send ringback tone for MGCP system 
#ifdef CALL_MGCP
		if (Sys_iServiceType != MGCP_SERVICE_TYPE_KAIMEN)
		{
			bSend = FALSE;
		}
#endif

		if (Task_iRingType == RING_TYPE_ADVANCED)
		{
			if (!_HandleFileData(TRUE, bSend))
			{
				SdramRingFile();	// restart ring
			}
		}
		else if (Task_iRingType == RING_TYPE_USER)
		{
			if (!_HandleFileData(TRUE, FALSE))
			{
				SdramRingFile();	// restart ring
			}
			DtmfRun();
		}
		else
		{
			DtmfRun();
		}
	}
#ifdef CALL_SIP
#ifdef OEM_263
	else if (Task_bOnHold)
	{
		if (!_HandleFileData(TRUE, FALSE))
		{
			SdramRingFile();	// ring file as call hold file
		}
	}
#endif
#else
	else if (Task_bCallHold)
	{
//		if (!_HandleRingData(FALSE, TRUE))
		if (Ac97_iDtmfCode == DTMF_SIGNAL_DIAL)
		{
			if (!_HandleFileData(TRUE, TRUE))
			{
				SdramRingFile();	// ring file as call hold file
			}
		}
		else
		{
			if (!_HandleFileData(FALSE, TRUE))
			{
				SdramRingFile();	// ring file as call hold file
			}
			DtmfRun();
		}
	}
#endif
	else
	{
		DtmfRun();
	}

	_bNeedBuffer = FALSE;
}

