www.pudn.com > OS.rar > FS_DS.c, change:2007-01-16,size:15960b


//============================================== 
//include head file 
//============================================== 
#include ".\System\GPL162002_Far\include\system_head.h" 
#include ".\Component\GPL162002_Far\Include\FileSystem\vfs.h" 
#include "..\Include\Snd_ArithmConfig.h" 
#include ".\Component\GPL162002_Far\Include\Sound\Public\SndSACM.h" 
#include ".\Component\GPL162002_Far\Include\Sound\Public\NandFS_DS.h" 
#include ".\Component\GPL162002_Far\Include\Sound\Public\MP3.h" 
 
//guili 2005.11.10 cfwei set this const because to skip first frame data(I think), 
//for first frame data is not good. But when bitrate is not 16kbp, the const is always 
//equal 16,then must skip 24 words when bitrate=24kbps, but only skip 16words, so  
//play noise 
//#define C_NFAT_DVR1600DS_SkipCount 16	//guili 2005.11.10 
#define C_NFAT_DVR1600DS_SkipCount 	0	//guili 2005.11.10 
 
//============================================== 
#ifdef C_SND_DVR1600_SUPPORT 
#ifdef C_SND_A1600_SKIPPLAY_SUPPORT 
	extern unsigned int Snd_A1600_GetWordsPerFrame(void); 
	extern unsigned int Snd_A1600_GetModeCode(LPTR DataPtr); 
	extern unsigned long Snd_Get_A1600SkipOffset(unsigned long StartTime); 
	extern unsigned long Snd_Skip_A1600_ReturnLength(unsigned long DataTime); 
	 
	extern unsigned long SACM_Decode_Length_L; 
	extern unsigned int SACM_A1600_ModeCode; 
	extern unsigned long Snd_A1600_ulDataLength; 
#endif 
#endif 
 
#ifdef C_SND_A1800_SUPPORT 
#ifdef C_SND_A1800_SKIPPLAY_SUPPORT 
	extern unsigned long Snd_A1800_ulDataLength; 
	extern unsigned int SACM_A1800_ModeCode; 
	extern unsigned int SACM_Decode_Length_L; 
	extern unsigned int SACM_Decode_Length_H; 
 
	extern unsigned int Snd_A1800_GetModeCode(unsigned long DataPtr); 
	extern unsigned int Snd_A1800_GetResMode(unsigned long DataPtr); 
	extern void Snd_Skip_A1800_ReturnLength(unsigned long DataTime); 
	extern unsigned long Snd_A1800_GetTotalTime( unsigned int * DataPtr ); 
	extern unsigned long Snd_Get_A1800SkipOffset(unsigned long StartTime); 
#endif 
#endif 
 
#ifdef C_SND_MP3_SUPPORT 
	unsigned long ulFrame_Count_MP3; 
#endif 
 
//============================================== 
 
#ifdef FAT 
//---------------------------------------------- 
 
int NFAT_DS_fodenum = -1; 
int NFAT_DVR1600DS_readCount; 
int NFAT_DVR1600DS_header[3]; 
 
#ifdef FARRELEASE 
void NFAT_DS_Open( int *short_this, unsigned char * path, int flag) 
#else 
void NFAT_DS_Open( int *short_this, LPTR path, int flag) 
#endif 
{ 
	//NFAT_DS_fodenum = SpFSopen(path, flag);			//guili 2005.10.22 
	NFAT_DS_fodenum = open(path, flag);					//guili 2005.10.22 
} 
 
void NFAT_DS_SetHandle( int *short_this, int fhnd ) 
{ 
//	if( NFAT_DS_fodenum != -1 ) SpFSclose( NFAT_DS_fodenum );	//if e100, not close 
	if( NFAT_DS_fodenum != -1 ) close( NFAT_DS_fodenum );		//if e100, not close 
	NFAT_DS_fodenum = fhnd; 
} 
 
//#ifdef FARRELEASE 
//void NFAT_DS_GetData( int *short_this, unsigned char* dest_addr,unsigned int length) 
//#else 
void NFAT_DS_GetData( int *short_this, LPTR dest_addr,UINT length) 
//#endif 
{ 
	//SpFSread( NFAT_DS_fodenum, dest_addr, length);			//guili 2005.10.22 
	read( NFAT_DS_fodenum, dest_addr<<1, length<<1);			//guili 2005.10.22	//xiaolei add &.2006/02/17 
} 
 
void NFAT_DS_Close( int *short_this ) 
{ 
	if( NFAT_DS_fodenum != -1 ) 
	{ 
		//SpFSclose( NFAT_DS_fodenum );	//guili 2005.10.22 
		close( NFAT_DS_fodenum );		//guili 2005.10.22 
		NFAT_DS_fodenum = -1; 
	} 
} 
 
#ifdef C_SND_DVR_SUPPORT 
void NFAT_DVR1600DS_SetHandle( int *short_this, int fhnd ) 
{ 
	ULONG *hsize = (ULONG*)NFAT_DVR1600DS_header; 
	NFAT_DS_fodenum = fhnd; 
	NFAT_DVR1600DS_readCount = 0; 
	//SpFSread( NFAT_DS_fodenum, (LPTR)NFAT_DVR1600DS_header, 3);	//guili 2005.10.22 
	//SpFSlseek( NFAT_DS_fodenum, C_NFAT_DVR1600DS_SkipCount, 1);	//guili 2005.10.22 
	read( NFAT_DS_fodenum, (LPTR)NFAT_DVR1600DS_header<<1, 3*2);	//guili 2005.10.22 
	lseek( NFAT_DS_fodenum, C_NFAT_DVR1600DS_SkipCount<<1, 1);	//guili 2005.10.22 
	*hsize -= (C_NFAT_DVR1600DS_SkipCount*2); 
} 
 
//#ifdef FARRELEASE 
//void NFAT_DVR1600DS_GetData( int *short_this, unsigned char * dest_addr,unsigned int length) 
//#else 
void NFAT_DVR1600DS_GetData( int *short_this, LPTR dest_addr,UINT length) 
//#endif 
{ 
	while( NFAT_DVR1600DS_readCount  3 ) 
	{ 
		WVUI( dest_addr++, NFAT_DVR1600DS_header[NFAT_DVR1600DS_readCount] ); 
		NFAT_DVR1600DS_readCount++; 
		length--; if( length=0 ) return; 
	} 
 
	//SpFSread( NFAT_DS_fodenum, dest_addr, length);	//guili 2005.10.22 
	read( NFAT_DS_fodenum, dest_addr<<1, length<<1 );	//guili 2005.10.22 
} 
#endif//--C_SND_DVR_SUPPORT-- 
 
//=========== stand alone PlayNandFAT API ================ 
 
NFlashFAT_DATA_SOURCE_St NFATDSource = {NFAT_DS_GetData,NFAT_DS_Open,NFAT_DS_SetHandle,NFAT_DS_Close}; 
#ifdef C_SND_DVR_SUPPORT 
NFlashFAT_DATA_SOURCE_St NFATDVR1600Source = {NFAT_DVR1600DS_GetData,NFAT_DS_Open,NFAT_DVR1600DS_SetHandle,NFAT_DS_Close}; 
#endif 
 
unsigned int Snd_PlayNandFAT( int _CodecType, int handle ) 
{ 
	unsigned int HeadBuf[4]; 
	unsigned long offset; 
	 
	extern void SACM_Stop(void); 
	 
	if( handle<0 ) return 0; 
	 
	Snd_Stop(0); //== to avoid re-entry, stop first. 
//Play the speech word while MP3 Playing, Change the "Snd_Stop(0)" to "SACM_Stop()" 
	//SACM_Stop();	2006/12/14 xiaolei 在播放完MP3后再播放NandFat数据会出现问题.CurID变量没有置0 
    //== note! NFDSource is not re-entry able! 
#ifdef C_SND_A1800_SKIPPLAY_SUPPORT		//2007/01/13 add 
	#ifdef FARRELEASE 
		offset = &HeadBuf; 
		read( handle, offset < 1, 3 < 1); 
		SACM_A1800_ModeCode = Snd_A1800_GetModeCode( &HeadBuf ); 
		lseek( handle, -6, SEEK_CUR ); 
	#else 
		read( handle, SP2LP( HeadBuf < 1 ), 3 < 1); 
		SACM_A1800_ModeCode = Snd_A1800_GetModeCode( SP2LP(HeadBuf) ); 
		lseek( handle, -6, SEEK_CUR ); 
	#endif 
#endif 
 
#ifdef C_SND_DVR_SUPPORT 
	if(_CodecType == C_CODEC_DVR1600PLAY) 
	{ 
		NFATDVR1600Source.SetHandle((int*)&NFATDVR1600Source,handle); 
		return Snd_SACM_PlaySource(_CodecType, (DATA_SOURCE_St*)&NFATDVR1600Source ); 
	} 
	else 
#endif 
	{ 
		NFATDSource.SetHandle((int*)&NFATDSource,handle); 
		return Snd_SACM_PlaySource(_CodecType, (DATA_SOURCE_St*)&NFATDSource ); 
	} 
} 
 
#ifdef C_SND_MP3_SUPPORT 
#if 0 
//=====================For MP3 Play only=========================== 
unsigned int Snd_PlayMP3FAT( const char *filename ) 
{ 
	struct stat stFileInfo; 
	unsigned int handle; 
	long FileLength; 
 
	Snd_Stop(0); //== to avoid re-entry, stop first. 
    if(stat(filename, &stFileInfo)) 
    { 
    	return -1; 
    } 
 
    //MeadiaPlayer_SetEQmode(M_EQMode);				//xiaolei add for MP3 Mode Set 
 
    FileLength = stFileInfo.st_size; 
	handle = open(filename, O_RDONLY); 
	if( handle  0 ) 
	{ 
		return -1; 
	} 
 
	//== note! NFDSource is not re-entry able! 
	NFATDSource.SetHandle((int*)&NFATDSource,handle); 
	return Snd_SACM_PlayMP3Source(FileLength >> 1, (DATA_SOURCE_St*)&NFATDSource ); 
} 
 
unsigned int Snd_PlayMP3FATTime( const char *filename, unsigned long Start_time,long End_time ) 
{ 
	int retval; 
	long FileLength; 
	unsigned int handle; 
	unsigned long offset; 
	st_MP3FILE_INFO  mp3info; 
	struct stat filestatus; 
 
	Snd_Stop(0); //== to avoid re-entry, stop first. 
	retval = GetMp3Info(filename, &mp3info); 
	if(0 == retval) 
	{ 
		stat(filename, &filestatus); 
		offset = filestatus.st_size/mp3info.total_time; 
		offset = offset * Start_time; 
		if(End_time == -1) 
		{ 
			FileLength = filestatus.st_size - offset; 
		} 
		else 
		{ 
			FileLength = filestatus.st_size/mp3info.total_time*(End_time-Start_time); 
		} 
	} 
	else { 
		return -1; 
	} 
 
	handle = open (filename, O_RDONLY); 
	NFATDSource.SetHandle((int*)&NFATDSource, handle); 
	lseek (handle, offset, SEEK_SET); 
	return Snd_SACM_PlayMP3Source(FileLength >> 1, (DATA_SOURCE_St*)&NFATDSource ); 
} 
 
int Snd_PlayMP3FATTimeOffset(const char *filename, unsigned long Offset, unsigned long lenth, unsigned int flag) 
{ 
	int retval; 
	long FileLength; 
	unsigned int handle; 
	unsigned long offset; 
	st_MP3FILE_INFO  mp3info; 
	struct stat filestatus; 
#if 0 
	Snd_Stop(0); //== to avoid re-entry, stop first. 
	retval = GetMp3Info(filename, &mp3info); 
	if(0 == retval) 
	{ 
		stat(filename, &filestatus); 
		offset = filestatus.st_size/mp3info.total_time; 
		offset = offset * Start_time; 
		if(End_time == -1) 
		{ 
			FileLength = filestatus.st_size - offset; 
		} 
		else 
		{ 
			FileLength = filestatus.st_size/mp3info.total_time*(End_time-Start_time); 
		} 
	} 
	else { 
		return -1; 
	} 
 
	handle = open (filename, O_RDONLY); 
	NFATDSource.SetHandle((int*)&NFATDSource, handle); 
	lseek (handle, offset, SEEK_SET); 
	return Snd_SACM_PlayMP3Source(FileLength >> 1, (DATA_SOURCE_St*)&NFATDSource ); 
#endif 
} 
 
#endif 
#endif 
//=======================xiaolei add for MP3 only 2006/08/11================ 
//Function:	到文件的偏移处开始播放. 这个函数适用于起始头不是SACM数据的文件, 而不是SACM文件的Seek播放 
unsigned int Snd_PlayNandFAT_Index( int _CodecType, int handle , unsigned long offset) 
{ 
	if( handle<0 ) return 0; 
 
	Snd_Stop(0); //== to avoid re-entry, stop first. 
    //== note! NFDSource is not re-entry able! 
 
	NFATDSource.SetHandle((int*)&NFATDSource,handle); 
	lseek( handle, offset<<1, 0);			//guili 2005.10.22 
	return Snd_SACM_PlaySource(_CodecType, (DATA_SOURCE_St*)&NFATDSource ); 
} 
 
//--------------------------------------------- 
#ifdef C_SND_DVR1600_SUPPORT 
#ifdef C_SND_A1600_SKIPPLAY_SUPPORT 
unsigned int Snd_A1600_Skip_PlayNandFAT( int _CodecType, int handle, unsigned long StartTime, unsigned long EndTime ) 
{ 
	unsigned int HeadBuf[3]; 
	unsigned long offset; 
	 
	if( handle<0 ) return 0; 
	if( EndTime = StartTime ) return 0; 
	 
	Snd_Stop(0); //== to avoid re-entry, stop first. 
 
	NFATDSource.SetHandle((int*)&NFATDSource,handle); 
 
	//SpFSread( handle, SP2LP(HeadBuf), 3);		//guili 2005.10.22 
	read( handle, SP2LP(HeadBuf<<1), 3*2);		//guili 2005.10.22 
 
	SACM_A1600_ModeCode = Snd_A1600_GetModeCode( SP2LP(HeadBuf) ); 
 
	offset = Snd_Get_A1600SkipOffset( StartTime ); 
	//offset = offset + 3;						//guili 2005.10.25 
	//SpFSlseek( handle, offset, 0);			//guili 2005.10.22 
	//lseek( handle, offset<<1, 0);				//guili 2005.10.22  marked by guili 2005.10.25  
	lseek( handle, offset<<1, 1);				//guili 2005.10.25  SEEK_CUR 
	 
	if( EndTime == 0xffffffff ) 
	{ 
		EndTime = Snd_A1600_GetTotalTime(HeadBuf); 
	} 
	 
	SACM_Decode_Length_L = Snd_Skip_A1600_ReturnLength(EndTime - StartTime); 
			//frame number                 a frame a16 data number                word->byte 
 
	return Snd_SACM_PlaySource(_CodecType, (DATA_SOURCE_St*)&NFATDSource ); 
 
} 
 
unsigned int Snd_A1600_Skip_PlayFAT_NoLen( int _CodecType, int handle, unsigned long StartTime, unsigned long EndTime ) 
{ 
	unsigned int HeadBuf[3]; 
	unsigned long offset; 
	 
	if( handle<0 ) return 0; 
	if( EndTime = StartTime ) return 0; 
	 
	Snd_Stop(0); //== to avoid re-entry, stop first. 
 
	NFATDSource.SetHandle((int*)&NFATDSource,handle); 
 
	//SpFSread( handle, SP2LP(HeadBuf), 3);		//guili 2005.10.22 
	read( handle, (SP2LP(HeadBuf + 2))<<1, 2);		//guili 2005.10.22 
	 
	HeadBuf[0] = Snd_A1600_ulDataLength; 
	HeadBuf[1] = Snd_A1600_ulDataLength >> 16; 
 
	SACM_A1600_ModeCode = Snd_A1600_GetModeCode( SP2LP(HeadBuf) ); 
 
	offset = Snd_Get_A1600SkipOffset( StartTime ); 
	//offset = offset + 3;						//guili 2005.10.25 
	//SpFSlseek( handle, offset, 0);			//guili 2005.10.22 
	//lseek( handle, offset<<1, 0);				//guili 2005.10.22  marked by guili 2005.10.25  
	lseek( handle, offset<<1, 1);				//guili 2005.10.25  SEEK_CUR 
	 
	if( EndTime == 0xffffffff ) 
	{ 
		EndTime = Snd_A1600_GetTotalTime(&HeadBuf); 
	} 
	 
	SACM_Decode_Length_L = Snd_Skip_A1600_ReturnLength(EndTime - StartTime); 
	//frame number                 a frame a16 data number                word->byte 
 
	return Snd_SACM_PlaySource(_CodecType, (DATA_SOURCE_St*)&NFATDSource ); 
 
} 
#endif 
#endif 
 
#ifdef C_SND_A1800_SUPPORT 
#ifdef C_SND_A1800_SKIPPLAY_SUPPORT 
//Function: 实现A1800跳播的函数: 输入参数为起始时间 
unsigned int Snd_A1800_Skip_PlayNandFATTime( int _CodecType, int handle, unsigned long StartTime, unsigned long EndTime ) 
{ 
	unsigned int HeadBuf[4]; 
	unsigned long offset; 
	 
	if( handle<0 ) 
	{ 
		return 0; 
	} 
	if( EndTime = StartTime ) 
	{ 
		return 0; 
	} 
	 
	//to avoid re-entry, stop first. 
	Snd_Stop(0); 
	//Set the Handle 
	NFATDSource.SetHandle((int*)&NFATDSource, handle); 
#ifdef FARRELEASE 
	offset = &HeadBuf; 
	read( handle, offset < 1, 3 < 1); 
	SACM_A1800_ModeCode = Snd_A1800_GetModeCode( &HeadBuf ); 
#else 
	read( handle, SP2LP( HeadBuf < 1 ), 3 < 1); 
	SACM_A1800_ModeCode = Snd_A1800_GetModeCode( SP2LP(HeadBuf) ); 
#endif 
 
	offset = Snd_Get_A1800SkipOffset( StartTime );		//word number 
	lseek( handle, offset < 1, SEEK_CUR); 
 
	if( EndTime == 0xffffffff ) 
	{ 
		EndTime = Snd_A1800_GetTotalTime( &HeadBuf ); 
	} 
	 
	Snd_Skip_A1800_ReturnLength(EndTime - StartTime); 
 
	return Snd_SACM_PlaySource(_CodecType, (DATA_SOURCE_St*)&NFATDSource ); 
 
} 
 
//Function: 实现A1800跳播的函数: 输入参数为起始长度, 以word为单位 
//Parament: 输入第一个参数必须为C_CODEC_A1800_SKIP, 表示跳播 
unsigned int Snd_A1800_Skip_PlayNandFAT( int _CodecType, int handle, unsigned long StartLength, unsigned long EndLength ) 
{ 
	unsigned int HeadBuf[3], uiPerFrameNumber; 
	unsigned long offset, TatalLength, ulTempLength; 
 
	if( handle<0 ) 
	{ 
		return 0; 
	} 
	if( EndLength = StartLength ) 
	{ 
		return 0; 
	} 
 
	//to avoid re-entry, stop first. 
	Snd_Stop(0); 
	//Set the Handle 
	NFATDSource.SetHandle((int*)&NFATDSource, handle); 
#ifdef FARRELEASE 
	offset = &HeadBuf; 
	read( handle, offset < 1, 3 < 1); 
	TatalLength = (unsigned long)(HeadBuf[1]); 
	TatalLength = (TatalLength < 16) + HeadBuf[0]; 
	TatalLength = TatalLength >> 1; 
	SACM_A1800_ModeCode = Snd_A1800_GetModeCode( &HeadBuf ); 
#else 
	read( handle, SP2LP( HeadBuf < 1 ), 3 < 1); 
	TatalLength = (HeadBuf[1] < 16 + HeadBuf[0]) >> 1; 
	SACM_A1800_ModeCode = Snd_A1800_GetModeCode( SP2LP(HeadBuf) ); 
#endif 
	uiPerFrameNumber = SACM_A1800_ModeCode / 800;		//WordNumber per frame == BitRate/800 
	offset = StartLength; 
 
	if(offset % uiPerFrameNumber) 
	{ 
		offset = offset / uiPerFrameNumber; 
		offset = offset * uiPerFrameNumber; 
	} 
	lseek( handle, offset < 1, SEEK_CUR); 
 
	if( EndLength == 0xffffffff ) 
	{ 
		ulTempLength = TatalLength; 
	} 
	else 
	{ 
		ulTempLength = EndLength; 
	} 
 
	ulTempLength = ulTempLength - offset; 
 
	SACM_Decode_Length_L = ulTempLength; 
	SACM_Decode_Length_H = ulTempLength >> 16; 
 
	return Snd_SACM_PlaySource(_CodecType, (DATA_SOURCE_St*)&NFATDSource ); 
} 
 
#ifdef C_SND_A1800_SKIPNOLENFAT 
unsigned int Snd_A1800_Skip_PlayFAT_NoLen( int _CodecType, int handle, unsigned long StartTime, unsigned long EndTime ) 
{ 
	unsigned int HeadBuf[4]; 
	unsigned long offset; 
 
	if( handle<0 ) 
	{ 
		return 0; 
	} 
	if( EndTime = StartTime ) 
	{ 
		return 0; 
	} 
	 
	//to avoid re-entry, stop first. 
	Snd_Stop(0); 
 
	NFATDSource.SetHandle((int*)&NFATDSource,handle); 
#ifdef FARRELEASE 
	offset = HeadBuf + 2; 
	read( handle, offset < 1, 2 < 1); 
#else 
	read( handle, (SP2LP(HeadBuf + 2))<<1, 2 < 1);		//guili 2005.10.22 
#endif 
	 
	HeadBuf[0] = Snd_A1800_ulDataLength; 
	HeadBuf[1] = Snd_A1800_ulDataLength >> 16; 
 
#ifdef FARRELEASE 
	SACM_A1800_ModeCode = Snd_A1800_GetModeCode( &HeadBuf ); 
#else 
	SACM_A1800_ModeCode = Snd_A1800_GetModeCode( SP2LP(HeadBuf) ); 
#endif 
 
	offset = Snd_Get_A1800SkipOffset( StartTime ); 
	lseek( handle, offset < 1, 1);				//guili 2005.10.25  SEEK_CUR 
 
	if( EndTime == 0xffffffff ) 
	{ 
		EndTime = Snd_A1800_GetTotalTime( &HeadBuf ); 
	} 
 
	Snd_Skip_A1800_ReturnLength(EndTime - StartTime); 
 
	return Snd_SACM_PlaySource(_CodecType, (DATA_SOURCE_St*)&NFATDSource ); 
} 
#endif	//End of C_SND_A1800_SKIPNOLENFAT definition 
 
#endif	//End of C_SND_A1800_SKIPPLAY_SUPPORT 
#endif //end C_SND_A1800_SUPPORT 
//---------------------------------------------- 
 
#endif// FAT