Files
GTASource/rage/scaleform/Src/GKernel/GSound.cpp
expvintl 419f2e4752 init
2025-02-23 17:40:52 +08:00

182 lines
4.8 KiB
C++

/**********************************************************************
Filename : GSound.h
Content : Sound samples
Created : January 23, 2007
Authors : Andrew Reisse
Notes :
History :
Copyright : (c) 1998-2006 Scaleform Corp. All Rights Reserved.
Licensees may use this file in accordance with the valid Scaleform
Commercial License Agreement provided with the software.
This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR ANY PURPOSE.
**********************************************************************/
#include "GSound.h"
#ifndef GFC_NO_SOUND
#include "GMemory.h"
#include "GHeapNew.h"
#include "GFunctions.h"
#include "GStd.h"
#if defined(GFX_AMP_SERVER) && !defined(GHEAP_DEBUG_INFO)
#include "GFxAmpServer.h"
#endif
GSoundData::GSoundData(UInt format, UInt rate, UInt length, UInt dsize)
: GSoundDataBase(format, rate, length), pData(NULL), DataSize(dsize)
{
pData = (UByte*)GMEMALIGN(DataSize, 32, GStat_Sound_Mem);
GMemUtil::Set(pData,0,DataSize);
#if defined(GFX_AMP_SERVER) && !defined(GHEAP_DEBUG_INFO)
GFxAmpServer::GetInstance().AddSound(DataSize);
#endif
}
GSoundData::~GSoundData()
{
#if defined(GFX_AMP_SERVER) && !defined(GHEAP_DEBUG_INFO)
GFxAmpServer::GetInstance().RemoveSound(DataSize);
#endif
GFREE_ALIGN(pData);
}
#define STREAM_SOUND_DATA_CHUNK_SIZE 16384
//////////////////////////////////////////////////////////////////////////
//
GAppendableSoundData::DataChunk::DataChunk(UInt capacity)
: pNext(NULL), DataSize(0), StartSample(0), SampleCount(0)
{
pData = (UByte*)GMEMALIGN(capacity, 32, GStat_Sound_Mem);
GMemUtil::Set(pData,0,capacity);
}
GAppendableSoundData::DataChunk::~DataChunk()
{
GFREE_ALIGN(pData);
}
GAppendableSoundData::GAppendableSoundData(UInt format, UInt rate)
: GSoundDataBase(format, rate, 0), pFirstChunk(NULL), pFillChunk(NULL), pReadChunk(NULL),
DataSize(0), ReadPos(0)
{
Format |= GSoundDataBase::Sample_Stream;
}
GAppendableSoundData::~GAppendableSoundData()
{
while(pFirstChunk)
{
DataChunk* ptmp = pFirstChunk->pNext;
delete pFirstChunk;
pFirstChunk = ptmp;
}
}
UByte* GAppendableSoundData::LockDataForAppend(UInt length, UInt dsize)
{
ChunkLock.Lock();
GASSERT(dsize < STREAM_SOUND_DATA_CHUNK_SIZE);
if (!pFirstChunk)
{
pFirstChunk = GNEW DataChunk(STREAM_SOUND_DATA_CHUNK_SIZE);
pFillChunk = pFirstChunk;
pReadChunk = pFillChunk;
}
UByte* pbuffer = 0;
if (dsize > STREAM_SOUND_DATA_CHUNK_SIZE - pFillChunk->DataSize)
{
pFillChunk->pNext = GNEW DataChunk(STREAM_SOUND_DATA_CHUNK_SIZE);
pFillChunk->pNext->StartSample = pFillChunk->StartSample + pFillChunk->SampleCount;
pFillChunk = pFillChunk->pNext;
}
pbuffer = pFillChunk->pData + pFillChunk->DataSize;
pFillChunk->DataSize += dsize;
pFillChunk->SampleCount += length;
DataSize += dsize;
Length += length;
return pbuffer;
}
void GAppendableSoundData::UnlockData()
{
ChunkLock.Unlock();
}
UInt GAppendableSoundData::GetData(UByte* buff, UInt dsize)
{
GLock::Locker lock(&ChunkLock);
if (!pReadChunk)
return 0;
UInt got_bytes = 0;
while(dsize > 0)
{
UInt ds = dsize;
if (ReadPos + dsize > pReadChunk->DataSize)
{
ds = pReadChunk->DataSize - ReadPos;
if (ds == 0)
{
if (!pReadChunk->pNext)
return got_bytes;
pReadChunk = pReadChunk->pNext;
ReadPos = 0;
continue;
}
}
GMemUtil::Copy(buff+got_bytes, pReadChunk->pData + ReadPos, ds);
dsize -= ds;
ReadPos += ds;
got_bytes += ds;
}
return got_bytes;
}
bool GAppendableSoundData::SeekPos(UInt pos)
{
GLock::Locker lock(&ChunkLock);
if (!pReadChunk)
return false;
UInt lpos = 0;
pReadChunk = pFirstChunk;
while(1)
{
lpos += pReadChunk->DataSize;
if (pos < lpos)
{
ReadPos = pos - (lpos - pReadChunk->DataSize);
return true;
}
if (!pReadChunk->pNext)
break;
pReadChunk = pReadChunk->pNext;
}
return false;
}
//////////////////////////////////////////////////////////////////////////
//
GSoundFile::GSoundFile(const char* fname, UInt rate, UInt length, bool streaming)
: GSoundDataBase(GSoundDataBase::Sample_File, rate, length)
{
if (streaming)
Format |= GSoundDataBase::Sample_Stream;
UPInt len = G_strlen(fname) + 1;
pFileName = (char*)GALLOC(len, GStat_Sound_Mem);
GMemUtil::Set(pFileName,0,len);
G_strcpy(pFileName, len, fname);
}
GSoundFile::~GSoundFile()
{
GFREE(pFileName);
}
#endif // GFC_NO_SOUND