axmol/CocosDenshion/uphone/SoundDataManager.cpp

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;
}