arduino-audio-tools
AudioSource.h
1 #pragma once
2 #include "AudioTools/CoreAudio/AudioBasic/Str.h"
3 
4 namespace audio_tools {
5 
13 class AudioSource {
14 public:
16  virtual void begin() = 0;
17 
19  virtual Stream* nextStream(int offset) = 0;
20 
22  virtual Stream* previousStream(int offset) {
23  return nextStream(-offset);
24  };
25 
27  virtual Stream* selectStream(int index) {
28  LOGE("Not Supported!");
29  return nullptr;
30  }
31 
33  virtual Stream* setIndex(int index) {
34  return selectStream(index);
35  }
36 
38  virtual Stream* selectStream(const char* path) = 0;
39 
41  virtual void setTimeoutAutoNext(int millisec) {
42  timeout_auto_next_value = millisec;
43  }
44 
46  virtual int timeoutAutoNext() {
47  return timeout_auto_next_value;
48  }
49 
50  // only the ICYStream supports this
51  virtual bool setMetadataCallback(void (*fn)(MetaDataType info, const char* str, int len), ID3TypeSelection sel=SELECT_ICY) {
52  return false;
53  }
54 
56  virtual void setTimeout(int millisec) {};
57 
59  virtual bool isAutoNext() {return true; }
60 
62  Stream* operator[](int idx){
63  return setIndex(idx);
64  }
65 
66 
67 protected:
68  int timeout_auto_next_value = 500;
69 };
70 
78 public:
80  }
81 
82  AudioSourceCallback(Stream* (*nextStreamCallback)(int offset), void (*onStartCallback)() = nullptr) {
83  TRACED();
84  this->onStartCallback = onStartCallback;
85  this->nextStreamCallback = nextStreamCallback;
86  }
87 
89  virtual void begin() override {
90  TRACED();
91  if (onStartCallback != nullptr) onStartCallback();
92  };
93 
95  virtual Stream* nextStream(int offset) override {
96  TRACED();
97  return nextStreamCallback == nullptr ? nullptr : nextStreamCallback(offset);
98  }
99 
101  virtual Stream* selectStream(int index) override {
102  LOGI("selectStream: %d", index);
103  if (indexStreamCallback==nullptr){
104  LOGI("setCallbackSelectStream not provided");
105  if (index>0) {
106  begin();
107  return nextStream(index);
108  } else {
109  // nextStream(0) will return the directory but we need a file
110  return nextStream(1);
111  }
112  }
113  return indexStreamCallback(index);
114  }
116  virtual Stream* selectStream(const char* path) override {
117  this->path = path;
118  return indexStreamCallback == nullptr ? nullptr : indexStreamCallback(-1);
119  };
120 
121  void setCallbackOnStart(void (*callback)()) {
122  onStartCallback = callback;
123  }
124 
125  void setCallbackNextStream(Stream* (*callback)(int offset)) {
126  nextStreamCallback = callback;
127  }
128 
129  void setCallbackSelectStream(Stream* (*callback)(int idx)) {
130  indexStreamCallback = callback;
131  }
132 
133  virtual bool isAutoNext() override {
134  return auto_next;
135  }
136 
137  virtual void setAutoNext(bool a){
138  auto_next = a;
139  }
140 
141  // returns the requested path: relevant when provided idx in callback is -1
142  virtual const char* getPath() {
143  return path;
144  }
145 
146 protected:
147  void (*onStartCallback)() = nullptr;
148  bool auto_next = true;
149  Stream* (*nextStreamCallback)(int offset) = nullptr;
150  Stream* (*indexStreamCallback)(int index) = nullptr;
151  const char*path=nullptr;
152 };
153 
154 #if defined(USE_URL_ARDUINO) && ( defined(ESP32) || defined(ESP8266) )
155 
162 class AudioSourceURL : public AudioSource {
163 public:
164  template<typename T, size_t N>
165  AudioSourceURL(AbstractURLStream& urlStream, T(&urlArray)[N], const char* mime, int startPos = 0) {
166  TRACED();
167  this->actual_stream = &urlStream;
168  this->mime = mime;
169  this->urlArray = urlArray;
170  this->max = N;
171  this->pos = startPos - 1;
172  this->timeout_auto_next_value = 20000;
173  }
174 
176  virtual void begin() override {
177  TRACED();
178  this->pos = 0;
179  }
180 
182  Stream* selectStream(int idx) override {
183  pos = idx;
184  if (pos < 0) {
185  pos = 0;
186  LOGI("url array out of limits: %d -> %d", idx, pos);
187  }
188  if (pos >= size()) {
189  pos = size() - 1;
190  LOGI("url array out of limits: %d -> %d", idx, pos);
191  }
192  LOGI("selectStream: %d/%d -> %s", pos, size() - 1, value(pos));
193  if (started) actual_stream->end();
194  actual_stream->begin(value(pos), mime);
195  started = true;
196  return actual_stream;
197  }
198 
200  Stream* nextStream(int offset) override {
201  pos += offset;
202  if (pos < 0 || pos >= size()) {
203  pos = 0;
204  }
205  LOGI("nextStream: %d/%d -> %s", pos, max-1, value(pos));
206  return selectStream(pos);
207  }
208 
210  Stream* previousStream(int offset) override {
211  pos -= offset;
212  if (pos < 0 || pos >= size()) {
213  pos = size() - 1;
214  }
215  LOGI("previousStream: %d/%d -> %s", pos, size() - 1, value(pos));
216  return selectStream(pos);
217  }
218 
220  Stream* selectStream(const char* path) override {
221  LOGI("selectStream: %s", path);
222  if (started) actual_stream->end();
223  actual_stream->begin(path, mime);
224  started = true;
225  return actual_stream;
226  }
227 
228  int index() {
229  return pos;
230  }
231 
232  const char *toStr() {
233  return value(pos);
234  }
235 
237  void setTimeout(int millisec){
238  actual_stream->setTimeout(millisec);
239  }
240 
241  // provides go not to the next on error
242  virtual bool isAutoNext() {
243  return true;
244  };
245 
246  // only the ICYStream supports this
247  bool setMetadataCallback(void (*fn)(MetaDataType info, const char* str, int len), ID3TypeSelection sel=SELECT_ICY) {
248  TRACEI();
249  return actual_stream->setMetadataCallback(fn);
250  }
251 
252 
253 protected:
254  AbstractURLStream* actual_stream = nullptr;
255  const char** urlArray = nullptr;
256  int pos = 0;
257  int max = 0;
258  const char* mime = nullptr;
259  bool started = false;
260 
262  AudioSourceURL() = default;
263 
264  virtual const char* value(int pos){
265  if (urlArray==nullptr) return nullptr;
266  return urlArray[pos];
267  }
268 
269  virtual int size(){
270  return max;
271  }
272 
273 };
274 
284 public:
285  template<typename T, size_t N>
286  AudioSourceDynamicURL(AbstractURLStream& urlStream, T(&urlArray)[N], const char* mime, int startPos = 0) {
287  this->actual_stream = &urlStream;
288  this->mime = mime;
289  this->pos = startPos - 1;
290  this->timeout_auto_next_value = 20000;
291  for (int j=0;j<N;j++){
292  addURL(urlArray[j]);
293  }
294  }
295 
296  AudioSourceDynamicURL(AbstractURLStream& urlStream, const char* mime, int startPos = 0) {
297  this->actual_stream = &urlStream;
298  this->mime = mime;
299  this->pos = startPos - 1;
300  this->timeout_auto_next_value = 20000;
301  }
302 
304  void addURL(const char* url){
305  url_vector.push_back(url);
306  }
307 
308  void clear(){
309  url_vector.clear();
310  }
311 
312 protected:
313  Vector<Str> url_vector;
314 
315  const char* value(int pos) override {
316  return url_vector[pos].c_str();
317  }
318 
319  int size() override {
320  return url_vector.size();
321  }
322 
323 };
324 
325 
326 #endif
327 
328 }
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:77
virtual void begin() override
Reset actual stream and move to root.
Definition: AudioSource.h:89
virtual bool isAutoNext() override
Returns default setting go to the next.
Definition: AudioSource.h:133
virtual Stream * selectStream(int index) override
Returns selected audio stream.
Definition: AudioSource.h:101
virtual Stream * selectStream(const char *path) override
Returns audio stream by path.
Definition: AudioSource.h:116
virtual Stream * nextStream(int offset) override
Returns next (with positive index) or previous stream (with negative index)
Definition: AudioSource.h:95
Audio Source which provides the data via the network from an URL. The URLs are stored in an Vector of...
Definition: AudioSource.h:283
void addURL(const char *url)
add a new url: a copy of the string will be stored on the heap
Definition: AudioSource.h:304
Abstract Audio Data Source for the AudioPlayer which is used by the Audio Players.
Definition: AudioSource.h:13
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:41
virtual void setTimeout(int millisec)
Sets the timeout of Stream in milliseconds.
Definition: AudioSource.h:56
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:27
virtual bool isAutoNext()
Returns default setting go to the next.
Definition: AudioSource.h:59
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:46
virtual Stream * setIndex(int index)
same as selectStream - I just prefer this name
Definition: AudioSource.h:33
virtual Stream * nextStream(int offset)=0
Returns next audio stream.
virtual Stream * previousStream(int offset)
Returns previous audio stream.
Definition: AudioSource.h:22
Stream * operator[](int idx)
access with array syntax
Definition: AudioSource.h:62
Audio Source which provides the data via the network from an URL.
Definition: AudioSource.h:162
Stream * previousStream(int offset) override
Opens the Previous url from the array.
Definition: AudioSource.h:210
Stream * selectStream(int idx) override
Opens the selected url from the array.
Definition: AudioSource.h:182
virtual void begin() override
Setup Wifi URL.
Definition: AudioSource.h:176
virtual bool isAutoNext()
Returns default setting go to the next.
Definition: AudioSource.h:242
Stream * selectStream(const char *path) override
Opens the selected url.
Definition: AudioSource.h:220
void setTimeout(int millisec)
Sets the timeout of the URL Stream in milliseconds.
Definition: AudioSource.h:237
Stream * nextStream(int offset) override
Opens the next url from the array.
Definition: AudioSource.h:200
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: AudioConfig.h:823