diff --git a/mkxp.conf.sample b/mkxp.conf.sample index 819c0a6..fd38497 100644 --- a/mkxp.conf.sample +++ b/mkxp.conf.sample @@ -173,6 +173,14 @@ # midi.reverb=false +# Number of OpenAL sources to allocate for SE playback. +# If there are a lot of sounds playing at the same time +# and audibly cutting each other off, try increasing +# this number. Maximum: 64. +# +# SE.sourceCount=6 + + # Give a hint on which language the game title as # specified in the Game.ini is, useful if the encoding # is being falsely detected. Relevant only if mkxp was diff --git a/src/audio.cpp b/src/audio.cpp index d984bdc..c1b171b 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -60,10 +60,11 @@ struct AudioPrivate MeWatchState state; } meWatch; - AudioPrivate() + AudioPrivate(const Config &conf) : bgm(ALStream::Looped, "bgm"), bgs(ALStream::Looped, "bgs"), - me(ALStream::NotLooped, "me") + me(ALStream::NotLooped, "me"), + se(conf) { meWatch.active = false; meWatch.termReq = false; @@ -238,8 +239,8 @@ struct AudioPrivate } }; -Audio::Audio() - : p(new AudioPrivate) +Audio::Audio(const Config &conf) + : p(new AudioPrivate(conf)) {} diff --git a/src/audio.h b/src/audio.h index 496dbe4..cb3e9fb 100644 --- a/src/audio.h +++ b/src/audio.h @@ -33,6 +33,7 @@ * quite make out their meaning yet) */ struct AudioPrivate; +struct Config; class Audio { @@ -75,7 +76,7 @@ public: #endif private: - Audio(); + Audio(const Config &conf); ~Audio(); friend struct SharedStatePrivate; diff --git a/src/config.cpp b/src/config.cpp index ae1d71b..9166ddb 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -141,6 +141,7 @@ Config::Config() { midi.chorus = false; midi.reverb = false; + SE.sourceCount = 6; } void Config::read(int argc, char *argv[]) @@ -165,6 +166,7 @@ void Config::read(int argc, char *argv[]) PO_DESC(midi.soundFont, std::string) \ PO_DESC(midi.chorus, bool) \ PO_DESC(midi.reverb, bool) \ + PO_DESC(SE.sourceCount, int) \ PO_DESC(customScript, std::string) \ PO_DESC(pathCache, bool) \ PO_DESC(useScriptNames, bool) @@ -221,6 +223,8 @@ void Config::read(int argc, char *argv[]) #undef PO_DESC #undef PO_DESC_ALL + + SE.sourceCount = clamp(SE.sourceCount, 1, 64); } static std::string baseName(const std::string &path) diff --git a/src/config.h b/src/config.h index 3f7143b..c22b44a 100644 --- a/src/config.h +++ b/src/config.h @@ -66,6 +66,11 @@ struct Config bool reverb; } midi; + struct + { + int sourceCount; + } SE; + bool useScriptNames; std::string customScript; diff --git a/src/sharedstate.cpp b/src/sharedstate.cpp index a2f78e5..a7fbcde 100644 --- a/src/sharedstate.cpp +++ b/src/sharedstate.cpp @@ -107,6 +107,7 @@ struct SharedStatePrivate midiState(threadData->config), #endif graphics(threadData), + audio(threadData->config), fontState(threadData->config), stampCounter(0) { diff --git a/src/soundemitter.cpp b/src/soundemitter.cpp index 1cad920..2fce12c 100644 --- a/src/soundemitter.cpp +++ b/src/soundemitter.cpp @@ -24,6 +24,7 @@ #include "sharedstate.h" #include "filesystem.h" #include "exception.h" +#include "config.h" #include "util.h" #include @@ -76,7 +77,7 @@ private: /* Before: [a][b][c][d], After (index=1): [a][c][d][b] */ static void -arrayPushBack(size_t array[], size_t size, size_t index) +arrayPushBack(std::vector &array, size_t size, size_t index) { size_t v = array[index]; @@ -86,10 +87,14 @@ arrayPushBack(size_t array[], size_t size, size_t index) array[size-1] = v; } -SoundEmitter::SoundEmitter() - : bufferBytes(0) +SoundEmitter::SoundEmitter(const Config &conf) + : bufferBytes(0), + srcCount(conf.SE.sourceCount), + alSrcs(srcCount), + atchBufs(srcCount), + srcPrio(srcCount) { - for (int i = 0; i < SE_SOURCES; ++i) + for (size_t i = 0; i < srcCount; ++i) { alSrcs[i] = AL::Source::gen(); atchBufs[i] = 0; @@ -99,7 +104,7 @@ SoundEmitter::SoundEmitter() SoundEmitter::~SoundEmitter() { - for (int i = 0; i < SE_SOURCES; ++i) + for (size_t i = 0; i < srcCount; ++i) { AL::Source::stop(alSrcs[i]); AL::Source::del(alSrcs[i]); @@ -124,24 +129,24 @@ void SoundEmitter::play(const std::string &filename, /* Try to find first free source */ size_t i; - for (i = 0; i < SE_SOURCES; ++i) + for (i = 0; i < srcCount; ++i) if (AL::Source::getState(alSrcs[srcPrio[i]]) != AL_PLAYING) break; /* If we didn't find any, try to find the lowest priority source * with the same buffer to overtake */ - if (i == SE_SOURCES) - for (size_t j = 0; j < SE_SOURCES; ++j) + if (i == srcCount) + for (size_t j = 0; j < srcCount; ++j) if (atchBufs[srcPrio[j]] == buffer) i = j; /* If we didn't find any, overtake the one with lowest priority */ - if (i == SE_SOURCES) + if (i == srcCount) i = 0; /* Push the used source to the back of the priority list */ size_t srcIndex = srcPrio[i]; - arrayPushBack(srcPrio, SE_SOURCES, i); + arrayPushBack(srcPrio, srcCount, i); AL::Source::ID src = alSrcs[srcIndex]; AL::Source::stop(src); @@ -164,7 +169,7 @@ void SoundEmitter::play(const std::string &filename, void SoundEmitter::stop() { - for (int i = 0; i < SE_SOURCES; i++) + for (size_t i = 0; i < srcCount; i++) AL::Source::stop(alSrcs[i]); } diff --git a/src/soundemitter.h b/src/soundemitter.h index 70ea48f..a340e99 100644 --- a/src/soundemitter.h +++ b/src/soundemitter.h @@ -27,10 +27,10 @@ #include "boost-hash.h" #include - -#define SE_SOURCES 6 +#include struct SoundBuffer; +struct Config; struct SoundEmitter { @@ -42,13 +42,14 @@ struct SoundEmitter /* Byte count sum of all cached / playing buffers */ uint32_t bufferBytes; - AL::Source::ID alSrcs[SE_SOURCES]; - SoundBuffer *atchBufs[SE_SOURCES]; + const size_t srcCount; + std::vector alSrcs; + std::vector atchBufs; /* Indices of sources, sorted by priority (lowest first) */ - size_t srcPrio[SE_SOURCES]; + std::vector srcPrio; - SoundEmitter(); + SoundEmitter(const Config &conf); ~SoundEmitter(); void play(const std::string &filename,