arduino-audio-tools
Loading...
Searching...
No Matches
ICYStreamT.h
1#pragma once
2#include "AudioTools/CoreAudio/AudioHttp/AbstractURLStream.h"
3#include "AudioTools/CoreAudio/AudioMetaData/MetaDataICY.h"
4#include "AudioToolsConfig.h"
5
6namespace audio_tools {
7
41template <class T>
43 public:
44 ICYStreamT(int readBufferSize = DEFAULT_BUFFER_SIZE) {
45 TRACEI();
46 setReadBufferSize(readBufferSize);
47 }
48
50 ICYStreamT(const char* ssid, const char* password,
51 int readBufferSize = DEFAULT_BUFFER_SIZE)
52 : ICYStreamT(readBufferSize) {
53 TRACEI();
54 setSSID(ssid);
55 setPassword(password);
56 }
57
58 ICYStreamT(Client& clientPar, int readBufferSize = DEFAULT_BUFFER_SIZE)
59 : ICYStreamT(readBufferSize) {
60 TRACEI();
61 setClient(clientPar);
62 }
63
65 virtual bool setMetadataCallback(void (*fn)(MetaDataType info,
66 const char* str,
67 int len)) override {
68 TRACED();
69 callback = fn;
70 icy.setCallback(fn);
71 return true;
72 }
73
74 // Performs an HTTP request to the indicated URL with ICY metadata enabled
75 virtual bool begin(const char* urlStr, const char* acceptMime = nullptr,
76 MethodID action = GET, const char* reqMime = "",
77 const char* reqData = "") override {
78 TRACED();
79 // accept metadata
80 addRequestHeader("Icy-MetaData", "1");
81 bool result = url.begin(urlStr, acceptMime, action, reqMime, reqData);
82
83 if (result) {
84 // setup icy
85 ICYUrlSetup icySetup;
86 int iceMetaint = icySetup.setup(*this);
87 // callbacks from http request
88 icySetup.executeCallback(callback);
89 icy.setIcyMetaInt(iceMetaint);
90 icy.begin();
91
92 if (!icy.hasMetaData()) {
93 LOGW("url does not provide metadata");
94 }
95 }
96 return result;
97 }
98
100 virtual void end() override {
101 TRACED();
102 url.end();
103 icy.end();
104 }
105
107 virtual int available() override { return url.available(); }
108
110 virtual size_t readBytes(uint8_t* data, size_t len) override {
111 size_t result = 0;
112 if (icy.hasMetaData()) {
113 // get data
114 int read = url.readBytes(data, len);
115 // remove metadata from data
116 int pos = 0;
117 for (int j = 0; j < read; j++) {
118 icy.processChar(data[j]);
119 if (icy.isData()) {
120 data[pos++] = data[j];
121 }
122 }
123 result = pos;
124 } else {
125 // fast access if there is no metadata
126 result = url.readBytes(data, len);
127 }
128 LOGD("%s: %zu -> %zu", LOG_METHOD, len, result);
129 return result;
130 }
131
132 // Reads a single audio byte, skipping metadata via the MetaDataICY state engine
133 virtual int read() override {
134 int ch = -1;
135
136 // get next data byte
137 do {
138 ch = url.read();
139 if (ch == -1) {
140 break;
141 }
142
143 icy.processChar(ch);
144 } while (!icy.isData());
145 return ch;
146 }
147
149 operator bool() { return url; }
150
151 void setReadBufferSize(int readBufferSize) {
152 url.setReadBufferSize(readBufferSize);
153 }
154
156 void setSSID(const char* ssid) override { url.setSSID(ssid); }
157
159 void setPassword(const char* password) override { url.setPassword(password); }
160
162 void setPowerSave(bool active) { url.setPowerSave(active); }
163
165 void setCACert(const char* cert) { url.setCACert(cert); }
167 void addRequestHeader(const char* key, const char* value) override {
168 url.addRequestHeader(key, value);
169 }
171 const char* getReplyHeader(const char* key) override {
172 return url.getReplyHeader(key);
173 }
174
176 virtual HttpRequest& httpRequest() override { return url.httpRequest(); }
177
179 void setClient(Client& client) override { url.setClient(client); }
180
181 void setConnectionClose(bool flag) override { url.setConnectionClose(flag); }
182 const char* urlStr() override { return url.urlStr(); }
183 size_t totalRead() override { return url.totalRead(); };
184 int contentLength() override { return url.contentLength(); };
185 bool waitForData(int timeout) override { return url.waitForData(timeout); }
186
187 protected:
188 T url;
189 MetaDataICY icy; // icy state machine
190 void (*callback)(MetaDataType info, const char* str, int len) = nullptr;
191};
192
193} // namespace audio_tools
Abstract Base class for all URLStream implementations.
Definition AbstractURLStream.h:17
Definition NoArduino.h:169
Simple API to process get, put, post, del http requests I tried to use Arduino HttpClient,...
Definition HttpRequest.h:25
Icecast/Shoutcast audio stream that separates ICY metadata from audio bytes.
Definition ICYStreamT.h:42
size_t totalRead() override
Total amout of data that was consumed so far.
Definition ICYStreamT.h:183
bool waitForData(int timeout) override
Definition ICYStreamT.h:185
virtual size_t readBytes(uint8_t *data, size_t len) override
Reads audio bytes, stripping out any interleaved ICY metadata.
Definition ICYStreamT.h:110
void setPowerSave(bool active)
If set to true, activates power save mode at the cost of performance (ESP32 only).
Definition ICYStreamT.h:162
void addRequestHeader(const char *key, const char *value) override
Adds/Updates a request header.
Definition ICYStreamT.h:167
void setCACert(const char *cert)
Define the Root PEM certificate for TLS/SSL.
Definition ICYStreamT.h:165
void setSSID(const char *ssid) override
Sets the ssid that will be used for logging in (when calling begin)
Definition ICYStreamT.h:156
const char * urlStr() override
Provides the url as string.
Definition ICYStreamT.h:182
ICYStreamT(const char *ssid, const char *password, int readBufferSize=DEFAULT_BUFFER_SIZE)
Default constructor.
Definition ICYStreamT.h:50
void setConnectionClose(bool flag) override
Add Connection: close to request header.
Definition ICYStreamT.h:181
int contentLength() override
Provides the reported data size from the http reply.
Definition ICYStreamT.h:184
void setClient(Client &client) override
(Re-)defines the client
Definition ICYStreamT.h:179
virtual bool setMetadataCallback(void(*fn)(MetaDataType info, const char *str, int len)) override
Defines the metadata callback function.
Definition ICYStreamT.h:65
void setPassword(const char *password) override
Sets the password that will be used for logging in (when calling begin)
Definition ICYStreamT.h:159
virtual void end() override
Ends the processing.
Definition ICYStreamT.h:100
virtual HttpRequest & httpRequest() override
provides access to the HttpRequest
Definition ICYStreamT.h:176
virtual int available() override
Delegates available() from the underlying stream.
Definition ICYStreamT.h:107
const char * getReplyHeader(const char *key) override
Provides reply header info.
Definition ICYStreamT.h:171
Resolve icy-metaint from HttpRequest and execute metadata callbacks.
Definition MetaDataICY.h:235
int setup(AbstractURLStream &url)
Definition MetaDataICY.h:239
void executeCallback(void(*callback)(MetaDataType info, const char *str, int len))
Definition MetaDataICY.h:255
Icecast/Shoutcast Metadata Handling. Metadata class which splits the data into audio and metadata....
Definition MetaDataICY.h:25
virtual void setCallback(void(*fn)(MetaDataType info, const char *str, int len)) override
Defines the metadata callback function.
Definition MetaDataICY.h:42
virtual void begin() override
Resets all counters and restarts the prcessing.
Definition MetaDataICY.h:57
virtual bool hasMetaData()
Returns true if the ICY stream contains metadata.
Definition MetaDataICY.h:83
virtual void end() override
Resets all counters and restarts the prcessing.
Definition MetaDataICY.h:63
virtual void setIcyMetaInt(int value) override
Defines the ICE metaint value which is provided by the web call!
Definition MetaDataICY.h:37
virtual bool isData()
returns true if the actual bytes is an audio data byte (e.g.mp3)
Definition MetaDataICY.h:80
virtual void processChar(char ch)
character based state engine
Definition MetaDataICY.h:89
MetaDataType
Type of meta info.
Definition AbstractMetaData.h:11
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10