-
-
Notifications
You must be signed in to change notification settings - Fork 237
Pipelines
Currently it is already possible in the Arduino AudioTools Library to define some processing chains: Audio Objects are connected to other objects e.g. by adding the dependent object as parameter in the constructor.
I2SStream i2s
VolumeStream vol(i2s);
Since the very beginning of the library, I planned to have some Pipeline class that would help to define such chains in a more intuitive way. I finally committed this functionality to the Github:
An output pipeline acts as an audio sink, so you can write data to it. All pipeline processing components are added with the help of the add()
method, finally we define the final output with setOutput()
.
Calling the optional begin()
calls the begin method on all pipeline components which will start them with the default values. Instead of calling begin you can however still start the components individually, the regular way.
Any subclass of ModifyingStream can be used as pipleline component.
Pipeline pipeline;
I2SStream i2s;
VolumeStream volume;
pipeline.add(volume);
pipleine.setOutput(i2s);
pipeline.begin();
Example
Here is a full working example of an internet streaming application, that provides a volume control and outputs the data with 32 bits:
#include "AudioTools.h"
#include "AudioCodecs/CodecMP3Helix.h"
URLStream url("ssid","password");
Pipeline pipeline;
MP3DecoderHelix helix;
EncodedAudioStream dec(&helix);
VolumeStream volume;
NumberFormatConverterStream bits;
I2SStream i2s;
StreamCopy copier(pipeline, url);
void setup(){
Serial.begin(115200);
AudioLogger::instance().begin(Serial, AudioLogger::Warning);
// mp3 radio
url.begin("http://stream.srg-ssr.ch/m/rsj/mp3_128","audio/mp3");
// predefine define some values
volume.setVolume(0.5);
bits.setToBits(32);
// setup pipeline
pipeline.add(dec);
pipeline.add(volume);
pipeline.add(bits);
pipeline.setOutput(i2s);
// start all components with their default values
pipeline.begin();
}
void loop(){
copier.copy();
}
We can just copy the mp3 data into the pipeline!
In input pipeline is an audio source, so you can read data from it. All pipeline processing components are added with the help of the add()
method and we start the chain by defining the input with setInput()
. Calling begin()
calls the begin method on all pipeline components. Any subclass of ModifyingStream can be used a pipeline component.
Pipeline pipeline;
I2SStream i2s;
VolumeStream volume;
pipleine.setInput(i2s);
pipeline.add(volume);
pipeline.begin();
Example
Here is a full working example of an internet streaming application, that provides a volume control and outputs the data with 32 bits:
#include "AudioTools.h"
#include "AudioCodecs/CodecMP3Helix.h"
#include "AudioLibs/AudioBoardStream.h"
URLStream url("ssid","password");
Pipeline pipeline;
MP3DecoderHelix helix;
EncodedAudioStream dec(&helix);
VolumeStream volume;
NumberFormatConverterStream bits;
AudioBoardStream i2s(AudioKitEs8388V1);
StreamCopy copier(i2s, pipeline);
void setup(){
Serial.begin(115200);
AudioLogger::instance().begin(Serial, AudioLogger::Warning);
// start i2s
i2s.begin();
// mp3 radio
url.begin("http://stream.srg-ssr.ch/m/rsj/mp3_128","audio/mp3");
// predefine define some values
volume.setVolume(0.5);
bits.setToBits(32);
// setup pipeline
pipeline.setInput(url);
pipeline.add(dec);
pipeline.add(volume);
pipeline.add(bits);
pipeline.addNotifyAudioChange(i2s);
// start all components with their default values
pipeline.begin();
}
void loop(){
copier.copy();
}
We just copy the pipeline to the i2s output. However we need to start i2s separately because this is not part of the pipeline and thus
we also need to make sure that i2s is informed about format changes: we can do this like in the example above using addNotifyAudioChange()
or we can activate the format change handling in the copier with copier.setSynchAudioInfo(true)
.