mirror of https://github.com/axmolengine/axmol.git
208 lines
5.0 KiB
C++
208 lines
5.0 KiB
C++
#include "SoundDataManager.h"
|
|
#include "FileUtils.h"
|
|
#include "SoundPlayer.h"
|
|
|
|
#define BREAK_IF(cond) if (cond) break;
|
|
|
|
unsigned int BKDRHash(const char *str)
|
|
{
|
|
unsigned int seed = 31; // 31 131 1313 13131 131313 etc..
|
|
unsigned int hash = 0;
|
|
|
|
while (*str)
|
|
{
|
|
hash = hash * seed + (*str++);
|
|
}
|
|
|
|
return (hash & 0x7FFFFFFF);
|
|
}
|
|
|
|
SoundDataManager::SoundDataManager()
|
|
: m_pEffects(NULL)
|
|
{
|
|
m_pHRes = new ResourceHandle;
|
|
m_pSoundMap = new SoundInfoMap;
|
|
}
|
|
|
|
SoundDataManager::~SoundDataManager()
|
|
{
|
|
removeAllEffects();
|
|
|
|
if (m_pHRes)
|
|
{
|
|
delete m_pHRes;
|
|
m_pHRes = NULL;
|
|
}
|
|
|
|
if (m_pSoundMap)
|
|
{
|
|
delete m_pSoundMap;
|
|
m_pSoundMap = NULL;
|
|
}
|
|
}
|
|
|
|
void SoundDataManager::setResEntry(const void* pResEntry)
|
|
{
|
|
if (pResEntry)
|
|
{
|
|
m_pHRes->setResourceEntry(pResEntry);
|
|
}
|
|
}
|
|
|
|
void SoundDataManager::setSoundResInfo(const T_SoundResInfo ResInfo[], int nCount)
|
|
{
|
|
// first, clear the map before
|
|
if (!m_pSoundMap->empty())
|
|
{
|
|
m_pSoundMap->clear();
|
|
}
|
|
|
|
// second, insert the pairs
|
|
for (int i = 0; i < nCount; ++i)
|
|
{
|
|
std::string name = (ResInfo[i]).FileName;
|
|
int nResID = (ResInfo[i]).nResID;
|
|
|
|
m_pSoundMap->insert(SoundInfoMap::value_type(name, nResID));
|
|
}
|
|
}
|
|
|
|
int SoundDataManager::loadSoundData(const char* pszFilePath)
|
|
{
|
|
int nSoundID = 0;
|
|
|
|
if (! FileUtils::isFileExisted(pszFilePath))
|
|
{
|
|
// if the file is not existed, find in the ResourceInfo
|
|
nSoundID = loadFromResourceInfo(pszFilePath);
|
|
}
|
|
else
|
|
{
|
|
// load effect info from file
|
|
nSoundID = loadFromFile(pszFilePath);
|
|
}
|
|
|
|
return nSoundID;
|
|
}
|
|
|
|
tEffectElement* SoundDataManager::getSoundData(int nSoundID)
|
|
{
|
|
tEffectElement* pElement = NULL;
|
|
HASH_FIND_INT(m_pEffects, &nSoundID, pElement);
|
|
|
|
return pElement;
|
|
}
|
|
|
|
void SoundDataManager::unloadEffect(int nSoundID)
|
|
{
|
|
do
|
|
{
|
|
tEffectElement* pElement = NULL;
|
|
HASH_FIND_INT(m_pEffects, &nSoundID, pElement);
|
|
BREAK_IF(!pElement);
|
|
|
|
delete [] (pElement->pDataBuffer);
|
|
HASH_DEL(m_pEffects, pElement);
|
|
free(pElement);
|
|
} while (0);
|
|
}
|
|
|
|
void SoundDataManager::removeAllEffects()
|
|
{
|
|
for (tEffectElement *pElement = m_pEffects; pElement != NULL; )
|
|
{
|
|
int nSoundID = pElement->nSoundID;
|
|
pElement = (tEffectElement*)pElement->hh.next;
|
|
unloadEffect(nSoundID);
|
|
}
|
|
}
|
|
|
|
int SoundDataManager::loadFromResourceInfo(const char* pFileKey)
|
|
{
|
|
SoundInfoMap::iterator iter;
|
|
iter = m_pSoundMap->find(pFileKey);
|
|
int nSoundID = 0;
|
|
|
|
do
|
|
{
|
|
BREAK_IF(iter == m_pSoundMap->end());
|
|
|
|
// if we have loaded the file before,break
|
|
tEffectElement *pElement = NULL;
|
|
HASH_FIND_INT(m_pEffects, &iter->second, pElement);
|
|
if (pElement)
|
|
{
|
|
nSoundID = iter->second;
|
|
break;
|
|
}
|
|
|
|
unsigned int nSize = 0;
|
|
const void* pData = m_pHRes->LoadConstRawData(iter->second, &nSize);
|
|
BREAK_IF(!pData);
|
|
|
|
// copy the data
|
|
unsigned char* pSoundData = new unsigned char[nSize];
|
|
MemCopy(pSoundData, pData, nSize);
|
|
|
|
// record the id
|
|
nSoundID = iter->second;
|
|
|
|
// add the data to hash map
|
|
pElement = (tEffectElement*)calloc(sizeof(*pElement), 1);
|
|
pElement->nSoundID = nSoundID;
|
|
pElement->pDataBuffer = pSoundData;
|
|
pElement->nDataSize = nSize;
|
|
pElement->FileName = pFileKey;
|
|
pElement->nPlayerSoundID = -1;
|
|
HASH_ADD_INT(m_pEffects, nSoundID, pElement);
|
|
} while (0);
|
|
|
|
return nSoundID;
|
|
}
|
|
|
|
int SoundDataManager::loadFromFile(const char* pFilePath)
|
|
{
|
|
int nSoundID = 0;
|
|
|
|
do
|
|
{
|
|
int nID = BKDRHash(pFilePath);
|
|
|
|
// if we have loaded the file before,break
|
|
tEffectElement *pElement = NULL;
|
|
HASH_FIND_INT(m_pEffects, &nID, pElement);
|
|
if (pElement)
|
|
{
|
|
nSoundID = nID;
|
|
break;
|
|
}
|
|
|
|
// calculate the buffer size we needed
|
|
SoundPlayer TempPlayer;
|
|
int nBufferSize = TempPlayer.GetFileBufferSize(pFilePath);
|
|
// can not calculate the size,load failed
|
|
BREAK_IF(nBufferSize < 0);
|
|
|
|
// load the file data
|
|
unsigned char* buffer = NULL;
|
|
buffer = new unsigned char[nBufferSize];
|
|
BREAK_IF(!buffer);
|
|
int nSize = TempPlayer.DecodeFile(buffer, nBufferSize, pFilePath);
|
|
BREAK_IF(nSize < 0);
|
|
|
|
// record the id
|
|
nSoundID = nID;
|
|
|
|
// add the data to hash map
|
|
pElement = (tEffectElement*)calloc(sizeof(*pElement), 1);
|
|
pElement->nSoundID = nSoundID;
|
|
pElement->pDataBuffer = buffer;
|
|
pElement->nDataSize = nBufferSize;
|
|
pElement->FileName = "";
|
|
pElement->nPlayerSoundID = -1;
|
|
HASH_ADD_INT(m_pEffects, nSoundID, pElement);
|
|
} while (0);
|
|
|
|
return nSoundID;
|
|
}
|