So far I have always preferred to send audio using the networking functionality of the micro-controllers. This is usually fast and reliable. Many examples can be found in my communications examples folder using different protocols.

Using Wires

But we can also send audio signals over a physical wire. I prefer to use the Serial protocol because this is well supported across all environments.

Just to proof the case I had a simple demo which was sending some some audio via the Serial TX pin and receives them back on the RX pin in order to play it back

Serial Communication gets unreliable at high bit rates and it can happen that a single byte can get lost. This has the consequence that some nice audio is turning suddenly into noise! A usual sample rate is 44100 samples per second. If we use stereo with 16 bit we will need a baud rate of >= 1587600 which is well above the reliable range!

Using 8 bit Samples

When we use 8 bit samples instead of 16 bits we not only can half the needed baud rate, but we also solve the issue of the lost bytes: If some bytes get lost, this will not be audible. The consequence is only that the channels get switched. In our framework we can use a codec to translate between the 8 and 16 bits. The minimum baud rate for 44100 samples stereo is 793800.

Here is the new example that uses 8 bits.

This is by far my preferred solution: It is technically very simple and efficient!

Using A Codec – E.g. ADPCM

ADPCM is an efficient codec that we can use on micrcontrollers and that provides a compression ratio of 1:4. But here as well, any lost bytes will lead to decoding errors. I noticed in my tests that a baud rate up to 115200 is usually very reliable.

I added some container functionality that can provide next to the audio segments also meta data and other information. The audio information is checked with a checksum and invalid segments are discarded.

Here is the related example that can handle stereo with 44100 samples / second.

Dependencies


3 Comments

Eugenio Mercol · 11. December 2023 at 9:27

Sorry, I have to use Wemos Lolin32 lite Board.. thanx

    pschatzmann · 11. December 2023 at 9:41

    Well, it was your choice to treat warnings as errors. Just change your settings to their original values

Eugenio · 11. December 2023 at 8:03

Hi Phil, thanks for the Audiotool library. I’m trying to use it for a project but, for some reason, it returns a compilation error on most ESP32 boards. Wemos, LOLIN, Pico, SparkFun, TTGO do not work.
It has only worked for me on ESP32-C3-DevKit, Adafruit-QT-Py-esp32-C3, LOLIN-C3-mini, T-OI TTGO RISC-V PLUS ESP32 C3,

Looks like, if only works on “C3” family boards

Can you help me with that? I need to use it in LOLIN ESP32 mini..
Thanx!!

The error is always the same for most boards:

src/AudioTools/StreamCopy.h: In instantiation of ‘size_t audio_tools::StreamCopyT::write(size_t, size_t&) [with T = unsigned char; size_t = unsigned int]’:
src/AudioTools/StreamCopy.h:425:41: required from here
src/AudioTools/StreamCopy.h:338:22: error: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘long int’ [-Werror=format=]

define LOGD(fmt, …) if (AudioLogger::instance().level()<=AudioLogger::Debug) { LOG_OUT_PGMEM(AudioLogger::Debug, fmt, ##VA_ARGS);}

LOGD(“write: %d -> %d”, open, (int) written);

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *