⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mass_wma.c

📁 TELECHIPS MP3解决方案UMS实现源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#if defined(WMA_DEC_INCLUDE)

#include "SMC.H"
#include "SMC_FS.H"
#include "SMC_FILE.H"

#include "tcc730.h"
#include "filesystem.h"
#include "mass_common.h"

#include "wma.h"
#include "genlib.h"

#if defined(MMC_INCLUDE)
#include "mmc_fs.h"

#if defined(MMC_DEBUG)
#include "mmc_debug.h"
#else
#define MMC_ASSERT(__expr)
#define MMC_BREAK()
#define MMC_BREAK_EX(__expr)
#endif

#endif

///////////////////////////////////////////////////////////////////////////////

#ifndef UNREFERENCED_PARAMETER
#define UNREFERENCED_PARAMETER(__param)	((__param) = (__param))
#endif

///////////////////////////////////////////////////////////////////////////////
// Refer to Windows Header file "initguid.h"

#define GUID_SIZE		16
#define DEFINE_GUID(_name, _l, _w1, _w2, _b1, _b2, _b3, _b4, _b5, _b6, _b7, _b8)	\
const unsigned char _name[GUID_SIZE] = 			\
		{	((_l)      ) & 0xff,		\
			((_l) >>  8) & 0xff,		\
			((_l) >> 16) & 0xff,		\
			((_l) >> 24) & 0xff,		\
			((_w1)     ) & 0xff,		\
			((_w1) >> 8) & 0xff,		\
			((_w2)     ) & 0xff,		\
			((_w2) >> 8) & 0xff,		\
			(_b1) & 0xff,				\
			(_b2) & 0xff,				\
			(_b3) & 0xff,				\
			(_b4) & 0xff,				\
			(_b5) & 0xff,				\
			(_b6) & 0xff,				\
			(_b7) & 0xff,				\
			(_b8) & 0xff}

///////////////////////////////////////////////////////////////////////////////

enum WMA_FLAGS {
	WMA_PLAY = 1,			// Music play
	WMA_PAUSE,				// Music play wait
	WMA_RESERVED_,			// 
	WMA_WAIT,				// Encode wait
	WMA_ERR1,				// No flash memory error
	WMA_ERR2,				// No format error
	WMA_ERR3,				// No file
	WMA_REW,				// REW
	WMA_FF,					// FF
	WMA_FLGAS_COUNT
};

///////////////////////////////////////////////////////////////////////////////

#pragma	memory=data_seg(TCC730_INTERNAL)
void (*CodecAudioDecodeFnct)(TypeCodecSharedBox *);
ubyte CodecFrameErrCtr;
ubyte	Play_Mode;

TypeCodecSharedBox	CodecShared;

static unsigned long* g_lpdwCurPlayPos;

static unsigned g_nRepeatTimeA;
static unsigned long g_dwRepeatPosA;
static unsigned long g_dwRepeatPosB;

extern int g_ActiveDrive;
extern int g_nCoderHandle;

extern ubyte gTempBuf2[];
#pragma memory=default

extern int		TCC730_SMC_ConvertErrorCode(int nMMCErrCode);
#if defined(MMC_INCLUDE)
extern int		TCC730_MMC_ConvertErrorCode(int nMMCErrCode);
#endif


static void _loc_InitWMARingBuffer(void)
{
	CodecShared.InputBufferValidData  = 0; 							// num of char
    CodecShared.InputBufferWPointer   = CodecShared.InputBufferPointer;		// write pointer
	CodecShared.InputBufferRPointer   = CodecShared.InputBufferPointer;		// read pointer

	CodecShared.OutputBufferValidData = 0; 							// num of char
    CodecShared.OutputBufferWPointer   = CodecShared.OutputBufferPointer; 	// write pointer
	CodecShared.OutputBufferRPointer   = CodecShared.OutputBufferPointer;	// read pointer
	CodecShared.OutputBufferEnd = CodecShared.OutputBufferPointer + CodecShared.OutputBufferLength;

	CodecShared.IisSyncFlag0 = 0; 
	CodecShared.IisSyncFlag1 = 0;		
	CodecShared.CodecInvokeSyncFlag = CODEC_DONE;		
}

static int _loc_SeekSectorForward(int nSeekSectorCount)
{
	int nError;

	switch(g_ActiveDrive)
	{

		#ifdef MMC_INCLUDE
		case DRIVE_MMC :	MMC_ASSERT(nSeekSectorCount >= 0);		// It should be positive value
							nError = TCC730_MMC_SetFileSectorPointer( g_nCoderHandle,
												 					  nSeekSectorCount,
												 					  MMC_FILE_CURRENT,
												 					  gTempBuf );
							if (nError != 0) nError = TCC730_MMC_ConvertErrorCode(nError);
							break;
		#else
		case DRIVE_SMC :
		#endif
		case DRIVE_NFL :	if ( SMC_FILE_SeekFile( g_nCoderHandle,SEEK_CURRENT,(long)nSeekSectorCount*512,gTempBuf ) == 0xFFFFFFFF )
							{
								nError = SMC_ERR_FILE_NOT_FOUND;
								nError = TCC730_SMC_ConvertErrorCode(nError);
							}
							else	nError = SMC_ERR_NOERROR;	
							break;
		
		default :			nError = ERR_CARD_NOT_DETECTED;
	}

	return nError;
}

static int _loc_SeekSectorBackward(int nSeekSectorCount)
{
	int nError;

	switch(g_ActiveDrive)
	{

		#ifdef MMC_INCLUDE
		case DRIVE_MMC :	MMC_ASSERT(nSeekSectorCount >= 0);		// It should be positive value
							nError = TCC730_MMC_SetFileSectorPointer( g_nCoderHandle,
																	  -nSeekSectorCount,
																	  MMC_FILE_CURRENT,
												 					  gTempBuf );
							if (nError != 0) nError = TCC730_MMC_ConvertErrorCode(nError);
							break;
		#else
		case DRIVE_SMC :
		#endif

		case DRIVE_NFL :	if ( SMC_FILE_SeekFile( g_nCoderHandle,SEEK_CURRENT,-(long)nSeekSectorCount*512,gTempBuf ) == 0xFFFFFFFF )
							{
								nError = SMC_ERR_FILE_NOT_FOUND;
								nError = TCC730_SMC_ConvertErrorCode(nError);
							}
							else	nError = SMC_ERR_NOERROR;		
							break;


		default :			nError = ERR_CARD_NOT_DETECTED;
	}

	return nError;
}


static void _loc_SearchRepeatPosA(void)
{
	switch(g_ActiveDrive)
	{

		#if defined(MMC_INCLUDE)
		case DRIVE_MMC :	TCC730_MMC_SetFileSectorPointer(g_nCoderHandle, g_dwRepeatPosA, MMC_FILE_BEGIN, gTempBuf);
							break;
		#else
		case DRIVE_SMC :
		#endif

		case DRIVE_NFL :	SMC_FILE_SeekFile( g_nCoderHandle,SEEK_BEGIN,(long)g_dwRepeatPosA*512,gTempBuf );
							break;
		
		default :			;
	}
}

// Try to set point A
static void _loc_OperateRepeatA(unsigned nRemainPacket)
{
	switch(g_ActiveDrive)
	{

		#if defined(MMC_INCLUDE)
		case DRIVE_MMC :	TCC730_MMC_GetFileSectorPointer(g_nCoderHandle, &g_dwRepeatPosA);
							break;
		#else
		case DRIVE_SMC :
		#endif

		case DRIVE_NFL :	g_dwRepeatPosA = SMC_FILE_SeekFile( g_nCoderHandle,SEEK_CURRENT,(long)0,gTempBuf );
							g_dwRepeatPosA = g_dwRepeatPosA/512;
							break;
		
		default :			g_dwRepeatPosA = 0;
							g_nRepeatTimeA = 0;
	}

	if (nRemainPacket >= CodecShared.InputBufferValidData)
	{
		g_nRepeatTimeA = 512 + CodecShared.InputBufferValidData - nRemainPacket;
	}
	else
	{
		g_dwRepeatPosA--;
		g_nRepeatTimeA = CodecShared.InputBufferValidData - nRemainPacket;
	}

	CodecShared.SeekFlag = 0x11;	// Position A was setted
	
}

// Try to set point B
static void _loc_OperateRepeatB(void)
{
	switch(g_ActiveDrive)
	{
	
		#if defined(MMC_INCLUDE)
		case DRIVE_MMC :	TCC730_MMC_GetFileSectorPointer(g_nCoderHandle, &g_dwRepeatPosB);
							break;
		#else
		case DRIVE_SMC :
		#endif

		case DRIVE_NFL :	g_dwRepeatPosB = SMC_FILE_SeekFile( g_nCoderHandle,SEEK_CURRENT,(long)0,gTempBuf );
							g_dwRepeatPosB = g_dwRepeatPosB/512;
							break;
		
		default :			g_dwRepeatPosB = 0;
	}
}

static void _loc_OperateRepeat(void)
{
	int							i;
	unsigned long				dwFilePos;
	CONST_FAKE unsigned char*	lpTemp;


	switch(g_ActiveDrive)
	{

		#if defined(MMC_INCLUDE)
		case DRIVE_MMC :	TCC730_MMC_GetFileSectorPointer(g_nCoderHandle, &dwFilePos);
							break;
		#else
		case DRIVE_SMC :
		#endif					

		case DRIVE_NFL :	dwFilePos = SMC_FILE_SeekFile( g_nCoderHandle,SEEK_CURRENT,(long)0,gTempBuf );
							dwFilePos = dwFilePos/512;
							break;

		default :			dwFilePos = 0;
	}

	if (dwFilePos < g_dwRepeatPosB)	return;

	// Search 0x8200 when return to RepeatA
	_loc_InitWMARingBuffer();
	_loc_SearchRepeatPosA();
				
	for (i = 0; i < 2; i++)
	{
		switch(g_ActiveDrive)
		{

			#if defined(MMC_INCLUDE)
			case DRIVE_MMC :	TCC730_MMC_ReadFileSector(g_nCoderHandle, CodecShared.InputBufferWPointer);
								break;					
			#else
			case DRIVE_SMC :
			#endif					

			case DRIVE_NFL :	SMC_FILE_ReadFile( g_nCoderHandle,CodecShared.InputBufferWPointer,512 );
								break;	
		}

		CodecShared.InputBufferWPointer += 512;
	}

	lpTemp = (CONST_FAKE unsigned char*)&CodecShared.InputBufferPointer[512 - g_nRepeatTimeA - 1];

	if ((lpTemp[0] == 0x82) && (lpTemp[1] == 0x00) && (lpTemp[2] == 0x00))
	{
		g_nRepeatTimeA++;
	}
	else if ((lpTemp[2] == 0x82) && (lpTemp[3] == 0x00) && (lpTemp[4] == 0x00))
	{
		g_nRepeatTimeA--;
	}
	else if (!((lpTemp[1] == 0x82) && (lpTemp[2] == 0x00) && (lpTemp[3] == 0x00)))
	{
		CodecShared.FrameErrorFlag = 12;
		CodecShared.InputBufferValidData = 512 * 2;
		CodecShared.InputBufferWPointer = &CodecShared.InputBufferPointer[0];
		CodecShared.CodecInvokeSyncFlag = CODEC_INVOKE;
		return;
	}

	CodecShared.InputBufferValidData = g_nRepeatTimeA + 512;
	CodecShared.InputBufferWPointer = &CodecShared.InputBufferPointer[0];

	CodecShared.CodecInvokeSyncFlag = CODEC_INVOKE;
	CodecShared.SeekFlag = 0x13;	//Start at the RepeatA
}

static void _loc_CheckWMARepeat(unsigned nLen)
{
	unsigned nRemainPacket;

	UNREFERENCED_PARAMETER(nLen);

	if(CodecShared.SeekFlag == 0)
		return;
	
	nRemainPacket = (CodecShared.RemainedBitInPacketHi << 13)
				  | ((CodecShared.RemainedBitInPacketLo >> 3) & 0x1ffe);

	if(nRemainPacket < (512 + CodecShared.InputBufferValidData))
	{
		switch(CodecShared.SeekFlag)
		{
		case 0x10:	// Before setting RepeatA
			_loc_OperateRepeatA(nRemainPacket);
			break;

		case 0x12:	//Before Set RepeatB
			_loc_OperateRepeatB();
			// no break 

		case 0x14:	//During the block repeat
			_loc_OperateRepeat();
			break;

		default :
			// What shall I do?
			;
		}
	}
}

ubyte TCC730_WMADecoderInit(uword drive, uword f_index, long *ptr, ubyte volume, ubyte EQ)
{
	int i, nError;

	g_lpdwCurPlayPos = (unsigned long*)ptr;

	nError = Get_File_Info(drive, f_index, &FileInfo);
	if (nError != SM_OK)
		return (ubyte)nError;

	if (FileInfo.Size.nLong == 0)
		return SM_OK;


	switch(drive)
	{
		#if defined(MMC_INCLUDE)
		case DRIVE_MMC :	nError = TCC730_MMC_OpenFileByIndex( f_index,
																 MMC_FILE_FLAG_READ | MMC_FILE_FLAG_CACHE,
																 &g_nCoderHandle,
																 gTempBuf );
							g_ActiveDrive = DRIVE_MMC;
							break;
		#else
		case DRIVE_SMC :
		#endif					

		case DRIVE_NFL :	nError = SMC_MPX_OpenFileByIndex( drive,f_index,OPEN_R,(unsigned int*)&g_nCoderHandle,gTempBuf );
							g_ActiveDrive = DRIVE_NFL;
							break;

		default :			nError = ERR_CARD_NOT_DETECTED;
	}

	if (nError != 0) return nError;

	TCC730_ZeroMemory(&CodecShared, sizeof(TypeCodecSharedBox));

	CodecFrameErrCtr = 0; 	
	CodecShared.EqualizerModeControl =EQ;// SysInfo.EqualizerMode;	
	CodecShared.EQ_VolumeFlag = 3;		// Enable Equalizer and Volume 
	CodecShared.VolumeControl = volume;		//SysInfo.Volume;

	CodecShared.StartDecodingFlag = 0;		
	CodecAudioDecodeFnct = (void ( *)(TypeCodecSharedBox *)) WMADecoder;

	CodecAudioDecodeFnct(&CodecShared);
	
	_loc_InitWMARingBuffer();

	for (i = 0; i < 20; i++)
	{
		// Fill Input Buffer	
		while(RingReadFilePutStr(512))
			;

		CodecAudioDecodeFnct(&CodecShared);

		if(CodecShared.FrameErrorFlag == 0)
			break;
	}

	Play_Mode = WMA_PLAY;	
	Set_PLL1();	

	if(i >= 20)
	{
		// Error, In next flow, skip to next song.  		
		PLL1DATA = 0x55c;		//44.1 khz
	}

	return SM_OK;
}

ubyte RingReadFilePutStr(uword len)
{
	if ((CodecShared.InputBufferLength - CodecShared.InputBufferValidData) < 512)
		return FALSE;		// can't put, buffer is not enough

	if ((CodecShared.MediaMode & 0xf0) != 0x20)		//0x2? WMA
		return FALSE;

	_loc_CheckWMARepeat(len);

	if ((CodecShared.InputBufferLength - CodecShared.InputBufferValidData) < 512)
		return FALSE;		// can't put, buffer is not enough

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -