Audio source decoding improvements.

- Streaming sources now also stream the file contents instead of loading it into memory, by default. Added a new stream type enum parameter to newSource ("file" or "memory").
- Audio file decoding now chooses the most appropriate decoder based on the file contents instead of the file extension.
- Videos now stream audio from the file instead of loading all of the video file into memory for use with audio decoding.
This commit is contained in:
Alex Szpakowski
2022-04-21 19:57:32 -03:00
parent d5865e160c
commit c09fef8e79
20 changed files with 318 additions and 468 deletions
+28 -27
View File
@@ -23,6 +23,7 @@
#ifndef LOVE_NO_MODPLUG
#include "common/Exception.h"
#include "common/Data.h"
namespace love
{
@@ -31,12 +32,11 @@ namespace sound
namespace lullaby
{
ModPlugDecoder::ModPlugDecoder(Data *data, int bufferSize)
: Decoder(data, bufferSize)
ModPlugDecoder::ModPlugDecoder(Stream *stream, int bufferSize)
: Decoder(stream, bufferSize)
, plug(0)
, duration(-2.0)
{
// Set some ModPlug settings.
settings.mFlags = MODPLUG_ENABLE_OVERSAMPLING | MODPLUG_ENABLE_NOISE_REDUCTION;
settings.mChannels = 2;
@@ -60,10 +60,29 @@ ModPlugDecoder::ModPlugDecoder(Data *data, int bufferSize)
ModPlug_SetSettings(&settings);
// Load the module.
plug = ModPlug_Load(data->getData(), (int) data->getSize());
// ModPlug has no streaming API. Miserable.
// We don't want to load the entire stream immediately if it's big, because
// it might not be compatible with ModPlug. So we just try to load 4MB and
// see if that works, and then load the whole thing if it does.
if (stream->getSize() > 1024 * 1024 * 4)
{
data.set(stream->read(1024 * 1024 * 4), Acquire::NORETAIN);
if (plug == 0)
plug = ModPlug_Load(data->getData(), (int)data->getSize());
if (plug == nullptr)
throw love::Exception("Could not load file with ModPlug.");
stream->seek(0);
ModPlug_Unload(plug);
}
data.set(stream->read(stream->getSize()), Acquire::NORETAIN);
// Load the module.
plug = ModPlug_Load(data->getData(), (int)data->getSize());
if (plug == nullptr)
throw love::Exception("Could not load file with ModPlug.");
// set master volume for delicate ears
@@ -72,32 +91,14 @@ ModPlugDecoder::ModPlugDecoder(Data *data, int bufferSize)
ModPlugDecoder::~ModPlugDecoder()
{
if (plug != 0)
if (plug != nullptr)
ModPlug_Unload(plug);
}
bool ModPlugDecoder::accepts(const std::string &ext)
{
static const std::string supported[] =
{
"699", "abc", "amf", "ams", "dbm", "dmf",
"dsm", "far", "it", "j2b", "mdl", "med",
"mid", "mod", "mt2", "mtm", "okt", "pat",
"psm", "s3m", "stm", "ult", "umx", "xm",
};
for (const auto &s : supported)
{
if (s.compare(ext) == 0)
return true;
}
return false;
}
love::sound::Decoder *ModPlugDecoder::clone()
{
return new ModPlugDecoder(data.get(), bufferSize);
StrongRef<Stream> s(stream->clone(), Acquire::NORETAIN);
return new ModPlugDecoder(s, bufferSize);
}
int ModPlugDecoder::decode()