Building a Digital Music Player with I2S?! What is I2S! EB#45

Using MicroSD Cards with ESP32 Boards: A Step-by-Step Guide to Playing Audio Files

Let's imagine you got a microcontroller board like this ESP32 and you just recorded an awesome sound clip which sounds like this: “Stay Creative!” Now of course you want to play back this sound with the help of the ESP32, so what do you do?

Well, the input side is pretty straightforward by simply adding a micro SD card breakout board to the ESP32 through its SPI interface. Due to this fast data line, all the bits of the original audio file can be read by the ESP32 without losing any audio quality. That means we still got the original resolution of 16 bits which describes in how many steps our original analog audio signal was digitally converted. Also, the sampling rate of 44.1 kHz is kept intact which describes how often the voltage of the analog signal got sampled; in this case around every 22.7uS.

Also, the higher the sampling rate, the closer we are to the real analog signal, but let me tell you that 16 bits and 44.1kHz sounds pretty good. So, the input side is done and for the output side we could use the internal DAC aka Digital to Analog Converter of the ESP32 to create the analog audio signal.

But sadly, it only comes with a resolution of 8 bits which would act as a bottleneck for our audio quality. Instead, I wanted to use this MAX98357A amplifier breakout board which uses I2S to communicate. So, in this video we will find out what I2S is and why it is pretty handy to use and along the way we will not only learn working with the I2S amplifier board but also with an I2S microphone board.

This video is sponsored by JLCPCB, who produce high-quality PCBs for a very affordable price. After over 3 years of using their service, I can still highly recommend it. So why not upload your Gerber files today and receive your PCB?

What is I2S?

I2S stands for Inter-IC Sound, which is a standard for audio interfaces on ICs (Integrated Circuits). In short, it's like the Ethernet protocol of the audio world, designed to communicate data between devices. Now you might be wondering what I2S transmits and how does it work. Let me tell you.

I2S transmits stereo audio over an inter-IC bus, which makes it very handy for creating multi-channel sound systems. The word select line constantly changes between high and low; this is due to the fact that this bus transmits stereo audio where the low state of the word select line indicates the left channel and the high state stands for the right channel.

Also, I2S generates a clock signal whose frequency depends on the sampling rate, bit resolution, and whether you want to transmit mono or stereo. In our microphone example, we selected 44.1 kHz with 16 bits and stereo which means we have to multiply 44.1 kHz by 16 which equals 1.411 MHz which is also the frequency we are measuring.

I2S Basics

In this section, we will delve into the basics of I2S and why it is a pretty easy-to-implementation and handy-to-use communication interface when it comes to receiving and sending digital audio.

I2S transmits data over an inter-IC bus which means that the clock signal generated by the transmitter is used to synchronize the receiver. This way, the audio data bits sent out by the microphone can be read by the ESP32 which is pretty standard knowledge you should know from my SPI, I2C, or CAN video.

But what makes I2S special? It's the frequency of the clock signal it transmits which allows for adjusting to different sampling rates and bit resolutions. In our example, we selected a 44.1 kHz with 16 bits and stereo, but you can choose any other configuration depending on your needs.

In the next section, we will explore how I2S works in practice using an ESP32 board.

Using I2S with ESP32 Boards

Now that we have covered the basics of I2S, let's dive into a real-world example where I2S is used with an ESP32 board.

This time though, the coding was not only about the I2S write part but also about SPI which is why instead of writing all of the code by me which could have taken months, I decided to use the available ESP8266 audio library and some code bits from Spark fun.

In the following paragraphs, we will see how everything works together.

WEBVTTKind: captionsLanguage: enLet’s imagine you got a microcontrollerboard like this ESP32 and you just recordedan awesome sound clip which sounds like this:“Stay Creative!”Now of course you want to playback this soundwith the help of the ESP32, so what do youdo?Well, the input side is pretty straightforwardby simply adding a micro SD card breakoutboard to the ESP32 through its SPI interface.Due to this fast data line, all the bits ofthe original audio file can be read by theESP32 without losing any audio quality.That means we still got the original resolutionof 16 bits which describes in how many stepsour original analog audio signal was digitallyconverted.As a rule of thumb, the more bits we got,the closer we are to the original analog signal.Also the sampling rate of 44.1 kHz is keptintact which describes how often the voltageof the analog signal got sampled; in thiscase around every 22.7uS.And once again the higher the sampling rate,the closer we got to the real analog signalbut let me tell you that 16 bits and 44.1kHz sounds pretty good.So the input side is done and for the outputside we could use the internal DAC aka Digitalto Analog Converter of the ESP32 to createthe analog audio signal.But sadly it only comes with a resolutionof 8 bits which would act as a bottleneckfor our audio quality.Instead I wanted to use this MAX98357A amplifierbreakout board which uses I2S to communicate.So in this video we will find out what I2Sis and why it is pretty handy to use and alongthe way we will not only learn working withthe I2S amplifier board but also with an I2Smicrophone board.Let’s get started!This video is sponsored by JLCPCB, who producehigh quality PCBs for a very affordable price.After over 3 years of using their serviceI can still highly recommend it.So why not upload your Gerber files todayand receive your PCBs sometimes even withina week.First off, I want to say that we are not forcedto use an I2S DAC Amplifier board on the output.We could also build up a 16 bit R-2R DAC butthat would require 16 pins of the ESP32 andthus is not practically useable.Or we could simply get a 16 bit DAC IC whichwe could hook up to the ESP32 through forexample I2C.But then again if we already use a communicationprotocol, why not use I2S which was specificallydesigned for audio applications.I2S stands for Inter-IC Sound and it is anelectrical serial bus interface used for obviouslyconnecting digital audio devices.It communicates PCM audio data which standsfor Pulse-Code Modulation and that is a methodto digitally represent sampled analog signalswhich is for example used by our .wav soundfile.It basically stores the binary values of allthe sampled analog voltage values in it andthat is basically what we want to send aroundwith I2S.For a first practical example however let’snot start off with the amplifier board butinstead with this INMP441 Microphone breakoutboard.With it the I2S concept will be easier tounderstand since we only have to read in datawith the microphone while we would have toread in data and send out data with the microsd card and the amplifier board.But anyway the microphone features 6 pinsof which 2 are for power, 3 are for the I2Sinterface and one is kind of a bonus to selectwhether the microphone outputs its data onthe left or right channel.The three pins required for the I2S are calledword select, serial clock and serial data.In the case of the amplifier board later onthey feature slightly different names butstill mean the same thing.So as a first test I soldered wires to the5 important pins and continued by having alook at the ESP32 pinout diagram in orderto find out where to connect the I2S pinsand to my surprise there were no specificpins mentioned.As it turns out the ESP32 comes with two I2Speripherals but you can select the pins forthem by yourself.So I decided on pins 15, 2 and 4 accordingto this wiring diagram and after connectinga micro USB cable, I had a quick look at theI2S programming guide page for the ESP32.I simply copied a bit of the shown code inorder to not only set the resolution to 16bits and the sampling rate to 44.1kHz butalso to initialize and start the I2S communication.All I had to add were a couple of lines tooutput the received data through the serialmonitor.And after uploading the code and opening theserial monitor we can see that by whistlinginto the microphone or tapping it, the serialmonitor or even better the serial plotterseems to react accordingly, awesome.That means everything works fine and it wastime to have a look at the three I2S pinson the oscilloscope.First off we can see that the word selectlines constantly alter between high and low.The reason is that this bus transmits stereoaudio and so the low state of the word selectline indicates the left channel and the highstate stands for the right channel.By the way in this example we only got dataon the left channel because the unconnectedL/R pins defines that.Then we got the Serial Clock generated bythe ESP32 at whose rising edge the data ofthe Serial Data gets sampled.This way the audio data bits send out by themicrophone can be read by the ESP32 whichis pretty standard communication interfaceknowledge you should know from my SPI, I2Cor for example CAN video.But what is special about this communicationis the frequency of the clock signal.It is actually adjustable and depends on thesampling rate, bit resolution and whetheryou want to transmit mono or stereo.In our microphone example we selected 44.1kHzwith 16 bits and stereo which means we haveto multiply 44.1kHz 16 by 2 which equals 1.411MHzwhich is also the frequency we are measuring.Now of course at this point we could alterthe received microphone data to for examplecreate a voice changer or even a pretty scientificsound level meter but that was not the goalof this video.Instead I soldered wires to my I2S amplifierboard as well as the micro SD card board andhooked it all up to the ESP32 according tothis wiring diagram.This time though the coding was not only aboutthe I2S write part but also about SPI whichis why instead of writing all of the codeby me which could have taken months, I decidedto use the available ESP8266 audio libraryand some code bits from Spark fun.But in the code we can still see that theI2S part is pretty straightforward to implement.And after uploading the code, connecting aspeaker and inserting the micro SD card withthe sound file, we can hear this: “StayCreative!”Awesome!And just like that you are now familiar withthe I2S basics and all in all I can say thatit is a pretty easy to implement and handyto use communication interface when it comesto receiving and sending digital audio.And if you are interested in a more advancedvideo about the topic then I would highlyrecommend checking out bitluni’s video aboutcreating a sound driver for the ULP of theESP32.But anyway I hope you enjoyed this video andlearned something new.If so don’t forget to like, share, subscribeand hit the notification bell.Stay creative and I will see you next time