arduino-audio-tools
AudioSource.h
1 #pragma once
2 
3 namespace audio_tools {
4 
12 class AudioSource {
13 public:
15  virtual void begin() = 0;
16 
18  virtual Stream* nextStream(int offset) = 0;
19 
21  virtual Stream* previousStream(int offset) {
22  return nextStream(-offset);
23  };
24 
26  virtual Stream* selectStream(int index) {
27  LOGE("Not Supported!");
28  return nullptr;
29  }
30 
32  virtual Stream* setIndex(int index) {
33  return selectStream(index);
34  }
35 
37  virtual Stream* selectStream(const char* path) = 0;
38 
40  virtual void setTimeoutAutoNext(int millisec) {
41  timeout_auto_next_value = millisec;
42  }
43 
45  virtual int timeoutAutoNext() {
46  return timeout_auto_next_value;
47  }
48 
49  // only the ICYStream supports this
50  virtual bool setMetadataCallback(void (*fn)(MetaDataType info, const char* str, int len), ID3TypeSelection sel=SELECT_ICY) {
51  return false;
52  }
53 
55  virtual void setTimeout(int millisec) {};
56 
58  virtual bool isAutoNext() {return true; }
59 
60 
61 protected:
62  int timeout_auto_next_value = 500;
63 };
64 
72 public:
74  }
75 
76  AudioSourceCallback(Stream* (*nextStreamCallback)(int offset), void (*onStartCallback)() = nullptr) {
77  TRACED();
78  this->onStartCallback = onStartCallback;
79  this->nextStreamCallback = nextStreamCallback;
80  }
81 
83  virtual void begin() override {
84  TRACED();
85  if (onStartCallback != nullptr) onStartCallback();
86  };
87 
89  virtual Stream* nextStream(int offset) override {
90  TRACED();
91  return nextStreamCallback == nullptr ? nullptr : nextStreamCallback(offset);
92  }
93 
95  virtual Stream* selectStream(int index) override {
96  LOGI("selectStream: %d", index);
97  if (indexStreamCallback==nullptr){
98  LOGI("setCallbackSelectStream not provided");
99  if (index>0) {
100  begin();
101  return nextStream(index);
102  } else {
103  // nextStream(0) will return the directory but we need a file
104  return nextStream(1);
105  }
106  }
107  return indexStreamCallback(index);
108  }
110  virtual Stream* selectStream(const char* path) override {
111  this->path = path;
112  return indexStreamCallback == nullptr ? nullptr : indexStreamCallback(-1);
113  };
114 
115  void setCallbackOnStart(void (*callback)()) {
116  onStartCallback = callback;
117  }
118 
119  void setCallbackNextStream(Stream* (*callback)(int offset)) {
120  nextStreamCallback = callback;
121  }
122 
123  void setCallbackSelectStream(Stream* (*callback)(int idx)) {
124  indexStreamCallback = callback;
125  }
126 
127  virtual bool isAutoNext() override {
128  return auto_next;
129  }
130 
131  virtual void setAutoNext(bool a){
132  auto_next = a;
133  }
134 
135  // returns the requested path: relevant when provided idx in callback is -1
136  virtual const char* getPath() {
137  return path;
138  }
139 
140 protected:
141  void (*onStartCallback)() = nullptr;
142  bool auto_next = true;
143  Stream* (*nextStreamCallback)(int offset) = nullptr;
144  Stream* (*indexStreamCallback)(int index) = nullptr;
145  const char*path=nullptr;
146 };
147 
148 #if defined(USE_URL_ARDUINO) && ( defined(ESP32) || defined(ESP8266) )
149 
156 class AudioSourceURL : public AudioSource {
157 public:
158  template<typename T, size_t N>
159  AudioSourceURL(AbstractURLStream& urlStream, T(&urlArray)[N], const char* mime, int startPos = 0) {
160  TRACED();
161  this->actual_stream = &urlStream;
162  this->mime = mime;
163  this->urlArray = urlArray;
164  this->max = N;
165  this->pos = startPos - 1;
166  this->timeout_auto_next_value = 20000;
167  }
168 
170  virtual void begin() override {
171  TRACED();
172  this->pos = 0;
173  }
174 
176  Stream* selectStream(int idx) override {
177  pos = idx;
178  if (pos < 0) {
179  pos = 0;
180  LOGI("url array out of limits: %d -> %d", idx, pos);
181  }
182  if (pos >= size()) {
183  pos = size() - 1;
184  LOGI("url array out of limits: %d -> %d", idx, pos);
185  }
186  LOGI("selectStream: %d/%d -> %s", pos, size() - 1, value(pos));
187  if (started) actual_stream->end();
188  actual_stream->begin(value(pos), mime);
189  started = true;
190  return actual_stream;
191  }
192 
194  Stream* nextStream(int offset) override {
195  pos += offset;
196  if (pos < 0 || pos >= size()) {
197  pos = 0;
198  }
199  LOGI("nextStream: %d/%d -> %s", pos, max-1, value(pos));
200  return selectStream(pos);
201  }
202 
204  Stream* previousStream(int offset) override {
205  pos -= offset;
206  if (pos < 0 || pos >= size()) {
207  pos = size() - 1;
208  }
209  LOGI("previousStream: %d/%d -> %s", pos, size() - 1, value(pos));
210  return selectStream(pos);
211  }
212 
214  Stream* selectStream(const char* path) override {
215  LOGI("selectStream: %s", path);
216  if (started) actual_stream->end();
217  actual_stream->begin(path, mime);
218  started = true;
219  return actual_stream;
220  }
221 
222  int index() {
223  return pos;
224  }
225 
226  const char *toStr() {
227  return value(pos);
228  }
229 
231  void setTimeout(int millisec){
232  actual_stream->setTimeout(millisec);
233  }
234 
235  // provides go not to the next on error
236  virtual bool isAutoNext() {
237  return true;
238  };
239 
240  // only the ICYStream supports this
241  bool setMetadataCallback(void (*fn)(MetaDataType info, const char* str, int len), ID3TypeSelection sel=SELECT_ICY) {
242  TRACEI();
243  return actual_stream->setMetadataCallback(fn);
244  }
245 
246 
247 protected:
248  AbstractURLStream* actual_stream = nullptr;
249  const char** urlArray;
250  int pos = 0;
251  int max = 0;
252  const char* mime = nullptr;
253  bool started = false;
254 
256  AudioSourceURL() = default;
257 
258  virtual const char* value(int pos){
259  return urlArray[pos];
260  }
261 
262  virtual int size(){
263  return max;
264  }
265 
266 };
267 
277 public:
278  template<typename T, size_t N>
279  AudioSourceDynamicURL(AbstractURLStream& urlStream, T(&urlArray)[N], const char* mime, int startPos = 0) {
280  this->actual_stream = &urlStream;
281  this->mime = mime;
282  this->pos = startPos - 1;
283  this->timeout_auto_next_value = 20000;
284  for (int j=0;j<N;j++){
285  addURL(urlArray[j]);
286  }
287  }
288 
289  AudioSourceDynamicURL(AbstractURLStream& urlStream, const char* mime, int startPos = 0) {
290  this->actual_stream = &urlStream;
291  this->mime = mime;
292  this->pos = startPos - 1;
293  this->timeout_auto_next_value = 20000;
294  }
295 
297  void addURL(const char* url){
298  url_vector.push_back(url);
299  }
300 
301  void clear(){
302  url_vector.clear();
303  }
304 
305 protected:
306  Vector<StrExt> url_vector;
307 
308  const char* value(int pos) override {
309  return url_vector[pos].c_str();
310  }
311 
312  int size() override {
313  return url_vector.size();
314  }
315 
316 };
317 
318 
319 #endif
320 
321 }
Abstract Base class for all URLStream implementations.
Definition: AbstractURLStream.h:11
Callback Audio Data Source which is used by the Audio Players.
Definition: AudioSource.h:71
virtual void begin() override
Reset actual stream and move to root.
Definition: AudioSource.h:83
virtual bool isAutoNext() override
Returns default setting go to the next.
Definition: AudioSource.h:127
virtual Stream * selectStream(int index) override
Returns selected audio stream.
Definition: AudioSource.h:95
virtual Stream * selectStream(const char *path) override
Returns audio stream by path.
Definition: AudioSource.h:110
virtual Stream * nextStream(int offset) override
Returns next (with positive index) or previous stream (with negative index)
Definition: AudioSource.h:89
Audio Source which provides the data via the network from an URL. The URLs are stored in an Vector of...
Definition: AudioSource.h:276
void addURL(const char *url)
add a new url: a copy of the string will be stored on the heap
Definition: AudioSource.h:297
Abstract Audio Data Source for the AudioPlayer which is used by the Audio Players.
Definition: AudioSource.h:12
virtual void setTimeoutAutoNext(int millisec)
Sets the timeout which is triggering to move to the next stream. - the default value is 500 ms.
Definition: AudioSource.h:40
virtual void setTimeout(int millisec)
Sets the timeout of Stream in milliseconds.
Definition: AudioSource.h:55
virtual Stream * selectStream(int index)
Returns audio stream at the indicated index (the index is zero based, so the first value is 0!...
Definition: AudioSource.h:26
virtual bool isAutoNext()
Returns default setting go to the next.
Definition: AudioSource.h:58
virtual Stream * selectStream(const char *path)=0
Returns audio stream by path.
virtual void begin()=0
Reset actual stream and move to root.
virtual int timeoutAutoNext()
Provides the timeout which is triggering to move to the next stream.
Definition: AudioSource.h:45
virtual Stream * setIndex(int index)
same as selectStream - I just prefer this name
Definition: AudioSource.h:32
virtual Stream * nextStream(int offset)=0
Returns next audio stream.
virtual Stream * previousStream(int offset)
Returns previous audio stream.
Definition: AudioSource.h:21
Audio Source which provides the data via the network from an URL.
Definition: AudioSource.h:156
Stream * previousStream(int offset) override
Opens the Previous url from the array.
Definition: AudioSource.h:204
Stream * selectStream(int idx) override
Opens the selected url from the array.
Definition: AudioSource.h:176
virtual void begin() override
Setup Wifi URL.
Definition: AudioSource.h:170
virtual bool isAutoNext()
Returns default setting go to the next.
Definition: AudioSource.h:236
Stream * selectStream(const char *path) override
Opens the selected url.
Definition: AudioSource.h:214
void setTimeout(int millisec)
Sets the timeout of the URL Stream in milliseconds.
Definition: AudioSource.h:231
Stream * nextStream(int offset) override
Opens the next url from the array.
Definition: AudioSource.h:194
AudioSourceURL()=default
allow use with empty constructor in subclasses
Definition: NoArduino.h:125
ID3TypeSelection
Enum to filter by type of metadata.
Definition: AbstractMetaData.h:8
MetaDataType
Type of meta info.
Definition: AbstractMetaData.h:11
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition: AnalogAudio.h:10