arduino-audio-tools
All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Modules Pages
MultiDecoder.h
1
2#pragma once
3
4#include "AudioTools/AudioCodecs/AudioCodecsBase.h"
5#include "AudioTools/CoreAudio/AudioBasic/StrView.h"
6#include "AudioTools/CoreAudio/AudioMetaData/MimeDetector.h"
7
8namespace audio_tools {
9
20class MultiDecoder : public AudioDecoder {
21 public:
23 MultiDecoder() = default;
26
28 bool begin() override {
29 mime_detector.begin();
30 is_first = true;
31 return true;
32 }
33
35 void end() override {
36 if (actual_decoder.decoder != nullptr && actual_decoder.is_open) {
37 actual_decoder.decoder->end();
38 }
39 actual_decoder.is_open = false;
40 actual_decoder.decoder = nullptr;
41 actual_decoder.mime = nullptr;
42 is_first = true;
43 }
44
46 void addDecoder(AudioDecoder& decoder, const char* mime) {
47 DecoderInfo info{mime, &decoder};
48 decoder.addNotifyAudioChange(*this);
49 decoders.push_back(info);
50 }
51
54 void addDecoder(AudioDecoder& decoder, const char* mime,
55 bool (*check)(uint8_t* data, size_t len)) {
56 addDecoder(decoder, mime);
57 mime_detector.setCheck(mime, check);
58 }
59
60 virtual void setOutput(Print& out_stream) override {
61 p_print = &out_stream;
62 for (int j = 0; j < decoders.size(); j++) {
63 decoders[j].decoder->setOutput(out_stream);
64 }
65 }
66
68 void setMimeSource(AbstractURLStream& url) { p_url_stream = &url; }
69
72 bool selectDecoder(const char* mime) {
73 bool result = false;
74 // do nothing if no change
75 if (StrView(mime).equals(actual_decoder.mime)) {
76 is_first = false;
77 return true;
78 }
79 // close actual decoder
80 end();
81
82 // find the corresponding decoder
83 for (int j = 0; j < decoders.size(); j++) {
84 DecoderInfo info = decoders[j];
85 if (StrView(info.mime).equals(mime)) {
86 LOGI("New decoder found for %s (%s)", info.mime, mime);
87 actual_decoder = info;
88 // define output if it has not been defined
89 if (p_print != nullptr &&
90 actual_decoder.decoder->getOutput() == nullptr) {
91 actual_decoder.decoder->setOutput(*p_print);
92 }
93 actual_decoder.decoder->begin();
94 result = true;
95 }
96 }
97 is_first = false;
98 return result;
99 }
100
101 size_t write(const uint8_t* data, size_t len) override {
102 if (is_first) {
103 const char* mime = nullptr;
104 if (p_url_stream != nullptr) {
105 // get content type from http header
106 mime = p_url_stream->getReplyHeader(CONTENT_TYPE);
107 if (mime) LOGI("mime from http request: %s", mime);
108 }
109 if (mime == nullptr) {
110 // use the mime detector
111 mime_detector.write((uint8_t*)data, len);
112 mime = mime_detector.mime();
113 if (mime) LOGI("mime from mime_detector: %s", mime);
114 }
115 if (mime != nullptr) {
116 // select the decoder based on the detemined mime type
117 if (!selectDecoder(mime)) {
118 LOGE("The decoder could not be found for %s", mime);
119 actual_decoder.decoder = &nop;
120 actual_decoder.is_open = true;
121 }
122 }
123 is_first = false;
124 }
125 // check if we have a decoder
126 if (actual_decoder.decoder == nullptr) return 0;
127 // decode the data
128 return actual_decoder.decoder->write(data, len);
129 }
130
131 virtual operator bool() {
132 if (actual_decoder.decoder == &nop) return false;
133 return is_first || actual_decoder.is_open;
134 };
135
136 protected:
137 struct DecoderInfo {
138 const char* mime = nullptr;
139 AudioDecoder* decoder = nullptr;
140 bool is_open = false;
141 DecoderInfo() = default;
142 DecoderInfo(const char* mime, AudioDecoder* decoder) {
143 this->mime = mime;
144 this->decoder = decoder;
145 }
146 } actual_decoder;
147 Vector<DecoderInfo> decoders{0};
148 MimeDetector mime_detector;
149 CodecNOP nop;
150 AbstractURLStream* p_url_stream = nullptr;
151 bool is_first = true;
152};
153
154} // namespace audio_tools
Abstract Base class for all URLStream implementations.
Definition AbstractURLStream.h:17
virtual const char * getReplyHeader(const char *header)=0
Provides reply header information.
Decoding of encoded audio into PCM data.
Definition AudioCodecsBase.h:18
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
Dummy no implmentation Codec. This is used so that we can initialize some pointers to decoders and en...
Definition AudioCodecsBase.h:124
Logic to detemine the mime type from the content. By default the following mime types are supported (...
Definition MimeDetector.h:23
void setCheck(const char *mime, bool(*check)(uint8_t *start, size_t len))
adds/updates the checking logic for the indicated mime
Definition MimeDetector.h:47
size_t write(uint8_t *data, size_t len)
write the header to determine the mime
Definition MimeDetector.h:40
const char * mime()
Definition MimeDetector.h:68
Manage multiple decoders: the actual decoder is only opened when it has been selected....
Definition MultiDecoder.h:20
MultiDecoder()=default
Default constructor.
bool selectDecoder(const char *mime)
Definition MultiDecoder.h:72
void addDecoder(AudioDecoder &decoder, const char *mime, bool(*check)(uint8_t *data, size_t len))
Definition MultiDecoder.h:54
void setMimeSource(AbstractURLStream &url)
Defines url stream from which we determine the mime type from the reply header.
Definition MultiDecoder.h:68
void end() override
closes the actual decoder
Definition MultiDecoder.h:35
void addDecoder(AudioDecoder &decoder, const char *mime)
Adds a decoder that will be selected by it's mime type.
Definition MultiDecoder.h:46
MultiDecoder(AbstractURLStream &url)
Provides a URLStream to look up the mime type from the http reply header.
Definition MultiDecoder.h:25
bool begin() override
Enables the automatic mime type determination.
Definition MultiDecoder.h:28
virtual void setOutput(Print &out_stream) override
Defines where the decoded result is written to.
Definition MultiDecoder.h:60
Definition NoArduino.h:62
A simple wrapper to provide string functions on existing allocated char*. If the underlying char* is ...
Definition StrView.h:28
virtual bool equals(const char *str)
checks if the string equals indicated parameter string
Definition StrView.h:165
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
Definition MultiDecoder.h:137