mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-04-21 21:52:04 +02:00
Merge pull request #128 from Splendide-Imaginarius/mkxp-z-s32
Support S32 audio sample formats
This commit is contained in:
commit
47030733c8
4 changed files with 60 additions and 8 deletions
|
@ -208,6 +208,8 @@ inline uint8_t formatSampleSize(int sdlFormat)
|
|||
case AUDIO_S16MSB :
|
||||
return 2;
|
||||
|
||||
case AUDIO_S32LSB :
|
||||
case AUDIO_S32MSB :
|
||||
case AUDIO_F32LSB :
|
||||
case AUDIO_F32MSB :
|
||||
return 4;
|
||||
|
|
|
@ -56,7 +56,8 @@ struct ALDataSource
|
|||
ALDataSource *createSDLSource(SDL_RWops &ops,
|
||||
const char *extension,
|
||||
uint32_t maxBufSize,
|
||||
bool looped);
|
||||
bool looped,
|
||||
int fallbackMode);
|
||||
|
||||
ALDataSource *createVorbisSource(SDL_RWops &ops,
|
||||
bool looped);
|
||||
|
|
|
@ -204,10 +204,11 @@ struct ALStreamOpenHandler : FileSystem::OpenHandler
|
|||
SDL_RWops *srcOps;
|
||||
bool looped;
|
||||
ALDataSource *source;
|
||||
int fallbackMode;
|
||||
std::string errorMsg;
|
||||
|
||||
ALStreamOpenHandler(SDL_RWops &srcOps, bool looped)
|
||||
: srcOps(&srcOps), looped(looped), source(0)
|
||||
: srcOps(&srcOps), looped(looped), source(0), fallbackMode(0)
|
||||
{}
|
||||
|
||||
bool tryRead(SDL_RWops &ops, const char *ext)
|
||||
|
@ -240,7 +241,7 @@ struct ALStreamOpenHandler : FileSystem::OpenHandler
|
|||
}
|
||||
}
|
||||
|
||||
source = createSDLSource(*srcOps, ext, STREAM_BUF_SIZE, looped);
|
||||
source = createSDLSource(*srcOps, ext, STREAM_BUF_SIZE, looped, fallbackMode);
|
||||
}
|
||||
catch (const Exception &e)
|
||||
{
|
||||
|
@ -261,6 +262,15 @@ void ALStream::openSource(const std::string &filename)
|
|||
source = handler.source;
|
||||
needsRewind.clear();
|
||||
|
||||
// Try fallback mode, e.g. for handling S32->F32 sample format conversion
|
||||
if (!source)
|
||||
{
|
||||
handler.fallbackMode = 1;
|
||||
shState->fileSystem().openRead(handler, filename.c_str());
|
||||
source = handler.source;
|
||||
needsRewind.clear();
|
||||
}
|
||||
|
||||
if (!source)
|
||||
{
|
||||
char buf[512];
|
||||
|
|
|
@ -37,11 +37,25 @@ struct SDLSoundSource : ALDataSource
|
|||
SDLSoundSource(SDL_RWops &ops,
|
||||
const char *extension,
|
||||
uint32_t maxBufSize,
|
||||
bool looped)
|
||||
bool looped,
|
||||
int fallbackMode)
|
||||
: srcOps(ops),
|
||||
looped(looped)
|
||||
{
|
||||
sample = Sound_NewSample(&srcOps, extension, 0, maxBufSize);
|
||||
if (fallbackMode == 0)
|
||||
{
|
||||
sample = Sound_NewSample(&srcOps, extension, 0, maxBufSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We're here because a previous attempt resulted in S32 format.
|
||||
|
||||
Sound_AudioInfo desired;
|
||||
SDL_memset(&desired, '\0', sizeof (Sound_AudioInfo));
|
||||
desired.format = AUDIO_F32SYS;
|
||||
|
||||
sample = Sound_NewSample(&srcOps, extension, &desired, maxBufSize);
|
||||
}
|
||||
|
||||
if (!sample)
|
||||
{
|
||||
|
@ -49,6 +63,30 @@ struct SDLSoundSource : ALDataSource
|
|||
throw Exception(Exception::SDLError, "SDL_sound: %s", Sound_GetError());
|
||||
}
|
||||
|
||||
if (fallbackMode == 0)
|
||||
{
|
||||
bool validFormat = true;
|
||||
|
||||
switch (sample->actual.format)
|
||||
{
|
||||
// OpenAL Soft doesn't support S32 formats.
|
||||
// https://github.com/kcat/openal-soft/issues/934
|
||||
case AUDIO_S32LSB :
|
||||
case AUDIO_S32MSB :
|
||||
validFormat = false;
|
||||
}
|
||||
|
||||
if (!validFormat)
|
||||
{
|
||||
// Unfortunately there's no way to change the desired format of a sample.
|
||||
// https://github.com/icculus/SDL_sound/issues/91
|
||||
// So we just have to close the sample (which closes the file too),
|
||||
// and retry with a new desired format.
|
||||
Sound_FreeSample(sample);
|
||||
throw Exception(Exception::SDLError, "SDL_sound: format not supported by OpenAL: %d", sample->actual.format);
|
||||
}
|
||||
}
|
||||
|
||||
sampleSize = formatSampleSize(sample->actual.format);
|
||||
|
||||
alFormat = chooseALFormat(sampleSize, sample->actual.channels);
|
||||
|
@ -124,7 +162,8 @@ struct SDLSoundSource : ALDataSource
|
|||
ALDataSource *createSDLSource(SDL_RWops &ops,
|
||||
const char *extension,
|
||||
uint32_t maxBufSize,
|
||||
bool looped)
|
||||
bool looped,
|
||||
int fallbackMode)
|
||||
{
|
||||
return new SDLSoundSource(ops, extension, maxBufSize, looped);
|
||||
return new SDLSoundSource(ops, extension, maxBufSize, looped, fallbackMode);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue