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