#include "page1.h"
#include "p_dsp.h"

static XCHAR _iReadSdramHi;
static XSHORT _iReadLen; 

void ConvertReadFileOpen(UCHAR iSdramHi)
{
	_iReadSdramHi = iSdramHi;
	_iReadLen = 0;
}

void _ConvertReadFile(UCHAR iLength)
{
	DSHORT iCurLen;
	DCHAR iOffset, iLen;

	iLen = iLength;
	iCurLen = _iReadLen;
	iOffset = (UCHAR)iCurLen;

	sdram_read(_iReadSdramHi, P_HIBYTE(iCurLen), SRAM_DMA_DWORD);
	if (iOffset)
	{
		p_memcpy_x2x((PXCHAR)Sdram_pDataCache, (PXCHAR)(Sdram_pDataCache+iOffset), iLen);
	}

	if (iLen)
	{
		_iReadLen += iLen;
	}
	else
	{
		_iReadLen += 256;
	}

	if (_iReadLen < iCurLen)	// 64k limit
	{
		_iReadSdramHi ++;
	}
}

void _DspInit(UCHAR iDspType)
{
	DCHAR iType;

	iType = iDspType;
	DspDownloadCode(Dsp_cCodeSdramHi[iType], Dsp_cCodeSdramLo[iType], Dsp_cCodeSize[iType]);
}

void _EncodeInit(UCHAR iDspType, UCHAR iSrcSdramHi, UCHAR iDstSdramHi)
{
	DspExecuteAndWait(Dsp_cCodecInit[iDspType]);

	ConvertReadFileOpen(iSrcSdramHi);
	SoloFileOpen(iDstSdramHi, TRUE, FILE_ONE_PAGE_SIZE);

	DspWriteDMC(PMIN_AGC_USAGE, FALSE);
	DspWriteDMC(PMIN_AEC_USAGE, FALSE);
	DspWriteDMC(ENC_INPUT_SDRAM_HI, DSP_INPUT_SDRAM_HI);
	DspWriteDMC(DEC_OUTPUT_SDRAM_LO, 0);
	DspWriteDMC(ENC_OUTPUT_SDRAM_HI, DSP_OUTPUT_SDRAM_HI);
	DspWriteDMC(ENC_OUTPUT_SDRAM_LO, 0);
}

void _DecodeInit(UCHAR iDspType, UCHAR iSrcSdramHi, UCHAR iDstSdramHi)
{
	DspExecuteAndWait(Dsp_cCodecInit[iDspType]);

	ConvertReadFileOpen(iSrcSdramHi);
	SoloFileOpen(iDstSdramHi, TRUE, FILE_ONE_PAGE_SIZE*2);

	DspWriteDMC(DEC_INPUT_SDRAM_HI, DSP_INPUT_SDRAM_HI);
	DspWriteDMC(DEC_INPUT_SDRAM_LO, 0);
	DspWriteDMC(DEC_OUTPUT_SDRAM_HI, DSP_OUTPUT_SDRAM_HI);
	DspWriteDMC(DEC_OUTPUT_SDRAM_LO, 0);
}

void _DecodeG729Frame()
{
	// put the 12 input bytes into from input file to Sdram_pDataCache 
	_ConvertReadFile(G729_COMPRESSED);
	sdram_write(DSP_INPUT_SDRAM_HI, 0, G729_COMPRESSED/4);

	DspExecuteAndWait(Dsp_c8KDecode[CODEC_G729]);

	sdram_read(DSP_OUTPUT_SDRAM_HI, 0, PCM_RAW_LEN/4);
	// put the 160 output bytes from Sdram_pDataCache to output file
	SoloFileWriteSdramCache(PCM_RAW_LEN);
}

void _EncodeGsm610Frame()
{
	// put the 320 input bytes into from input file to Sdram_pDataCache 
	_ConvertReadFile(256);
	sdram_write(DSP_INPUT_SDRAM_HI, 0, 64);
	_ConvertReadFile(64);
	sdram_write(DSP_INPUT_SDRAM_HI, 1, 16);

	DspExecuteAndWait(Dsp_c8KEncode[CODEC_GSM610]);

	sdram_read(DSP_OUTPUT_SDRAM_HI, 0, GSM610_LEN/4+1);
	SoloFileWriteSdramCache(GSM610_LEN);
}

void _EncodeiLBCFrame()
{
	// put the 480 input bytes into from input file to Sdram_pDataCache 
	_ConvertReadFile(256);
	sdram_write(DSP_INPUT_SDRAM_HI, 0, 64);
	_ConvertReadFile(224);
	sdram_write(DSP_INPUT_SDRAM_HI, 1, 56);

	DspExecuteAndWait(Dsp_c8KEncode[CODEC_ILBC]);

	sdram_read(DSP_OUTPUT_SDRAM_HI, 0, ILBC_LEN/4+1);
	SoloFileWriteSdramCache(ILBC_LEN);
}

void _EncodeG711uFrame()
{
	_ConvertReadFile(PCM_RAW_LEN);
	sdram_write(DSP_INPUT_SDRAM_HI, 0, PCM_RAW_LEN/4);

	DspExecuteAndWait(Dsp_c8KEncode[CODEC_G711U]);

	sdram_read(DSP_OUTPUT_SDRAM_HI, 0, G711_LEN/4);
	SoloFileWriteSdramCache(G711_LEN);
}

void _EncodeG711aFrame()
{
	_ConvertReadFile(PCM_RAW_LEN);
	sdram_write(DSP_INPUT_SDRAM_HI, 0, PCM_RAW_LEN/4);

	DspExecuteAndWait(Dsp_c8KEncode[CODEC_G711A]);

	sdram_read(DSP_OUTPUT_SDRAM_HI, 0, G711_LEN/4);
	SoloFileWriteSdramCache(G711_LEN);
}

void ConvertRing()
{
	DSHORT i, iLen;
	DLONG iRawRingLen, k;

	// restore pcm data from g.729 files
	_DspInit(CODEC_G729);
	_DecodeInit(CODEC_G729, RING_G729_SDRAM_HI, AC97_IN_SDRAM_HI);

	SdramReadFlags();
	iLen = PXCHAR2USHORT((PXCHAR)(Sdram_pDataCache+FLAGS_RING_SIZE));
	for (i = 0; i < iLen; i += G729_COMPRESSED)
	{
		_DecodeG729Frame();
	}
	iRawRingLen = SoloFileClose();

	BootIndication(13);
	Led_Blink(NORMAL_LIGHT);

	// begin convert

	// gsm610
	_DspInit(CODEC_GSM610);
	_EncodeInit(CODEC_GSM610, AC97_IN_SDRAM_HI, RING_GSM610_SDRAM_HI);

	for (k = 0; k < iRawRingLen; k += PCM_RAW_LEN*2)
	{
		_EncodeGsm610Frame();
	}
	SoloFileClose();

	BootIndication(14);
	Led_Blink(NORMAL_LIGHT);

	// ilbc 30ms
	_DspInit(CODEC_ILBC);
	_EncodeInit(CODEC_ILBC, AC97_IN_SDRAM_HI, RING_ILBC_SDRAM_HI);

	for (k = 0; k < iRawRingLen; k += PCM_RAW_LEN*3)
	{
		_EncodeiLBCFrame();
	}
	SoloFileClose();

	BootIndication(15);
	Led_Blink(NORMAL_LIGHT);

	// g711u
	_DspInit(CODEC_G711U);
	_EncodeInit(CODEC_G711U, AC97_IN_SDRAM_HI, RING_G711U_SDRAM_HI);

	for (k = 0; k < iRawRingLen; k += PCM_RAW_LEN)
	{
		_EncodeG711uFrame();
	}
	SoloFileClose();

//	BootIndication(15);
	Led_Blink(NORMAL_LIGHT);

	// g711A
	_DspInit(CODEC_G711A);
	_EncodeInit(CODEC_G711A, AC97_IN_SDRAM_HI, RING_G711A_SDRAM_HI);

	for (k = 0; k < iRawRingLen; k += PCM_RAW_LEN)
	{
		_EncodeG711aFrame();
	}
	SoloFileClose();
}

