updated mpg123 to 1.17.0

This commit is contained in:
fysx
2014-01-28 00:30:52 +01:00
parent 35f95a0c58
commit 4b6c1b51c9
533 changed files with 40135 additions and 11448 deletions
@@ -0,0 +1,462 @@
// ------------------------------------------------------------------------------------------------
#include <windows.h>
#include <string>
#include <vector>
#include <IIEP_FileIn.H>
#include <IIEP_Hash.H>
#include <IIEP_String.H>
// ------------------------------------------------------------------------------------------------
struct MEM_FILE_IDX
{
MEM_FILE_IDX(void)
{
m_dwID = 0;
m_dwLength = 0;
m_pucData = 0;
}
DWORD m_dwID; // hash ID of filename
DWORD m_dwLength; // file length
PBYTE m_pucData; // memory pointer
};
static std::vector <MEM_FILE_IDX> s_vecMemFile;
// ------------------------------------------------------------------------------------------------
// name: SearchMemFile()
// desc:
// ------------------------------------------------------------------------------------------------
static std::vector <MEM_FILE_IDX> :: iterator SearchMemFile(PCWSTR pcwsFileName)
{
DWORD dwID = IIEP::HashFNV_1a(pcwsFileName);
std::vector <MEM_FILE_IDX>::iterator it;
for (it = s_vecMemFile.begin(); it < s_vecMemFile.end(); it ++)
{
if (it -> m_dwID == dwID) return it;
}
return s_vecMemFile.end();
}
// ------------------------------------------------------------------------------------------------
static std::vector <MEM_FILE_IDX> :: iterator SearchMemFile(const char *pcszFileName)
{
WORD wzNameBuffer[0x1000];
wzNameBuffer[0] = 0;
IIEP::StringFromANSI(pcszFileName, wzNameBuffer, 0x1000);
return SearchMemFile(wzNameBuffer);
}
// ------------------------------------------------------------------------------------------------
// name: CreateMemoryFile()
// desc:
// ------------------------------------------------------------------------------------------------
bool IIEP::CreateMemoryFile(PVOID pMemory, DWORD dwLength, PCWSTR pcwsFileName)
{
if (0 == pcwsFileName || 0 == *pcwsFileName) return false;
RemoveMemoryFile(pcwsFileName);
DWORD dwID = IIEP::HashFNV_1a(pcwsFileName);
MEM_FILE_IDX soIDX;
soIDX.m_dwID = dwID;
soIDX.m_dwLength = dwLength;
soIDX.m_pucData = (PBYTE) pMemory;
s_vecMemFile.push_back(soIDX);
return true;
}
// ------------------------------------------------------------------------------------------------
bool IIEP::CreateMemoryFile(PVOID pMemory, DWORD dwLength, const char *pcszFileName)
{
WORD wzNameBuffer[0x1000];
wzNameBuffer[0] = 0;
StringFromANSI(pcszFileName, wzNameBuffer, 0x1000);
return CreateMemoryFile(pMemory, dwLength, wzNameBuffer);
}
// ------------------------------------------------------------------------------------------------
// name: RemoveMemoryFile()
// desc:
// ------------------------------------------------------------------------------------------------
bool IIEP::RemoveMemoryFile(PCWSTR pcwsFileName)
{
if (0 == pcwsFileName || 0 == *pcwsFileName) return false;
std::vector <MEM_FILE_IDX>::iterator it = SearchMemFile(pcwsFileName);
if (it == s_vecMemFile.end()) return false;
s_vecMemFile.erase(it);
return true;
}
// ------------------------------------------------------------------------------------------------
bool IIEP::RemoveMemoryFile(const char *pcszFileName)
{
WORD wzNameBuffer[0x1000];
wzNameBuffer[0] = 0;
StringFromANSI(pcszFileName, wzNameBuffer, 0x1000);
return RemoveMemoryFile(wzNameBuffer);
}
// ------------------------------------------------------------------------------------------------
void IIEP::RemoveMemoryFile(void)
{
s_vecMemFile.clear();
}
// ------------------------------------------------------------------------------------------------
// name: CFileIn()
// desc:
// ------------------------------------------------------------------------------------------------
IIEP::CFileIn::CFileIn(void)
{
m_pFile = 0;
m_pucMemData = 0;
m_dwLength = 0;
m_dwReadPos = 0;
}
// ------------------------------------------------------------------------------------------------
// name: ~CFileIn()
// desc:
// ------------------------------------------------------------------------------------------------
IIEP::CFileIn::~CFileIn(void)
{
Close();
}
// ------------------------------------------------------------------------------------------------
// name: Open()
// desc:
// ------------------------------------------------------------------------------------------------
bool IIEP::CFileIn::Open(const char *pcszFileName)
{
WORD wzNameBuffer[0x1000];
wzNameBuffer[0] = 0;
StringFromANSI(pcszFileName, wzNameBuffer, 0x1000);
return Open(wzNameBuffer);
}
// ------------------------------------------------------------------------------------------------
bool IIEP::CFileIn::Open(const WORD *pcwsFileName)
{
Close();
if (0 == pcwsFileName || 0 == *pcwsFileName) return false;
std::vector <MEM_FILE_IDX>::iterator it = SearchMemFile(pcwsFileName);
if (it == s_vecMemFile.end()) // not found in memory
{
m_pFile = _wfopen(pcwsFileName, L"rb");
if (m_pFile)
{
return true; // found DOS file
}
return false;
}
if (s_vecMemFile.empty()) return false;
m_pucMemData = it -> m_pucData;
m_dwLength = it -> m_dwLength;
return true;
}
// ------------------------------------------------------------------------------------------------
// name: Close()
// desc:
// ------------------------------------------------------------------------------------------------
void IIEP::CFileIn::Close(void)
{
if (m_pFile)
{
fclose(m_pFile);
m_pFile = 0;
}
m_pucMemData = 0;
m_dwLength = 0;
m_dwReadPos = 0;
}
// ------------------------------------------------------------------------------------------------
// name: GetFileSize()
// desc:
// ------------------------------------------------------------------------------------------------
DWORD IIEP::CFileIn::GetFileSize(void) const
{
if (m_pFile)
{
DWORD dwPostion = ftell(m_pFile);
fseek(m_pFile, 0, SEEK_END);
DWORD dwFileSize = ftell(m_pFile);
fseek(m_pFile, dwPostion, SEEK_SET);
return dwFileSize;
}
return m_dwLength;
}
// ------------------------------------------------------------------------------------------------
// name: GetReadPosition()
// desc:
// ------------------------------------------------------------------------------------------------
DWORD IIEP::CFileIn::GetReadPosition(void) const
{
if (m_pFile)
{
return ftell(m_pFile);
}
return m_dwReadPos;
}
// ------------------------------------------------------------------------------------------------
// name: Seek()
// desc:
// ------------------------------------------------------------------------------------------------
bool IIEP::CFileIn::Seek(long nOffset, long nOrigin)
{
if (m_pFile)
{
return (0 == fseek(m_pFile, nOffset, nOrigin));
}
if (m_pucMemData)
{
switch (nOrigin)
{
case SEEK_SET:
if (nOffset < 0 || nOffset >= (long) m_dwLength) return false;
m_dwReadPos = nOffset;
return true;
case SEEK_CUR:
nOffset += m_dwReadPos;
if (nOffset < 0 || nOffset >= (long) m_dwLength) return false;
m_dwReadPos = nOffset;
return true;
case SEEK_END:
ASSERT(nOffset <= 0); // Õâ¸ö±ØÐëÊǸºÊý
nOffset = m_dwLength - 1 + nOffset;
if (nOffset < 0 || nOffset >= (long) m_dwLength) return false;
m_dwReadPos = nOffset;
return true;
}
}
return false;
}
// ------------------------------------------------------------------------------------------------
// name: Read()
// desc:
// ------------------------------------------------------------------------------------------------
DWORD IIEP::CFileIn::Read(PVOID pDataBuffer, DWORD dwReadSize)
{
if (m_pFile)
{
return (DWORD) fread(pDataBuffer, 1, dwReadSize, m_pFile);
}
if (m_pucMemData)
{
if (m_dwReadPos + dwReadSize > m_dwLength) dwReadSize = m_dwLength - m_dwReadPos;
memcpy(pDataBuffer, m_pucMemData + m_dwReadPos, dwReadSize);
m_dwReadPos += dwReadSize;
return dwReadSize;
}
return 0;
}
// ------------------------------------------------------------------------------------------------
// name: ReadAnsiLine()
// desc:
// ------------------------------------------------------------------------------------------------
bool IIEP::CFileIn::ReadAnsiLine(std::string &strLine)
{
BYTE ucChar = 0;
strLine.clear();
while (ReadB(ucChar))
{
if (0x0D == ucChar)
{
}
else
if (0x0A == ucChar)
{
return true;
}
else
{
strLine.push_back(ucChar);
}
}
if (strLine.empty()) return false;
return true;
}
// ------------------------------------------------------------------------------------------------
// name: ReadUnicodeLine()
// desc:
// ------------------------------------------------------------------------------------------------
bool IIEP::CFileIn::ReadUnicodeLine(std::wstring &wstrLine, bool bBigEndian)
{
WORD wChar = 0;
wstrLine.clear();
while (bBigEndian ? ReadInverseW(wChar) : ReadW(wChar))
{
if (0x000D == wChar)
{
}
else
if (0x000A == wChar)
{
return true;
}
else
{
wstrLine.push_back(wChar);
}
}
if (wstrLine.empty()) return false;
return true;
}
// ------------------------------------------------------------------------------------------------
// name: ReadAnsiString()
// desc:
// ------------------------------------------------------------------------------------------------
bool IIEP::CFileIn::ReadAnsiString(char *pszBuffer, DWORD dwBufferLength)
{
DWORD dwIndex = 0;
BYTE ucChar;
while (ReadB(ucChar))
{
if (dwIndex >= dwBufferLength) return true;
pszBuffer[dwIndex ++] = ucChar;
if (0 == ucChar)
{
return true;
}
}
return false;
}
// ------------------------------------------------------------------------------------------------
// name: ReadUnicodeString()
// desc:
// ------------------------------------------------------------------------------------------------
bool IIEP::CFileIn::ReadUnicodeString(WORD *pwzBuffer, DWORD dwBufferLength)
{
DWORD dwIndex = 0;
WORD wChar;
ReadInverseW(wChar);
if (wChar == 0xFFFE) // Unicode
{
while (ReadW(wChar))
{
if (dwIndex >= dwBufferLength) return true;
pwzBuffer[dwIndex ++] = wChar;
if (0 == wChar)
{
return true;
}
}
}
else
if (wChar == 0xFEFF) // Unicode big endian
{
while (ReadInverseW(wChar))
{
if (dwIndex >= dwBufferLength) return true;
pwzBuffer[dwIndex ++] = wChar;
if (0 == wChar)
{
return true;
}
}
}
return false;
}
// ------------------------------------------------------------------------------------------------
@@ -0,0 +1,122 @@
// ------------------------------------------------------------------------------------------------
#include <stdarg.h>
#include <stdio.h>
#include <windows.h>
#include <IIEP_Def.H>
// ------------------------------------------------------------------------------------------------
static bool s_bLogFileOpened = false;
// ------------------------------------------------------------------------------------------------
// name: DebugLog()
// desc:
// ------------------------------------------------------------------------------------------------
void IIEP::DebugLog(const char *pcszFormat, ...)
{
#ifdef _DEBUG
char cBuffer[0x8000];
va_list pcArg;
va_start(pcArg, pcszFormat);
_vsnprintf(cBuffer, 0x8000, pcszFormat, pcArg);
va_end(pcArg);
::OutputDebugStringA(cBuffer);
#endif
}
// ------------------------------------------------------------------------------------------------
void IIEP::DebugLog(const WORD *pcwsFormat, ...)
{
#ifdef _DEBUG
WCHAR wcBuffer[0x8000];
va_list pcArg;
va_start(pcArg, pcwsFormat);
_vsnwprintf(wcBuffer, 0x8000, pcwsFormat, pcArg);
va_end(pcArg);
::OutputDebugStringW(wcBuffer);
#endif
}
// ------------------------------------------------------------------------------------------------
// name: WriteLog()
// desc:
// ------------------------------------------------------------------------------------------------
void IIEP::WriteLog(const char *pcszFormat, ...)
{
char cBuffer[0x8000];
va_list pcArg;
va_start(pcArg, pcszFormat);
_vsnprintf(cBuffer, 0x8000, pcszFormat, pcArg);
va_end(pcArg);
FILE *phFile;
#define LOG_FILE "C:\\IIEP.LOG"
if (s_bLogFileOpened)
{
phFile = fopen(LOG_FILE, "a+");
}
else
{
phFile = fopen(LOG_FILE, "w");
s_bLogFileOpened = true;
}
if (phFile)
{
fprintf(phFile, cBuffer);
fclose(phFile);
}
}
// ------------------------------------------------------------------------------------------------
void IIEP::WriteLog(const WORD *pcwsFormat, ...)
{
WCHAR wcBuffer[0x8000];
va_list pcArg;
va_start(pcArg, pcwsFormat);
_vsnwprintf(wcBuffer, 0x8000, pcwsFormat, pcArg);
va_end(pcArg);
FILE *phFile;
#define LOG_FILE "C:\\IIEP.LOG"
if (s_bLogFileOpened)
{
phFile = fopen(LOG_FILE, "a");
}
else
{
phFile = fopen(LOG_FILE, "w");
s_bLogFileOpened = true;
}
if (phFile)
{
fwprintf(phFile, wcBuffer);
fclose(phFile);
}
}
// ------------------------------------------------------------------------------------------------
@@ -0,0 +1,35 @@
// ------------------------------------------------------------------------------------------------
#include <windows.h>
#include <IIEP_Def.H>
// ------------------------------------------------------------------------------------------------
// name: Lock()
// desc:
// ------------------------------------------------------------------------------------------------
void IIEP::CMutex::Lock(void)
{
while (m_bLocked)
{
::Sleep(1);
}
m_bLocked = true;
}
// ------------------------------------------------------------------------------------------------
// name: Wait()
// desc:
// ------------------------------------------------------------------------------------------------
void IIEP::CMutex::Wait(void)
{
while (m_bLocked)
{
::Sleep(1);
}
}
// ------------------------------------------------------------------------------------------------
@@ -0,0 +1,586 @@
// ------------------------------------------------------------------------------------------------
#include <IIEP_Def.H>
#include <CORE/SourceFilter_MP3.H>
// ------------------------------------------------------------------------------------------------
extern BYTE g_ucWaveHeader[WAVE_HEADER_LENGTH];
// ------------------------------------------------------------------------------------------------
// name: CMP3Stream()
// desc:
// ------------------------------------------------------------------------------------------------
static size_t read_sub(int fd, void *pBuf, size_t nSize)
{
if (fd)
{
IIEP::CMP3Stream *pcoStream = (IIEP::CMP3Stream *) fd;
return pcoStream -> ReadFile(pBuf, nSize);
}
return 0;
}
// ------------------------------------------------------------------------------------------------
// name: CMP3Stream()
// desc:
// ------------------------------------------------------------------------------------------------
static off_t seek_sub(int fd, off_t nOffset, int iOrigin)
{
if (fd)
{
IIEP::CMP3Stream *pcoStream = (IIEP::CMP3Stream *) fd;
return pcoStream -> SeekFile(nOffset, iOrigin);
}
return 0;
}
// ------------------------------------------------------------------------------------------------
// name: CMP3Stream()
// desc:
// ------------------------------------------------------------------------------------------------
IIEP::CMP3Stream::CMP3Stream(void)
{
m_dwKBPerSec = INFINITE;
m_dwTimeStart = 0;
m_pcoMH = 0;
m_dwTotalBlocks = 0;
m_dwAlignment = 4;
m_dwLength = 0;
m_dwPosition = 0;
memcpy(m_ucHeader, g_ucWaveHeader, WAVE_HEADER_LENGTH);
m_dwDataBufPos = 0;
m_dwDataBufLen = 0;
m_bSeekFlag = false;
}
// ------------------------------------------------------------------------------------------------
// name: ~CMP3Stream()
// desc:
// ------------------------------------------------------------------------------------------------
IIEP::CMP3Stream::~CMP3Stream(void)
{
Close();
}
// ------------------------------------------------------------------------------------------------
// name: SetSeekFlag()
// desc: called by IIEP::CPlayer::SetMediaPosition(QWORD qwPosition)
// ------------------------------------------------------------------------------------------------
void IIEP::CMP3Stream::SetSeekFlag(void)
{
m_bSeekFlag = true;
}
// ------------------------------------------------------------------------------------------------
// name: Open()
// desc:
// ------------------------------------------------------------------------------------------------
bool IIEP::CMP3Stream::Open(const WORD *pcwsFileName, CMediaType &coMT, DWORD dwKBPerSec)
{
Close();
//
if (MPG123_OK != mpg123_init())
{
goto OPEN_FAIL;
}
m_pcoMH = mpg123_new(NULL, NULL);
if (0 == m_pcoMH)
{
goto OPEN_FAIL;
}
if (false == OpenFile(pcwsFileName))
{
goto OPEN_FAIL;
}
if (MPG123_OK != mpg123_replace_reader(m_pcoMH, read_sub, seek_sub))
{
goto OPEN_FAIL;
}
if (MPG123_OK != mpg123_open_fd(m_pcoMH, (int) this))
{
goto OPEN_FAIL;
}
long nRate;
int iChannels;
int iEncoding;
if (MPG123_OK != mpg123_getformat(m_pcoMH, &nRate, &iChannels, &iEncoding))
{
goto OPEN_FAIL;
}
// Ensure that this output format will not change (it could, when we allow it)
mpg123_format_none(m_pcoMH);
mpg123_format(m_pcoMH, nRate, iChannels, iEncoding);
// scan & get total samples
mpg123_scan(m_pcoMH);
off_t nOff = mpg123_length(m_pcoMH);
if (nOff < 0)
{
goto OPEN_FAIL;
}
m_dwTotalBlocks = (DWORD) nOff;
// set other format
m_dwAlignment = iChannels * 2;
if (0 == m_dwAlignment)
{
m_dwAlignment = 4;
}
m_dwLength = m_dwTotalBlocks * m_dwAlignment + WAVE_HEADER_LENGTH;
WORD wChannels = (WORD ) iChannels;
DWORD dwSamplesPerSec = (DWORD) nRate;
DWORD dwAvgBytesPerSec = m_dwAlignment * dwSamplesPerSec;
WORD wBlockAlign = (WORD ) m_dwAlignment;
WORD wBitsPerSample = 16;
PWORD pwData;
PDWORD pdwData;
pdwData = (PDWORD) &m_ucHeader[0x04];
*pdwData = m_dwTotalBlocks * m_dwAlignment + WAVE_HEADER_LENGTH - 8;
pwData = (PWORD) &m_ucHeader[0x16];
*pwData = wChannels;
pdwData = (PDWORD) &m_ucHeader[0x18];
*pdwData = dwSamplesPerSec;
pdwData = (PDWORD) &m_ucHeader[0x1C];
*pdwData = dwAvgBytesPerSec;
pwData = (PWORD) &m_ucHeader[0x20];
*pwData = wBlockAlign;
pwData = (PWORD) &m_ucHeader[0x22];
*pwData = wBitsPerSample;
pdwData = (PDWORD) &m_ucHeader[0x28];
*pdwData = m_dwTotalBlocks * m_dwAlignment;
coMT.majortype = MEDIATYPE_Stream;
coMT.subtype = MEDIASUBTYPE_WAVE;
SetPointer(0);
m_dwTimeStart = ::timeGetTime();
return true;
OPEN_FAIL:
Close();
return false;
}
// ------------------------------------------------------------------------------------------------
// name: Close()
// desc:
// ------------------------------------------------------------------------------------------------
void IIEP::CMP3Stream::Close(void)
{
m_coFileIn.Close();
if (m_pcoMH)
{
mpg123_close (m_pcoMH);
mpg123_delete(m_pcoMH);
m_pcoMH = 0;
}
mpg123_exit();
m_dwTimeStart = 0;
m_dwTotalBlocks = 0;
m_dwLength = 0;
m_dwPosition = 0;
m_bSeekFlag = false;
m_nDataBegin = 0;
m_nDataTotal = 0;
}
// ------------------------------------------------------------------------------------------------
// name: SetPointer()
// desc:
// ------------------------------------------------------------------------------------------------
HRESULT IIEP::CMP3Stream::SetPointer(LONGLONG llPos)
{
if (llPos < 0 || llPos > (LONGLONG) m_dwLength)
{
return S_FALSE;
}
m_dwPosition = (DWORD) llPos;
if (llPos < WAVE_HEADER_LENGTH)
{
mpg123_seek(m_pcoMH, 0, SEEK_SET);
m_dwDataBufLen = 0;
}
else
{
if (m_bSeekFlag && m_dwAlignment > 0)
{
m_bSeekFlag = false;
mpg123_seek(m_pcoMH, (long) (m_dwPosition - WAVE_HEADER_LENGTH) / m_dwAlignment, SEEK_SET);
m_dwDataBufLen = 0;
}
}
return S_OK;
}
// ------------------------------------------------------------------------------------------------
// name: Read()
// desc:
// ------------------------------------------------------------------------------------------------
HRESULT IIEP::CMP3Stream::Read(PBYTE pucBuffer,
DWORD dwBytesToRead,
BOOL bAlign,
LPDWORD pdwBytesRead)
{
if (0 == m_pcoMH) return S_FALSE;
CAutoLock lck(&m_csLock);
DWORD dwReadLength;
// wait until the bytes are here
DWORD dwTime = ::timeGetTime();
if (m_dwPosition + dwBytesToRead > m_dwLength)
{
dwReadLength = m_dwLength - m_dwPosition;
}
else
{
dwReadLength = dwBytesToRead;
}
DWORD dwTimeToArrive = (m_dwPosition + dwReadLength) / m_dwKBPerSec;
if (dwTime - m_dwTimeStart < dwTimeToArrive)
{
::Sleep(dwTimeToArrive - dwTime + m_dwTimeStart);
}
// read data
DWORD dwRead = 0;
if (m_dwPosition < WAVE_HEADER_LENGTH)
{
DWORD dwPatchLen = WAVE_HEADER_LENGTH - m_dwPosition;
if (dwReadLength < dwPatchLen)
{
dwPatchLen = dwReadLength;
}
memcpy(pucBuffer, m_ucHeader + m_dwPosition, dwPatchLen);
m_dwPosition += dwPatchLen;
dwReadLength -= dwPatchLen;
pucBuffer += dwPatchLen;
dwRead += dwPatchLen;
}
if (dwReadLength > 0)
{
while (m_dwDataBufLen < dwReadLength)
{
if (m_dwDataBufLen > 0)
{
memcpy(pucBuffer, m_ucDataBuffer + m_dwDataBufPos, m_dwDataBufLen);
dwRead += m_dwDataBufLen;
dwReadLength -= m_dwDataBufLen;
pucBuffer += m_dwDataBufLen;
m_dwDataBufPos += m_dwDataBufLen;
m_dwDataBufLen = 0;
}
if (DecodeFrame() == false) break;
}
if (dwReadLength > 0)
{
if (m_dwDataBufLen >= dwReadLength)
{
memcpy(pucBuffer, m_ucDataBuffer + m_dwDataBufPos, dwReadLength);
dwRead += dwReadLength;
m_dwDataBufPos += dwReadLength;
m_dwDataBufLen -= dwReadLength;
}
}
}
m_dwPosition += dwRead;
*pdwBytesRead = dwRead;
return S_OK;
}
// ------------------------------------------------------------------------------------------------
// name: Size()
// desc:
// ------------------------------------------------------------------------------------------------
LONGLONG IIEP::CMP3Stream::Size(LONGLONG *pSizeAvailable)
{
// LONGLONG llCurrentAvailable = Int32x32To64((::timeGetTime() - m_dwTimeStart), m_dwKBPerSec);
LONGLONG llLength = (LONGLONG) m_dwTotalBlocks * m_dwAlignment + WAVE_HEADER_LENGTH;
if (pSizeAvailable)
{
// *pSizeAvailable = min(llLength, llCurrentAvailable);
*pSizeAvailable = llLength;
}
return llLength;
}
// ------------------------------------------------------------------------------------------------
// name: Alignment()
// desc:
// ------------------------------------------------------------------------------------------------
DWORD IIEP::CMP3Stream::Alignment(void)
{
return m_dwAlignment;
}
// ------------------------------------------------------------------------------------------------
// name: Lock()
// desc:
// ------------------------------------------------------------------------------------------------
void IIEP::CMP3Stream::Lock(void)
{
m_csLock.Lock();
}
// ------------------------------------------------------------------------------------------------
// name: Unlock()
// desc:
// ------------------------------------------------------------------------------------------------
void IIEP::CMP3Stream::Unlock(void)
{
m_csLock.Unlock();
}
// ------------------------------------------------------------------------------------------------
// name: DecodeFrame()
// desc:
// ------------------------------------------------------------------------------------------------
bool IIEP::CMP3Stream::DecodeFrame(void)
{
if (0 == m_dwDataBufLen)
{
m_dwDataBufPos = 0;
}
if (m_dwDataBufPos + m_dwDataBufLen + MP3_DECODE_LEN > MP3_DECODE_BUF_LEN)
{
return true;
}
size_t nBytesRead = 0;
mpg123_read(m_pcoMH, m_ucDataBuffer + m_dwDataBufPos + m_dwDataBufLen, MP3_DECODE_LEN, &nBytesRead);
m_dwDataBufLen += (DWORD) nBytesRead;
return (m_dwDataBufLen > 0);
}
// ------------------------------------------------------------------------------------------------
// name: OpenFile()
// desc:
// ------------------------------------------------------------------------------------------------
bool IIEP::CMP3Stream::OpenFile(const WORD *pcwsFileName)
{
if (m_coFileIn.Open(pcwsFileName))
{
m_nDataBegin = 0;
m_nDataTotal = m_coFileIn.GetFileSize();
// check ID3 Tag V2.x
BYTE ucBuffer[8];
bool bFound;
TRY_ID3_AGAIN:
bFound = false;
if (6 == m_coFileIn.Read(ucBuffer, 6))
{
if (ucBuffer[0] == 'I' &&
ucBuffer[1] == 'D' &&
ucBuffer[2] == '3')
{
bFound = true;
DWORD dwHeaderSize;
if (m_coFileIn.ReadInverseDW(dwHeaderSize))
{
dwHeaderSize = ((dwHeaderSize & 0x7F000000) >> 3) +
((dwHeaderSize & 0x007F0000) >> 2) +
((dwHeaderSize & 0x00007F00) >> 1) +
((dwHeaderSize & 0x0000007F) );
dwHeaderSize += 10;
m_nDataBegin += dwHeaderSize;
m_nDataTotal -= dwHeaderSize;
if (ucBuffer[3] >= 0x03) // ID3 Tag version >= 2.3
{
if (ucBuffer[5] & 0x40) // has extended header
{
if (m_coFileIn.ReadInverseDW(dwHeaderSize))
{
dwHeaderSize = ((dwHeaderSize & 0x7F000000) >> 3) +
((dwHeaderSize & 0x007F0000) >> 2) +
((dwHeaderSize & 0x00007F00) >> 1) +
((dwHeaderSize & 0x0000007F) );
dwHeaderSize += 4;
m_nDataBegin += dwHeaderSize;
m_nDataTotal -= dwHeaderSize;
}
}
}
}
}
}
SeekFile(0, SEEK_SET);
if (bFound)
{
goto TRY_ID3_AGAIN;
}
/*
m_coFileIn.Read(ucBuffer, 2);
if (ucBuffer[0] != 0xFF || ucBuffer[1] < 0xF0)
{
m_nDataBegin ++;
m_nDataTotal --;
SeekFile(0, SEEK_SET);
goto TRY_ID3_AGAIN;
}
SeekFile(0, SEEK_SET);
*/
return true;
}
return false;
}
// ------------------------------------------------------------------------------------------------
// name: ReadFile()
// desc:
// ------------------------------------------------------------------------------------------------
DWORD IIEP::CMP3Stream::ReadFile(PVOID pBuf, DWORD dwLen)
{
return m_coFileIn.Read(pBuf, dwLen);
}
// ------------------------------------------------------------------------------------------------
// name: SeekFile()
// desc:
// ------------------------------------------------------------------------------------------------
long IIEP::CMP3Stream::SeekFile(long nOffset, int iOrigin)
{
switch (iOrigin)
{
case SEEK_SET:
if (nOffset < 0 || nOffset >= m_nDataTotal) return -1;
break;
case SEEK_CUR:
nOffset += (m_coFileIn.GetReadPosition() - m_nDataBegin);
if (nOffset < 0 || nOffset >= m_nDataTotal) return -1;
break;
case SEEK_END:
nOffset = m_nDataTotal - 1 + nOffset;
if (nOffset < 0 || nOffset >= m_nDataTotal) return -1;
break;
}
if (m_coFileIn.Seek(nOffset + m_nDataBegin, SEEK_SET))
{
return nOffset;
}
return -1;
}
// ------------------------------------------------------------------------------------------------