1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-05 15:05:40 +02:00

support raw audio

This commit is contained in:
Laserlicht 2023-10-07 16:09:56 +02:00
parent 088ce9b948
commit 63fbaa8380
2 changed files with 52 additions and 0 deletions

View File

@ -142,6 +142,30 @@ Mix_Chunk *CSoundHandler::GetSoundChunk(const AudioPath & sound, bool cache)
}
}
Mix_Chunk *CSoundHandler::GetSoundChunk(std::pair<std::unique_ptr<ui8 []>, si64> & data, bool cache)
{
try
{
std::vector<ui8> startBytes = std::vector<ui8>(data.first.get(), data.first.get() + 100);
if (cache && soundChunksRaw.find(startBytes) != soundChunksRaw.end())
return soundChunksRaw[startBytes].first;
SDL_RWops *ops = SDL_RWFromMem(data.first.get(), (int)data.second);
Mix_Chunk *chunk = Mix_LoadWAV_RW(ops, 1); // will free ops
if (cache)
soundChunksRaw.insert({startBytes, std::make_pair (chunk, std::move (data.first))});
return chunk;
}
catch(std::exception &e)
{
logGlobal->warn("Cannot get sound chunk: %s", e.what());
return nullptr;
}
}
int CSoundHandler::ambientDistToVolume(int distance) const
{
const auto & distancesVector = ambientConfig["distances"].Vector();
@ -197,6 +221,31 @@ int CSoundHandler::playSound(const AudioPath & sound, int repeats, bool cache)
return channel;
}
int CSoundHandler::playSound(std::pair<std::unique_ptr<ui8 []>, si64> & data, int repeats, bool cache)
{
int channel;
Mix_Chunk *chunk = GetSoundChunk(data, cache);
if (chunk)
{
channel = Mix_PlayChannel(-1, chunk, repeats);
if (channel == -1)
{
logGlobal->error("Unable to play sound, error %s", Mix_GetError());
if (!cache)
Mix_FreeChunk(chunk);
}
else if (cache)
initCallback(channel);
else
initCallback(channel, [chunk](){ Mix_FreeChunk(chunk);});
}
else
channel = -1;
return channel;
}
// Helper. Randomly select a sound from an array and play it
int CSoundHandler::playSoundFromSet(std::vector<soundBase::soundID> &sound_vec)
{

View File

@ -41,8 +41,10 @@ private:
using CachedChunk = std::pair<Mix_Chunk *, std::unique_ptr<ui8[]>>;
std::map<AudioPath, CachedChunk> soundChunks;
std::map<std::vector<ui8>, CachedChunk> soundChunksRaw;
Mix_Chunk *GetSoundChunk(const AudioPath & sound, bool cache);
Mix_Chunk *GetSoundChunk(std::pair<std::unique_ptr<ui8 []>, si64> & data, bool cache);
/// have entry for every currently active channel
/// vector will be empty if callback was not set
@ -76,6 +78,7 @@ public:
// Sounds
int playSound(soundBase::soundID soundID, int repeats=0);
int playSound(const AudioPath & sound, int repeats=0, bool cache=false);
int playSound(std::pair<std::unique_ptr<ui8 []>, si64> & data, int repeats, bool cache=false);
int playSoundFromSet(std::vector<soundBase::soundID> &sound_vec);
void stopSound(int handler);