mirror of
https://github.com/love2d/love.git
synced 2026-08-20 20:49:54 +02:00
Try probing the audio type if extension matching fails (resolves #1487)
At the moment it still only tries a single decoder if it does find a matching extension. It might be a good idea to simply always probe, but try the matching decoder first, that way you could name your mp3 .ogg.
This commit is contained in:
@@ -8,6 +8,8 @@ Released: N/A
|
|||||||
* Added love.window.get/setVSync, to allow setting vsync without recreating the window.
|
* Added love.window.get/setVSync, to allow setting vsync without recreating the window.
|
||||||
* Added love.window.getSafeArea, currently only fully implemented on iOS.
|
* Added love.window.getSafeArea, currently only fully implemented on iOS.
|
||||||
|
|
||||||
|
* Changed audio file type detection, so it probes all supported backends for unrecognized extensions.
|
||||||
|
|
||||||
* Fixed the deprecation system not fully restarting when love.event.quit("restart") is used.
|
* Fixed the deprecation system not fully restarting when love.event.quit("restart") is used.
|
||||||
* Fixed love.math.hash returning an incorrect hash for certain input sizes.
|
* Fixed love.math.hash returning an incorrect hash for certain input sizes.
|
||||||
* Fixed t.audio.mixwithsystem.
|
* Fixed t.audio.mixwithsystem.
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "common/config.h"
|
#include "common/config.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include "Sound.h"
|
#include "Sound.h"
|
||||||
|
|
||||||
@@ -38,6 +39,27 @@
|
|||||||
# include "CoreAudioDecoder.h"
|
# include "CoreAudioDecoder.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct DecoderImpl
|
||||||
|
{
|
||||||
|
love::sound::Decoder *(*create)(love::filesystem::FileData *data, int bufferSize);
|
||||||
|
bool (*accepts)(const std::string& ext);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename DecoderType>
|
||||||
|
DecoderImpl DecoderImplFor()
|
||||||
|
{
|
||||||
|
DecoderImpl decoderImpl;
|
||||||
|
decoderImpl.create = [](love::filesystem::FileData *data, int bufferSize) -> love::sound::Decoder*
|
||||||
|
{
|
||||||
|
return new DecoderType(data, bufferSize);
|
||||||
|
};
|
||||||
|
decoderImpl.accepts = [](const std::string& ext) -> bool
|
||||||
|
{
|
||||||
|
return DecoderType::accepts(ext);
|
||||||
|
};
|
||||||
|
return decoderImpl;
|
||||||
|
}
|
||||||
|
|
||||||
namespace love
|
namespace love
|
||||||
{
|
{
|
||||||
namespace sound
|
namespace sound
|
||||||
@@ -66,37 +88,53 @@ sound::Decoder *Sound::newDecoder(love::filesystem::FileData *data, int bufferSi
|
|||||||
std::string ext = data->getExtension();
|
std::string ext = data->getExtension();
|
||||||
std::transform(ext.begin(), ext.end(), ext.begin(), tolower);
|
std::transform(ext.begin(), ext.end(), ext.begin(), tolower);
|
||||||
|
|
||||||
sound::Decoder *decoder = nullptr;
|
std::vector<DecoderImpl> possibleDecoders = {
|
||||||
|
|
||||||
// Find a suitable decoder here, and return it.
|
|
||||||
if (false)
|
|
||||||
/* nothing */;
|
|
||||||
#ifndef LOVE_NO_MODPLUG
|
#ifndef LOVE_NO_MODPLUG
|
||||||
else if (ModPlugDecoder::accepts(ext))
|
DecoderImplFor<ModPlugDecoder>(),
|
||||||
decoder = new ModPlugDecoder(data, bufferSize);
|
|
||||||
#endif // LOVE_NO_MODPLUG
|
#endif // LOVE_NO_MODPLUG
|
||||||
#ifndef LOVE_NOMPG123
|
#ifndef LOVE_NOMPG123
|
||||||
else if (Mpg123Decoder::accepts(ext))
|
DecoderImplFor<Mpg123Decoder>(),
|
||||||
decoder = new Mpg123Decoder(data, bufferSize);
|
|
||||||
#endif // LOVE_NOMPG123
|
#endif // LOVE_NOMPG123
|
||||||
else if (VorbisDecoder::accepts(ext))
|
DecoderImplFor<VorbisDecoder>(),
|
||||||
decoder = new VorbisDecoder(data, bufferSize);
|
|
||||||
#ifdef LOVE_SUPPORT_GME
|
#ifdef LOVE_SUPPORT_GME
|
||||||
else if (GmeDecoder::accepts(ext))
|
DecoderImplFor<GmeDecoder>(),
|
||||||
decoder = new GmeDecoder(data, bufferSize);
|
|
||||||
#endif // LOVE_SUPPORT_GME
|
#endif // LOVE_SUPPORT_GME
|
||||||
#ifdef LOVE_SUPPORT_COREAUDIO
|
#ifdef LOVE_SUPPORT_COREAUDIO
|
||||||
else if (CoreAudioDecoder::accepts(ext))
|
DecoderImplFor<CoreAudioDecoder>(),
|
||||||
decoder = new CoreAudioDecoder(data, bufferSize);
|
|
||||||
#endif
|
#endif
|
||||||
else if (WaveDecoder::accepts(ext))
|
DecoderImplFor<WaveDecoder>(),
|
||||||
decoder = new WaveDecoder(data, bufferSize);
|
// DecoderImplFor<FLACDecoder>(),
|
||||||
/*else if (FLACDecoder::accepts(ext))
|
// DecoderImplFor<OtherDecoder>(),
|
||||||
decoder = new FLACDecoder(data, bufferSize);*/
|
};
|
||||||
|
|
||||||
// else if (OtherDecoder::accept(ext))
|
// First find a matching decoder based on extension
|
||||||
|
for (DecoderImpl &possibleDecoder : possibleDecoders)
|
||||||
|
{
|
||||||
|
if (possibleDecoder.accepts(ext))
|
||||||
|
return possibleDecoder.create(data, bufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If that fails, start probing instead
|
||||||
|
std::stringstream decodingErrors;
|
||||||
|
decodingErrors << "Failed to determine file type:\n";
|
||||||
|
for (DecoderImpl &possibleDecoder : possibleDecoders)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
sound::Decoder *decoder = possibleDecoder.create(data, bufferSize);
|
||||||
return decoder;
|
return decoder;
|
||||||
|
}
|
||||||
|
catch (love::Exception &e)
|
||||||
|
{
|
||||||
|
decodingErrors << e.what() << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Probing failed too, bail with the accumulated errors
|
||||||
|
throw love::Exception(decodingErrors.str().c_str());
|
||||||
|
|
||||||
|
// Unreachable, but here to prevent (possible) warnings
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // lullaby
|
} // lullaby
|
||||||
|
|||||||
Reference in New Issue
Block a user