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
+15 -38
View File
@@ -34,40 +34,32 @@ namespace lullaby
// Callbacks
static wuff_sint32 read_callback(void *userdata, wuff_uint8 *buffer, size_t *size)
{
WaveFile *input = (WaveFile *) userdata;
size_t bytes_left = input->size - input->offset;
size_t target_size = *size < bytes_left ? *size : bytes_left;
memcpy(buffer, input->data + input->offset, target_size);
input->offset += target_size;
*size = target_size;
auto stream = (Stream *) userdata;
size_t readsize = stream->read(buffer, *size);
*size = readsize;
return WUFF_SUCCESS;
}
static wuff_sint32 seek_callback(void *userdata, wuff_uint64 offset)
{
WaveFile *input = (WaveFile *)userdata;
input->offset = (size_t) (offset < input->size ? offset : input->size);
auto stream = (Stream *) userdata;
stream->seek(offset, Stream::SEEKORIGIN_BEGIN);
return WUFF_SUCCESS;
}
static wuff_sint32 tell_callback(void *userdata, wuff_uint64 *offset)
{
WaveFile *input = (WaveFile *)userdata;
*offset = input->offset;
auto stream = (Stream *) userdata;
*offset = stream->tell();
return WUFF_SUCCESS;
}
wuff_callback WaveDecoderCallbacks = {read_callback, seek_callback, tell_callback};
static wuff_callback WaveDecoderCallbacks = {read_callback, seek_callback, tell_callback};
WaveDecoder::WaveDecoder(Data *data, int bufferSize)
: Decoder(data, bufferSize)
WaveDecoder::WaveDecoder(Stream *stream, int bufferSize)
: Decoder(stream, bufferSize)
{
dataFile.data = (char *) data->getData();
dataFile.size = data->getSize();
dataFile.offset = 0;
int wuff_status = wuff_open(&handle, &WaveDecoderCallbacks, &dataFile);
int wuff_status = wuff_open(&handle, &WaveDecoderCallbacks, stream);
if (wuff_status < 0)
throw love::Exception("Could not open WAVE");
@@ -78,13 +70,13 @@ WaveDecoder::WaveDecoder(Data *data, int bufferSize)
throw love::Exception("Could not retrieve WAVE stream info");
if (info.channels > 2)
throw love::Exception("Multichannel audio not supported");
throw love::Exception("WAVE Multichannel audio not supported");
if (info.format != WUFF_FORMAT_PCM_U8 && info.format != WUFF_FORMAT_PCM_S16)
{
wuff_status = wuff_format(handle, WUFF_FORMAT_PCM_S16);
if (wuff_status < 0)
throw love::Exception("Could not set output format");
throw love::Exception("Could not set WAVE output format");
}
}
catch (love::Exception &)
@@ -99,25 +91,10 @@ WaveDecoder::~WaveDecoder()
wuff_close(handle);
}
bool WaveDecoder::accepts(const std::string &ext)
{
static const std::string supported[] =
{
"wav"
};
for (const auto& s : supported)
{
if (s.compare(ext) == 0)
return true;
}
return false;
}
love::sound::Decoder *WaveDecoder::clone()
{
return new WaveDecoder(data.get(), bufferSize);
StrongRef<Stream> s(stream->clone(), Acquire::NORETAIN);
return new WaveDecoder(s, bufferSize);
}
int WaveDecoder::decode()