From 1f903accd95361735c841c87fdc6494ad3331b40 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Wed, 7 Jun 2023 13:19:45 +1000 Subject: Flesh out audio state machine for playback Also fix mono playback --- src/codecs/include/codec.hpp | 3 ++- src/codecs/include/mad.hpp | 6 ++---- src/codecs/mad.cpp | 35 ++++++++++++----------------------- 3 files changed, 16 insertions(+), 28 deletions(-) (limited to 'src/codecs') diff --git a/src/codecs/include/codec.hpp b/src/codecs/include/codec.hpp index 9dd717c9..c8a68ff3 100644 --- a/src/codecs/include/codec.hpp +++ b/src/codecs/include/codec.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -32,7 +33,7 @@ class ICodec { uint32_t sample_rate_hz; }; - virtual auto GetOutputFormat() -> OutputFormat = 0; + virtual auto GetOutputFormat() -> std::optional = 0; enum ProcessingError { MALFORMED_DATA }; diff --git a/src/codecs/include/mad.hpp b/src/codecs/include/mad.hpp index 3b1f5757..ea16cdc8 100644 --- a/src/codecs/include/mad.hpp +++ b/src/codecs/include/mad.hpp @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -24,7 +25,7 @@ class MadMp3Decoder : public ICodec { ~MadMp3Decoder(); auto CanHandleType(StreamType type) -> bool override; - auto GetOutputFormat() -> OutputFormat override; + auto GetOutputFormat() -> std::optional override; auto ResetForNewStream() -> void override; auto SetInput(cpp::span input) -> void override; auto GetInputPosition() -> std::size_t override; @@ -37,9 +38,6 @@ class MadMp3Decoder : public ICodec { mad_frame frame_; mad_synth synth_; - mad_header header_; - bool has_decoded_header_; - int current_sample_; }; diff --git a/src/codecs/mad.cpp b/src/codecs/mad.cpp index 2e55d4c6..5044c22f 100644 --- a/src/codecs/mad.cpp +++ b/src/codecs/mad.cpp @@ -8,6 +8,7 @@ #include #include +#include #include "mad.h" @@ -34,31 +35,29 @@ MadMp3Decoder::MadMp3Decoder() { mad_stream_init(&stream_); mad_frame_init(&frame_); mad_synth_init(&synth_); - mad_header_init(&header_); } MadMp3Decoder::~MadMp3Decoder() { mad_stream_finish(&stream_); mad_frame_finish(&frame_); mad_synth_finish(&synth_); - mad_header_finish(&header_); } auto MadMp3Decoder::CanHandleType(StreamType type) -> bool { return type == STREAM_MP3; } -auto MadMp3Decoder::GetOutputFormat() -> OutputFormat { - return OutputFormat{ +auto MadMp3Decoder::GetOutputFormat() -> std::optional { + if (synth_.pcm.channels == 0 || synth_.pcm.samplerate == 0) { + return {}; + } + return std::optional({ .num_channels = static_cast(synth_.pcm.channels), - .bits_per_sample = 16, - .sample_rate_hz = - synth_.pcm.samplerate == 0 ? 44100 : synth_.pcm.samplerate, - }; + .bits_per_sample = 24, + .sample_rate_hz = synth_.pcm.samplerate, + }); } -auto MadMp3Decoder::ResetForNewStream() -> void { - has_decoded_header_ = false; -} +auto MadMp3Decoder::ResetForNewStream() -> void {} auto MadMp3Decoder::SetInput(cpp::span input) -> void { mad_stream_buffer(&stream_, @@ -71,16 +70,6 @@ auto MadMp3Decoder::GetInputPosition() -> std::size_t { } auto MadMp3Decoder::ProcessNextFrame() -> cpp::result { - if (!has_decoded_header_) { - // The header of any given frame should be representative of the - // entire stream, so only need to read it once. - mad_header_decode(&header_, &stream_); - has_decoded_header_ = true; - - // TODO: Use the info in the header for something. I think the - // duration will help with seeking? - } - // Whatever was last synthesized is now invalid, so ensure we don't try to // send it. current_sample_ = -1; @@ -128,7 +117,6 @@ auto MadMp3Decoder::WriteOutputSamples(cpp::span output) for (int channel = 0; channel < synth_.pcm.channels; channel++) { // TODO(jacqueline): output 24 bit samples when (if?) we have a downmix // step in the pipeline. - /* uint32_t sample_24 = scaleToBits(synth_.pcm.samples[channel][current_sample_], 24); output[output_byte++] = static_cast((sample_24 >> 16) & 0xFF); @@ -136,11 +124,12 @@ auto MadMp3Decoder::WriteOutputSamples(cpp::span output) output[output_byte++] = static_cast((sample_24)&0xFF); // 24 bit samples must still be aligned to 32 bits. The LSB is ignored. output[output_byte++] = static_cast(0); - */ + /* uint16_t sample_16 = scaleToBits(synth_.pcm.samples[channel][current_sample_], 16); output[output_byte++] = static_cast((sample_16 >> 8) & 0xFF); output[output_byte++] = static_cast((sample_16)&0xFF); + */ } current_sample_++; } -- cgit v1.2.3