decoder/mad: eliminate the loop in SubmitPCM()
libmad has a hard-coded maximum PCM buffer size; if we make our output_buffer just as large, we can avoid the loop, because any possible size will fit.
This commit is contained in:
@@ -108,14 +108,13 @@ mad_plugin_init(const ConfigBlock &block)
|
|||||||
|
|
||||||
class MadDecoder {
|
class MadDecoder {
|
||||||
static constexpr size_t READ_BUFFER_SIZE = 40960;
|
static constexpr size_t READ_BUFFER_SIZE = 40960;
|
||||||
static constexpr size_t MP3_DATA_OUTPUT_BUFFER_SIZE = 2048;
|
|
||||||
|
|
||||||
struct mad_stream stream;
|
struct mad_stream stream;
|
||||||
struct mad_frame frame;
|
struct mad_frame frame;
|
||||||
struct mad_synth synth;
|
struct mad_synth synth;
|
||||||
mad_timer_t timer;
|
mad_timer_t timer;
|
||||||
unsigned char input_buffer[READ_BUFFER_SIZE];
|
unsigned char input_buffer[READ_BUFFER_SIZE];
|
||||||
int32_t output_buffer[MP3_DATA_OUTPUT_BUFFER_SIZE];
|
int32_t output_buffer[sizeof(mad_pcm::samples) / sizeof(mad_fixed_t)];
|
||||||
SignedSongTime total_time;
|
SignedSongTime total_time;
|
||||||
SongTime elapsed_time;
|
SongTime elapsed_time;
|
||||||
SongTime seek_time;
|
SongTime seek_time;
|
||||||
@@ -847,30 +846,16 @@ MadDecoder::UpdateTimerNextFrame() noexcept
|
|||||||
DecoderCommand
|
DecoderCommand
|
||||||
MadDecoder::SubmitPCM(unsigned i, unsigned pcm_length) noexcept
|
MadDecoder::SubmitPCM(unsigned i, unsigned pcm_length) noexcept
|
||||||
{
|
{
|
||||||
unsigned max_samples = sizeof(output_buffer) /
|
|
||||||
sizeof(output_buffer[0]) /
|
|
||||||
MAD_NCHANNELS(&frame.header);
|
|
||||||
|
|
||||||
while (i < pcm_length) {
|
|
||||||
unsigned int num_samples = pcm_length - i;
|
unsigned int num_samples = pcm_length - i;
|
||||||
if (num_samples > max_samples)
|
|
||||||
num_samples = max_samples;
|
|
||||||
|
|
||||||
i += num_samples;
|
|
||||||
|
|
||||||
mad_fixed_to_24_buffer(output_buffer, &synth,
|
mad_fixed_to_24_buffer(output_buffer, &synth,
|
||||||
i - num_samples, i,
|
i, i + num_samples,
|
||||||
MAD_NCHANNELS(&frame.header));
|
MAD_NCHANNELS(&frame.header));
|
||||||
num_samples *= MAD_NCHANNELS(&frame.header);
|
num_samples *= MAD_NCHANNELS(&frame.header);
|
||||||
|
|
||||||
auto cmd = client->SubmitData(input_stream, output_buffer,
|
return client->SubmitData(input_stream, output_buffer,
|
||||||
sizeof(output_buffer[0]) * num_samples,
|
sizeof(output_buffer[0]) * num_samples,
|
||||||
frame.header.bitrate / 1000);
|
frame.header.bitrate / 1000);
|
||||||
if (cmd != DecoderCommand::NONE)
|
|
||||||
return cmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
return DecoderCommand::NONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline DecoderCommand
|
inline DecoderCommand
|
||||||
|
Reference in New Issue
Block a user