arduino-audio-tools
All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Modules Pages
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
25template <class T>
27 public:
28 ICYStreamT(int readBufferSize = DEFAULT_BUFFER_SIZE) {
29 TRACEI();
30 setReadBufferSize(readBufferSize);
31 }
32
34 ICYStreamT(const char* ssid, const char* password,
35 int readBufferSize = DEFAULT_BUFFER_SIZE)
36 : ICYStreamT(readBufferSize) {
37 TRACEI();
38 setSSID(ssid);
39 setPassword(password);
40 }
41
42 ICYStreamT(Client& clientPar, int readBufferSize = DEFAULT_BUFFER_SIZE)
43 : ICYStreamT(readBufferSize) {
44 TRACEI();
45 setClient(clientPar);
46 }
47
49 virtual bool setMetadataCallback(void (*fn)(MetaDataType info,
50 const char* str,
51 int len)) override {
52 TRACED();
53 callback = fn;
54 icy.setCallback(fn);
55 return true;
56 }
57
58 // Icy http get request to the indicated url
59 virtual bool begin(const char* urlStr, const char* acceptMime = nullptr,
60 MethodID action = GET, const char* reqMime = "",
61 const char* reqData = "") override {
62 TRACED();
63 // accept metadata
64 addRequestHeader("Icy-MetaData", "1");
65 bool result = url.begin(urlStr, acceptMime, action, reqMime, reqData);
66
67 if (result) {
68 // setup icy
69 ICYUrlSetup icySetup;
70 int iceMetaint = icySetup.setup(*this);
71 // callbacks from http request
72 icySetup.executeCallback(callback);
73 icy.setIcyMetaInt(iceMetaint);
74 icy.begin();
75
76 if (!icy.hasMetaData()) {
77 LOGW("url does not provide metadata");
78 }
79 }
80 return result;
81 }
82
84 virtual void end() override {
85 TRACED();
86 url.end();
87 icy.end();
88 }
89
91 virtual int available() override { return url.available(); }
92
94 virtual size_t readBytes(uint8_t* data, size_t len) override {
95 size_t result = 0;
96 if (icy.hasMetaData()) {
97 // get data
98 int read = url.readBytes(data, len);
99 // remove metadata from data
100 int pos = 0;
101 for (int j = 0; j < read; j++) {
102 icy.processChar(data[j]);
103 if (icy.isData()) {
104 data[pos++] = data[j];
105 }
106 }
107 result = pos;
108 } else {
109 // fast access if there is no metadata
110 result = url.readBytes(data, len);
111 }
112 LOGD("%s: %zu -> %zu", LOG_METHOD, len, result);
113 return result;
114 }
115
116 // Read character and processes using the MetaDataICY state engine
117 virtual int read() override {
118 int ch = -1;
119
120 // get next data byte
121 do {
122 ch = url.read();
123 if (ch == -1) {
124 break;
125 }
126
127 icy.processChar(ch);
128 } while (!icy.isData());
129 return ch;
130 }
131
132 operator bool() { return url; }
133
134 void setReadBufferSize(int readBufferSize) {
135 url.setReadBufferSize(readBufferSize);
136 }
137
139 void setSSID(const char* ssid) override { url.setSSID(ssid); }
140
142 void setPassword(const char* password) override { url.setPassword(password); }
143
146 void setPowerSave(bool active) { url.setPowerSave(active); }
147
149 void setCACert(const char* cert) { url.setCACert(cert); }
151 void addRequestHeader(const char* key, const char* value) override {
152 url.addRequestHeader(key, value);
153 }
155 const char* getReplyHeader(const char* key) override {
156 return url.getReplyHeader(key);
157 }
158
160 virtual HttpRequest& httpRequest() override { return url.httpRequest(); }
161
163 void setClient(Client& client) override { url.setClient(client); }
164
165 void setConnectionClose(bool flag) override { url.setConnectionClose(flag); }
166 const char* urlStr() override { return url.urlStr(); }
167 size_t totalRead() override { return url.totalRead(); };
168 int contentLength() override { return url.contentLength(); };
169 bool waitForData(int timeout) override { return url.waitForData(timeout); }
170
171 protected:
172 T url;
173 MetaDataICY icy; // icy state machine
174 void (*callback)(MetaDataType info, const char* str, int len) = nullptr;
175};
176
177} // 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 which splits the data into metadata and audio data....
Definition ICYStreamT.h:26
size_t totalRead() override
Total amout of data that was consumed so far.
Definition ICYStreamT.h:167
bool waitForData(int timeout) override
Definition ICYStreamT.h:169
virtual size_t readBytes(uint8_t *data, size_t len) override
reads the audio bytes
Definition ICYStreamT.h:94
void setPowerSave(bool active)
Definition ICYStreamT.h:146
void addRequestHeader(const char *key, const char *value) override
Adds/Updates a request header.
Definition ICYStreamT.h:151
void setCACert(const char *cert)
Define the Root PEM Certificate for SSL:
Definition ICYStreamT.h:149
void setSSID(const char *ssid) override
Sets the ssid that will be used for logging in (when calling begin)
Definition ICYStreamT.h:139
const char * urlStr() override
Provides the url as string.
Definition ICYStreamT.h:166
ICYStreamT(const char *ssid, const char *password, int readBufferSize=DEFAULT_BUFFER_SIZE)
Default constructor.
Definition ICYStreamT.h:34
void setConnectionClose(bool flag) override
Add Connection: close to request header.
Definition ICYStreamT.h:165
int contentLength() override
Provides the reported data size from the http reply.
Definition ICYStreamT.h:168
void setClient(Client &client) override
(Re-)defines the client
Definition ICYStreamT.h:163
virtual bool setMetadataCallback(void(*fn)(MetaDataType info, const char *str, int len)) override
Defines the meta data callback function.
Definition ICYStreamT.h:49
void setPassword(const char *password) override
Sets the password that will be used for logging in (when calling begin)
Definition ICYStreamT.h:142
virtual void end() override
Ends the processing.
Definition ICYStreamT.h:84
virtual HttpRequest & httpRequest() override
provides access to the HttpRequest
Definition ICYStreamT.h:160
virtual int available() override
provides the available method from the URLStream
Definition ICYStreamT.h:91
const char * getReplyHeader(const char *key) override
Provides reply header info.
Definition ICYStreamT.h:155
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