arduino-audio-tools: a Stream-based audio library for microcontrollers and the desktop
Audio Tools (a powerful Audio library for Microcontrollers and the Desktop)
At a glance
- What is it?
- arduino-audio-tools turns audio processing into the same Stream pattern Arduino developers already use for Serial and files. It is header-only C++ glue, useful when you need to move PCM between a microphone, a decoder and an I2S amplifier without writing your own buffer plumbing.
- Who is it for?
- Adopt arduino-audio-tools if you are building an ESP32 or similar microcontroller device that has to read audio from one place, optionally decode or process it, and write it to another, and you want that wiring to look like Arduino Stream code. Do not adopt it if you need a permissively licensed library for a closed product, or if your audio pipeline is a single fixed codec path that a smaller library already covers.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 6 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem arduino-audio-tools actually solves
Audio on a microcontroller is mostly plumbing. A microphone produces samples in one format, a decoder produces them in another, an I2S peripheral wants them in a third, and somewhere in between you need buffering, sample-rate handling and a place to put the result. Most projects end up writing that plumbing by hand, once per combination of hardware.
arduino-audio-tools replaces that work with a set of header-only C++ classes that follow the Arduino Stream convention. The README describes the library as "the glue which makes different audio processing components and libraries work together", and that is the honest framing. It is not a codec in itself, and it is not a board support package. It is the layer that lets a decoder, a filter and an output device be connected in a few lines.
The intended audience is people already comfortable with Arduino sketches who now need real audio: an ESP32 streaming a file to an I2S DAC, a device that sends audio over the network, a desktop build of the same sketch. The library also builds as a CMake C++ library, and the README links to a wiki page about running an audio sketch on Linux, Windows and OS/X, so the same source can be exercised off-device.
How the Stream model moves samples through the library
Everything in the library is a stream. An Audio Source is something you read from, an Audio Sink is something you write to, and most concrete classes are one or the other. Decoders and encoders sit in the middle: the README points to an EncodedAudioStream that wraps a decoder or encoder for formats such as MP3, AAC, WAV and FLAC.
Connecting two streams is done with a copier. The example in the README creates a MemoryStream over a byte array, an I2SStream for output, and a StreamCopy that pulls from one and pushes to the other. Each stream has a configuration object passed to begin(), and defaultConfig() supplies values that the README says will usually "just work".
The same shape covers effects, filters, converters, buffers and generated tones. An AudioEffectStream wraps effect implementations such as Boost, Distortion, Echo and Reverb; a FilteredStream wraps filters; a ConverterStream wraps format converters; a QueueStream wraps buffer implementations. Because they all present the same read and write interface, a chain can be assembled by nesting them, and swapping the final stage changes the hardware without touching the rest of the sketch. The README makes this explicit: replacing I2SStream with AnalogAudioStream gives analog output instead of digital.
Installing arduino-audio-tools and streaming a file to I2S
The library is distributed as an Arduino library and as a CMake C++ library. The repository carries a library.properties file at the top level, which is the manifest the Arduino IDE reads, so the normal route is the Arduino Library Manager or a manual install into your sketchbook libraries folder. The README does not spell out a single install command, so check the Library Manager entry or the repository itself for the current package.
For a CMake or desktop build, the top-level CMakeLists.txt is the entry point, and the examples directory contains an examples-desktop folder alongside the board-specific ones. The README links to a wiki page titled Running an Audio Sketch on the Desktop for that path.
Once installed, the smallest real use is the README example: stream a file held in flash memory to I2S. Note the includes and the three configuration values.
#include "AudioTools.h"
#include "StarWars30.h"
uint8_t channels = 2;
uint16_t sample_rate = 22050;
uint8_t bits_per_sample = 16;
MemoryStream music(StarWars30_raw, StarWars30_raw_len);
I2SStream i2s;
StreamCopy copier(i2s, music);The setup function begins the I2S stream with a configuration derived from defaultConfig(TX_MODE), overrides the sample rate, channel count and bit depth, then begins the memory stream. The loop calls copier.copy() repeatedly, which moves whatever is available from the source to the sink.
void setup(){
Serial.begin(115200);
auto config = i2s.defaultConfig(TX_MODE);
config.sample_rate = sample_rate;
config.channels = channels;
config.bits_per_sample = bits_per_sample;
i2s.begin(config);
music.begin();
}
void loop(){
copier.copy();
}With a matching I2S DAC wired to the board, you should hear the file play. If nothing comes out, the sample rate and bit depth in the configuration are the first things to check against what your DAC expects.
The library also ships a built-in logger. The README says the default log level is warning and output goes to Serial, and that you can change it from your sketch by calling into the AudioTools logging API. Raising the level is the quickest way to see what a stream is doing when a chain produces silence.
Where the library stops helping
The library is a connector, not a guarantee. If a decoder needs more RAM than your board has, or your sample rate is higher than the I2S peripheral can clock, arduino-audio-tools will not fix either problem; it will just pass the failure along. The README's claim that defaultConfig() will "usually" work is deliberately hedged, and the class documentation is where the real configuration parameters live.
Dependencies are another boundary. The README states that depending on the example you might need to install additional libraries, and links to a wiki page on optional libraries. The repository's own example folders reflect that: there are separate directories for VS1053 hardware, for the AudioKit, for custom boards, and for TTS, each with its own requirements. A sketch copied from one folder will not necessarily compile in another without those extras.
The licence is the sharpest constraint. The project is GPL-3.0. For an open source device or a personal build that is fine. For firmware you intend to ship in a closed product, GPL-3.0 is a different kind of decision than a permissive library licence, and it is worth reading the licence text rather than assuming the header-only distribution changes anything. That is a statement about what the licence says, not legal advice.
Finally, this is not the right tool if you want a finished application. There is no configuration file, no service to run and no command-line player. You write a sketch or a C++ program and compile it.
How it compares with ESP32-audioI2S and similar libraries
The closest alternative for ESP32 work is ESP32-audioI2S, which targets a narrower job: playing an audio stream on an ESP32 by calling its own API. You hand it a URL or a file and it handles the decode and the I2S output. The difference in approach is that ESP32-audioI2S owns the pipeline, while arduino-audio-tools gives you the pieces and expects you to assemble them.
That trade-off cuts both ways. If your requirement is exactly "play this MP3 on an ESP32 over I2S", ESP32-audioI2S is less code and fewer decisions. If your requirement is "read from a microphone, run a filter, encode to a format, and send it over the network, and also build the same thing on my laptop", the fixed pipeline is the wrong shape and the stream composition in arduino-audio-tools is the point.
The same distinction applies against the underlying codec libraries. The README links to arduino-libhelix as an optional dependency, which is a decoder. arduino-audio-tools does not replace it; it wraps it so the decoder output can be treated as a stream. If you only ever need one decoder and one output, you can use the decoder library directly and skip the abstraction layer.
Maintenance, releases and the cost of upgrading
The repository is not archived, and the last push was on 2026-09-25. Releases are frequent and dated: v1.2.6 was published on 2026-09-02, v1.2.5 on 2026-06-23, and v1.2.4 on 2026-05-29. That cadence is the practical argument for the library, because audio on microcontrollers depends on codec and board support that changes often.
The upgrade cost sits in the API surface you actually touch. The README notes that configuration is passed to begin() through a configuration object, and that defaultConfig() provides a starting proposal. Configuration structs are the kind of thing that grows fields between minor releases, and each stream class has its own. If you pin a version, read the release notes for the versions you skip before moving.
The other recurring cost is the optional libraries. Because examples pull in decoders, DSP libraries and board-specific drivers, a working build is a combination of versions, not a single dependency. Keeping a note of which optional libraries your sketch needs, and at which versions, is cheaper than rediscovering it after an upgrade.
On licensing: the project is GPL-3.0, and the repository ships a License.txt at the top level. The README does not document any alternative licensing arrangement, so treat the GPL as the terms you are working under.
Editorial conclusion
Adopt arduino-audio-tools if you are building an ESP32 or similar microcontroller device that has to read audio from one place, optionally decode or process it, and write it to another, and you want that wiring to look like Arduino Stream code. Do not adopt it if you need a permissively licensed library for a closed product, or if your audio pipeline is a single fixed codec path that a smaller library already covers. Before committing, verify which optional libraries your chosen example needs, check that your target board appears in the examples directory, and confirm the GPL-3.0 terms against how you intend to distribute the firmware.
Frequently asked questions
How do I install arduino-audio-tools?
The library is published as an Arduino library, with a library.properties manifest at the top level of the repository, so the usual route is the Arduino Library Manager or a manual install into your libraries folder. It also builds as a CMake C++ library through the top-level CMakeLists.txt, and the README links to a wiki page about running an audio sketch on the desktop.
Can I play audio with an Arduino using arduino-audio-tools?
Yes. The README's example streams a file stored in flash memory to an I2S output using MemoryStream, I2SStream and StreamCopy, and the library also provides an AudioPlayer class and decoders for MP3, AAC, WAV and FLAC. The result depends on your board having a suitable output device, such as an I2S DAC.
Can an Arduino drive a speaker with arduino-audio-tools?
The library provides output streams, including I2SStream for digital output and AnalogAudioStream for analog output, and the README notes that swapping one for the other changes the output type. Whether a speaker can be connected directly depends on your board and its output stage, which the README does not cover.
How can I use arduino-audio-tools to detect sound?
The library treats audio input the same way it treats output: you read from an Audio Source and write to an Audio Sink, and you can insert filters, converters or effects in between. The README lists filter and converter streams together with a 3 Band Equalizer, and points to examples demonstrating the different scenarios.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/pschatzmann-arduino-audio-tools)