arduino-audio-tools
ICYStream.h
1 #pragma once
2 #ifdef USE_URL_ARDUINO
3 
4 #include "AudioConfig.h"
5 #include "URLStreamBuffered.h"
6 #include "AudioTools/CoreAudio/AudioMetaData/MetaDataICY.h"
7 
8 namespace audio_tools {
9 
22 class ICYStream : public AbstractURLStream {
23  public:
24  ICYStream(int readBufferSize = DEFAULT_BUFFER_SIZE) {
25  TRACEI();
26  setReadBufferSize(readBufferSize);
27  }
28 
29  ICYStream(Client& clientPar, int readBufferSize = DEFAULT_BUFFER_SIZE) {
30  TRACEI();
31  setReadBufferSize(readBufferSize);
32  setClient(clientPar);
33  }
34 
36  ICYStream(const char* network, const char* password,
37  int readBufferSize = DEFAULT_BUFFER_SIZE) {
38  TRACEI();
39  setReadBufferSize(readBufferSize);
40  setSSID(network);
41  setPassword(password);
42  }
43 
45  virtual bool setMetadataCallback(void (*fn)(MetaDataType info,
46  const char* str,
47  int len)) override {
48  TRACED();
49  callback = fn;
50  icy.setCallback(fn);
51  return true;
52  }
53 
54  // Icy http get request to the indicated url
55  virtual bool begin(const char* urlStr, const char* acceptMime = nullptr,
56  MethodID action = GET, const char* reqMime = "",
57  const char* reqData = "") override {
58  TRACED();
59  // accept metadata
60  url.httpRequest().header().put("Icy-MetaData", "1");
61  bool result = url.begin(urlStr, acceptMime, action, reqMime, reqData);
62 
63  if (result) {
64  // setup icy
65  ICYUrlSetup icySetup;
66  int iceMetaint = icySetup.setup(url.httpRequest());
67  // callbacks from http request
68  icySetup.executeCallback(callback);
69  icy.setIcyMetaInt(iceMetaint);
70  icy.begin();
71 
72  if (!icy.hasMetaData()) {
73  LOGW("url does not provide metadata");
74  }
75  }
76  return result;
77  }
78 
80  virtual void end() override {
81  TRACED();
82  url.end();
83  icy.end();
84  }
85 
87  virtual int available() override { return url.available(); }
88 
90  virtual size_t readBytes(uint8_t* data, size_t len) override {
91  size_t result = 0;
92  if (icy.hasMetaData()) {
93  // get data
94  int read = url.readBytes(data, len);
95  // remove metadata from data
96  int pos = 0;
97  for (int j = 0; j < read; j++) {
98  icy.processChar(data[j]);
99  if (icy.isData()) {
100  data[pos++] = data[j];
101  }
102  }
103  result = pos;
104  } else {
105  // fast access if there is no metadata
106  result = url.readBytes(data, len);
107  }
108  LOGD("%s: %zu -> %zu", LOG_METHOD, len, result);
109  return result;
110  }
111 
112  // Read character and processes using the MetaDataICY state engine
113  virtual int read() override {
114  int ch = -1;
115 
116  // get next data byte
117  do {
118  ch = url.read();
119  if (ch == -1) {
120  break;
121  }
122 
123  icy.processChar(ch);
124  } while (!icy.isData());
125  return ch;
126  }
127 
128  operator bool() { return url; }
129 
131  virtual HttpRequest& httpRequest() override { return url.httpRequest(); }
132 
133  void setReadBufferSize(int readBufferSize) {
134  url.setReadBufferSize(readBufferSize);
135  }
136 
138  void setClient(Client& client) override { url.setClient(client); }
139 
141  void setSSID(const char* ssid) override { url.setSSID(ssid); }
142 
144  void setPassword(const char* password) override { url.setPassword(password); }
145 
148  void setPowerSave(bool active) { url.setPowerSave(active);}
149 
150  protected:
151  URLStream url;
152  MetaDataICY icy; // icy state machine
153  void (*callback)(MetaDataType info, const char* str, int len) = nullptr;
154 };
155 
156 } // namespace audio_tools
157 #endif
Abstract Base class for all URLStream implementations.
Definition: AbstractURLStream.h:11
Definition: NoArduino.h:139
Simple API to process get, put, post, del http requests I tried to use Arduino HttpClient,...
Definition: HttpRequest.h:26
virtual HttpRequestHeader & header()
provides access to the request header
Definition: HttpRequest.h:161
Icecast/Shoutcast Audio Stream which splits the data into metadata and audio data....
Definition: ICYStream.h:22
virtual HttpRequest & httpRequest() override
provides access to the HttpRequest
Definition: ICYStream.h:131
virtual size_t readBytes(uint8_t *data, size_t len) override
reads the audio bytes
Definition: ICYStream.h:90
void setPowerSave(bool active)
Definition: ICYStream.h:148
ICYStream(const char *network, const char *password, int readBufferSize=DEFAULT_BUFFER_SIZE)
Default constructor.
Definition: ICYStream.h:36
void setSSID(const char *ssid) override
Sets the ssid that will be used for logging in (when calling begin)
Definition: ICYStream.h:141
void setClient(Client &client) override
(Re-)defines the client
Definition: ICYStream.h:138
virtual bool setMetadataCallback(void(*fn)(MetaDataType info, const char *str, int len)) override
Defines the meta data callback function.
Definition: ICYStream.h:45
void setPassword(const char *password) override
Sets the password that will be used for logging in (when calling begin)
Definition: ICYStream.h:144
virtual void end() override
Ends the processing.
Definition: ICYStream.h:80
virtual int available() override
provides the available method from the URLStream
Definition: ICYStream.h:87
Resolve icy-metaint from HttpRequest and execute metadata callbacks.
Definition: MetaDataICY.h:259
int setup(HttpRequest &http)
Fills the metaint from the Http Request and executes metadata callbacks on http reply parameters.
Definition: MetaDataICY.h:262
void executeCallback(void(*callback)(MetaDataType info, const char *str, int len))
Executes the metadata callbacks with data provided from the http request result parameter.
Definition: MetaDataICY.h:277
Icecast/Shoutcast Metadata Handling. Metadata class which splits the data into audio and metadata....
Definition: MetaDataICY.h:26
virtual void setCallback(void(*fn)(MetaDataType info, const char *str, int len)) override
Defines the metadata callback function.
Definition: MetaDataICY.h:48
virtual void begin() override
Resets all counters and restarts the prcessing.
Definition: MetaDataICY.h:61
virtual bool hasMetaData()
Returns true if the ICY stream contains metadata.
Definition: MetaDataICY.h:92
virtual void end() override
Resets all counters and restarts the prcessing.
Definition: MetaDataICY.h:67
virtual void setIcyMetaInt(int value) override
Defines the ICE metaint value which is provided by the web call!
Definition: MetaDataICY.h:43
virtual bool isData()
returns true if the actual bytes is an audio data byte (e.g.mp3)
Definition: MetaDataICY.h:87
virtual void processChar(char ch)
character based state engine
Definition: MetaDataICY.h:102
Represents the content of a URL as Stream. We use the WiFi.h API.
Definition: URLStream.h:26
virtual HttpRequest & httpRequest() override
provides access to the HttpRequest
Definition: URLStream.h:185
virtual bool begin(const char *urlStr, const char *acceptMime=nullptr, MethodID action=GET, const char *reqMime="", const char *reqData="") override
Execute http request: by default we use a GET request.
Definition: URLStream.h:80
void setPowerSave(bool ps)
Definition: URLStream.h:194
void setSSID(const char *ssid) override
Sets the ssid that will be used for logging in (when calling begin)
Definition: URLStream.h:70
void setClient(Client &clientPar) override
(Re-)defines the client
Definition: URLStream.h:67
void setPassword(const char *password) override
Sets the password that will be used for logging in (when calling begin)
Definition: URLStream.h:73
MetaDataType
Type of meta info.
Definition: AbstractMetaData.h:11
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition: AudioConfig.h:823