mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Merge pull request #89 from ArseniyShestakov/improveSoundHandler
Nobody touched sounds in years. Code looks good and if it fixes the error, there is no reason not to pull it.
This commit is contained in:
commit
aef22002ad
@ -125,11 +125,10 @@ void CSoundHandler::release()
|
||||
{
|
||||
Mix_HaltChannel(-1);
|
||||
|
||||
std::map<soundBase::soundID, Mix_Chunk *>::iterator it;
|
||||
for (it=soundChunks.begin(); it != soundChunks.end(); it++)
|
||||
for (auto &chunk : soundChunks)
|
||||
{
|
||||
if (it->second)
|
||||
Mix_FreeChunk(it->second);
|
||||
if (chunk.second)
|
||||
Mix_FreeChunk(chunk.second);
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,44 +136,20 @@ void CSoundHandler::release()
|
||||
}
|
||||
|
||||
// Allocate an SDL chunk and cache it.
|
||||
Mix_Chunk *CSoundHandler::GetSoundChunk(soundBase::soundID soundID)
|
||||
Mix_Chunk *CSoundHandler::GetSoundChunk(std::string &sound, bool cache)
|
||||
{
|
||||
// Find its name
|
||||
auto fname = sounds[soundID];
|
||||
if (fname.empty())
|
||||
return nullptr;
|
||||
|
||||
// Load and insert
|
||||
try
|
||||
{
|
||||
auto data = CResourceHandler::get()->load(ResourceID(std::string("SOUNDS/") + fname, EResType::SOUND))->readAll();
|
||||
if (cache && soundChunks.find(sound) != soundChunks.end())
|
||||
return soundChunks[sound];
|
||||
|
||||
SDL_RWops *ops = SDL_RWFromMem(data.first.release(), data.second);
|
||||
Mix_Chunk *chunk;
|
||||
chunk = Mix_LoadWAV_RW(ops, 1); // will free ops
|
||||
soundChunks.insert(std::pair<soundBase::soundID, Mix_Chunk *>(soundID, chunk));
|
||||
return chunk;
|
||||
}
|
||||
catch(std::exception &e)
|
||||
{
|
||||
logGlobal->warnStream() << "Cannot get sound " << soundID << " chunk: " << e.what();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Mix_Chunk *CSoundHandler::GetSoundChunk(std::string &sound)
|
||||
{
|
||||
if (sound.empty())
|
||||
return nullptr;
|
||||
|
||||
// Load and insert
|
||||
try
|
||||
{
|
||||
auto data = CResourceHandler::get()->load(ResourceID(std::string("SOUNDS/") + sound, EResType::SOUND))->readAll();
|
||||
|
||||
SDL_RWops *ops = SDL_RWFromMem(data.first.release(), data.second);
|
||||
Mix_Chunk *chunk;
|
||||
chunk = Mix_LoadWAV_RW(ops, 1); // will free ops
|
||||
Mix_Chunk *chunk = Mix_LoadWAV_RW(ops, 1); // will free ops
|
||||
|
||||
if (cache)
|
||||
soundChunks.insert(std::pair<std::string, Mix_Chunk *>(sound, chunk));
|
||||
|
||||
return chunk;
|
||||
}
|
||||
catch(std::exception &e)
|
||||
@ -188,48 +163,36 @@ Mix_Chunk *CSoundHandler::GetSoundChunk(std::string &sound)
|
||||
int CSoundHandler::playSound(soundBase::soundID soundID, int repeats)
|
||||
{
|
||||
assert(soundID < soundBase::sound_after_last);
|
||||
if (!initialized)
|
||||
return -1;
|
||||
auto sound = sounds[soundID];
|
||||
logGlobal->traceStream() << "Attempt to play sound " << soundID << " with file name " << sound << " with cache";
|
||||
|
||||
int channel;
|
||||
Mix_Chunk *chunk = GetSoundChunk(soundID);
|
||||
|
||||
if (chunk)
|
||||
{
|
||||
channel = Mix_PlayChannel(-1, chunk, repeats);
|
||||
if (channel == -1)
|
||||
logGlobal->errorStream() << "Unable to play sound file " << soundID << " , error " << Mix_GetError();
|
||||
else
|
||||
callbacks[channel];//insert empty callback
|
||||
}
|
||||
else
|
||||
{
|
||||
channel = -1;
|
||||
}
|
||||
|
||||
return channel;
|
||||
return playSound(sound, repeats, true);
|
||||
}
|
||||
|
||||
int CSoundHandler::playSound(std::string sound, int repeats)
|
||||
int CSoundHandler::playSound(std::string sound, int repeats, bool cache)
|
||||
{
|
||||
if (!initialized)
|
||||
if (!initialized || sound.empty())
|
||||
return -1;
|
||||
|
||||
int channel;
|
||||
Mix_Chunk *chunk = GetSoundChunk(sound);
|
||||
Mix_Chunk *chunk = GetSoundChunk(sound, cache);
|
||||
|
||||
if (chunk)
|
||||
{
|
||||
channel = Mix_PlayChannel(-1, chunk, repeats);
|
||||
if (channel == -1)
|
||||
logGlobal->errorStream() << "Unable to play sound file " << sound << " , error " << Mix_GetError();
|
||||
else
|
||||
callbacks[channel];//insert empty callback
|
||||
}
|
||||
else
|
||||
{
|
||||
channel = -1;
|
||||
logGlobal->errorStream() << "Unable to play sound file " << sound << " , error " << Mix_GetError();
|
||||
if (!cache)
|
||||
Mix_FreeChunk(chunk);
|
||||
}
|
||||
else if (cache)
|
||||
callbacks[channel];
|
||||
else
|
||||
callbacks[channel] = [chunk]{ Mix_FreeChunk(chunk);};
|
||||
}
|
||||
else
|
||||
channel = -1;
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
@ -41,10 +41,9 @@ private:
|
||||
SettingsListener listener;
|
||||
void onVolumeChange(const JsonNode &volumeNode);
|
||||
|
||||
std::map<soundBase::soundID, Mix_Chunk *> soundChunks;
|
||||
std::map<std::string, Mix_Chunk *> soundChunks;
|
||||
|
||||
Mix_Chunk *GetSoundChunk(soundBase::soundID soundID);
|
||||
Mix_Chunk *GetSoundChunk(std::string &sound);
|
||||
Mix_Chunk *GetSoundChunk(std::string &sound, bool cache);
|
||||
|
||||
//have entry for every currently active channel
|
||||
//std::function will be nullptr if callback was not set
|
||||
@ -60,7 +59,7 @@ public:
|
||||
|
||||
// Sounds
|
||||
int playSound(soundBase::soundID soundID, int repeats=0);
|
||||
int playSound(std::string sound, int repeats=0);
|
||||
int playSound(std::string sound, int repeats=0, bool cache=false);
|
||||
int playSoundFromSet(std::vector<soundBase::soundID> &sound_vec);
|
||||
void stopSound(int handler);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user