2014-06-10 18:31:19 +02:00
|
|
|
#ifndef __AUDIOHARDWARE
|
|
|
|
#define __AUDIOHARDWARE
|
|
|
|
|
|
|
|
// IStream
|
|
|
|
#include <Objidl.h>
|
|
|
|
|
|
|
|
enum eDecoderType
|
|
|
|
{
|
|
|
|
DECODER_NULL,
|
|
|
|
DECODER_VORBIS,
|
|
|
|
DECODER_WAVE,
|
|
|
|
DECODER_WINDOWSMEDIA,
|
|
|
|
DECODER_QUICKTIME,
|
|
|
|
|
|
|
|
// Custom
|
|
|
|
DECODER_FLAC
|
|
|
|
};
|
|
|
|
|
2014-08-23 00:07:08 +02:00
|
|
|
// 1.0/Steam structure
|
2018-01-28 23:43:55 +01:00
|
|
|
class NOVMT CAEDataStreamOld final : IStream
|
2014-06-10 18:31:19 +02:00
|
|
|
{
|
|
|
|
private:
|
|
|
|
HANDLE hHandle;
|
|
|
|
char* pFilename;
|
|
|
|
bool bOpened;
|
|
|
|
DWORD dwCurrentPosition, dwStartPosition;
|
|
|
|
DWORD dwLength;
|
|
|
|
DWORD dwID;
|
|
|
|
bool bEncrypted;
|
|
|
|
LONG nRefCount;
|
|
|
|
|
|
|
|
public:
|
|
|
|
void operator delete(void* data)
|
|
|
|
{
|
|
|
|
// Call SA operator delete
|
|
|
|
GTAdelete(data);
|
|
|
|
}
|
|
|
|
|
2017-02-05 22:52:22 +01:00
|
|
|
CAEDataStreamOld() = delete;
|
2014-06-10 18:31:19 +02:00
|
|
|
|
2014-08-23 00:07:08 +02:00
|
|
|
~CAEDataStreamOld()
|
2014-06-10 18:31:19 +02:00
|
|
|
{
|
|
|
|
if ( bOpened )
|
|
|
|
{
|
|
|
|
CloseHandle(hHandle);
|
|
|
|
bOpened = false;
|
|
|
|
}
|
2017-03-02 01:35:13 +01:00
|
|
|
if ( pFilename != nullptr )
|
|
|
|
{
|
|
|
|
GTAdelete(pFilename);
|
|
|
|
pFilename = nullptr;
|
|
|
|
}
|
2014-06-10 18:31:19 +02:00
|
|
|
}
|
|
|
|
|
2017-10-20 00:58:06 +02:00
|
|
|
inline DWORD GetID() const
|
2014-06-10 18:31:19 +02:00
|
|
|
{ return dwID; }
|
2017-10-20 00:58:06 +02:00
|
|
|
inline HANDLE GetFile() const
|
2014-06-10 18:31:19 +02:00
|
|
|
{ return hHandle; }
|
|
|
|
|
|
|
|
public:
|
|
|
|
// Custom methods
|
2017-03-02 01:35:13 +01:00
|
|
|
DWORD Seek(LONG nToSeek, DWORD nPoint);
|
|
|
|
DWORD FillBuffer(void* pBuf, DWORD nLen);
|
2017-10-20 00:58:06 +02:00
|
|
|
DWORD GetCurrentPosition() const
|
2017-03-02 01:35:13 +01:00
|
|
|
{
|
|
|
|
LARGE_INTEGER filePointer;
|
|
|
|
filePointer.QuadPart = 0;
|
|
|
|
SetFilePointerEx( hHandle, filePointer, &filePointer, FILE_CURRENT );
|
|
|
|
return DWORD(filePointer.QuadPart - dwStartPosition);
|
|
|
|
}
|
2014-08-23 00:07:08 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
// 1.01 structure
|
2018-01-28 23:43:55 +01:00
|
|
|
class NOVMT CAEDataStreamNew final : IStream
|
2014-08-23 00:07:08 +02:00
|
|
|
{
|
|
|
|
private:
|
|
|
|
void* pUselessMalloc;
|
|
|
|
|
|
|
|
HANDLE hHandle;
|
|
|
|
char* pFilename;
|
|
|
|
bool bOpened;
|
|
|
|
DWORD dwCurrentPosition, dwStartPosition;
|
|
|
|
DWORD dwLength;
|
|
|
|
DWORD dwID;
|
|
|
|
bool bEncrypted;
|
|
|
|
LONG nRefCount;
|
|
|
|
|
|
|
|
public:
|
|
|
|
void operator delete(void* data)
|
|
|
|
{
|
|
|
|
// Call SA operator delete
|
|
|
|
GTAdelete(data);
|
|
|
|
}
|
|
|
|
|
2017-02-05 22:52:22 +01:00
|
|
|
CAEDataStreamNew() = delete;
|
2014-08-23 00:07:08 +02:00
|
|
|
|
|
|
|
~CAEDataStreamNew()
|
|
|
|
{
|
|
|
|
if ( bOpened )
|
|
|
|
{
|
|
|
|
CloseHandle(hHandle);
|
|
|
|
bOpened = false;
|
|
|
|
}
|
2017-03-02 01:35:13 +01:00
|
|
|
if ( pFilename != nullptr )
|
|
|
|
{
|
|
|
|
GTAdelete(pFilename);
|
|
|
|
pFilename = nullptr;
|
|
|
|
}
|
2014-08-23 00:07:08 +02:00
|
|
|
}
|
|
|
|
|
2017-10-20 00:58:06 +02:00
|
|
|
inline DWORD GetID() const
|
2014-08-23 00:07:08 +02:00
|
|
|
{ return dwID; }
|
2017-10-20 00:58:06 +02:00
|
|
|
inline HANDLE GetFile() const
|
2014-08-23 00:07:08 +02:00
|
|
|
{ return hHandle; }
|
|
|
|
|
|
|
|
public:
|
|
|
|
// Custom methods
|
2017-03-02 01:35:13 +01:00
|
|
|
DWORD Seek(LONG nToSeek, DWORD nPoint);
|
|
|
|
DWORD FillBuffer(void* pBuf, DWORD nLen);
|
2017-10-20 00:58:06 +02:00
|
|
|
DWORD GetCurrentPosition() const
|
2017-03-02 01:35:13 +01:00
|
|
|
{
|
|
|
|
LARGE_INTEGER filePointer;
|
|
|
|
filePointer.QuadPart = 0;
|
|
|
|
SetFilePointerEx( hHandle, filePointer, &filePointer, FILE_CURRENT );
|
|
|
|
return DWORD(filePointer.QuadPart - dwStartPosition);
|
|
|
|
}
|
2014-08-23 00:07:08 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
class CAEDataStream
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
static bool m_bUseNewStruct;
|
|
|
|
|
|
|
|
private:
|
2017-02-05 22:52:22 +01:00
|
|
|
~CAEDataStream() = delete;
|
|
|
|
CAEDataStream() = delete;
|
2014-08-23 00:07:08 +02:00
|
|
|
|
|
|
|
public:
|
|
|
|
static void SetStructType(bool bNew)
|
|
|
|
{ m_bUseNewStruct = bNew; }
|
|
|
|
static bool IsNew()
|
|
|
|
{ return m_bUseNewStruct; }
|
|
|
|
|
|
|
|
// This is handled by GTA so we can leave it that way
|
2014-06-10 18:31:19 +02:00
|
|
|
bool Initialise();
|
2014-08-23 00:07:08 +02:00
|
|
|
|
|
|
|
unsigned int Seek(long nToSeek, int nPoint)
|
|
|
|
{ if ( m_bUseNewStruct )
|
|
|
|
return reinterpret_cast<CAEDataStreamNew*>(this)->Seek(nToSeek, nPoint);
|
|
|
|
return reinterpret_cast<CAEDataStreamOld*>(this)->Seek(nToSeek, nPoint); }
|
|
|
|
|
|
|
|
unsigned int FillBuffer(void* pBuf, unsigned long nLen)
|
|
|
|
{ if ( m_bUseNewStruct )
|
|
|
|
return reinterpret_cast<CAEDataStreamNew*>(this)->FillBuffer(pBuf, nLen);
|
|
|
|
return reinterpret_cast<CAEDataStreamOld*>(this)->FillBuffer(pBuf, nLen); }
|
|
|
|
|
2017-10-20 00:58:06 +02:00
|
|
|
unsigned int GetCurrentPosition() const
|
2014-08-23 00:07:08 +02:00
|
|
|
{ if ( m_bUseNewStruct )
|
2017-10-20 00:58:06 +02:00
|
|
|
return reinterpret_cast<const CAEDataStreamNew*>(this)->GetCurrentPosition();
|
|
|
|
return reinterpret_cast<const CAEDataStreamOld*>(this)->GetCurrentPosition(); }
|
2014-08-23 00:07:08 +02:00
|
|
|
|
2017-10-20 00:58:06 +02:00
|
|
|
inline DWORD GetID() const
|
2014-08-23 00:07:08 +02:00
|
|
|
{ if ( m_bUseNewStruct )
|
2017-10-20 00:58:06 +02:00
|
|
|
return reinterpret_cast<const CAEDataStreamNew*>(this)->GetID();
|
|
|
|
return reinterpret_cast<const CAEDataStreamOld*>(this)->GetID(); }
|
2014-08-23 00:07:08 +02:00
|
|
|
|
2017-10-20 00:58:06 +02:00
|
|
|
inline HANDLE GetFile() const
|
2014-08-23 00:07:08 +02:00
|
|
|
{ if ( m_bUseNewStruct )
|
2017-10-20 00:58:06 +02:00
|
|
|
return reinterpret_cast<const CAEDataStreamNew*>(this)->GetFile();
|
|
|
|
return reinterpret_cast<const CAEDataStreamOld*>(this)->GetFile(); }
|
2014-06-10 18:31:19 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class CAEStreamingDecoder
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
CAEDataStream* pStream;
|
|
|
|
|
|
|
|
public:
|
|
|
|
CAEStreamingDecoder(CAEDataStream* stream)
|
|
|
|
: pStream(stream)
|
|
|
|
{
|
2017-03-02 01:35:13 +01:00
|
|
|
if ( stream != nullptr )
|
2014-06-10 18:31:19 +02:00
|
|
|
stream->Initialise();
|
|
|
|
}
|
|
|
|
|
|
|
|
inline CAEDataStream* GetStream()
|
|
|
|
{ return pStream; }
|
2017-10-20 00:58:06 +02:00
|
|
|
inline const CAEDataStream* GetStream() const
|
|
|
|
{ return pStream; }
|
2014-06-10 18:31:19 +02:00
|
|
|
|
|
|
|
virtual bool Initialise()=0;
|
2017-03-02 01:35:13 +01:00
|
|
|
virtual uint32_t FillBuffer(void* pBuf,uint32_t nLen)=0;
|
2014-06-10 18:31:19 +02:00
|
|
|
|
2017-10-20 00:58:06 +02:00
|
|
|
virtual uint32_t GetStreamLengthMs() const =0;
|
|
|
|
virtual uint32_t GetStreamPlayTimeMs() const =0;
|
2017-03-02 01:35:13 +01:00
|
|
|
virtual void SetCursor(uint32_t nTime)=0;
|
2017-10-20 00:58:06 +02:00
|
|
|
virtual uint32_t GetSampleRate() const =0;
|
2014-06-10 18:31:19 +02:00
|
|
|
|
2014-06-14 02:15:14 +02:00
|
|
|
virtual ~CAEStreamingDecoder();
|
2014-06-10 18:31:19 +02:00
|
|
|
|
2017-10-20 00:58:06 +02:00
|
|
|
virtual uint32_t GetStreamID() const =0;
|
2014-06-10 18:31:19 +02:00
|
|
|
};
|
|
|
|
|
2017-03-02 01:35:13 +01:00
|
|
|
static_assert(sizeof(CAEDataStreamOld) == 0x28, "Wrong size: CAEDataStreamOld");
|
|
|
|
static_assert(sizeof(CAEDataStreamNew) == 0x2C, "Wrong size: CAEDataStreamNew");
|
|
|
|
|
2014-06-10 18:31:19 +02:00
|
|
|
#endif
|