arduino-audio-tools
All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Modules Pages
MimeDetector.h
1#pragma once
2
3#include "AudioTools/AudioCodecs/HeaderParserAAC.h"
4#include "AudioTools/AudioCodecs/HeaderParserMP3.h"
5#include "AudioTools/CoreAudio/AudioBasic/StrView.h"
6
7namespace audio_tools {
8
24 public:
25 MimeDetector() {
26 setCheck("audio/vnd.wave", checkWAV);
27 setCheck("audio/ogg", checkOGG);
28 setCheck("video/MP2T", checkMP2T);
29 setCheck("audio/prs.sid", checkSID);
30 setCheck("audio/mpeg", checkMP3Ext);
31 setCheck("audio/aac", checkAACExt);
32 }
33
34 bool begin() {
35 is_first = true;
36 return true;
37 }
38
40 size_t write(uint8_t* data, size_t len) {
41 actual_mime = default_mime;
42 determineMime(data, len);
43 return len;
44 }
45
47 void setCheck(const char* mime, bool (*check)(uint8_t* start, size_t len)) {
49 for (int j = 0; j < checks.size(); j++) {
50 Check l_check = checks[j];
51 if (mime_str.equals(l_check.mime)) {
52 l_check.check = check;
53 return;
54 }
55 }
56 Check check_to_add{mime, check};
57 checks.push_back(check_to_add);
58 }
59
60 // /// Define the callback that will notify about mime changes
61 void setMimeCallback(void (*callback)(const char*)) {
62 TRACED();
63 this->notifyMimeCallback = callback;
64 }
65
68 const char* mime() {
69 return actual_mime;
70 }
71
72 static bool checkAAC(uint8_t* start, size_t len) {
73 return start[0] == 0xFF &&
74 (start[1] == 0xF0 || start[1] == 0xF1 || start[1] == 0xF9);
75 }
76
77 static bool checkAACExt(uint8_t* start, size_t len) {
78 // checking logic for files
79 if (memcmp(start+4, "ftypM4A", 7) == 0) {
80 return true;
81 }
82 // check for streaming
83 HeaderParserAAC aac;
84 // it should start with a synch word
85 int pos = aac.findSyncWord((const uint8_t*)start, len);
86 if (pos == -1) {
87 return false;
88 }
89 // make sure that it is not an mp3
90 if (aac.isValid(start+pos, len-pos)) {
91 return false;
92 }
93 return true;
94 }
95
96 static bool checkMP3(uint8_t* start, size_t len) {
97 return memcmp(start, "ID3", 3) == 0 ||
98 (start[0] == 0xFF && ((start[1] & 0xE0) == 0xE0));
99 }
100
101 static bool checkMP3Ext(uint8_t* start, size_t len) {
102 HeaderParserMP3 mp3;
103 return mp3.isValid(start, len);
104 }
105
106 static bool checkWAV(uint8_t* start, size_t len) {
107 return memcmp(start, "RIFF", 4) == 0;
108 }
109
110 static bool checkOGG(uint8_t* start, size_t len) {
111 return memcmp(start, "OggS", 4) == 0;
112 }
113
115 static bool checkMP2T(uint8_t* start, size_t len) {
116 if (len < 189) return start[0] == 0x47;
117
118 return start[0] == 0x47 && start[188] == 0x47;
119 }
120
122 static bool checkSID(uint8_t* start, size_t len) {
123 return memcmp(start, "PSID", 4) == 0 || memcmp(start, "RSID", 4) == 0;
124 }
125
127 void setDefaultMime(const char* mime) { default_mime = mime; }
128
129 protected:
130 struct Check {
131 const char* mime = nullptr;
132 bool (*check)(uint8_t* data, size_t len) = nullptr;
133 Check(const char* mime, bool (*check)(uint8_t* data, size_t len)) {
134 this->mime = mime;
135 this->check = check;
136 }
137 Check() = default;
138 };
139 Vector<Check> checks{0};
140 bool is_first = false;
141 const char* actual_mime = nullptr;
142 const char* default_mime = nullptr;
143 void (*notifyMimeCallback)(const char* mime) = nullptr;
144
146 void determineMime(void* data, size_t len) {
147 if (is_first) {
148 actual_mime = lookupMime((uint8_t*)data, len);
149 if (notifyMimeCallback != nullptr && actual_mime != nullptr) {
150 notifyMimeCallback(actual_mime);
151 }
152 is_first = false;
153 }
154 }
155
157 const char* lookupMime(uint8_t* data, size_t len) {
158 for (int j = 0; j < checks.size(); j++) {
159 Check l_check = checks[j];
160 if (l_check.check(data, len)) {
161 return l_check.mime;
162 }
163 }
164 return default_mime;
165 }
166};
167
168} // namespace audio_tools
Logic to detemine the mime type from the content. By default the following mime types are supported (...
Definition MimeDetector.h:23
static bool checkSID(uint8_t *start, size_t len)
Commodore 64 SID File.
Definition MimeDetector.h:122
void determineMime(void *data, size_t len)
Update the mime type.
Definition MimeDetector.h:146
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
const char * lookupMime(uint8_t *data, size_t len)
Default logic which supports aac, mp3, wav and ogg.
Definition MimeDetector.h:157
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
void setDefaultMime(const char *mime)
Provides the default mime type if no mime could be determined.
Definition MimeDetector.h:127
static bool checkMP2T(uint8_t *start, size_t len)
MPEG-2 TS Byte Stream Format.
Definition MimeDetector.h:115
A simple wrapper to provide string functions on existing allocated char*. If the underlying char* is ...
Definition StrView.h:28
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 AudioConfig.h:885
Definition MimeDetector.h:130