So far I have always used the Arduino loop to do the audio processing with the hint, that there must not be any longer delay added to the processing.
If you have some blocking functions in the loop, the solution is to run the audio in a separate task. I have added some nice concurrency C++ classes to my framework which help that we can keep the sketch quite short.
Arduino Example Sketch
I am using a simple internet streaming sketch as example which is using some long delays in the loop(). The copy of the mp3 data from the url to the decoder is executed in a separate task:
#include "AudioTools.h"
#include "AudioCodecs/CodecMP3Helix.h"
#include "AudioLibs/AudioBoardStream.h"
URLStream url("ssid","password"); // or replace with ICYStream to get metadata
AudioBoardStream i2s(AudioKitEs8388V1); // final output of decoded stream
EncodedAudioStream dec(&i2s, new MP3DecoderHelix()); // Decoding stream
StreamCopy copier(dec, url); // copy url to decoder
Task task("mp3-copy", 10000, 1, 0);
void setup(){
Serial.begin(115200);
AudioLogger::instance().begin(Serial, AudioLogger::Info);
// setup i2s
auto config = i2s.defaultConfig(TX_MODE);
i2s.begin(config);
// setup I2S based on sampling rate provided by decoder
dec.begin();
// mp3 radio
url.begin("http://stream.srg-ssr.ch/m/rsj/mp3_128","audio/mp3");
// start copy task
task.begin([](){copier.copy();});
}
void loop(){
delay(1000);
Serial.println("ping...");
}
The core of the example is the Task class which requires a name, the stack size, the priority and the core.
Usually we would just call copier.copy() in the loop. But in the example we want to do this in a separate task.
In order to start the task we just call begin() by passing a global method or a lambda expression like in the example above.
Here is the output from the Serial Monitor:
22:19:33.534 -> [I] StreamCopy.h : 149 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops
22:19:33.566 -> ping...
22:19:33.598 -> [I] StreamCopy.h : 149 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops
22:19:33.694 -> [I] StreamCopy.h : 149 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops
22:19:33.727 -> [I] StreamCopy.h : 149 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops
22:19:33.790 -> [I] StreamCopy.h : 149 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops
22:19:33.854 -> [I] StreamCopy.h : 149 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops
22:19:33.918 -> [I] StreamCopy.h : 149 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops
22:19:33.982 -> [I] StreamCopy.h : 149 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops
22:19:34.078 -> [I] StreamCopy.h : 149 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops
22:19:34.111 -> [I] StreamCopy.h : 149 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops
22:19:34.175 -> [I] StreamCopy.h : 149 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops
22:19:34.239 -> [I] StreamCopy.h : 149 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops
22:19:34.304 -> [I] StreamCopy.h : 149 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops
22:19:34.368 -> [I] StreamCopy.h : 149 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops
22:19:34.433 -> [I] StreamCopy.h : 149 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops
22:19:34.497 -> [I] StreamCopy.h : 149 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops
22:19:34.561 -> [I] StreamCopy.h : 149 - ping...
22:19:34.561 -> StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops
0 Comments