arduino-audio-tools
All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Modules Pages
ContainerM4A.h
1#pragma once
2
3#include "AudioTools/AudioCodecs/AudioCodecsBase.h"
4#include "AudioTools/AudioCodecs/M4AAudioDemuxer.h"
5#include "AudioTools/AudioCodecs/MultiDecoder.h"
6
7namespace audio_tools {
8
18 public:
27
34
39 void setOutput(Print& out_stream) override {
40 if (p_decoder != nullptr && p_decoder->getOutput()!=&out_stream) {
41 p_decoder->setOutput(out_stream);
42 }
44 }
45
50 bool isResultPCM() override { return p_decoder != nullptr ? true : false; }
51
56 bool begin() override {
57 demux.begin();
59 is_active = true;
60 return true;
61 }
62
66 void end() override {
67 TRACED();
68 is_active = false;
70 if (p_decoder) p_decoder->end();
71 }
72
79 size_t write(const uint8_t* data, size_t len) override {
80 if (is_active == false) return len;
81 demux.write(data, len);
82 return len;
83 }
84
89 operator bool() override { return is_active; }
107 }
108
114 bool setDecoder(MultiDecoder& decoder) {
115 p_decoder = &decoder;
117 return true;
118 }
119
120 M4AAudioDemuxer& getDemuxer() {
121 return demux;
122 }
123
124 protected:
125 bool is_active = false;
127 false;
130
137 static void decodeAudio(const M4AAudioDemuxer::Frame& frame, void* ref) {
138 ContainerM4A* self = static_cast<ContainerM4A*>(ref);
139 if (self->p_decoder == nullptr) {
140 self->p_print->write(frame.data, frame.size);
141 return;
142 }
143 MultiDecoder& dec = *(self->p_decoder);
144 const char* old_mime = dec.selectedMime();
145
146 // select decoder based on mime type
147 if (!dec.selectDecoder(frame.mime)) {
148 const char* mime = frame.mime ? frame.mime : "(nullptr)";
149 LOGE("No decoder found for mime type: %s", mime);
150 return;
151 }
152
153 // for ALAC only: process magic cookie if not done yet
154 if (StrView(frame.mime) == "audio/alac" &&
156 auto& magic_cookie = self->demux.getALACMagicCookie();
157 if (magic_cookie.size() > 0) {
158 if (!dec.setCodecConfig(magic_cookie.data(), magic_cookie.size())) {
159 LOGE("Failed to set ALAC magic cookie for decoder: %s",
160 dec.selectedMime());
161 }
162 }
163 self->is_magic_cookie_processed = true;
164 }
165 // write encoded data to decoder
166 dec.write(frame.data, frame.size);
167
168 // restore previous decoder
169 dec.selectDecoder(old_mime);
170
171 }
172};
173
174} // namespace audio_tools
virtual void setOutput(AudioStream &out_stream)
Defines where the decoded result is written to.
Definition AudioCodecsBase.h:36
virtual void addNotifyAudioChange(AudioInfoSupport &bi)
Adds target to be notified about audio changes.
Definition AudioTypes.h:151
Shared functionality of all buffers.
Definition Buffers.h:22
Parent class for all container formats.
Definition AudioCodecsBase.h:86
M4A Demuxer that extracts audio from M4A/MP4 containers. The audio is decoded into pcm with the help ...
Definition ContainerM4A.h:17
void setOutput(Print &out_stream) override
Set the output stream for decoded or raw audio.
Definition ContainerM4A.h:39
static void decodeAudio(const M4AAudioDemuxer::Frame &frame, void *ref)
Static callback for demuxed audio frames. Handles decoder selection and magic cookie for ALAC.
Definition ContainerM4A.h:137
ContainerM4A()
Default constructor: If no decoder is provided, the raw audio data is provided to the defined output.
Definition ContainerM4A.h:23
bool is_active
True if demuxer is active.
Definition ContainerM4A.h:125
void end() override
End the demuxer and decoder, releasing resources.
Definition ContainerM4A.h:66
virtual void setChunkOffsetsBuffer(BaseBuffer< uint32_t > &buffer)
Sets the buffer to use for sample sizes. This is currently not used!
Definition ContainerM4A.h:105
size_t write(const uint8_t *data, size_t len) override
Feed data to the demuxer for parsing.
Definition ContainerM4A.h:79
bool setDecoder(MultiDecoder &decoder)
Sets the decoder to use for audio frames.
Definition ContainerM4A.h:114
MultiDecoder * p_decoder
Pointer to the MultiDecoder.
Definition ContainerM4A.h:128
bool is_magic_cookie_processed
True if ALAC magic cookie has been processed.
Definition ContainerM4A.h:126
bool isResultPCM() override
Returns true if the result is PCM (decoder is present).
Definition ContainerM4A.h:50
ContainerM4A(MultiDecoder &decoder)
Constructor with decoder. Sets up the demuxer and decoder notification.
Definition ContainerM4A.h:33
bool begin() override
Initialize the demuxer and decoder.
Definition ContainerM4A.h:56
virtual void setSampleSizesBuffer(BaseBuffer< stsz_sample_size_t > &buffer)
Sets the buffer to use for sample sizes. You can use this to provide a custom buffer that does not re...
Definition ContainerM4A.h:97
M4AAudioDemuxer demux
Internal demuxer instance.
Definition ContainerM4A.h:129
A simple M4A audio data demuxer which is providing AAC, MP3 and ALAC frames.
Definition M4AAudioDemuxer.h:11
Vector< uint8_t > & getALACMagicCookie()
Returns the ALAC magic cookie (codec config).
Definition M4AAudioDemuxer.h:61
bool begin()
Initializes the demuxer and resets state.
Definition M4AAudioDemuxer.h:30
void setReference(void *ref)
Sets a reference pointer for callbacks.
Definition M4AAudioDemuxer.h:67
void write(const uint8_t *data, size_t len)
Writes data to the demuxer for parsing.
Definition M4AAudioDemuxer.h:49
void setCallback(FrameCallback cb) override
Defines the callback that returns the audio frames.
Definition M4AAudioDemuxer.h:22
void setSampleSizesBuffer(BaseBuffer< stsz_sample_size_t > &buffer)
Sets the buffer to use for sample sizes.
Definition M4ACommonDemuxer.h:377
void setChunkOffsetsBuffer(BaseBuffer< uint32_t > &buffer)
Sets the buffer to use for sample sizes.
Definition M4ACommonDemuxer.h:384
Manage multiple decoders: the actual decoder is only opened when it has been selected....
Definition MultiDecoder.h:21
void setOutput(Print &out_stream) override
Defines where the decoded result is written to.
Definition MultiDecoder.h:65
bool setCodecConfig(const uint8_t *data, size_t len) override
Sets the config to the selected decoder.
Definition MultiDecoder.h:149
bool selectDecoder(const char *mime)
Definition MultiDecoder.h:75
void end() override
closes the actual decoder
Definition MultiDecoder.h:40
bool begin() override
Enables the automatic mime type determination.
Definition MultiDecoder.h:29
Definition NoArduino.h:62
A simple wrapper to provide string functions on existing allocated char*. If the underlying char* is ...
Definition StrView.h:28
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
Definition M4ACommonDemuxer.h:27