home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Game Audio Programming
/
GameAudioProgramming.iso
/
Game_Audio
/
audio_sdk
/
src
/
AudioLib
/
FileStream.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
2002-09-09
|
8KB
|
327 lines
/***********************************************************\
Copyright (C) James Boer, 2002.
All rights reserved worldwide.
This software is provided "as is" without express or implied
warranties. You may freely copy and compile this source into
applications you distribute provided that the copyright text
below is included in the resulting source code, for example:
"Portions Copyright (C) James Boer, 2002"
\***********************************************************/
#include "FileStream.h"
#include "AudioMgr.h"
using namespace std;
using namespace Audio;
IMPLEMENT_POOL(FileStream);
//------------------------------------------------------------------------//
FileStream::FileStream()
{
Clear();
}
//------------------------------------------------------------------------//
FileStream::~FileStream()
{
assert(m_iRefCount == 0);
}
//------------------------------------------------------------------------//
void FileStream::Clear()
{
m_iRefCount = 0;
m_pFile = 0;
m_nSize = 0;
m_sFileName.erase();
m_pBuffer = 0;
m_nReadPtr = 0;
m_bBuffered = false;
}
//------------------------------------------------------------------------//
HRESULT FileStream::Open(std::string sFileName)
{
if(m_pFile)
return E_FAIL;
m_sFileName = sFileName;
m_pFile = fopen(sFileName.c_str(), "rb");
if(!m_pFile)
{
_getcwd(DXAudioMgr()->GetCurrentWorkingPath(), MAX_PATH);
chdir(DXAudioMgr()->GetAudioSystemPath());
m_pFile = fopen(sFileName.c_str(), "rb");
chdir(DXAudioMgr()->GetCurrentWorkingPath());
if(!m_pFile)
return E_FAIL;
}
fseek(m_pFile, 0, SEEK_END);
m_nSize = ftell(m_pFile);
fseek(m_pFile, 0, SEEK_SET);
// Cache the entire file in memory if it is relatively small
// 44100 * 2 * 2 (2 second 16-bit buffer at 44.1KHz)
if(m_nSize <= 176400 && DXAudioMgr()->GetInit()->m_bAutoStream)
m_pBuffer = new uint8[m_nSize];
return S_OK;
}
//------------------------------------------------------------------------//
void FileStream::Close()
{
SAFE_DELETE_ARRAY(m_pBuffer);
if(m_pFile)
{
fclose(m_pFile);
m_pFile = 0;
}
Clear();
}
//------------------------------------------------------------------------//
HRESULT FileStream::QueryInterface(
const struct _GUID& guid,
void** ppInterface)
{
if (guid == IID_IStream)
*ppInterface = (IStream*)this;
else if (guid == IID_ISequentialStream)
*ppInterface = (ISequentialStream*)this;
else if (guid == IID_IUnknown)
*ppInterface = (IUnknown*)this;
else
return E_NOTIMPL;
((IUnknown*)*ppInterface)->AddRef();
return S_OK;
}
//------------------------------------------------------------------------//
ULONG FileStream::AddRef()
{
InterlockedIncrement(&m_iRefCount);
return m_iRefCount;
}
//------------------------------------------------------------------------//
ULONG FileStream::Release()
{
int32 iPrev = InterlockedDecrement(&m_iRefCount);
if(iPrev == 0)
{
Close();
FileStream::DestroyObject(this);
}
assert(m_iRefCount >= 0);
return m_iRefCount;
}
// ISequentialStream Interface
//------------------------------------------------------------------------//
HRESULT FileStream::Read(
/* [length_is][size_is][out] */ void *pv,
/* [in] */ ULONG cb,
/* [out] */ ULONG *pcbRead)
{
if(!m_pFile)
return E_FAIL;
uint32 nRead;
if(m_pBuffer)
{
if(!m_bBuffered)
{
uint32 nFullRead = fread((uint8*)m_pBuffer, 1, m_nSize, m_pFile);
if(nFullRead != m_nSize)
return E_FAIL;
m_bBuffered = true;
}
nRead = ClampMax(cb, m_nSize - m_nReadPtr);
memcpy(pv, m_pBuffer + m_nReadPtr, nRead);
m_nReadPtr += cb;
}
else
{
nRead = fread((uint8*)pv, 1, cb, m_pFile);
}
if(pcbRead)
*pcbRead = nRead;
return S_OK;
}
//------------------------------------------------------------------------//
HRESULT FileStream::Write(
/* [size_is][in] */ const void *pv,
/* [in] */ ULONG cb,
/* [out] */ ULONG *pcbWritten)
{
return E_NOTIMPL;
}
// IStream Interface
//------------------------------------------------------------------------//
HRESULT FileStream::Seek(
/* [in] */ LARGE_INTEGER dlibMove,
/* [in] */ DWORD dwOrigin,
/* [out] */ ULARGE_INTEGER *plibNewPosition)
{
if(!m_pFile)
return E_FAIL;
uint32 nSeek = (uint32)dlibMove.QuadPart;
if(m_pBuffer)
{
switch(dwOrigin)
{
case SEEK_SET:
m_nReadPtr = dlibMove.QuadPart;
break;
case SEEK_CUR:
m_nReadPtr += dlibMove.QuadPart;
break;
case SEEK_END:
m_nReadPtr = m_nSize - dlibMove.QuadPart;
break;
};
if(plibNewPosition)
plibNewPosition->QuadPart = m_nReadPtr;
}
else
{
if(fseek(m_pFile, nSeek, dwOrigin))
return E_FAIL;
if(plibNewPosition)
plibNewPosition->QuadPart = ftell(m_pFile);
}
return S_OK;
}
//------------------------------------------------------------------------//
HRESULT FileStream::SetSize(
/* [in] */ ULARGE_INTEGER libNewSize)
{
return E_NOTIMPL;
}
//------------------------------------------------------------------------//
HRESULT FileStream::CopyTo(
/* [unique][in] */ IStream *pstm,
/* [in] */ ULARGE_INTEGER cb,
/* [out] */ ULARGE_INTEGER *pcbRead,
/* [out] */ ULARGE_INTEGER *pcbWritten)
{
return E_NOTIMPL;
}
//------------------------------------------------------------------------//
HRESULT FileStream::Commit(
/* [in] */ DWORD grfCommitFlags)
{
return E_NOTIMPL;
}
//------------------------------------------------------------------------//
HRESULT FileStream::Revert(void)
{
return E_NOTIMPL;
}
//------------------------------------------------------------------------//
HRESULT FileStream::LockRegion(
/* [in] */ ULARGE_INTEGER libOffset,
/* [in] */ ULARGE_INTEGER cb,
/* [in] */ DWORD dwLockType)
{
return E_NOTIMPL;
}
//------------------------------------------------------------------------//
HRESULT FileStream::UnlockRegion(
/* [in] */ ULARGE_INTEGER libOffset,
/* [in] */ ULARGE_INTEGER cb,
/* [in] */ DWORD dwLockType)
{
return E_NOTIMPL;
}
//------------------------------------------------------------------------//
HRESULT FileStream::Stat(
/* [out] */ STATSTG *pstatstg,
/* [in] */ DWORD grfStatFlag)
{
if(!pstatstg)
return E_INVALIDARG;
pstatstg->pwcsName = 0;
if(grfStatFlag == 1)
{
pstatstg->pwcsName = (WCHAR*)CoTaskMemAlloc(MAX_PATH * sizeof(WCHAR));
ConvertAnsiStringToWide(pstatstg->pwcsName, m_sFileName.c_str());
}
else
pstatstg->pwcsName = 0;
pstatstg->type = STGTY_STREAM;
pstatstg->cbSize.QuadPart = m_nSize;
pstatstg->atime.dwHighDateTime = 0;
pstatstg->atime.dwLowDateTime = 0;
pstatstg->ctime.dwHighDateTime = 0;
pstatstg->ctime.dwLowDateTime = 0;
pstatstg->mtime.dwHighDateTime = 0;
pstatstg->mtime.dwLowDateTime = 0;
pstatstg->grfLocksSupported = 0;
return S_OK;
}
//------------------------------------------------------------------------//
HRESULT FileStream::Clone(
/* [out] */ IStream **ppstm)
{
IAudioStream* pStream;
if(!AudioMgr()->CreateAudioStream(pStream))
return E_FAIL;
if(FAILED(pStream->Open(m_sFileName)))
{
pStream->Release();
return E_FAIL;
}
LARGE_INTEGER liPos;
if(m_pBuffer)
liPos.QuadPart = m_nReadPtr;
else
liPos.QuadPart = ftell(m_pFile);
pStream->Seek(liPos, SEEK_SET, 0);
*ppstm = (IStream*)pStream;
return S_OK;
}