Practical Audio DSP Projects With The Esp32 Ebook
Practical Audio DSP Projects With The Esp32 Ebook
books
Practical
Audio DSP Projects
with the ESP32
Easy and Affordable Digital Signal Processing
ON STAGE
ESP32 DevKitC
/DAC
Pmod I2S2 ADC
Ts
FIR, IIR, & the FF
guration
hone pin confi
// I2S microp
//
in_MIC()
void i2s_setp
{ n_config =
n_config_t pi
const i2s_pi
{ C,
= I2S_SCK_MI
.bck_io_num
I2S_WS_MIC, // No output
.ws_io_num = NO_CHANGE,
m = I2S_PIN_ // Input from
.data_out_nu
= I2S_SD_MIC
.data_in_num
}; in_config);
I2S_PORT0, &p
i2s_set_pin(
}
Dogan Ibrahim
Ahmet Ibrahim
Practical Audio DSP Projects
with the ESP32
Easy and Affordable Digital Signal Processing
●
Dogan Ibrahim
Ahmet Ibrahim
Practical Audio DSP Projects with the ESP32 - UK.indd 3 06-07-2023 10:40
● This is an Elektor Publication. Elektor is the media brand of
Elektor International Media B.V.
PO Box 11, NL-6114-ZG Susteren, The Netherlands
Phone: +31 46 4389444
● All rights reserved. No part of this book may be reproduced in any material form, including photocopying, or
storing in any medium by electronic means and whether or not transiently or incidentally to some other use of this
publication, without the written permission of the copyright holder except in accordance with the provisions of the
Copyright Designs and Patents Act 1988 or under the terms of a licence issued by the Copyright Licencing Agency
Ltd., 90 Tottenham Court Road, London, England W1P 9HE. Applications for the copyright holder's permission to
reproduce any part of the publication should be addressed to the publishers.
● Declaration
The author, editor, and publisher have used their best efforts in ensuring the correctness of the information contained
in this book. They do not assume, and hereby disclaim, any liability to any party for any loss or damage caused by
errors or omissions in this book, whether such errors or omissions result from negligence, accident or any other cause.
All the programs given in the book are Copyright of the Author and Elektor International Media. These programs
may only be used for educational purposes. Written permission from the Author or Elektor must be obtained before
any of these programs can be used for commercial purposes.
Elektor is the world's leading source of essential technical information and electronics products for pro engineers,
electronics designers, and the companies seeking to engage them. Each day, our international team develops and delivers
high-quality content - via a variety of media channels (including magazines, video, digital media, and social media) in
several languages - relating to electronics design and DIY electronics. www.elektormagazine.com
●4
Practical Audio DSP Projects with the ESP32 - UK.indd 4 06-07-2023 10:40
Contents
Contents
Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.2.14 UART . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.2.23 Wi-Fi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.2.24 Bluetooth . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
●5
Practical Audio DSP Projects with the ESP32 - UK.indd 5 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
2.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Chapter 4 • Elementary Projects using The Arduino IDE and the ESP32 DevKitC . 30
4.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.10.2 Project 10: Controlling LEDS connected to ESP32 DevKitC from a mobile phone 64
Chapter 5 • Sound . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
5.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
●6
Practical Audio DSP Projects with the ESP32 - UK.indd 6 06-07-2023 10:40
Contents
6.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
6.12 Project 8: Play all songs on the SD card — using an external volume control . . . 119
6.14 Project 10: Internet radio in stereo with volume control . . . . . . . . . . . . . . . . . 122
6.15 Project 11: Playing an MP3 file stored in the flash memory . . . . . . . . . . . . . . . 123
6.16 Project 12: List of files stored in the flash memory . . . . . . . . . . . . . . . . . . . . . 128
●7
Practical Audio DSP Projects with the ESP32 - UK.indd 7 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
10.3 Using computer-aided techniques for the design of FIR filters . . . . . . . . . . . . . 168
●8
Practical Audio DSP Projects with the ESP32 - UK.indd 8 06-07-2023 10:40
Contents
11.7 Computer-aided design tools for the design of IIR digital filters . . . . . . . . . . . . 191
Chapter 12 • Designing FIR Digital Filters with the ESP32 DevKitC . . . . . . . . . . . 196
12.5 Project 2: Signal input-output with two independent I2S ports . . . . . . . . . . . . . 202
12.10 Design of FIR digital filters from the first principles (without using a library) . . 218
Chapter 13 • Designing IIR Digital Filters with the ESP32 DevKitC . . . . . . . . . . . 235
13.4.2 Project 2: Design of IIR low-pass filter from the first principles . . . . . . . . . . . 239
●9
Practical Audio DSP Projects with the ESP32 - UK.indd 9 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Appendix A . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
Appendix B . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
● 10
Practical Audio DSP Projects with the ESP32 - UK.indd 10 06-07-2023 10:40
Preface
Digital Signal Processing (DSP) is the process of capturing, analyzing, and manipulating
analog or digital signals by any type of digital processor including digital computers and
microcontrollers.
The theory of DSP is quite complex and requires a good understanding of higher-level
mathematics and discrete time systems. Students new to DSP are usually taught the the-
ory in great detail with very few or no practical applications. For example, in many cases a
student can derive complex equations for digital filters or Fast Fourier Transforms (FFT) but
is unable to implement a simple digital filter in real life. Some institutions use tools such
as MATLAB to derive the coefficients of digital filters and then to simulate the behavior of
these filters on a PC. Although simulation can be an invaluable tool in teaching, it is never
the same as real-time or real-life implementations.
The aim of this book is to teach the basic principles of DSP and to introduce DSP from a
practical point of view using the bare minimum of mathematics. The level of discrete-time
systems theory is sufficient to permit implementing DSP applications in real time. The
emphasis of the book is on practical aspects of DSP such as design issues and real-time
implementation issues. The practical implementation is described using the highly popular
and widely available, low-cost, ESP32 DevKitC microcontroller development board enabling
readers to easily and quickly design as well as implement DSP applications running in real
time. The architectures of dedicated DSP processors are complex and this adds additional
exertion to students who may want to implement DSP applications using such tools.
Using the ESP32 microcontroller, readers should be able to implement DSP applications
with sampling frequencies within the audio range. Programming is accomplished using the
well-liked and widely available Arduino IDE and the C language compiler. The DSP pro-
jects given in the book are based on using the I2S bus. The standard ESP32 processor is
equipped with two independent I2S bus modules that can easily be interfaced to I2S-com-
patible digital microphones or amplifiers.
The early sections of the book include simple projects using basic electronic components
such as LEDs, LCD, sensors, and pushbuttons. These sections are aimed to provide a review
of the basic programming concepts of the ESP32 processor using the Arduino IDE.
Later sections of the book include audio-based sound and DSP projects, including the fol-
lowing:
● 11
Practical Audio DSP Projects with the ESP32 - UK.indd 11 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
This book is primarily intended for students and practicing engineers who may want to
learn the practical implementation of audio sound projects and DSPs in real time. Some
working knowledge of MATLAB will be useful, especially in understanding the theory of dis-
crete-time systems, Z-transforms, digital filters, and FFT. Previous knowledge of advanced
electronics is not necessary but readers should have a basic understanding of electronics
and electronic systems. Also, previous knowledge of the C programming language, espe-
cially in an Arduino IDE environment with an ESP32 processor will be invaluable.
We hope that you find the book useful and enjoyable, and swiftly get to developing your
next audio-based projects based on the ideas given in this book.
● 12
Practical Audio DSP Projects with the ESP32 - UK.indd 12 06-07-2023 10:40
Chapter 1 • The ESP32 Processor
1.1 Overview
The ESP8266 from Espressif has been a highly popular processor costing less than $10.
It is basically a WiFi enabled microcontroller with GPIOs that can be used in small moni-
toring and control applications. The ESP8266 has been developed by Shanghai-based Chi-
nese manufacturer Espressif Systems and incorporates a full TCP/IP stack. There is a vast
amount of information, tutorials, datasheets, applications notes, books, and projects based
on the ESP8266. Several companies have created small development boards based on this
processor, such as the ESP8266 Arduino and NodeMCU series.
Espressif has released a new and more powerful processor than the ESP8266, called the
ESP32. Although ESP32 has not been developed to replace the ESP8266, it improves on it
in many aspects. The new ESP32 processor not only has WiFi support but it also has a Blue-
tooth communications module, making the processor communicate with Bluetooth-compat-
ible devices. The ESP32 CPU is the 32-bit Xtensa LX6 which is very similar to the ESP8266
CPU, but in addition it has two cores, more data memory, more GPIOs, higher CPU speed,
ADC converters with higher resolution, DAC converter, and CAN bus connectivity.
● 13
Practical Audio DSP Projects with the ESP32 - UK.indd 13 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Table 1.1 shows comparison of the basic features of ESP32 and ESP8266 processors.
● 14
Practical Audio DSP Projects with the ESP32 - UK.indd 14 06-07-2023 10:40
Chapter 1 • The ESP32 Processor
Figure 1.2 shows the system structure, consisting of two core Harvard architecture CPUs
named PRO_CPU (for Protocol CPU) and APP_CPU (for Application CPU). The modules in the
middle of the two CPUs are common to both CPUs. Detailed information about the internal
architecture of the ESP32 can be obtained from the ESP32 Technical Reference Manual,
Espressif Systems. Some information about the internal modules is given below.
● 15
Practical Audio DSP Projects with the ESP32 - UK.indd 15 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
An 8 MHz accurate internal clock is also available. The programmer can either select the
external or the internal clock.
● 16
Practical Audio DSP Projects with the ESP32 - UK.indd 16 06-07-2023 10:40
Chapter 1 • The ESP32 Processor
1.2.14 UART
Three UARTs with speeds up to 5 Mbps are provided for RS232, RS485 and IrDA serial
communications.
● 17
Practical Audio DSP Projects with the ESP32 - UK.indd 17 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32 Chapter 1 • The ESP32 Processor
1.2.23 Wi-Fi
ESP32 includes a WiFi module that can be used in projects to communicate with other WiFi
devices, such as mobile phones, PCs, laptops, iPads, etc., through a network router.
1.2.24 Bluetooth
A Bluetooth module is included on the ESP32 processor. With the help of this module, you
can develop projects to communicate with other Bluetooth-compatible devices, such as
mobile phones, PCs, iPads, and others.
● 18
Practical Audio DSP Projects with the ESP32 - UK.indd 18 06-07-2023 10:40
Chapter 1 • The ESP32 Processor
Some popular ESP32 development boards available at the time of authoring this book in-
clude:
• SparkFun ESP32 thing
• Geekcreit ESP32 Development Board
• HiLetgo ESP-WROOM-32 Development Board
• LoLin32 ESP32 Development Board
• Pycom LoPy Development Board
• ESP32 OLED Development Board
• Makerfocus ESP32 Development Board
• ESPS32 Test Board
• ESP32-EVB
• ESP32 Development Board by Pesky Products
• MakerHawk ESP32 Development Board
• Huzzah32 Development Board
• ESPea32
• NodeMCU-32s
• Node32S
• ESP32 DevKitC
● 19
Practical Audio DSP Projects with the ESP32 - UK.indd 19 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
2.1 Overview
In the last chapter, you had a look at the architecture of the ESP32 processor and its basic
features and advantages. You have also read about some of the popular ESP32 develop-
ment boards available in the marketplace.
Currently, ESP32 DevKitC is one of the most popular development boards based on the
ESP32 processor. In this book, all projects to replicate at home or in your lab are based on
this development board. It is therefore important that you learn the architecture and the
features of this board in detail.
In this chapter, you will be looking at the features of the ESP32 DevKitC development board
in greater detail.
The board has two connectors located along each side of the board for GPIO, clock, and
power line interfaces. Each connector has 19 pins. As shown in Figure 2.2, the two connec-
tors carry the following signals:
● 20
Practical Audio DSP Projects with the ESP32 - UK.indd 20 06-07-2023 10:40
Chapter 2 • The ESP32 DevKitC Development Board
IO26 IO5
IO27 IO17
IO14 IO16
IO12 IO4
GND IO0
IO13 IO2
SD2 IO15
SD3 SD1
CMD SD0
+5V CLK
The board has a mini USB connector for connection to a PC. The board also receives its
power from the USB port. Standard +5 V from the USB port is converted into +3.3 V on
the board. In addition, two buttons are provided on the board named EN and BOOT, with
the following functions:
EN: This is the Reset button. Pressing this button resets the board.
BOOT: This is the Download button. The board is normally in operation mode where the
button is not pressed. Pressing and holding down this button and at the same time pressing
the EN button starts the firmware download mode allowing firmware to be downloaded to
the processor through the USB serial port.
The pins on the ESP32 DevKitC board have multiple functions. Figure 2.3 shows the func-
tions of each pin. For example, pin 10 is shared with functions GPIO port 26, DAC channel
2, ADC channel 19, RTC channel 7, and RX01.
● 21
Practical Audio DSP Projects with the ESP32 - UK.indd 21 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Note that GPIO34, GPIO35, GPIO36, GPIO37, GPIO38 and GPIO39 ports are input only
and cannot be used as output ports (GPIO37 and GPIO38 are not available on the ESP32
board).
The board operates at a typical power supply of +3.3 V although the absolute maximum
is specified as +3.6 V. It is recommended that the current capacity of each pin should not
exceed 6 mA, although the absolute maximum current capacity is specified as 12 mA. It
is therefore important to use current limiting resistors while driving external loads such as
LEDs. Depending upon the configuration, the RF power consumption during reception is
around 80 mA, and it can be in excess of 200 mA during a transmission.
● 22
Practical Audio DSP Projects with the ESP32 - UK.indd 22 06-07-2023 10:40
Chapter 3 • Using the Arduino IDE with the ESP32 DevKitC
Chapter 3 • U
sing the Arduino IDE with the
ESP32 DevKitC
3.1 Overview
By default, the ESP32 DevKitC is distributed with no programming firmware installed. It is
therefore necessary to install a programming language firmware on the processor permit-
ting user programs to be developed and uploaded to the processor. Just like the ESP8266,
the ESP32 processor is compatible with various programming languages such as C, Micro-
Python, and others.
The Arduino IDE is currently one of the most commonly used development environments
for microcontrollers, especially for the Arduino family of microcontrollers. This IDE is easy
to use, supports many microcontrollers, and includes a very rich library of functions that
make programming easier. Most electrical/electronic engineering students and people
whose hobbies are electronics are familiar with the Arduino IDE. In this chapter, you will be
learning how to incorporate the ESP32 processor software interface into the Arduino IDE
running on a Windows PC.
• Download and install the latest version of Arduino IDE 1.8.19 from the following
website:
https://www.arduino.cc/en/Main/Software
• Open your Arduino IDE and click File Preferences to open the Preferences
window. Locate the text box Additional Board Manager URLs at the bottom
of the window and enter the following text as shown in Figure 3.1. If the text
box contains another URL, add the new URL after separating it with a comma:
https://espressif.github.io/arduino-esp32/package_esp32_index.json
● 23
Practical Audio DSP Projects with the ESP32 - UK.indd 23 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
• Click OK.
• Click Tools Boards Board Managers window and search for ESP32 as
shown in Figure 3.2. Select the latest version.
• Click Install button. You should see the Installed message as shown in Figure
3.3. Close the window. At the time of writing this book, the version was 2.09.
• You should now test the installation to make sure that all the necessary
files have been loaded. You can make use of one of the supplied example
applications to make sure that a program can be uploaded to the ESP32
processor and is working correctly.
● 24
Practical Audio DSP Projects with the ESP32 - UK.indd 24 06-07-2023 10:40
Chapter 3 • Using the Arduino IDE with the ESP32 DevKitC
• Plug in your ESP32 DevKitC to your PC. You should see the red power LED on
the development board to turn ON. Start the Arduino IDE.
• Select the serial port number (Tools Port). In this example, this is COM5 as
shown in Figure 3.5.
• Open the example program in File Examples WiFi (in ESP32) WiFi
Scan as shown in Figure 3.6.
● 25
Practical Audio DSP Projects with the ESP32 - UK.indd 25 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Now, you will upload the program to your ESP 32 DevKitC. First of all, you have to put the
device into firmware upload mode. Press the Sketch Upload button on Arduino IDE to
compile and upload your program to the ESP32 DevKitC (on some devices, you may have to
keep the BOOT button pressed during the entire upload process). Wait until finished. After a
successful process, you should see a screen similar to the one shown in Figure 3.8 Release
the BOOT button if it was pressed during the upload.
● 26
Practical Audio DSP Projects with the ESP32 - UK.indd 26 06-07-2023 10:40
Chapter 3 • Using the Arduino IDE with the ESP32 DevKitC
• Now, open the Arduino IDE Serial monitor by clicking Tools Serial Monitor.
Make sure that the communication baud rate is set to 115200. You should see
a list of the access points close to you as shown in Figure 3.9 (You may have
to press the Reset button at the left of the board). The list is updated every 5
seconds.
• At this point, you have successfully installed the ESP32 processor into your
Arduino 1.8.19 IDE.
• Open your Arduino IDE and click File Preferences to open the Preferences
window. Locate the text box Additional Board Manager URLs at the bottom
of the window and enter the following text (Figure 3.10):
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/
package_esp32_index.json
● 27
Practical Audio DSP Projects with the ESP32 - UK.indd 27 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
• Click OK.
• Search for ESP32 and press the install button for esp32 by Espressif Systems.
At the time of writing this book, the version was 10.6.
• Select DOIT ESP32 DEVKIT V1 and port COM5. Click OK (Figure 3.11).
• To test the installation, you can write the program shown in Figure 3.12 and
upload it to the ESP32. This program will count up by one every 2 seconds and
display the result on the Serial Monitor.
● 28
Practical Audio DSP Projects with the ESP32 - UK.indd 28 06-07-2023 10:40
Chapter 3 • Using the Arduino IDE with the ESP32 DevKitC
• Click Sketch Upload (on some devices, you may have to keep the BOOT
button pressed during the entire upload process). The program will be compiled
and uploaded to your ESP32.
• Click Serial Monitor icon at the top right-hand side of the screen and set the
speed to 115200. You should see the program counting up and displaying on
the Serial Monitor as shown in Figure 3.13 (You may have to press the left
RESET button for the program to start).
This book uses the older, more familiar version 1.8.19 in all projects discussed.
● 29
Practical Audio DSP Projects with the ESP32 - UK.indd 29 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Chapter 4 • E
lementary Projects using
The Arduino IDE and the ESP32 DevKitC
4.1 Overview
In the previous chapter, you have seen how to update the Arduino IDE so that the pro-
grams developed using this IDE can be compiled and downloaded to the ESP32 DevKitC
development board.
This chapter is a review of using some of the basic features of the ESP32 processor with
the Arduino IDE. Readers familiar with developing basic projects using the ESP32 can skip
it if they want. In this chapter, projects will be developed to show how commonly required
operations can be programmed with the Arduino IDE. The example projects given cover
the following concepts:
• Using external LEDs (or buzzers, etc.)
• Using external pushbutton
• Using the PWM (Pulse Width Modulation) of the ESP32
• Using the ADC (Analog-to-Digital Converter) of the ESP32
• Using I2C LCD in a project
• Using the DAC (Digital-to-Analog Converter) of the ESP32
• Writing and reading from an SD card
• WiFi network programming
• Bluetooth programming
Interested readers can find many more useful working projects in the following Elektor
book (some of the projects in this book are taken from the following book):
All the projects given in this book have been tested and are fully working. The following
sub-headings will be used for each project wherever it is possible so that the projects can
be further developed if required by the readers:
• Project title
• Project description
• Aim of the project
• Project block diagram
• Project circuit diagram
• Project construction
• Project program listing
• Full description of the project program
• Suggestion for further work
● 30
Practical Audio DSP Projects with the ESP32 - UK.indd 30 06-07-2023 10:40
Chapter 4 • Elementary Projects using The Arduino IDE and the ESP32 DevKitC
The aim: The aim of this project is to show how external LEDs can be connected to a GPIO
port and how they can be turned on and off alternately.
Block diagram: The block diagram of the project is shown in Figure 4.1.
Circuit diagram: The circuit diagram of the project is shown in Figure 4.2. LED1 is con-
nected to GPIO port 22 and LED2 to GPIO port 23. The LEDs are connected to the port pins
through 330-Ohm current limiting resistors (higher or lower value resistors could also have
been connected for lower or higher light intensities, respectively). Assuming the voltage
drop across the LED is 2 V, the current through the LED will be:
Construction: A breadboard was used to construct the project. The LEDs are connected to
the ESP32 DevKitC through the current limiting resistors as shown in Figure 4.3.
● 31
Practical Audio DSP Projects with the ESP32 - UK.indd 31 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Program listing: The program listing of the project is very simple and is shown in Figure
4.4 (Program: Altflash). At the beginning of the program, variable names LED1 and LED2
are assigned to GPIO ports 22 and 23 respectively. Then the port pins are configured as
outputs. The main program is run continuously in a loop, where inside this loop LED1 and
LED2 are turned ON and OFF alternately with a one-second delay between each output.
/****************************************************************
* ALTERNATE FLASHING LEDs
* =======================
*
* In this program two LEDs are connected to port GPIO22 and
* GPIO23 of the ESP32 DevKitC. The program flashes the LEDs
* alternately with one second delay between each output
*
* Program: Altflash
* Date : April, 2023
**************************************************************/
#define LED1 22
#define LED2 23
#define ON HIGH
#define OFF LOW
● 32
Practical Audio DSP Projects with the ESP32 - UK.indd 32 06-07-2023 10:40
Chapter 4 • Elementary Projects using The Arduino IDE and the ESP32 DevKitC
void setup()
{
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
}
void loop()
{
digitalWrite(LED1, HIGH);
digitalWrite(LED2, LOW);
delay(1000);
digitalWrite(LED1, LOW);
digitalWrite(LED2, HIGH);
delay(1000);
}
The Aim: The aim of this project is to show how a pushbutton switch can be connected to
an ESP32 DevKitC GPIO port and how the port can be configured as an input.
Block diagram: The block diagram of the project is shown in Figure 4.5.
Circuit diagram: The circuit diagram of the project is shown in Figure 4.6. 8 LEDs are
connected to the GPIO ports through 330-Ohm current limiting resistors as follows:
● 33
Practical Audio DSP Projects with the ESP32 - UK.indd 33 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
GPIO23 (MSB)
GPIO22
GPIO1
GPIO3
GPIO21
GPIO19
GPIO18
GPIO5 (LSB)
Notice that a button can be connected in two different ways to a GPIO port. In Figure 4.7,
the output of the button is at logic 1 and goes to logic 0 when the button is pressed. In
Figure 4.8, the output of the button goes from logic 0 to logic 1 when the button is pressed.
In this example, the second method is used. Thus, GPIO pin is normally at logic 0 and goes
to logic 1 when the button is pressed.
● 34
Practical Audio DSP Projects with the ESP32 - UK.indd 34 06-07-2023 10:40
Chapter 4 • Elementary Projects using The Arduino IDE and the ESP32 DevKitC
Program listing: The program listing of the project is very simple and is shown in Figure
4.10 (Program: UpDown). At the beginning of the program, an array called LEDs is set up
to store the port numbers of the LEDs used in the project. The name Button is assigned to
GPIO port 17, and the names UP and DOWN are assigned to 0 and 1 respectively. Global
variable Count is initialized to zero. Then, the GPIO ports where the LEDs are connected
are configured as output ports, and the GPIO port where the Button is connected is con-
figured as an input port. Inside the main program, function Display is called, and Count is
sent as the argument. Then, the state of the Button is read: if the Button is not pressed
(Button_State equal to UP) then an UP count is performed. If on the other hand, the
Button is pressed (Button_State equal to DOWN) then a DOWN count is performed.
Notice that variable Count is reset at the end of the counts. i.e., during an UP count when
the count reaches 255, it is reset to 0 on the next cycle. Similarly, on a DOWN count when
the count reaches 0, it is reset to 255 on the next cycle.
● 35
Practical Audio DSP Projects with the ESP32 - UK.indd 35 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
/****************************************************************
* BINARY UP/DOWN COUNTER
* ======================
*
* In this program 8 LEDs are connected to port pins GPIO23,
* GPIO22, GPIO1, GPIO3, GPIO21, GPIO19, GPIO18, and GPIO5
* of the ESP32 DevKitC. In addition, a push-button switch
* is connected to port pin 17. Normally the switch output is
* at logic 0 and when the switch is pressed its output goes
* to logic 1. The program normally counts up. When the switch
* is pressed and held down then the program starts to count
* down from its last value. The appropriate LEDs are turned
* ON/OFF
*
*
* Program: UpDown
* Date : April, 2023
**************************************************************/
#define Button 17
#define UP 0
#define DOWN 1
int LEDs[] = {23, 22, 1, 3, 21, 19, 18, 5};
unsigned char Count = 0;
unsigned char Button_State;
//
// Set GPIO pins 23,22,1,3,21,19,18,5 as outputs and GPIO pin 17
// as input
//
void setup()
{
unsigned char i;
for(i=0; i < 8; i++)
{
pinMode(LEDs[i], OUTPUT);
}
pinMode(Button, INPUT);
}
//
// Turn ON the appropriate LED
//
void Display(unsigned char No, unsigned char L)
{
unsigned char j, m, i;
● 36
Practical Audio DSP Projects with the ESP32 - UK.indd 36 06-07-2023 10:40
Chapter 4 • Elementary Projects using The Arduino IDE and the ESP32 DevKitC
m = L - 1;
for(i = 0; i < L; i++)
{
j = pow(2, m);
digitalWrite(LEDs[i], (No & j));
m--;
}
}
//
// When the button is not pressed increment Count every second
// and send Count to GPIO pins. When the button is pressed
// count down from the last value and send Count to GPIO pins
// Notice that the width is 8-bits (i.e. there are 8 LEDs)
//
void loop()
{
Display(Count, 8);
Button_State = digitalRead(Button); // Read Button state
if(Button_State == UP) // If UP count
{
if(Count == 255)
Count = 0; // Reset Count
else
Count++; // Increment Count
}
else if(Button_State = DOWN) // If DOWN count
{
if(Count == 0)
Count = 255; // Reset Count
else
Count--; // Decreament Count
}
delay(1000); // Wait 1 second
}
The aim: The aim of this project is to show how PWM type waveform can be generated in
a program and how this waveform can be used to effectively vary the voltage applied to
an LED.
● 37
Practical Audio DSP Projects with the ESP32 - UK.indd 37 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Block diagram:
The block diagram of the project is shown in Figure 4.11.
Circuit diagram: The circuit diagram of the project is shown in Figure 4.12. An LED is
connected to the GPIO port 23 through a 330-ohm current limiting resistor.
Program listing: The program listing of the project is very simple and is shown in Figure
4.13 (Program: FadeLED). The fading of the LED is done by applying a PWM waveform to
the LED and then changing the duty cycle of this waveform, which effectively changes the
average voltage applied to the LED.
/****************************************************************
* CHANGING THE LED BRIGHTNESS
* ===========================
*
* In this program an LED is conencted to GPIO port pin 23.
* The program changes the brightness of the LED by varying
* the voltage applied to the LED. The LED PWM function is used
* in this project where the duty cycle of the PWM waveform is
● 38
Practical Audio DSP Projects with the ESP32 - UK.indd 38 06-07-2023 10:40
Chapter 4 • Elementary Projects using The Arduino IDE and the ESP32 DevKitC
//
// Set GPIO pin 23 as output. Setup the PWM channel 0 and attach
// GPIO pin 23 to this channel
//
void setup()
{
pinMode(LED, OUTPUT);
ledcSetup(channel, frequency, resolution);
ledcAttachPin(LED, channel);
}
//
// Change the brightness of the LED by varying the duty cycle
// from 0% (0) to 100% (255)
//
void loop()
{
for(int duty = 0; duty < 255; duty +=5)
{
ledcWrite(channel, duty);
delay(50);
}
Figure 4.14 shows a typical PWM waveform. The duty cycle is defined as the ratio of the
ON time to the period:
● 39
Practical Audio DSP Projects with the ESP32 - UK.indd 39 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
or
Thus, for example, when the duty cycle is 0% the ON time is 0, and when the duty cycle is
100% the OFF time is 0.
The program uses the LED PWM function of the ESP32 which consists of 16 independent
channels with configurable duty cycles, frequencies, and resolutions. A channel from 0 to
15, and a resolution from 1 to 16 bits can be selected. The PWM setup function is called
ledcSetup and it has the following format with integer parameters:
After the setup, you have to attach the GPIO pin that you will be using as the PWM pin to
the selected channel. This is done using function ledcAttach, which has the format:
The PWM waveform is then sent to the selected GPIO pin using function ledcWrite which
has the format:
where, for an 8-bit resolution, the duty cycle is 0 for 0% and 255 for 100%.
In this project, the frequency is set to 1000 Hz, and channel 0 is used with the GPIO pin
23. The resolution is set to 8 bits. The duty cycle is changed from 0 to 100% in steps of 5%
every 50 milliseconds. The effect is that the brightness of the LED changes from no light
(0% duty cycle) to full brightness (100% duty cycle) where the brightness is increased by
5% every 50 ms. Similarly, after the full brightness is reached the program waits for 500
ms and starts to fade the LED from full brightness to no light, again by 5% every 50 ms.
● 40
Practical Audio DSP Projects with the ESP32 - UK.indd 40 06-07-2023 10:40
Chapter 4 • Elementary Projects using The Arduino IDE and the ESP32 DevKitC
Suggestions: In Figure 4.13, the delay time is set to 50 ms and the duty cycle step is
set to 5. Try modifying both of these values and watch their effects on the LED bright-
ness.
The aim: The aim of this project is to show how an analog input (ADC) of the ESP32
DevKitC can be used to read analog data. In addition, it shows how to display data on the
PC screen.
Block diagram: Figure 4.15 shows the block diagram of the project.
Circuit Diagram: In this project, the TMP36 analog temperature chip is used to get the
ambient temperature. The TMP36 temperature sensor chip is a 3-pin device having the pin
layout as shown in Figure 4.16. The device operates with a power supply in the range of
2.7 V to 5.5 V and can measure the temperature in the range of –40 ºC to +125 ºC. The
output voltage of the device is proportional to the measured temperature and is given by:
C = (V – 500) / 10
Where C is the measured temperature in ºC, V is the output voltage of the sensor chip in
mV. Thus, for example, an output voltage of 800 mV corresponds to 30 ºC, and so on.
● 41
Practical Audio DSP Projects with the ESP32 - UK.indd 41 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Figure 4.17 shows the circuit diagram of the project. Two pins of the TMP36 are connected
to the +3.3 V power supply and the ground. The output pin of the TMP36 temperature sen-
sor chip is connected to GPIO4 which is also the ADC2_0 of the ESP32 DevKitC. The ADC is
12-bits wide and has a reference voltage of +3.3 V.
● 42
Practical Audio DSP Projects with the ESP32 - UK.indd 42 06-07-2023 10:40
Chapter 4 • Elementary Projects using The Arduino IDE and the ESP32 DevKitC
Program Listing: The program listing of the project is shown in Figure 4.19 (Program:
TMP36).
/****************************************************************
* THERMOMETER WITH SERIAL MONITOR
* ===============================
*
* In this program a TMP36 type analog temperature sensor chip
* is connected to GPIO pin 4 which is also an analog input.
* The program reads the ambient temperature every second and
* sends the readings to the Serial Monitor
*
*
* Program: TMP36
* Date : April, 2023
**************************************************************/
#define TMP36 4
void setup()
{
Serial.begin(9600);
}
//
// Read the ambient temperaure, convert into Degrees Centigrade
// and send the readings to the Serial Monitor. Repeat this
// process every second
● 43
Practical Audio DSP Projects with the ESP32 - UK.indd 43 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
//
void loop()
{
int Temp = analogRead(TMP36);
float mV = Temp * 3300.0 / 4096.0;
float Temperature = (mV - 500.0) / 10.0;
Serial.println(Temperature);
delay(1000);
}
At the beginning of the program, TMP36 is defined as port GPIO4, which is one of the
analog input ports of the ESP32 DevKitC, and the Serial Monitor baud rate is set to 9600.
The remainder of the program is executed in an endless loop. Inside this loop, the analog
output of the TMP36 is read using the analogRead library function. The reading is then
converted into absolute millivolts. Notice that the ADC reference voltage is 3300 mV and
the ADC is 12-bits wide (0 to 4095). The reading is then converted into Degrees Centigrade
by subtracting 500 and dividing by 10. The temperature values are then sent to the Serial
Monitor so that they can be displayed on the PC screen. To do this, click Tools Serial
Monitor and select the baud rate as 9600. A typical output from the Serial Monitor is
shown in Figure 4.20. You can make the display more user-friendly by displaying the text
Temperature before its value by modifying the code as follows. The resultant display is
shown in Figure 4.21.
● 44
Practical Audio DSP Projects with the ESP32 - UK.indd 44 06-07-2023 10:40
Chapter 4 • Elementary Projects using The Arduino IDE and the ESP32 DevKitC
It is important to mention at this point that the ESP32 DevKitC used by the author (any
many others as reported on the Internet) has ADC linearity problems which may result in
inaccurate readings. In order to get accurate results from the ADC, it is recommended to
carry out an experiment and create a table or an equation showing the actual relationship
between the analog input voltages and the digital values returned by the ADC. This table
or the equation can then be used to correct the ADC readings.
The aim: The aim of this project is to show how a character-based LCD can be interfaced
and used in an ESP32 DevKitC project and how numbers can be displayed on the LCD. An
I2C-compatible 16-character by 2-row LCD is used here.
Block diagram: The block diagram of the project is shown in Figure 4.22, A pushbutton
switch and an I2C LCD are connected to DevKitC
● 45
Practical Audio DSP Projects with the ESP32 - UK.indd 45 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
The LCD used in this project is based on the I2C interface. I2C is a multi-slave, multi-master,
single-ended serial bus used to attach low-speed peripheral devices to microcontrollers.
The bus consists of only two wires called SDA and SCL where SDA is the data line and SCL
is the clock line and up to 1008 slave devices can be supported on the bus. Both lines must
be pulled up to the supply voltage by suitable resistors. The clock signal is always generat-
ed by the bus master. The devices on the I2C bus can communicate at 100 kHz or 400 kHz.
GPIO ports 21 and 22 are available for use by the I2C bus interface on the ESP32 DevKitC,
where port 21 is the data line (SDA) and port 22 is the clock line (SCL).
Figure 4.23 shows the front and back of the I2C-based LCD. Notice that the LCD has a
small board mounted on its back to control the I2C interface. The LCD contrast is adjusted
through the small potentiometer mounted on this board. A jumper is provided on this board
to disable the backlight if required.
The I2C LCD used in this project has the address: 0x27.
Circuit diagram: The schematic (circuit diagram) of the project is shown in Figure 4.24.
The SDA and CL pins of the I2C LCD are connected to GPIO ports 21 and 22 respectively.
The pushbutton switch is connected to GPIO port 23 through a 10 k-ohm pull-up resistor to
simulate the occurrence of external events.
Construction: The ESP32 DevKitC board is mounted on a breadboard with the pushbutton
switch. The I2C LCD is connected to DevKitC through jumper wires as shown in Figure 4.25.
● 46
Practical Audio DSP Projects with the ESP32 - UK.indd 46 06-07-2023 10:40
Chapter 4 • Elementary Projects using The Arduino IDE and the ESP32 DevKitC
Program listing: Before programming the ESP32 for the I2C LCD, it is necessary to down-
load and include the I2C LCD library in your Arduino IDE folder. The steps to do this are
given below:
https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library
• Click the button Code (see Figure 4.27) and click Download ZIP. The library
ZIP file will be copied to your Downloads folder.
● 47
Practical Audio DSP Projects with the ESP32 - UK.indd 47 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
• Open your Arduino IDE. Click Sketch Include Library and select Add .ZIP
Library…
• Browse to the above-downloaded file and click Open. You should see the
message Library added to your libraries message at the bottom of the IDE
screen.
• Start the Arduino IDE. Go to File Examples and you should see Arduino-
LiquidCrystal_I2C examples in the drop-down menu if the library has been
installed correctly (Figure 4.28)
● 48
Practical Audio DSP Projects with the ESP32 - UK.indd 48 06-07-2023 10:40
Chapter 4 • Elementary Projects using The Arduino IDE and the ESP32 DevKitC
The program listing is shown in Figure 4.29 (program: LCDCounter). At the beginning of
the program, EVENTS is assigned to GPIO port 23 and I2C and LCD libraries are included in
the program. Variable Count is cleared to zero. In the setup routine, port 23 is configured
as input, LCD is initialized, and the text message Event Counter is displayed on the LCD.
The remainder of the program runs in an endless loop where the program waits until an
event occurs. A small delay is then introduced to the program to wait until the switch
contacts stop bouncing (called contact debouncing). The program then clears the LCD,
increments Count by one, converts it into a string using function snprintf and displays the
value of Count on the LCD.
/*************************************************************
* LCD EVENT COUNTER
* =================
*
* This is an event counter program with an LCD. Events are
* assumed to occur on GPIO port 23 where an event is the HIGH
* to LOW transition of this pin. In this project events are
* simulated using a push-button switch connected to GPIO23 and
* pulled high. An I2C LCD is connected to the ESP32 Devkitc.
*
* File: LCDCounter
* Date: April, 2023
* Author: Dogan Ibrahim
*************************************************************/
#define EVENTS 23
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
int Count = 0;
char Res[4];
//
// Set the LCD address to 0x27 and the configuration to
// 16 chars and 2 rows display. Also configure port 23 as
// an input
//
LiquidCrystal_I2C lcd(0x27, 16, 2); // LCD address 0x27
void setup()
{
pinMode(EVENTS, INPUT);
lcd.begin(); // Initialize LCD
lcd.backlight(); // Turn ON backlight
lcd.print("Event Counter"); // Display Text
}
● 49
Practical Audio DSP Projects with the ESP32 - UK.indd 49 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
void loop()
{
while(digitalRead(EVENTS) == 1); // Wait until event
delay(150); // Contact debounce
lcd.clear(); // Clear LCD
Count++; // Incement Count
snprintf(Res, 4, "%d", Count); // Covert to string
lcd.print(Res); // Display on LCD
}
LCD functions
The I2C LCD library supports the following functions:
The aim: The aim of this project is to show how the DAC on the ESP32 DevKitC can be used
to generate a sawtooth waveform.
● 50
Practical Audio DSP Projects with the ESP32 - UK.indd 50 06-07-2023 10:40
Chapter 4 • Elementary Projects using The Arduino IDE and the ESP32 DevKitC
Block diagram: Figure 4.30 shows the block diagram of the project. Here, the ESP32
processor generates the required sawtooth waveform as a digital signal, and then, the DAC
outputs this signal through the GPIO port reserved for the DAC. A PC-based oscilloscope
PSCGU250 is used in this project.
• The processor calculates the waveform points in real time and sends them to
the DAC
• The waveform points are stored in a look-up table. The processor reads these
points from the table and sends them to the DAC (this method is used to
generate any arbitrary waveform, or to generate higher frequency waveforms).
The rate at which the waveform points are sent to the DAC determines the frequency of
the waveform.
The DAC
A DAC converts digital signals to analog. Although a DAC can be an external component,
most microcontrollers have built-in DACs. For example, the ESP32 processor has two 8-bit
DACs. In external DACs, the digital input can either be in serial or parallel form. In external
parallel converters, the width of the digital input is equal to the width of the converter. For
example, 10-bit DACs have 10 input bits. External serial DACs in general use the SPI or the
I2C bus, and a clock and a data line are used to send the data to be converted to the DAC.
Parallel converters provide much faster conversion times, but they are housed in larger
packages.
DACs are manufactured as either unipolar or bipolar as far as the output voltages are con-
cerned. Unipolar converters can only output positive voltages, whereas bipolar converters
can output both positive and negative voltages.
● 51
Practical Audio DSP Projects with the ESP32 - UK.indd 51 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
The relationship between the digital input-output and the voltage reference of a DAC is
given by:
Where VO is the output voltage, Vref is the reference voltage, and n is the width of the con-
verter. For example, in an 8-bit converter with a +3.3 V reference voltage,
Thus, for example, if the input digital value is 00000001, the analog output voltage will be
12.89 mV, if the input digital value is 00000010, the analog output voltage will be 25.78
mV, and so on.
In this project, you will be generating a sawtooth waveform with the following specifica-
tions:
Circuit diagram: The circuit diagram of the system is shown in Figure 4.31. The ESP32
processor has two built-in 8-bit DACs on GPIO ports 25 and 26. In this project, you shall be
using the one at GPIO port 25.
Program listing: The program listing of the project is shown in Figure 4.32 (Program:
Sawtooth). At the beginning of the program, the sawtooth is assigned to GPIO port 25 and
it is configured as an analog port. Inside the main program, 11 steps are continuously sent
to the DAC with a 909-µs delay between each step. Function dacWrite is used to send the
steps to the DAC. This function has two arguments: DAC port number, and the digital value
to be converted into analog.
● 52
Practical Audio DSP Projects with the ESP32 - UK.indd 52 06-07-2023 10:40
Chapter 4 • Elementary Projects using The Arduino IDE and the ESP32 DevKitC
/*************************************************************
* SAWTOOTH WAVEFORM GENERATION
* ============================
*
* In this project a Sawtooth waveform is generated through the
* DAC at GPIO port 25 of teh ESP32 Devkitc.
*
* The specifications of the generated waveform are:
* Output voltage: 0 to +3.3V
* Frequency: 100 Hz (period 10 ms)
* Step size: 0.1 ms
*
* File: Sawtooth
* Date: April, 2023
* Author: Dogan Ibrahim
*************************************************************/
#define Sawtooth 25
int DAC_Value;
void setup()
{
pinMode(Sawtooth, ANALOG); // Configure as analog
}
void loop()
{
for(float i = 0; i <= 1; i=i+0.1)
{
DAC_Value = i * 255;
dacWrite(Sawtooth, DAC_Value); // Send to DAC
delayMicroseconds(909); // 909 us delay
}
}
Figure 4.33 shows the generated sawtooth waveform, captured on the PSCGU250 PC-
based oscilloscope. In this figure, the horizontal axis was 5 ms/division, and the vertical
axis was 1V /division.
● 53
Practical Audio DSP Projects with the ESP32 - UK.indd 53 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
The aim: The aim of this project is to show how an SD card can be interfaced to the ESP32
DevKitC and how data can be written to the SD card.
Block diagram: The block diagram of the project is shown in Figure 4.34. In this project,
a micro size SD card (microSD) adapter is used as shown in Figure 4.35. This card adapter
has the following specifications:
● 54
Practical Audio DSP Projects with the ESP32 - UK.indd 54 06-07-2023 10:40
Chapter 4 • Elementary Projects using The Arduino IDE and the ESP32 DevKitC
SDcards are non-volatile memory card formats developed by the SD Card Association
(SDA) for use in portable devices like mobile phones, cameras, etc. The family includes the
following members:
SDSC: Standard Capacity SD with a capacity of 2 GB, using FAT-12 and FAT-16.
SDHC: High Capacity SD with a capacity from 2 GB to 32 GB, using FAT-16 or
FAT-32 file system
SDXC: eXtended Capacity SD with a capacity from 32 GB to 2 TB, using the exFAT
file system.
The Arduino library supports only FAT-16 and FAT-32 formatted SD cards. A standard-size
SD card has 9 pins, while a microSD card has 8 pins (Figure 4.36).
Circuit Diagram: SD card adapters are controlled using the SPI bus of the processor. The
cardholder used in this project has the following 6 pins:
CS
SCK
MOSI
MISO
VCC
GND
● 55
Practical Audio DSP Projects with the ESP32 - UK.indd 55 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
The circuit diagram of the project is shown in Figure 4.37. SD card adapter is connected to
DevKitC through the standard SPI interface. The connections between the SD card module
and the DevKitC GPIO ports are as follows:
● 56
Practical Audio DSP Projects with the ESP32 - UK.indd 56 06-07-2023 10:40
Chapter 4 • Elementary Projects using The Arduino IDE and the ESP32 DevKitC
Program Listing: The program listing of the project is shown in Figure 4.39 (Program:
SD-CARD).
/****************************************************************
* WRITE TO SD CARD
* ================
*
* In this program a microSD card adapter is connected to the
* ESP32 DevKitC. The program generates random numbers every second
* and stored them on the SD card over 10 seconds (i.e. 10 numbers)
* are stored on the SD card. The data is stored in file TEST.TXT
* under directory called NUM
*
* Program: SD-CARD
* Date : April, 2023
* Author : Dogan Ibrahim
**************************************************************/
#include "SD.h"
#define SD_CS 5 // SD card CS pin
void setup()
{
Serial.begin(9600);
Serial.println(""); // New line
if(!SD.begin(SD_CS)) // Initialize SD card
{
Serial.println("Initialization failed");
while(1);
}
else
Serial.println("Initialization done");
}
//
// This is the main program. A file called TEST.TXT is created in
// directory NUM on the SD card. The program stores 10 integer random
// integer numbers in this file on the SD card
//
void loop()
{
File MyFile;
unsigned int RandomNumber;
char k;
if(SD.cardType() == CARD_NONE)
● 57
Practical Audio DSP Projects with the ESP32 - UK.indd 57 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
{
Serial.println("SD card is not found");
while(1);
}
The SD card should be formatted before it is used with the ESP32. The steps are as follows:
At the beginning of the program, the header file SD.h is included in the program and the
SD card chip select pin (SD_CS) is assigned to GPIO pin 5. Inside the setup routine, the SD
card library is initialized. Notice that the chip select pin must be specified as the argument
of library function SD.begin. The serial PC USB interface (Serial.begin) is also enabled so
that messages can be displayed on the PC screen while the program is running.
Inside the main program loop, the program checks if there is an SD card in the card
module. The program then creates a directory called NUM on the SD card using library
● 58
Practical Audio DSP Projects with the ESP32 - UK.indd 58 06-07-2023 10:40
Chapter 4 • Elementary Projects using The Arduino IDE and the ESP32 DevKitC
function SD.mkdir. Function SD.open creates a new file or opens an existing file. This
function has two arguments: the name of the file to be created or opened, and the mode.
The mode can either be FILE_WRITE or FILE_READ. When the FILE_WRITE mode is
used, data is added to the end of the file if the file exists, otherwise a new file is created.
Mode FILE_READ opens an existing file in read mode. Full path must be given to the file
including its directory name. In this program, the full path to the file was: /NUM/TEST.
TXT. Variable MyFile is set true if a new file has been created or an existing file is opened.
Message Random Numbers with an underline is written to the SD card as the heading. A
for loop is then set up which iterates 10 times. Inside this loop, integer random numbers
are generated and stored in the newly created file on the SD card. The program then waits
for one second. The file is closed at the end of the for loop. Closing the file physically saves
the data on the SD card. Notice that the function SD.flush() can also be used to save the
data physically on the SD card.
Figure 4.40 shows the SD card file structure after the program is run. The following data is
displayed on the PC screen on Serial Monitor while the program is running:
Initialization done
Writing to SD card
Data written
The data stored on the SD card is displayed on the PC as shown in Figure 4.41.
● 59
Practical Audio DSP Projects with the ESP32 - UK.indd 59 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Some of the commonly used SD card library functions are (see website: https://www.arduino
.cc/en/Reference/SD for a full explanation of each function and for additional functions):
The aim: The aim of this project is to show how an SD card can be interfaced to the ESP32
DevKitC and how data can be read from the SD card.
Block diagram: The block diagram of the project is shown in Figure 4.34.
Circuit diagram: The circuit diagram of the project as shown in Figure 4.37.
Program listing: The program listing of the project is shown in Figure 4.42 (Program:
SD-READ).
/****************************************************************
* READ FROM SD CARD
* =================
*
* In this program a microSD card module is connected to the
* ESP32 DevKitC. The program opens file TEST.TXT in directory NUM
* on the SD card and then reads and displays the contents (random
* numbers) of this file on the PC screen.
*
* Program: SD-READ
* Date : April, 2023
* Author : Dogan Ibrahim
**************************************************************/
#include "SD.h"
#define SD_CS 5 // SD card CS pin
● 60
Practical Audio DSP Projects with the ESP32 - UK.indd 60 06-07-2023 10:40
Chapter 4 • Elementary Projects using The Arduino IDE and the ESP32 DevKitC
void setup()
{
Serial.begin(9600);
Serial.println(""); // New line
if(!SD.begin(SD_CS)) // Initialize library
{
Serial.println("Initialization failed");
while(1);
}
else
Serial.println("Initialization done");
}
//
// This is the main program. File TEST.TXT is opened in directory
// NUM of the SD card and its contents are displayed on the PC screen
//
void loop()
{
File MyFile;
if(SD.cardType() == CARD_NONE)
{
Serial.println("SD card is not found");
while(1);
}
● 61
Practical Audio DSP Projects with the ESP32 - UK.indd 61 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
In this program, the file TEST.TXT in directory NUM on the SD card is opened in read mode
(FILE_READ). Then a while loop is formed to read all the data from the file and display it
on the PC screen. Figure 4.43 shows the output of the program.
The aim: The aim of this project is to show how WiFi network programming is carried out
using the ESP32 DevKitC development board.
Program listing: Figure 4.44 shows a program (Program: SCAN) that scans the surround-
ing WiFi networks and returns the various network parameters.
● 62
Practical Audio DSP Projects with the ESP32 - UK.indd 62 06-07-2023 10:40
Chapter 4 • Elementary Projects using The Arduino IDE and the ESP32 DevKitC
/*************************************************************
* SCAN WI-FI NETWORK
* ==================
*
* This program does a scan and displays the surrounding Wi-Fi
* networks. The following parameters of the found networks
* are displayed: Network name (SSID), signal strength (RSSI),
* and MAC address (BSSIDstr).
*
* File: SCAN
* Author: Dogan Ibrahim
* Date: April, 2023
*
**************************************************************/
#include «WiFi.h»
//
// Set mode to station, scan the surrounding Wi-Fi networks and
// display their details on the Serial Monitor
//
void setup()
{
Serial.begin(9600);
WiFi.mode(WIFI_STA); // Mode station
● 63
Practical Audio DSP Projects with the ESP32 - UK.indd 63 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
void loop()
{
// no code
}
In the above program, the returned data is displayed on the Serial Monitor. A sample out-
put is shown in Figure 4.45 (only a part of the output is shown here).
The LEDs are named LED1 and LED2 and valid commands are as follows (any other com-
mands are ignored by the program):
Block diagram: The block diagram of the project is shown in Figure 4.46.
● 64
Practical Audio DSP Projects with the ESP32 - UK.indd 64 06-07-2023 10:40
Chapter 4 • Elementary Projects using The Arduino IDE and the ESP32 DevKitC
Circuit diagram: The circuit diagram is as in Figure 4.2, where the LEDs are connected to
ports 22 (LED1) and 23 (LED2) through 330-Ohm current limiting resistors. The LEDs are
turned ON when the port output is at logic 1 (high) and turned OFF when the port output
is at logic 0 (low).
Smartphone application
In this project, an Android-based smartphone is used to send the UDP commands. Although
one could develop a mobile application to send the UDP commands, there are many freely
available UDP app in the Play Store that can be used to send and/or receive UDP packets.
The one used in this project is called UDP RECEIVER and SENDER by Wezzi Studios (ver-
sion 4.0). This application can send and receive UDP packets from any other device running
the UDP protocol. The screen is in two parts: the upper Sender part and the lower Receiver
part (see Figure 4.47). Before sending a packet, the user must enter the destination IP ad-
dress, port number, and the message to be sent. Clicking the SEND UDP MESSAGE button
will send the packet to its destination. In the Receiver part, the local IP address is given.
The user must specify the required port number. Received packets will then be displayed
on the screen.
● 65
Practical Audio DSP Projects with the ESP32 - UK.indd 65 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Inside the setup routine, the LED ports are configured as outputs and both LEDs are turned
OFF to start with. Then function Connect_WiFi is called to connect to local WiFi and UDP
is started on the local port.
The remainder of the program is executed in an endless loop. Inside this loop, the program
waits to receive a packet (command) from the UDP server (smartphone here). The received
packet is stored in the character array Packet and the program checks the command and
if this is a valid command, turns ON/OFF the LEDs as required.
if(Packet[1] == '=')
{
if(Packet[0] == '1')
{
if(Packet[2] == 'O' && Packet[3] == 'N')
{
digitalWrite(LED1, HIGH);
}
else if(Packet[2] == 'O' && Packet[3] == 'F' && Packet[4] == 'F')
{
digitalWrite(LED1, LOW);
● 66
Practical Audio DSP Projects with the ESP32 - UK.indd 66 06-07-2023 10:40
Chapter 4 • Elementary Projects using The Arduino IDE and the ESP32 DevKitC
}
}
else if(Packet[0] == '2')
{
if(Packet[2] == 'O' && Packet[3] == 'N')
{
digitalWrite(LED2, HIGH);
}
else if(Packet[2] == 'O' && Packet[3] == 'F' && Packet[4] == 'F')
{
digitalWrite(LED2, LOW);
}
}
/*************************************************************
* UDP BASED CONTROL FROM MOBILE PHONE
* ===================================
*
* This is an UDP based control program where 2 LEDs are connected
* to GPIO ports 22 and 23 of the ESP32 devkitc board, and named
* as LED1 and LED2. Commands are sent from an Android type
* mobile phone to turn the LEDs ON/OFF. The ESP32 Devkitc is
* configured as an UDP client in this application. The format of
* the commands are as follows:
*
* 1=ON turn ON LED1
* 1=OFF turn OFF LED1
* 2=ON turn ON LED2
* 2=OFF turn OFF LED2
*
*
* File: UDPControl
* Author: Dogan Ibrahim
* Date: April, 2023
*
**************************************************************/
#include "WiFi.h"
#include <WiFiUdp.h>
//
// LED assignments
//
#define LED1 22
#define LED2 23
WiFiUDP udp;
● 67
Practical Audio DSP Projects with the ESP32 - UK.indd 67 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
//
// Use local port 5000
//
const int Port = 5000;
char Packet[80];
//
// Local Wi-Fi name and password
//
const char* ssid = "BTHomeSpot-XNH";
const char* password = "493105abxyz";
//
// This function connects the ESP32 Devkitc to the local Wi-Fi
// network. The network name and passwors are as specifed earlier
void Connect_WiFi()
{
WiFi.begin(ssid, password);
while(WiFi.status() != WL_CONNECTED)
{
delay(1000);
}
}
//
// Configure LEDs as outputs, turn OFF the LEDs to start with,
// Connect to the local Wi-Fi. Also, UDP is started in local port
//
void setup()
{
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
digitalWrite(LED1, LOW);
digitalWrite(LED2, LOW);
Connect_WiFi();
udp.begin(Port);
}
//
// This is the main program loop. Inside the main program we read
// UDP packets and then control the LEDs as requested. The format
// of the control commands are:
//
// 1=ON or 1=OFF for LED1
// 2=ON or 2=OFF for LED2
● 68
Practical Audio DSP Projects with the ESP32 - UK.indd 68 06-07-2023 10:40
Chapter 4 • Elementary Projects using The Arduino IDE and the ESP32 DevKitC
//
// Any other commands are simply ignored by the program
//
void loop()
{
int PacketSize = udp.parsePacket();
if(PacketSize)
{
udp.read(Packet, PacketSize);
if(Packet[1]=='=')
{
if(Packet[0]=='1')
{
if(Packet[2]=='O' && Packet[3]=='N')
{
digitalWrite(LED1, HIGH);
}
else if(Packet[2]=='O' && Packet[3]=='F' && Packet[4]=='F')
{
digitalWrite(LED1, LOW);
}
}
else if(Packet[0]=='2')
{
if(Packet[2]=='O' && Packet[3]=='N')
{
digitalWrite(LED2, HIGH);
}
else if(Packet[2]=='O' && Packet[3]=='F' && Packet[4]=='F')
{
digitalWrite(LED2, LOW);
}
}
}
}
}
As an example, Figure 4.49 shows the command sent from the smartphone application to
turn on LED1 (command: 1=ON).
● 69
Practical Audio DSP Projects with the ESP32 - UK.indd 69 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Description: In this project, a 4-channel relay board is connected to the ESP32 DevKitC
and the relay is controlled by sending commands from a Bluetooth classic app running on
an Android mobile phone. The following commands can be sent from the smartphone (#
character is the command terminator):
The aim: The aim of this project is to show how a 4-channel relay board can be connected
to the ESP32 DevKitC and also how it can be controlled using the Bluetooth classic commu-
nication feature with a mobile phone.
Block diagram: The block diagram of the project is given in Figure 4.50.
● 70
Practical Audio DSP Projects with the ESP32 - UK.indd 70 06-07-2023 10:40
Chapter 4 • Elementary Projects using The Arduino IDE and the ESP32 DevKitC
In this project, a 4-channel relay board (see Figure 4.51) from Elegoo (www.elegoo.com) is
used. This is an opto-coupled relay board having 4 inputs, one for each channel. The relay
inputs are at the bottom right-hand side of the board, while the relay outputs are located
at the top side of the board. The middle position of each relay is the common point, the
connection to its left is the normally closed (NC) contact, while the connection to the right
is the normally open (NO) contact. The relay contacts support AC 250 V at 10 A and 30 V
DC at 10 A. IN1, IN2, IN3 and IN4 are the active LOW inputs, which means that a relay
is activated when a logic LOW signal is applied to its input pin. Relay contacts are normally
closed (NC). Activating the relay changes the active contacts such that the common pin
and NC pin become the two relay contacts and at the same time the LED at the input cir-
cuit of the relay board corresponding to the activated relay is turned ON. The VCC can be
connected to either +3.3 V or +5 V. Jumper JD is used to select the voltage for the relay.
Caution Because the current drawn by a relay can be in excess of 80 mA, you must
remove this jumper and connect an external power supply (e.g., +5 V) to pin JD-VCC.
● 71
Practical Audio DSP Projects with the ESP32 - UK.indd 71 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Circuit diagram: The circuit diagram of the project is shown in Figure 4.52 where the
4-channel relay inputs IN1, IN2, IN3 and IN4 are connected to GPIO pins 5, 17, 16 and 4
respectively.
Program listing: The program listing is shown in Figure 4.53 (Program: BTRELAY).
/***********************************************************************
* BLUETOOTH CLASSIC 4-CHANNEL RELAY CONTROL
* =========================================
*
* In this program a 4-channel relay board is connected to input pins
* 5,17,16, and 4 of the ESp32 DevKitC. The program receives commands from
* a Bluetooth classic compatible mobile phone and controls the relays
*
* Program: BTRELAY
* Date : April, 2023
* Author : Dogan Ibrahim
**********************************************************************/
#include"BluetoothSerial.h"
BluetoothSerial BT;
//
// This function activates or de-activates the relays depending on
// received command in character array rcv. Command n=ON# activates
// Relayn, command n=OFF# de-activates Relayn. # is the terminator
//
void RelayControl()
{
if(rcv[1] == '=' && rcv[2] == 'O' && rcv[3] == 'N')
{
● 72
Practical Audio DSP Projects with the ESP32 - UK.indd 72 06-07-2023 10:40
Chapter 4 • Elementary Projects using The Arduino IDE and the ESP32 DevKitC
//
// Configure Relays as outputs, turn OFF the Relays to start with.
// Notice that a relay is turned OFF when logic HIGH is applied to its input
//
void setup()
{
for(int k = 0; k < 4; k++)
{
pinMode(RelayArray[k], OUTPUT); // Relays are outputs
digitalWrite(RelayArray[k], HIGH); // De-activate relays
}
BT.begin("ESPRelays"); // Initialize
}
void loop()
{
int dummy, k = 0, flag = 0;
while(1)
{
while(flag == 0) // while not terminator
{
● 73
Practical Audio DSP Projects with the ESP32 - UK.indd 73 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
At the beginning of the program, the header file BluetoothSerial.h is included in the pro-
gram, receive buffer rcv is defined, and connections between the relay board and ESP32
DevKitC are defined in byte array RelayArray. Inside the setup routine, all the relays are
configured as outputs, and they are de-activated. The serial Bluetooth is then initialized
to the name ESPRelays. Inside the main program loop, the program reads data from the
smartphone until the terminator character # is detected. The input buffer is then flashed so
that any remaining characters in the input buffer are deleted. The program then calls func-
tion RelayControl to activate or de-activate the relays based on the received command in
buffer rcv. Every valid command is confirmed by sending a message to the mobile phone.
For example, if the received command is 1=ON# then Relay1 is activated and message
Relay1 is activated is sent to the mobile phone. Similarly, command 1=OFF# de-activat-
ed Relay1 and so on for all the other relays. The main program loop then repeats, waiting
for a new command from the smartphone.
• The Android app installed in the previous project can also be used in this
project.
• Connect your ESP32 DevKitC to a power supply (e.g., PC USB port or a portable
power supply).
• Open the Bluetooth folder on your smartphone and pair the phone with
ESPRelay if requested. Delete any older pairings if not needed.
• Install and open the Serial Bluetooth Terminal on your mobile phone.
● 74
Practical Audio DSP Projects with the ESP32 - UK.indd 74 06-07-2023 10:40
Chapter 4 • Elementary Projects using The Arduino IDE and the ESP32 DevKitC
• Click Devices from the menu and then click on device ESPRelays. You should
see the Connected message displayed.
• Press and hold button M1 to save a command on the mobile phone. Enter the
command, e.g., 1=ON# as shown in Figure 4.54 and click the tick at the top
right-hand side of the screen. Repeat to save other commands in M2, M3, M4,
etc.
• Click button M1 to send command 1=ON# to the ESP32 DevKitC. Notice that
a confirmation message is displayed on the smartphone screen for every
command sent.
Figure 4.55, finally, shows some example commands sent to the ESP32 DevKitC.
● 75
Practical Audio DSP Projects with the ESP32 - UK.indd 75 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Chapter 5 • Sound
5.1 Overview
Sound waves are created by the vibration of objects, for example, the string of a guitar,
the speaker of a radio, a person's vocal tract, and so on. You can hear sounds because the
air movement causes eardrum vibrations, which in turn are converted into nervous signals
sent to the brain.
There are two types of waves: transverse waves and longitudinal waves. In longitudinal
waves, the vibrations are parallel to the direction of wave travel. Some examples of longi-
tudinal waves include ultrasound waves, sound waves, and seismic P-waves. In transverse
waves, the vibrations are at right angles to the direction of wave travel. Some examples of
transverse waves include ripples on the surface of water, electromagnetic waves (e.g., light
waves, radio waves, etc.), seismic S-waves, and others.
or T=1/f
where the time period is measured in seconds and frequency is measured in Hz (hertz). For
example, the period of a sound wave having a frequency of 50 Hz is given by:
T = 1 / 50 = 0.02 seconds, or 20 ms
● 76
Practical Audio DSP Projects with the ESP32 - UK.indd 76 06-07-2023 10:40
Chapter 5 • Sound
The frequency of a sound wave tells you about the pitch of that sound. A sound wave with
a higher frequency has a higher pitch. You should realize that most sound waves are made
up of combinations of lots of waves with different frequencies and amplitudes. For example,
in a conversation, people generate many sound waves with many combined frequencies
and amplitudes.
Of course, most sound waves are not pure like the ones shown above but made up of
combinations of lots of waves. Let's look at the sound waves corresponding to whistling,
speech, and music.
Wave speed
The wave speed is another feature of a wave. This is shown by the following mathematical
expression:
Where v is the wave speed in m/s, f is the frequency in Hz, and λ is the wavelength meas-
ured in metres (m).
For example, the wave speed of a wave with the frequency of 50 Hz and wavelength of 6
metres is given by:
v = 50 × 6 = 300 m/s
The speed of sound depends on the medium where it is created, its temperature and den-
sity. Some examples at 25 ºC are:
● 77
Practical Audio DSP Projects with the ESP32 - UK.indd 77 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
The human audio spectrum is divided into 7 bands with the following frequencies:
In digital audio recording, a microphone is still used to convert the sound signals into
electrical signals, but then these analog signals are converted into digital forms using
analog-to-digital converter hardware. The resulting digital signals are saved as files in
computer memory. Nowadays, it is also possible to use digital microphones and record
signals directly in digital form.
A concise comparison between key aspects of analog and digital audio signals is given
below.
Degradation of quality: the quality of analog audio degrades as tape cassettes or vinyl
record age. This degradation is also noticeable when a recording gets copied or played back
many times. Digital signals on the other hand do not degrade by aging. Digital signals can
be copied to other mediums without using their qualities.
Signal to noise ratio (SNR): SNR is the amount of noise generated when a recording is
played. In other words, it describes how much unwanted noise signal is present in a played
sound signal. SNR is measured in decibels (dB). The higher the value the less noise there is
in the signal. For example, if an audio signal has an SNR of 50 dB, it means that the level
of the desired signal is 50 dB higher than the level of noise. Analog audio signals have low
SNR when played. Digital signals on the other hand achieve higher SNR and hence sound
clearer when played back.
● 78
Practical Audio DSP Projects with the ESP32 - UK.indd 78 06-07-2023 10:40
Chapter 5 • Sound
Audio bandwidth: The audio bandwidth is the range of signals permitted to be recorded
or played back. The higher the bandwidth the higher will be the maximum signal that can
be recorded correctly. Analog recordings in general have higher and bandwidths which cor-
respond to higher resolutions without compromising the audio quality.
Media type: digital audio signals can be stored in digital memories. Nowadays, smart-
phones, iPads, and tablets can store thousands of digital audio files in very small places.
This is not the case with analog media. Tape cassettes or vinyl records are bulky and they
can store only a limited amount of data.
In this book, the coverage is mainly using digital audio files and carrying out digital audio
signal processing (DSP) using digital audio files.
PCM: This stands for Pulse-Code Modulation and there is no compression. The digital re-
cording is very close to its exact representation of analog sound. The average size of a PCM
file is about 10 MB per second. Therefore, a 3-minute PCM music file can take up to 30 MB
of disk space.
WAV: This stands for Waveform Audio file format, developed by Microsoft and IBM. Al-
though not all WAV files are uncompressed, most are and they are in PCM format with
wrappers, making them suitable for Windows systems. The average size of a WAV file is
about 10 MB per second. Therefore, a 3-minute WAV music file can take up to 30 MB of
disk space.
AIFF: This stands for Audio Interchange File Format and is similar to WAV. AIFF was de-
veloped by Apple for their MAC systems. AIFF is basically PCM-type files with wrappers,
making them suitable for MAC systems (they can be opened in Windows systems). Al-
though most AIFF audio files are uncompressed PCM files, there are compressed versions
as well called AIFF-C. The average size of a AIFF file is about 10 MB per second. Therefore,
a 3-minute AIFF music file can take up to 30 MB of disk space.
● 79
Practical Audio DSP Projects with the ESP32 - UK.indd 79 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
MP3: This stands for MPEG-1 Audio Layer 3. This format is very popular for music files. In
this format, the quality of sound is reduced beyond the hearing range of normal ear. Also,
the quality of the sound is reduced for sounds that are not easy to hear. Almost all digital
devices nowadays with audio playback capabilities (e.g., PCs, smartphones, tablets, smart
TVs, etc.) can play MP3 audio files. The average bitrate for an MP3 file is 128 kbits per
second which requires about 1 Megabytes of data per minute of audio. Note: do not mix up
MP3 and MP4. MP3 is audio only, while MP4 supports both audio and video.
AAC: This stands for Advanced Audio Coding. Although it was developed as a competitor
to MP3, it never became as popular as MP3 even though it uses a much more advanced
compression algorithm than the MP3. AAC is currently used by YouTube, iOS, Android, and
by PlayStations. AAC files are slightly smaller than MP3 files.
WMA: This stands for Windows Media Audio. It was developed as a competitor to MP3 and
its compression algorithm is very similar to AAC, giving higher-quality audio sound. WMA
is a proprietary format created by Microsoft and as such it has not become very popular.
WMA files are slightly larger than MP3 files.
FLAC: This stands for Free Lossless Audio Codec and it is a popular file format that can
compress a file by up to 60% without losing its quality. FLAC is the main competitor of MP3
for music files and it is currently regarded as the best audio file format as far as size and
sound quality are concerned. For example, a 3-minute FLAC music file takes about 15 MB
as compared to MP3 which takes only 3 MB.
ALAC: This stands for Apple Lossless Audio Codec and it is similar to FLAC, although it is
less efficient as far as compression is concerned. Apple products such as iOS and iTunes
support ALAC. ALC file size is similar to those of FLAC.
There is also a lossless version of the WMA file format, but it is not as efficient as the FLAC
or ALAC.
● 80
Practical Audio DSP Projects with the ESP32 - UK.indd 80 06-07-2023 10:40
Chapter 5 • Sound
● 81
Practical Audio DSP Projects with the ESP32 - UK.indd 81 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
6.1 Overview
The acronym DSP stands for one of two things: Digital Signal Processor, or Digital Signal
Processing. A Digital Signal Processor refers to specialized microcontroller hardware de-
signed to execute specialized instructions in real time.
The topic of this book is Digital Signal Processing — or DSP from here on in this book. DSP
is a very broad field covering signals from very low frequencies to very high frequencies.
In this book, we are only interested in audio signals covering the frequency range of 20
Hz to 20 kHz. In a typical DSP application, the input signal (e.g., from a microphone) can
either be digital or analog. In the case of analog input, the signal is converted into digital
form using an ADC (analog-to-digital converter) and is fed to a microcontroller for further
processing. The signal is then processed in one of these ways:
The resulting digital signal is converted back into analog using a DAC (digital-to-analog
converter) and sent to a loudspeaker or some other output device. All of the signal process-
ing is conducted using software algorithms running on the target microcontroller. It is much
easier to edit and manipulate digital signals than analog signals. DSP is used extensively
nowadays by professional music makers. Not surprisingly, many plugins are available on
PCs which simplify the editing and processing of already recorded music files.
The global audio DSP market size was valued at $11.06 billion in 2019 and is projected to
reach $23.43 billion by 2027 (Allied Market Research).
This book is about using the ESP32 DevKitC microcontroller development board in audio
DSP applications. Many working projects are given in the book to illustrate how simple
hardware can be set up around the ESP32 processor and how programs can be developed
to achieve audio DSP processing in real time.
● 82
Practical Audio DSP Projects with the ESP32 - UK.indd 82 06-07-2023 10:40
Chapter 6 • Audio DSP Projects
Figure 6.1 shows the block diagram of a conventional audio DSP system that does not
use the I2bus. Here, the audio signal is received from an analog microphone. This signal
is then converted into digital form using an ADC. The resulting digital signal is then fed
to a microcontroller which processes this digital signal. At the end, the signal is converted
back into analog using a DAC converter and is fed to a speaker. An analog amplifier (not
shown) is typically used to increase the signal level for the loudspeaker. In most low-fre-
quency applications, the ADC and DAC can be part of the microcontroller. In high-speed
and high-quality applications, it may be necessary to use external, professional-quality ADC
and DAC converters.
Figure 6.2 shows the block diagram of a digital audio DSP system using the I2S bus inter-
face. Here, a digital microphone is used and compatible with the I2S bus. The output of
the microphone, which is a digital signal, is fed to the microcontroller I2S bus input. The
signal is processed by the microcontroller as required and gets sent to an I2S-compatible
amplifier module in digital form. The output of the amplifier is an analog signal which drives
the speaker.
As you will be seeing in the example projects in this chapter, the microcontroller used in all
the projects is the ESP32 DevKitC.
Bit Clock: this pin is the serial clock line, usually denoted as BCLK. The clock runs contin-
uously.
Word Select: this pin is usually denoted by WS and it selects the channels. 0 corresponds
to left channel, while 1 corresponds to the right channel.
● 83
Practical Audio DSP Projects with the ESP32 - UK.indd 83 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Data: This pin is usually denoted by SD, or SDATA and is the serial data line. The data is
sent out in 2's complement format with the MSB bit first. The transmitter and receiver do
not need to have an agreed-upon word length; the transmitter sends what it has, and the
receiver takes what it can use. New data bits can be clocked out on the rising or falling edge
of the clock. However, they must be clocked in on the rising edge.
The bit clock is sent out for each bit of data on the data line. The frequency of this clock is
the given by the product of the sample rate, the number of bits per channel, and the num-
ber of channels. In a typical audio CD, the standard is the 44.1 kHz sample rate with 16 bits
of data. Assuming 2 channels (i.e., stereo), the bit clock frequency will be:
Therefore, if you want to send two channels of high-quality audio, you will need a clock rate
of 1.4112 MHz.
The telephone quality sound is sampled at 8 kHz with 8 bits and there is only one channel.
Therefore, to send telephone-quality audio you will need a clock frequency of:
8 kHz × 8 × 1 = 64 kHz
I2S allows up to 2 channels to be used on the same data line and this is selected by the
Word select bit. For 2 channel stereo operation the left audio is transmitted on the low cycle
of the Word select, and the right channel is transmitted on the high cycle. The I2S bus is not
like the I2C bus where multiple devices can be connected on the same bus line. In I2S only
two channels of a device can be used, and multiple devices cannot be connected to the bus.
The maximum length of the I2S bus is specified as 3 meters.
The bit clock and Word select signals can be generated with a receiver, transmitter, or a
third-party controller (see Figure 6.3).
● 84
Practical Audio DSP Projects with the ESP32 - UK.indd 84 06-07-2023 10:40
Chapter 6 • Audio DSP Projects
Figure 6.4: I2S bus timing (taken from the I2S specification).
In this book, you will be using the ESP32 DevKitC development board.
● 85
Practical Audio DSP Projects with the ESP32 - UK.indd 85 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
A useful mode is also supported where the output of I2S0 can be internally routed to the in-
ternal ESP32 DAC (internal DAC is 8 bits wide) so that direct analog output can be obtained
without any external I2S device.
There are no dedicated I2S pins on the ESP32. Instead, you configure/enable the
pins in your code using the supplied I2S library functions.
In the remaining sections of this chapter, projects are given using the I2S bus interface
of the ESP32 DevKitC for audio digital DSP. The following sub-sections are given for each
project where applicable:
• Title
• Description
• Block diagram
• Circuit diagram
• Construction (wherever possible)
• Program listing and full description
• Suggestions for further work (wherever possible)
The aim: The aim of this project is to show how a digital microphone can be connected to
the ESP32 processor and how audio signals can be captured and displayed.
Block diagram: Figure 6.5 shows the block diagram of the project.
● 86
Practical Audio DSP Projects with the ESP32 - UK.indd 86 06-07-2023 10:40
Chapter 6 • Audio DSP Projects
The INMP441 is a 6-pin, round shaped device with the following pin definitions:
VDD: +3.3 V
GND: power supply GND
SD: serial data
SCK: serial clock
WS: Word Select
L/R: left/right channel selection. When LOW, the microphone outputs signals
on the left channel. When HIGH, the microphone outputs signals on the
right channel
The microphone device is shipped with the pins unconnected. Six pins and a 6-way Dupont
cable are supplied with the microphone. You should use a fine-tip soldering iron to connect
the supplied pins to the microphone holes. The Dupont cable should then be connected to
the microphone pins.
Circuit diagram: Figure 6.7 shows the circuit diagram of the project. The connections
between the microphone and the ESP32 DevKitC are as follows:
● 87
Practical Audio DSP Projects with the ESP32 - UK.indd 87 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Notice that the microphone L/R pin is connected to GNS+D as you will be using the Left
channel only. Notice that there is a hole on the microphone device where the pin names are
written and this is where the actual microphone is.
Program listing: The program listing is shown in Figure 6.8 (Program: DigMic). At the
beginning of the program, the I2S library is included in the program and the GPIO connec-
tions between the ESP32 and INMP441 microphone are defined. Since you will be using the
I2S0, this is defined. The input buffer and its length are then defined. Function i2s_set-
pin() sets the pin configuration as defined earlier.
typedef struct
{
i2s_mode_t mode; /*I2S work mode*/
int sample_rate; /*I2S sample rate*/
i2s_bits_per_sample_t bits_per_sample; /*I2S bits per sample*/
i2s_channel_fmt_t channel_format; /*I2S channel format */
i2s_comm_format_t communication_format; /*I2S communication format
*/
int intr_alloc_flags; /*Flags used to allocate
interrupt*/
int dma_buf_count; /*I2S DMA Buffer Count */
int dma_buf_len; /*I2S DMA Buffer Length */
} i2s_config_t;
● 88
Practical Audio DSP Projects with the ESP32 - UK.indd 88 06-07-2023 10:40
Chapter 6 • Audio DSP Projects
Function setup() sets the Serial Monitor baud rate to 115200, calls functions i2s_install()
and i2s_setpin() and then starts the i2sport.
Function loop() is the main program loop. Here, data is received from the I2S interface by
calling function i2s_read(). The received samples are averaged and sent to the Serial Plot-
ter of the Arduino IDE. Notice that another function to receive samples is: i2s_pop_sam-
ple(), but this function may be removed in future releases of the I2S library.
https://docs.espressif.com/projects/esp-idf/en/v3.3/api-reference/peripherals/
i2s.html
Some of the commonly used I2S functions are (see the above link for the function argu-
ments):
/****************************************************************
* DIGITAL MICROPHONE SOUND CAPTURE
* ================================
*
* In this program an INMP441 digital microphone is used to capture
* sound signals using the I2S interface of the ESP32 DevKitC
* microcontroller development system. The captured waveform is
* displayed on the Serial Monitor
*
● 89
Practical Audio DSP Projects with the ESP32 - UK.indd 89 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
int16_t i, samples_read;
int bytes_read;
size_t bytesIn;
#define buffer_Len 64
int16_t i2s_Buffer[buffer_Len];
float mean_samples;
//
// INMP441 I2S microphone connections
//
#define I2S_WS 25 // WS pin
#define I2S_SD 32 // SD pin
#define I2S_SCK 33 // SCK pin
//
// I2S pin configuration
//
void i2s_setpin()
{
const i2s_pin_config_t pin_config =
{
.bck_io_num = I2S_SCK,
.ws_io_num = I2S_WS,
.data_out_num = I2S_PIN_NO_CHANGE, // Not used (output only)
.data_in_num = I2S_SD
};
i2s_set_pin(I2S_PORT, &pin_config);
}
//
// Configure I2S
//
void i2s_install()
{
const i2s_config_t i2s_config =
● 90
Practical Audio DSP Projects with the ESP32 - UK.indd 90 06-07-2023 10:40
Chapter 6 • Audio DSP Projects
{
.mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX),
.sample_rate = 44100,
.bits_per_sample = i2s_bits_per_sample_t(16),
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format=i2s_comm_format_t(I2S_COMM_FORMAT_I2S |
I2S_COMM_FORMAT_I2S_MSB),
.intr_alloc_flags = 0,
.dma_buf_count = 8,
.dma_buf_len = buffer_Len,
.use_apll = false
};
i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL);
}
void setup()
{
Serial.begin(115200); // Serial Monitor
i2s_install(); // Install i2s
i2s_setpin(); // COnfigure pins
i2s_start(I2S_PORT); // Start i2s
delay(500); // Small delay
}
//
// Read audio samples into i2s_Buffer, find the mean and send to plotter.
// bytesIn is the number of bytes read, i2s_Buffer stores the samples read
// buffer_Len is teh length of the buffer
//
void loop()
{
bytesIn = 0;
bytes_read = i2s_read(I2S_PORT,&i2s_Buffer,buffer_Len,&bytesIn,portMAX_DELAY);
samples_read = bytesIn / 8;
if(samples_read > 0)
{
mean_samples = 0;
for(i=0; i < samples_read; i++)
{
mean_samples = mean_samples + i2s_Buffer[i];
}
mean_samples = mean_samples / samples_read;
Serial.println(mean_samples); // Send to Serial Monitor (plotter)
● 91
Practical Audio DSP Projects with the ESP32 - UK.indd 91 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Compile and upload your program to the ESP32 DevKitC. Start the Serial Plotter, making
sure that the baud rate is set to 115,200. You should see a sound waveform similar to the
one shown in Figure 6.9 when it is quiet. Playing music near the microphone should change
the waveform. An example is shown in Figure 6.10.
● 92
Practical Audio DSP Projects with the ESP32 - UK.indd 92 06-07-2023 10:40
Chapter 6 • Audio DSP Projects
Figure 6.11 shows the SCK signal captured using a digital oscilloscope.
The aim: The aim of this project is to show how an I2S-compatible digital microphone as
well as an I2S-compatible class-D amplifier module and a speaker can be connected to the
ESP32 processor.
● 93
Practical Audio DSP Projects with the ESP32 - UK.indd 93 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Block diagram: Figure 6.12 shows the block diagram of the project.
Figure 6.13 shows the MAX98357A amplifier module. This module has the following fea-
tures:
• 3 W output power (into 4 ohms at 5 V). 4 ohm or 8 ohm speakers with voice
coils must be used (no dynamic speakers)
• Class-D amplifier module with on-board DAC decoder module
• 2.5 V to +5.5 V operation
• 2.4 mA quiescent current consumption
• 92% efficiency
• Only 25 μV RMS output noise
• 8 kHz to 96 kHz sampling
• 77 dB PSRR at 1 kHz
• Space-saving module (1.345 mm × 1.435 mm)
+ –: Speaker connection
LRC: I2S WS
BCLK: I2S SCK
DIN: I2S SD (this is the data input, not the SD pin)
GAIN: Gain set with a resistor
SD: L/R output select
GND: Power supply GND
VIN: Power (+3.3 V)
● 94
Practical Audio DSP Projects with the ESP32 - UK.indd 94 06-07-2023 10:40
Chapter 6 • Audio DSP Projects
The SD pin is for L/R output selection and shutdown mode. The various settings of the SD
pin are:
• Connect SD to GND (less than 0.16 V) to shut down the amplifier.
• Connect SD to a voltage between 0.16 V and 0.77 V for stereo average output
(i.e., Right + Left / 2).
• Connect SD between 0.77 V and 1.4 V for the Right channel only.
• Connect SD to higher than 1.4 V for the Left channel only.
The output signal of the amplifier is a 330-KHz PWM square wave with a duty cycle pro-
portional to the audio signal. The high-frequency component(s) of the signal are effectively
filtered out by the inductance of the speaker coil.
The output power of the amplifier at different power supply voltages is (for 10% THD. For
lower THD, the output power will be less):
The gain of the amplifier can be set at: 3 dB, 6 dB, 9 dB, 12 dB, and 15 dB using a resistor
as follows (the module should be powered down and up for the new gain to take effect):
The amplifier module can be connected to any pins of the ESP32 DevKitC development
board. Also, the amplifier power supply VIN can be connected to +5 V for higher power
output.
● 95
Practical Audio DSP Projects with the ESP32 - UK.indd 95 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Circuit diagram: The circuit diagram of the project is shown in Figure 6.14. the connec-
tions between the ESP32, INMP441, and MAX98357A are as follows. Notice here that the
amplifier gain is set to 15 dB:
Program listing: Figure 6.15 shows the program listing (Program: DigAmp). Part of this
program is similar to Figure 6.8. At the beginning of the program, the buffer size is set to
64 and buffer i2s_Buffer is declared. Then the microphone the amplifier connections are
defined as the GPIO ports of ESP32 as follows:
//
// INMP441 I2S microphone connections
//
#define I2S_WS_MIC 25
#define I2S_SD_MIC 32
#define I2S_SCK_MIC 33
//
● 96
Practical Audio DSP Projects with the ESP32 - UK.indd 96 06-07-2023 10:40
Chapter 6 • Audio DSP Projects
The two I2S modules I2S0 and I2S1 of ESP32 are assigned to I2S_PORT0 and I2S_PORT1,
respectively. I2S_PORT0 is used for the microphone and I2S_PORT1 is used for the am-
plifier. The program then configures the microphone and amplifier pins as follows. Notice
that the microphone has input and no output, and the amplifier has output and no input:
//
// I2S microphone pin configuration
//
void i2s_setpin_MIC()
{
const i2s_pin_config_t pin_config =
{
.bck_io_num = I2S_SCK_MIC,
.ws_io_num = I2S_WS_MIC,
.data_out_num = I2S_PIN_NO_CHANGE, // No output
.data_in_num = I2S_SD_MIC // Input from microphone
};
i2s_set_pin(I2S_PORT0, &pin_config);
}
//
// I2S amplifier pin configuration
//
void i2s_setpin_AMP()
{
const i2s_pin_config_t pin_config =
{
.bck_io_num = I2S_SCK_AMP,
.ws_io_num = I2S_WS_AMP,
.data_out_num = I2S_SD_AMP, // Output to amplifier
.data_in_num = I2S_PIN_NO_CHANGE // No input
};
i2s_set_pin(I2S_PORT1, &pin_config);
}
The program then installs the I2S0 for the microphone using a sampling rate of 44100 Hz,
16 bits and in RX mode:
● 97
Practical Audio DSP Projects with the ESP32 - UK.indd 97 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
//
// Configure I2S0 for microphone
//
void i2s_install_MIC()
{
const i2s_config_t i2s_config =
{
.mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX),
.sample_rate = 44100,
.bits_per_sample = i2s_bits_per_sample_t(16),
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S |
I2S_COMM_FORMAT_I2S_MSB),
.intr_alloc_flags = 0,
.dma_buf_count = 8,
.dma_buf_len = buffer_Len,
.use_apll = false
};
i2s_driver_install(I2S_PORT0, &i2s_config, 0, NULL);
}
v1 is also installed for the amplifier, where the sample rate and bit count is same as for the
microphone, but the mode is set to TX:
//
// Configure I2S1 for amplifier
//
void i2s_install_AMP()
{
const i2s_config_t i2s_config =
{
.mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_TX),
.sample_rate = 44100,
.bits_per_sample = i2s_bits_per_sample_t(16),
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S |
I2S_COMM_FORMAT_I2S_MSB),
.intr_alloc_flags = 0,
.dma_buf_count = 8,
.dma_buf_len = buffer_Len,
.use_apll = false
};
i2s_driver_install(I2S_PORT1, &i2s_config, 0, NULL);
}
● 98
Practical Audio DSP Projects with the ESP32 - UK.indd 98 06-07-2023 10:40
Chapter 6 • Audio DSP Projects
Inside the setup() function I2S is installed for the microphone and the amplifier, pins are
configured, and both I2S channels are started.
The main program runs continuously inside the loop() function, Here, function i2s_read()
captures audio data from the microphone. This data is then sent to the amplifier using
function i2s_write():
/****************************************************************
* DIGITAL MICROPHONE, AMPLIFIER AND SPEAKER
* =========================================
*
* In this program an INMP441 digital microphone is used to capture
* sound signals using the I2S interface of the ESP32 DevKitC
* microcontroller development system. Additionally, a MAX98357A
* class D amplifier module and a speaker are used in the project
* The program captures the audio signals, amplifies them and
* sends to the speaker
*
* Author : Dogan Ibrahim
* Program: DigAmp
* Date : April, 2023
**************************************************************/
#include <driver/i2s.h>
int bytes_read;
size_t bytesIn, bytesWritten;
#define buffer_Len 64
int16_t i2s_Buffer[buffer_Len];
//
// INMP441 I2S microphone connections
//
#define I2S_WS_MIC 25
#define I2S_SD_MIC 32
#define I2S_SCK_MIC 33
//
// MAX98357A amplifier connections
//
#define I2S_WS_AMP 21
#define I2S_SD_AMP 22
#define I2S_SCK_AMP 23
● 99
Practical Audio DSP Projects with the ESP32 - UK.indd 99 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
//
// I2S microphone pin configuration
//
void i2s_setpin_MIC()
{
const i2s_pin_config_t pin_config =
{
.bck_io_num = I2S_SCK_MIC,
.ws_io_num = I2S_WS_MIC,
.data_out_num = I2S_PIN_NO_CHANGE, // Not used (output only)
.data_in_num = I2S_SD_MIC
};
i2s_set_pin(I2S_PORT0, &pin_config);
}
//
// I2S amplifier pin configuration
//
void i2s_setpin_AMP()
{
const i2s_pin_config_t pin_config =
{
.bck_io_num = I2S_SCK_AMP,
.ws_io_num = I2S_WS_AMP,
.data_out_num = I2S_SD_AMP,
.data_in_num = I2S_PIN_NO_CHANGE
};
i2s_set_pin(I2S_PORT1, &pin_config);
}
//
// Configure I2S0 for microphone
//
void i2s_install_MIC()
{
const i2s_config_t i2s_config =
{
.mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX),
.sample_rate = 44100,
.bits_per_sample = i2s_bits_per_sample_t(16),
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S |
I2S_COMM_FORMAT_I2S_MSB),
.intr_alloc_flags = 0,
.dma_buf_count = 8,
● 100
Practical Audio DSP Projects with the ESP32 - UK.indd 100 06-07-2023 10:40
Chapter 6 • Audio DSP Projects
.dma_buf_len = buffer_Len,
.use_apll = false
};
i2s_driver_install(I2S_PORT0, &i2s_config, 0, NULL);
}
//
// Configure I2S1 for amplifier
//
void i2s_install_AMP()
{
const i2s_config_t i2s_config =
{
.mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_TX),
.sample_rate = 44100,
.bits_per_sample = i2s_bits_per_sample_t(16),
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S |
I2S_COMM_FORMAT_I2S_MSB),
.intr_alloc_flags = 0,
.dma_buf_count = 8,
.dma_buf_len = buffer_Len,
.use_apll = false
};
i2s_driver_install(I2S_PORT1, &i2s_config, 0, NULL);
}
void setup()
{
Serial.begin(115200);
i2s_install_MIC();
i2s_install_AMP();
i2s_setpin_MIC();
i2s_setpin_AMP();
i2s_start(I2S_PORT0);
i2s_start(I2S_PORT1);
}
//
// Read audio samples into i2s_Buffer from the microphone
// send the captured data to the amplifier and then to the
// speaker
//
void loop()
● 101
Practical Audio DSP Projects with the ESP32 - UK.indd 101 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
{
bytesIn = 0;
bytes_read = i2s_read(I2S_PORT0,&i2s_Buffer,buffer_Len,&bytesIn,portMAX_DELAY);
if(bytesIn > 0)
{
i2s_write(I2S_PORT1,&i2s_Buffer,bytesIn,&bytesWritten,portMAX_DELAY);
}
}
As an example, to increase the gain by a factor of 3, you will have to modify the code in-
side the program loop() as follows. The modified program is named as DigAmp2 on the
website of the book:
void loop()
{
bytesIn = 0;
bytes_read = i2s_read(I2S_PORT0,&i2s_Buffer,buffer_Len,&bytesIn,portMAX_DELAY);
if(bytesIn > 0)
{
for(int i=0; i < bytesIn; i++)i2s_Buffer[i]=3*i2s_Buffer[i];
i2s_write(I2S_PORT1,&i2s_Buffer,bytesIn,&bytesWritten,portMAX_DELAY);
}
The aim: The aim of this project is to show how MP3-compatible music stored on an SD
card can be played using your ESP32. It is assumed that you have already downloaded and
stored MP3-compatible music on your SD card.
Block diagram: Figure 6.16 shows the block diagram. In this project, you will be using the
MAX98357A I2S-compatible amplifier and a microSD card.
● 102
Practical Audio DSP Projects with the ESP32 - UK.indd 102 06-07-2023 10:40
Chapter 6 • Audio DSP Projects
Circuit diagram: You have already used a microSD card-based projects in Sections 4.8
and 4.9. Here, the same circuit diagram as the one in Figure 4.37 is used, but additionally,
the MAX98357A amplifier module and a speaker are added to the circuit.
Figure 6.17 shows the circuit diagram. The connections between the microSD card and
ESP32 DevKitC, as well as between the amplifier and the ESP32 are as follows:
● 103
Practical Audio DSP Projects with the ESP32 - UK.indd 103 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Program listing: In this project you will be using the ESP32-Audio I2S library to simplify
programming. The steps to load this library to your Arduino IDE are:
• Go to this website:
https://github.com/schreibfaul1/ESP32-audioI2S
• Click Code (green button) and save the .zip file in a folder on your hard disk.
The file is named: ESP32-audioI2S-master.zip.
• Browse to the library you just downloaded and click Open. You should see the
message Library added to your libraries. Check "include library" menu
at the bottom of the IDE screen.
Figure 6.18 shows the program listing (Program: SDMusic). It is assumed that a music file
called: sample-15s.mp3 (taken from website: https://samplelib.com/sample-mp3.html)
has already been stored on your microSD card. At the beginning of the program the library
headers used in te program are included. Then, the connections between the microSD card
adapter and ESP32, and between the amplifier and ESP32 are defined. CS of the card is
configured as output and set HIGH so that it is disabled to start with. The SPI bus is then
configured for the card and the card is started. If the microSD card is not accessible (e.g.,
wrong connections, card not in the header, or card not formatted correctly) the message
Error in microSD card is displayed and the program stops (waits forever). Otherwise, the
audio volume is set to 10 and the music file on the microSD card is opened. the volume
can be set to 21 in 22 steps (i.e., the maximum volume is 21). The number of steps can be
changed with function setVolumeSteps(). The loop() is called repeatedly. If everything
is correct, you should hear the music on your speaker. If there is no music, start the Serial
Monitor and check to make sure that the microSD card is accessed correctly (i.e., message
microSD card accessed correctly is displayed).
● 104
Practical Audio DSP Projects with the ESP32 - UK.indd 104 06-07-2023 10:40
Chapter 6 • Audio DSP Projects
/****************************************************************
* PLAY MUSIC STORED ON SD CARD THROUGH AMPLIFIER
* ==============================================
*
* In this program MP3 compatible music file is stored on microSD
* card. The program opens the file and plays the music on the
* speaker through the MAX98357A amplifier
*
* Author : Dogan Ibrahim
* Program: SDMusic
* Date : April, 2023
**************************************************************/
#include "Arduino.h"
#include "Audio.h"
#include "SD.h"
#include "FS.h"
//
// microSD card to ESP32 connections
//
#define CARD_MOSI 23
#define CARD_MISO 19
#define CARD_SCK 18
#define CARD_CS 5
//
// Define MAX98357A amplifier connections
//
#define I2S_BCLK 4
#define I2S_LRC 21
#define I2S_DOUT 22
void setup()
{
pinMode(CARD_CS, OUTPUT); // CS is output
digitalWrite(CARD_CS, HIGH); // CS HIGH
SPI.begin(CARD_SCK,CARD_MISO,CARD_MOSI); // Init SPI bus
● 105
Practical Audio DSP Projects with the ESP32 - UK.indd 105 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
}
Serial.println("microSD card accessed correctly");
void loop()
{
audio.loop();
}
The aim: The aim of this project is to show how more than one MP-compatible music
stored on the SD card can be played one after the other one.
The block diagram and circuit diagram of the project are in Figure 6.16 and Figure 6.17,
respectively.
● 106
Practical Audio DSP Projects with the ESP32 - UK.indd 106 06-07-2023 10:40
Chapter 6 • Audio DSP Projects
Program listing: Figure 6.20 shows the program listing (Program: SDMusic2). Four short
MP3-compatible music files with the names: sample-15s.mp3, sample-12s.mp3, sam-
ple-9s.mp3 and sample-6s.mp3 are taken from this website:
https://samplelib.com/sample-mp3.html
The first file is played inside the setup() routine. At the end of a file, the program jumps
to function called audio_eof_mp3(). Inside this file, the files in the playlist are defined so
that at the end of a file the program jumps here and continues with the next music file. The
integer variable PlayList chooses which file is to play next. This variable changes from 0 to
the maximum number of files, which is 4 in this example project. Initially, PlayList is set
to 1 so that the first time round the second file plays after the first one.
/****************************************************************
* PLAY LIST OF MUSIC FILES STORED ON SD CARD
* ==========================================
*
* In this program a list of MP3 compatible music files are stored
* on microSD card.The program opens these files and plays them
* continuously one after the other one
*
* Author : Dogan Ibrahim
* Program: SDMusic2
* Date : April, 2023
**************************************************************/
#include "Arduino.h"
#include "Audio.h"
#include "SD.h"
#include "FS.h"
//
// microSD card to ESP32 connections
● 107
Practical Audio DSP Projects with the ESP32 - UK.indd 107 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
//
#define CARD_MOSI 23
#define CARD_MISO 19
#define CARD_SCK 18
#define CARD_CS 5
//
// Define MAX98357A amplifier connections
//
#define I2S_BCLK 4
#define I2S_LRC 21
#define I2S_DOUT 22
int No_Of_Files = 4;
void setup()
{
pinMode(CARD_CS, OUTPUT); // CS is output
digitalWrite(CARD_CS, HIGH); // CS HIGH
SPI.begin(CARD_SCK,CARD_MISO,CARD_MOSI); // Init SPI bus
//
// Program jumps here at the end of a music file
//
void audio_eof_mp3(const char *info)
{
static int PlayList = 1;
if(PlayList == 0)audio.connecttoFS(SD,"sample-15s.mp3");
if(PlayList == 1)audio.connecttoFS(SD,"sample-12s.mp3");
if(PlayList == 2)audio.connecttoFS(SD,"sample-9s.mp3");
if(PlayList == 3)audio.connecttoFS(SD,"sample-6s.mp3");
● 108
Practical Audio DSP Projects with the ESP32 - UK.indd 108 06-07-2023 10:40
Chapter 6 • Audio DSP Projects
PlayList++;
if(PlayList == No_Of_Files)PlayList = 0;
}
void loop()
{
audio.loop();
}
The library provides a number of useful functions that can be used in your programs. Some
of these functions are listed here.
This function is called automatically when a music file is closed and a new one is opened. It
displays useful information about the file. The information is displayed on the Serial Monitor
which must already be opened. The function is called as follows:
● 109
Practical Audio DSP Projects with the ESP32 - UK.indd 109 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Further information on the audio library functions can be obtained from the following au-
dioI2S FAQ:
https://github.com/schreibfaul1/ESP32-audioI2S/wiki
The aim: The aim of this project is to show how you can access Internet radio stations with
your ESP32 DevKitC.
Block diagram: Figure 6.22 shows the block diagram of the project.
Circuit diagram: The circuit diagram, shown in Figure 6.23, is similar to Figure 6.17, but
there is no microSD card.
● 110
Practical Audio DSP Projects with the ESP32 - UK.indd 110 06-07-2023 10:40
Chapter 6 • Audio DSP Projects
Program listing: Figure 6.24 shows the program listing (Program: IRadio). At the be-
ginning of the program, the library headers used are included in the program. Then the
local Wi-Fi name (ssid) and password (pwd) are specified. The program then defines the
connection between the MAX98357A amplifier module and ESP32 DevKitC. Connection to
the local Wi-Fi is then done. If the Serial Monitor is opened, then the message Wi-Fi is
connected… will be displayed after successful access of the Wi-Fi router. The program sets
the volume and connects to a radio station over the Internet. In this project, connection is
made to the classic music station Klassik1 which has the following web link:
http://tuner.classical102.com/listen.pls
Two event-driven library functions are defined in the program. Function audio_showsta-
tion() displays the station name. Function audio_showstreamtitle() displays the name
of the current stream playing (this changes automatically as the stream is changed). Figure
6.25 is a typical display on the Serial Monitor.
/****************************************************************
* INTERNET RADIO
* ==============
*
* This is an Internet radio project. This program accesses
* an Internet radio station and sends its audio to a speaker
* through the I2S compatible amplifier
*
* In this program connection is made to the following station:
*
* http://tuner.classical102.com/listen.pls
*
* which is station: Klassik1
*
* Author : Dogan Ibrahim
● 111
Practical Audio DSP Projects with the ESP32 - UK.indd 111 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
* Program: IRadio
* Date : April, 2023
**************************************************************/
#include "Arduino.h"
#include "Audio.h"
#include "WiFi.h"
//
// Local Wi-Fi details
//
String ssid = "BTHomeSpot-XNH";
String pwd = "4934675t";
//
// Define MAX98357A amplifier connections
//
#define I2S_BCLK 4
#define I2S_LRC 21
#define I2S_DOUT 22
void setup()
{
Serial.begin(115200); // Serial Monitor
WiFi.disconnect();
delay(500);
WiFi.mode(WIFI_STA);
Serial.println("Connecting to internet...");
WiFi.begin(ssid.c_str(), pwd.c_str());
while(WiFi.status() != WL_CONNECTED) delay(1000);
Serial.println("Wi-Fi is connected...");
//
// Display station information
//
void audio_showstation(const char *info)
{
Serial.print("Station: ");
Serial.println(info);
}
● 112
Practical Audio DSP Projects with the ESP32 - UK.indd 112 06-07-2023 10:40
Chapter 6 • Audio DSP Projects
//
// Display stream title
//
void audio_showstreamtitle(const char *info)
{
Serial.print("Stream title: ");
Serial.println(info);
}
void loop()
{
audio.loop();
}
Figure 6.25: Displaying the station name and stream title on Serial Monitor.
Table 6.1 below lists some of the UK-based Internet radio stations that you may find inter-
esting (this table is taken from the Garfnet website at: https://garfnet.org.uk/cms/tables/
radio-frequencies/internet-radio-player/
● 113
Practical Audio DSP Projects with the ESP32 - UK.indd 113 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
The aim: The aim of this project is to show how text can be made audible on the loud-
speaker.
The block diagram and circuit diagram of the project are as in Figure 6.22 and Figure 6.23,
respectively.
Program listing: Figure 6.26 shows the program listing (Program: TTS). The program is
essentially the same as Figure 6.24, but here the following line of code is added to speak
the message Testing the device in the English language. Note that other languages can
also be used. e.g., use de instead of en for German etc:
/****************************************************************
* TEXT TO SPEECH
* ==============
*
* This is an In Internet based text-to-speech (TTS) application.
* The text entered is spoken on teh speaker
*
* Author : Dogan Ibrahim
● 114
Practical Audio DSP Projects with the ESP32 - UK.indd 114 06-07-2023 10:40
Chapter 6 • Audio DSP Projects
* Program: TTS
* Date : April, 2023
**************************************************************/
#include "Arduino.h"
#include "Audio.h"
#include "WiFi.h"
//
// Local Wi-Fi details
//
String ssid = "BTHomeSpot-XNH";
String pwd = "49356ytw";
//
// Define MAX98357A amplifier connections
//
#define I2S_BCLK 4
#define I2S_LRC 21
#define I2S_DOUT 22
void setup()
{
Serial.begin(115200); // Serial Monitor
WiFi.disconnect();
delay(500);
WiFi.mode(WIFI_STA);
Serial.println("Connecting to internet...");
WiFi.begin(ssid.c_str(), pwd.c_str());
while(WiFi.status() != WL_CONNECTED) delay(1000);
Serial.println("Wi-Fi is connected...");
void loop()
{
audio.loop();
}
● 115
Practical Audio DSP Projects with the ESP32 - UK.indd 115 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
The aim: The aim of this project is to show how all the file names on the SD card can be
read and then how these files can be played.
The block diagram and circuit diagram of the project are in Figure 6.16 and Figure 6.17,
respectively.
Program listing: Figure 6.27 shows the program listing (Program: PLAYALL). This pro-
gram is similar to Figure 6.20. At the beginning of the program, the library header files of
the libraries used are included in the program. The connections between the microSD card
and ESP32, and between the amplifier and ESP32, are then defined. Function getFiles()
reads the names of all the files on the microSD card and stores them in character array au-
diofilenames. This array is currently set to 20 but it can be increased if required. Variable
No_Of_Files stores the number of files on the card.
Inside the setup() routine, the microSD card is accessed. An error message is displayed
if the card is not inserted into its adapter, or if the card is not formatted correctly. The
program then plays the first music file on the card. The index number of the file and its
title are displayed on the Serial Monitor if it has been opened. Function audio_eof_mp3()
is called automatically when playing the first song is completed. Inside this function, the
remaining music files are played one after the other one, starting from the second file. The
index numbers and titles of the files are displayed on the Serial Monitor as they are played.
This process continues forever until stopped by the user, where all the files from the first
one to the last one are played consecutively.
/****************************************************************
* PLAY ALL THE MUSIC FILES ON THE SD CARD
* =======================================
*
* In this program all the music files stored on the microSD
* card are played one after the other one contunuously. There
* is no need to hardcode the names of the files. They are read
* automatically by the program at the start
*
* Author : Dogan Ibrahim
* Program: PLAYALL
* Date : April, 2023
**************************************************************/
#include "Arduino.h"
#include "Audio.h"
#include "SD.h"
● 116
Practical Audio DSP Projects with the ESP32 - UK.indd 116 06-07-2023 10:40
Chapter 6 • Audio DSP Projects
#include "FS.h"
//
// microSD card to ESP32 connections
//
#define CARD_MOSI 23
#define CARD_MISO 19
#define CARD_SCK 18
#define CARD_CS 5
//
// Define MAX98357A amplifier connections
//
#define I2S_BCLK 4
#define I2S_LRC 21
#define I2S_DOUT 22
String audiofilenames[20];
char * files;
int No_Of_Files = 0;
//
// Get the names of all the files on the card
//
void getFiles(File dir)
{
while(1)
{
File entry = dir.openNextFile();
if(!entry)break;
audiofilenames[No_Of_Files] = entry.name();
Serial.println(audiofilenames[No_Of_Files]);
No_Of_Files++;
entry.close();
}
}
//
// Setup routine. Access the card play the firsy file
//
void setup()
{
pinMode(CARD_CS, OUTPUT); // CS is output
● 117
Practical Audio DSP Projects with the ESP32 - UK.indd 117 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
//
// Get all file names stored on the card
//
File root = SD.open("/MyMusic");
getFiles(root);
root.close();
delay(1000);
SD.begin(CARD_CS);
//
// Program jumps here at the end of a music file
//
void audio_eof_mp3(const char *info)
{
static int PlayList = 1; // Second file
Serial.print("Next playing: "); // Display
Serial.print(PlayList); // Play index
Serial.print(" Title: "); // Display title
Serial.println(audiofilenames[PlayList]);
const char* f=audiofilenames[PlayList].c_str();
audio.connecttoFS(SD, f); // Play a file
PlayList++;
if(PlayList == No_Of_Files)PlayList = 0; // Back to first file
}
void loop()
● 118
Practical Audio DSP Projects with the ESP32 - UK.indd 118 06-07-2023 10:40
Chapter 6 • Audio DSP Projects
{
audio.loop();
}
Figure 6.28 shows the data displayed on the Serial Monitor as the music files are played.
Notice that in this example project, there were 5 files in directory /MyMusic of the mi-
croSD card with the following names:
sample-12s.mp3
sample-15s.mp3
sample-143172.mp3
sample-6s.mp3
sample-9s.mp3
Note: All the music files must have extension names .mp3 and they must all be saved in
directory /MyMusic of the microSD card.
The aim: The aim of this project is to show how a potentiometer can be used as a volume
control by connecting it to the amplifier module.
● 119
Practical Audio DSP Projects with the ESP32 - UK.indd 119 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Circuit diagram: The circuit diagram is shown in Figure 6.29. There are several methods
that can be used to change the volume of the output signal. Perhaps the easiest method
is to connect a 100-kohm potentiometer between the SD pin and the VIN pin. As was de-
scribed earlier in this chapter, connecting SD to a voltage has the following results:
• Connect SD to a voltage between 0.16 V and 0.77 V for stereo average output.
i.e., (Right + Left) / 2.
• Connect SD between 0.77 V and 1.4 V for the Right channel only.
By default, the SD pin is pulled down internally with a 100 k-ohm resistor and the voltage
at the SD pin is between 0.16 V and 0.77 V so that the output is a mixture of left and right
channels. An external resistor can be used to change the voltage at the SD pin so that the
volume of the amplifier can be changed. By varying the potentiometer arm, you can change
the voltage at the SD pin and hence control the volume of the amplifier.
Program listing: The program listing is same as the one in Figure 6.27 (Program: PLAY-
ALL). You may have to experiment with setting the volume in software before using the
external potentiometer-based volume control.
The aim: The aim of this project is to show how two identical MAX98357A amplifier mod-
ules can be connected in parallel for stereo output.
● 120
Practical Audio DSP Projects with the ESP32 - UK.indd 120 06-07-2023 10:40
Chapter 6 • Audio DSP Projects
Block diagram: Figure 6.30 shows the block diagram of the project.
Circuit diagram: The circuit diagram is shown in Figure 6.31. Essentially, the circuit di-
agram is very similar to Figure 6.23, but here two amplifier modules are used in parallel
with two speakers.
Program listing: The program listing is exactly the same as in Figure 6.24 (Program:
IRadio).
Figure 6.32 shows the project built on a breadboard (the SD card is not used in this pro-
ject).
● 121
Practical Audio DSP Projects with the ESP32 - UK.indd 121 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
The aim: The aim of this project is to show how a potentiometer can be connected to con-
trol the left and right channel volumes.
Circuit diagram: Figure 6.33 shows the circuit diagram of the project. A 100 k-ohm po-
tentiometer is connected from the SD pin to the VIN pin. The potentiometer controls the
left and right channel volumes.
Program listing: The program listing is exactly the same as in Figure 6.24 (Program:
IRadio). You should experiment with different software and hardware volume settings.
● 122
Practical Audio DSP Projects with the ESP32 - UK.indd 122 06-07-2023 10:40
Chapter 6 • Audio DSP Projects
6.15 Project 11: Playing an MP3 file stored in the flash memory
Description: In this project, an MP3 music file is stored in the flash memory of the ESP32
processor. This project shows how the file can be stored and then played on the loudspeak-
er through an amplifier.
The aim: The aim of this project is to show how a file can be stored in the flash memory
of the ESP32 and then how it can be played.
Block diagram: Figure 6.34 shows the block diagram of the project.
Circuit diagram: The circuit diagram, shown in Figure 6.35, consists of the ESP32 DevKitC
development board, the MAX98357A amplifier and a speaker.
The SPIFFS: This stands for Serial Peripheral Interface Flash File System. The ESP32 con-
tains a file system where a file can be stored in the flash memory of the processor. SPIFFS
allows part of the flash memory to be used as if it is a normal file system, where files can
be written to, read from, or deleted. This file system, however, does not support any direc-
tory structure, i.e., it is a flat structure (this was the case at the time of writing this book).
● 123
Practical Audio DSP Projects with the ESP32 - UK.indd 123 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
This actually means that if you create a file called /dir/myfile.txt, a file with the name /
dir/myfile.txt will be created, not a file called myfile.txt in folder dir. You can think of
the SPIFFS as a small SD card internal to ESP32. By default, the size of this file system is
several MB.
Arduino IDE supports a plugin where with the help of this you can upload files directly to
the ESP32 file system from a folder on your PC. This way for example, you copy your MP3
music file to a folder on your PC, and then copy this file to the file system on your ESP32.
This makes it very easy to manipulate files in the ESP32 file system.
The steps to install this plugin are as follows (note that at the time of writing this book,
version 2 of the Arduino IDE did not support this plugin):
https://github.com/me-no-dev/arduino-esp32fs-plugin/releases/
• Start your Arduino IDE and locate your Sketchbook location (if you are not
sure, go to File Preferences). If you have a default IDE installation, it
should be located at: C:\Users\Username\Documents\Arduino. See
Figure 6.36 for the author's location:
• Go to your Sketchbook location, and then create a folder under this location
called: tools.
• Unzip the downloaded .zip folder and copy the ESP32FS folder to the tools
folder that you just created (Figure 6.37).
● 124
Practical Audio DSP Projects with the ESP32 - UK.indd 124 06-07-2023 10:40
Chapter 6 • Audio DSP Projects
• To check that the plugin has been installed correctly, restart your Arduino IDE.
Make sure that the option: ESP32 Sketch Data Upload exists under IDE
option Tools (Figure 6.38).
• To check the ESP32 processor memory partition with the allocated SPIFFS,
choose the options: Tools Partition scheme, as shown in Figure 6.39.
● 125
Practical Audio DSP Projects with the ESP32 - UK.indd 125 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
• Create an empty IDE file with a name, for example, MyMP3 and save it.
• Locate where your Sketch folder is saved. Click Sketch Show Sketch
Folder. This is where your Sketch folder is (see Figure 6.40).
• Create a folder called: data inside your sketch folder. You should have the
following folder structure:
MyMp3/data
• Copy your MP3 music file to the folder data. The folder structure should now
be:
MyMP3/data/sample-12s.mp3
• You are now ready to upload your music file to ESP32. Connect your ESP32
DevKitC development board to your PC.
• Wait until the file is uploaded. The message SPIFFS Image Uploaded will be
displayed on your IDE (Figure 6.41).
● 126
Practical Audio DSP Projects with the ESP32 - UK.indd 126 06-07-2023 10:40
Chapter 6 • Audio DSP Projects
Now that you have uploaded your MP3 music file to the flash memory of the ESP32 proces-
sor, you are ready to write the program to play this music file.
Program listing: The program listing is shown in Figure 6.42 (Program: MyMP3). At
the beginning of the program, header files Arduino, Audio, and SPIFFS are included in the
program. The connections between the MAX98357A amplifier and the ESP32 are defined.
Inside the setup routine, the Serial Monitor is initialized to 115200 baud. SPIFFS is then
accessed. The message Error in SPIFFS is displayed on the Serial Monitor if there is an
error, otherwise, the message SPIFFS accessed correctly is displayed. The remainder
of the program configures the I2S bus, sets the amplifier volume to 10, and then plays the
music file.
/******************************************************************
* PLAY MUSIC STORED IN FLASH MEMORY
* =================================
*
* In this program an MP3 compatible music file is stored in the
* flah memory of the ESP32 processor.The program opens the file
* and plays the music on the speaker through the MAX98357A amplifier
*
* Author : Dogan Ibrahim
* Program: MyMP3
* Date : April, 2023
*******************************************************************/
#include "Arduino.h"
#include "Audio.h"
#include "SPIFFS.h"
//
// Define MAX98357A amplifier connections
//
#define I2S_BCLK 4
#define I2S_LRC 21
#define I2S_DOUT 22
void setup()
● 127
Practical Audio DSP Projects with the ESP32 - UK.indd 127 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
{
Serial.begin(115200); // Serial Monitor
if(!SPIFFS.begin(true)) // Start SPIFFS
{
Serial.println("Error in SPIFFS"); // SPIFFS error
while(true);
}
Serial.println("SPIFFS accessed correctly");
void loop()
{
audio.loop();
}
The aim: The aim of this project is to show how the files in the flash memory of the ESP32
processor can be listed.
Program listing: Figure 6.43 shows the program listing (Program: SPIFFSfiles). The
program opens the SPIFFS file structure and then lists the files on the Serial Monitor. Figure
6.44 shows an example output displayed on the Serial Monitor. Compile and upload the
program to the ESP32. Open the Serial Monitor making sure that the baud rate is set to
115200. Press the Reset button on the development board.
/****************************************************************
* LIST OF FILES IN FLASH MEMORY
* =============================
*
* This program lists the files in the flash memory of ESP32
*
* Author : Dogan Ibrahim
* Program: SPIFFSfiles
* Date : April, 2023
**************************************************************/
#include "SPIFFS.h"
● 128
Practical Audio DSP Projects with the ESP32 - UK.indd 128 06-07-2023 10:40
Chapter 6 • Audio DSP Projects
void setup()
{
Serial.begin(115200);
Serial.println("");
if (!SPIFFS.begin(true))
{
Serial.println("Error in SPIFFS");
while(1);
}
else
{
Serial.println("SPIFSF accessed correctly");
Serial.println("");
}
while(file)
{
Serial.print("FILE name: ");
Serial.println(file.name());
file = root.openNextFile();
}
}
void loop()
{}
● 129
Practical Audio DSP Projects with the ESP32 - UK.indd 129 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
The aim: the aim of this project is to show how a speaking event counter can be devel-
oped.
Block diagram: Figure 6.45 shows the block diagram of the project.
Circuit diagram: The circuit diagram is shown in Figure 6.46. A button is connected to
port pin GPIO36 (pin 3) such that normally the input is at logic 1 and goes to logic 0 when
the button is pressed.
● 130
Practical Audio DSP Projects with the ESP32 - UK.indd 130 06-07-2023 10:40
Chapter 6 • Audio DSP Projects
Program listing: Figure 6.47 shows the program listing (Program: EventSpeak). This
program uses the text-to-speech of the audio library and therefore the ESP32 is connected
to the local Wi-Fi router so that the Google TTS engine can be used by the audio library.
At the beginning of the program, the Wi-Fi name and password are defined and the con-
nections between the amplifier and ESP32 are defined. GPIO15 (pin 23) is defined to be
the button and is configured as an INPUT with its internal pull-up resistor enabled. As a
result, GPIO15 is at logic 1 unless the button is pressed. Inside the setup() routine, the
connection is made to Wi-Fi and the I2S bus is configured. The volume is set to 10 and the
message This is an event counter project is spoken on the speaker.
The remainder of the program runs inside the loop(). Here, the state of the button is
checked. If the button is pressed (Event_Button is at logic 0) then variable Count is in-
cremented by one and its final value is displayed on the Serial Monitor. At the same time,
the TTS engine is called and the final count is spoken on the speaker. Therefore, the user
should hear the sounds like ONE, TWO, THREE, etc. being spoken on the speaker as ex-
ternal events occur. A 30-ms delay is inserted inside the loop to disable contact bouncing
problems. The program runs forever until stopped by the user.
/****************************************************************
* SPEAKING EVENT COUNTER
* ======================
*
* This is a speaking event counter project.Events on port pin
* GPIO36 are counter and displayed dynamically on the Serial
* Monitor. At the same time the total is spoken on the speaker
*
* Author : Dogan Ibrahim
* Program: EventSpeak
* Date : April, 2023
**************************************************************/
#include "Arduino.h"
#include "Audio.h"
#include "WiFi.h"
//
// Local Wi-Fi details
//
String ssid = "TP-Link_6138";
String pwd = "2484r45";
//
// Define MAX98357A amplifier connections
//
#define I2S_BCLK 4
#define I2S_LRC 21
● 131
Practical Audio DSP Projects with the ESP32 - UK.indd 131 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
#define I2S_DOUT 22
//
// Set the Serial Monitor, connect to Wi-Fi, Configure I2S
// Set the amplifier volume
//
void setup()
{
Serial.begin(115200);
pinMode(Event_Button, INPUT_PULLUP);
WiFi.disconnect();
delay(500);
WiFi.mode(WIFI_STA);
Serial.println("Connecting to internet...");
WiFi.begin(ssid.c_str(), pwd.c_str());
while(WiFi.status() != WL_CONNECTED) delay(1000);
Serial.println("Wi-Fi is connected...");
//
// Here, the total count is displayed on Serial Monitor
// At the same time final count is spoken on the speaker
//
void loop()
{
audio.loop();
if(digitalRead(Event_Button) == 0)
{
Count++; // Increment Count
Serial.print("Count = "); // Heading
Serial.println(Count); // Display Count
Events = Count;
const char * f = Events.c_str();
audio.connecttospeech(f, "en"); // Speak Count
delay(30);
● 132
Practical Audio DSP Projects with the ESP32 - UK.indd 132 06-07-2023 10:40
Chapter 6 • Audio DSP Projects
}
}
Suggestions for further work: This project can be modified such that a temperature
sensor can be connected to the development board and the temperature (or the maximum
or minimum temperature, or when an alarm temperature value is reached) can be spoken
to the speaker.
● 133
Practical Audio DSP Projects with the ESP32 - UK.indd 133 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
7.1 Overview
Discrete-tme signals are usually obtained from analog signals by converting the signal from
analog into digital form using analog-to-digital converters (ADCs). This is also known as
the sampling process. The converted signal is then processed using a digital processor like
a microcontroller. The processed signal is usually converted back into analog form using a
digital-to-analog converter (DAC).
Digital signals are also known as discrete-time signals. Before going into the details of
digital signal processing theory, it is worthwhile to review the properties of discrete-time
signals, also called digital signals.
One of the important questions in sampling is: what should be the switching rate? In other
words, how often should the analog signal be sampled? Conceivably the simplest answer to
this question is that the sampling rate should be as fast as possible. However, unnecessarily
fast sampling rate requires many more samples to be stored, processed, or transmitted.
On the other hand, the original signal cannot be constructed if a low sampling rate is used.
Can you choose a sampling rate that is just adequate for the signal to be sampled without
loss of any information in the signal and without being too fast?
Thus, for example, a speech waveform having a frequency of 1 kHz should be sampled at
least 2 kHz, or 2,000 times per second. In general, if the frequency of the analog signal is
f, then the maximum sampling interval should be:
● 134
Practical Audio DSP Projects with the ESP32 - UK.indd 134 06-07-2023 10:40
Chapter 7 • Discrete-Time Signals
T = ½f
In practice, you choose a somewhat higher sampling frequency than given by Shannon's
theorem. For example, a signal having f = 1kHz is usually sampled at 5 kHz or even higher.
Figure 7.3 shows a typical discrete-time sinusoidal signal. This figure has been obtained
using the following MATLAB statements:
n = 0:20;
y = sin(2*pi*n/20);
stem(n, y, 'k', 'fill')
● 135
Practical Audio DSP Projects with the ESP32 - UK.indd 135 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Notice that you can also use the cosine version of the sinusoid, defined by
The first 6 sequences of an example discrete exponential signal with a = 0.2 is shown in
Figure 7.5. This figure has been obtained using the following MATLAB statements:
n = 0:6;
y = exp(0.2*n);
stem(n, y, 'k', 'fill')
● 136
Practical Audio DSP Projects with the ESP32 - UK.indd 136 06-07-2023 10:40
Chapter 7 • Discrete-Time Signals
An example is shown in Figure 7.6 with A = 1, a = 0.1, and n = 30. This figure has been
obtained using the following MATLAB statements:
n = 0:30;
y = exp(-0.1*n). *sin(2*pi*n/30);
stem(n, y, 'k', 'fill')
● 137
Practical Audio DSP Projects with the ESP32 - UK.indd 137 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Example 7.1
The block diagram of a discrete-time system is shown in Figure 7.8. Derive the output
equation y[n].
Solution 7.1
Figure 7.9 shows the signals at different parts of the block diagram. The output signal is
given by:
a1y[n-1] + a2y[n-2]
● 138
Practical Audio DSP Projects with the ESP32 - UK.indd 138 06-07-2023 10:40
Chapter 7 • Discrete-Time Signals
In general, the output sequence y[n] is found by the convolution process using the follow-
ing equation:
Example 7.2
The impulse response of a linear time-invariant system is shown in Figure 7.10. Calculate
the output response when the input sequence shown in Figure 7.11 is applied to the sys-
tem.
● 139
Practical Audio DSP Projects with the ESP32 - UK.indd 139 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Solution 7.2
The impulse response sequence is:
x[n] = [-2, 2, 1, 0, 3]
Using equation (7.1), with 5 samples, the output sequence is given by:
Thus,
y[0] = x[0].h[0]
y[1] = x[0].h[1] + x[1].h[0]
y[2] = x[0].h[2] + x[1].h[1] + x[2].h[0]
y[3] = x[0].h[3] + x[1].h[2] + x[2].h[1] + x[3].h[0]
y[4] = x[0].h[4] + x[1].h[3] + x[2].h[2] + x[3].h[1] + x[4].h[0]
or,
y[0] = -2 x 1 = -2
y[1] = -2 x (-2) + 2 x 1 = 6
y[2] = -2 x 3 + 2 x (-2) + 1 x 1 = -9
y[3] = -2 x (-1) + 2 x 3 + 1 x (-2) + 0 x 1 = 6
y[4] = -2 x 2 + 2 x (-1) + 1 x 3 + 0 x (-2) + 3 x 1= 0
● 140
Practical Audio DSP Projects with the ESP32 - UK.indd 140 06-07-2023 10:40
Chapter 7 • Discrete-Time Signals
MATLAB function conv can be used to perform the convolution operation. The required
statements for the above example are given below:
h = [1 -2 3 -1 2];
x = [-2 2 1 0 3];
y = conv(h, x)
y=
-2 6 -9 6 0 -3 11 -3 6
The following MATLAB program can be used to calculate and plot the output sequence using
convolution:
%
% Convolution program
%
h = input('Enter the impulse response sequence: ' );
x = input('Enter the input sequence: ');
y = conv(h, x);
L = length(y) ;
n = 0:1:L-1;
disp('Output sequence = ');
disp(y);
stem(n, y, 'k', 'fill');
xlabel('Time');
ylabel('Amplitude');
● 141
Practical Audio DSP Projects with the ESP32 - UK.indd 141 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
● 142
Practical Audio DSP Projects with the ESP32 - UK.indd 142 06-07-2023 10:40
Chapter 8 • The Z-Transform
8.1 Overview
The z-transform is an extremely useful tool for the analysis and design of digital signals
and processors. This tool is widely used by DSP designers for describing digital signals and
systems. In this chapter, you get to explore the basic properties of the z-transform and see
how it can be exploited in DSP applications.
(8.1)
The z-transform of a signal consists of an infinite series in the complex variable z-1 with
coefficients. The z-transform is used in digital systems just as the Laplace transform is used
in continuous-time systems. The response of a digital, system can be determined easily by
finding the z-transform of the output and then calculating the inverse z-transform, just like
the Laplace transform techniques used in continuous-time systems. You will now look at
how you can find the z-transforms of some commonly used discrete-time functions. Tables
of z-transforms for most of the commonly used functions are available on the Internet for
interested readers.
From (7.1),
or,
● 143
Practical Audio DSP Projects with the ESP32 - UK.indd 143 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
From (7.1),
or,
You can use the MATLAB function ztrans to find the z-transform as shown below for the unit
ramp function:
syms t
x = t;
ztrans(x)
ans =
z/(z - 1)^2
● 144
Practical Audio DSP Projects with the ESP32 - UK.indd 144 06-07-2023 10:40
Chapter 8 • The Z-Transform
recall that,
So that
Therefore, substituting,
or,
Using MATLAB,
syms a
syms t
x=sin(a*t);
ztrans(x)
ans =
(z*sin(a))/(z^2 - 2*cos(a)*z + 1)
● 145
Practical Audio DSP Projects with the ESP32 - UK.indd 145 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
• Given G(s), calculate the time response g(t) by finding the inverse Laplace
transform of G(s). Then, find the z-transform either from the first principles, or
by looking at the z-transform tables.
• Gives G(s), find the z-transform G(z) by looking at the tables which give the
Laplace transforms and their equivalent z-transforms.
• Given the Laplace transform G(s), express it in the form G(s) = N(s) / D(s) and
then use the following formula to find the z-transform G(z):
Where and the xn , n = 1,2,….p, are the roots of the equation D(s) = 0.
Example 8.1
Let
Solution 8.1
You can express G(s) as a sum of its partial fractions:
or,
● 146
Practical Audio DSP Projects with the ESP32 - UK.indd 146 06-07-2023 10:40
Chapter 8 • The Z-Transform
or,
Example 8.2
Find the inverse z-transform of the following polynomial using the long division method
Solution 8.2
Dividing the denominator into the numerator gives
● 147
Practical Audio DSP Projects with the ESP32 - UK.indd 147 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
y[0] = 1
y[1] = 4
y[2] = 8
y[3] = 8
………..
………..
Figure 8.3 shows the first few samples of the time sequence y(t)
Example 8.3
Repeat Example 8.2 using MATLAB to find the time sequence
Solution 8.3
The required MATLAB statements are given below. Notice that the numerator and denom-
inator polynomials are entered. Then the required length is entered and MATLAB function
impz calculates and returns the power series coefficients (impulse response) in x and the
time sequence in n:
num = [1 1 0];
den = [1 -3 4];
L = 5;
[x,n] = impz(num, den, L)
x=
1
4
8
8
● 148
Practical Audio DSP Projects with the ESP32 - UK.indd 148 06-07-2023 10:40
Chapter 8 • The Z-Transform
-8
n=
0
1
2
3
4
The following MATLAB program can be used to find the power series coefficients of any
polynomial in z-transform and then plot the time response:
%
% Inverse z-transform program
%
num = input('Enter the numerator coefficients: ' );
den = input('Enter the denominator coefficients: ');
L = input('Enter the required length: ');
[y, n] = impz(num, den, L)
n = 0:1:L-1;
stem(n, y, 'k', 'fill');
xlabel('Time');
ylabel('y(t)');
y=
1
4
8
8
-8
n=
0
1
2
● 149
Practical Audio DSP Projects with the ESP32 - UK.indd 149 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
3
4
Example 8.4
Find the inverse z-transform of the following function using partial fractions:
Solution 8.4
The above expression can be written as:
The values of A and B can be found by equating like powers in the numerator, i.e.
or
y[n] = -1 + 2n
y(0) = 0
y(1) = 1
● 150
Practical Audio DSP Projects with the ESP32 - UK.indd 150 06-07-2023 10:40
Chapter 8 • The Z-Transform
y(2) = 3
y(3) = 7
y(4) = 15
……….
……….
The coefficients of the partial expansion can easily be found by considering the general
z-transform of the form:
Example 8.5
Using the partial expansion method described above, find the inverse z-transform of
Solution 8.5
Rewriting the function as
● 151
Practical Audio DSP Projects with the ESP32 - UK.indd 151 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Thus,
z z
Y [ z] = +
z −1 z − 2
And the inverse z-transform is obtained from the tables as
Example 8.6
Find the inverse z-transform of
Solution 8.6
Rewriting the equation as
you obtain
● 152
Practical Audio DSP Projects with the ESP32 - UK.indd 152 06-07-2023 10:40
Chapter 8 • The Z-Transform
● 153
Practical Audio DSP Projects with the ESP32 - UK.indd 153 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
9.1 Overview
Filtering is the process where the frequency components comprised in a signal are altered.
Filters are the basic components of signal processing and telecommunication systems. In
general, the primary functions of a filter are one or more of the following:
• to modify the frequency spectrum of a signal;
• to confine a signal into a prescribed frequency band, for example, low-pass,
high-pass, or band-pass filters as in removing noise from the signal;
• to decompose a signal into two or more frequency bands.
Filters are used in many signal-processing applications, such as audio processing, video
processing, radio receivers and transmitters, radar, and biomedical signal processing.
Traditionally, all types of filters have been analog before the low-cost and wide availability
of digital processors. An analog filter handles analog signals (or continuous signals), while
digital filters perform mathematical operations on sampled, discrete-time signals. In the
early days, analog filters have been passive and designed using passive components such
as resistors, capacitors, and inductors. One of the major problems with analog filters was
that it was difficult to design filters with accurate frequency responses. In addition, the
analog filters were bulky, especially those designed for low-frequency operation. With the
invention and wide availability of the operational amplifiers, most general-purpose analog
filters are nowadays designed using these components. The design using operational am-
plifiers is based on using passive components of only resistors and capacitors. Although the
frequency responses of these filters can be selected more accurately than the all passive
filters, the problem is that such filters are designed to work at medium to high frequencies.
Digital filters are designed using digital processors, such as microcontrollers. These filters
offer many advantages compared to the analog filters: The frequency response of digital
filters can be controlled to great accuracy. For example, the cut-off frequency can be se-
lected with very high precision. Digital filters are especially useful at low frequencies where
the analog ones are bulky. Because the digital filters are based on filter programs, it is very
easy to change the frequency response of a filter, all that is required is to modify the pro-
gram. Digital filters can outperform analog filters usually in terms of phase responses. Dig-
ital filters have some disadvantages compared to analog filters. Perhaps the biggest disad-
vantage is that they can be more expensive than analog filters in low-volume applications.
The types of digital filters that you will be designing in this book are linear filters. Like linear
systems, linear filters are characterized by their impulse responses. In general, an impulse
response can be of finite or an infinite length. Two types of digital filters are commonly
used: Finite Impulse Response (FIR) digital filters and Infinite Impulse Response
(IIR) digital filters. Both types have some advantages and disadvantages that should be
carefully considered when designing a filter. Besides, it is necessary to consider all funda-
mental characteristics of a signal to be filtered as these are very important when deciding
which filter to use. In most cases, it is only one characteristic that really matters, and it is
whether it is necessary that the filter has linear phase characteristics or not. The FIR filters
are also known as non-recursive filters, and IIR filters are as recursive filters. A Finite
● 154
Practical Audio DSP Projects with the ESP32 - UK.indd 154 06-07-2023 10:40
Chapter 9 • Digital Filters
Impulse Response filter (FIR) has its impulse coefficients extending over a finite time
interval and are zero beyond that. Thus, for example, an Nth-order FIR filter has an impulse
response with (N + 1) coefficients. The basic characteristics of FIR digital filters are:
• Linear phase characteristic
• High-filter order (more complex circuits)
• Stability
In Infinite Impulse Response (IIR) type filters the impulse response has an infinite du-
ration. In reality, you do not compute an infinite number of terms for the implementation
of IIR filters. In these filters, the input-output samples of the filter are related by linear
difference equations, and the filter is designed using these equations. The basic character-
istics of IIR digital filters are:
• Non-linear phase characteristic
• Low-filter order (easier circuits)
• Potential of becoming unstable
One of the drawbacks of FIR filters is the high-order of the designed filter. The order of the
FIR filter is remarkably higher compared to an IIR filter with the same frequency response.
This is the reason why it is so important to use FIR filters only when the linear phase char-
acteristic is very important. In this chapter, you will be learning the basic theory of both
FIR- and IIR-type digital filters.
• FIR filters are used where linear phase characteristics are required. This is a
desirable property in many signal-processing applications, such as in audio
and video processing. IIR filters, on the other hand, can be used where linear
characteristics are not of concern.
• FIR filters require many tappings for high order and, consequently, they require
more memory. The same filter can be designed with IIR filters using a small
filter order with much less memory.
• FIR filters are more stable than the IIR filters as feedback is not involved.
• IIR filters can simulate analog filter responses. FIR filters, on the other hand,
cannot be designed from the theory of analog filters.
• IIR filters are more suitable in high-speed signal processing operations as they
require fewer arithmetic operations.
● 155
Practical Audio DSP Projects with the ESP32 - UK.indd 155 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
• IIR filters are very sensitive to filter coefficients and quantization errors. Thus,
processors with wider data path may be required for their implementation.
Filter response
Figure 9.1 shows the ideal frequency responses of the low-pass, high-pass, and band-pass
filters.
The band characteristics are shown in more detail in Figure 9.2 for the case of realizable
low-pass filters. Here, the pass-band and the stop-band may have ripples as shown in the
figure. The ideal cut-off frequency is at the midpoint between the pass-band and the stop-
band and is given by
● 156
Practical Audio DSP Projects with the ESP32 - UK.indd 156 06-07-2023 10:40
Chapter 9 • Digital Filters
The transition band is between the pass-band and the stop-band and is given by
The ripple in the pass-band varies between and The maximum ripple in the
pass-band is usually expressed in decibels and is given by
or,
Filter type
The second important issue in designing a digital filter is the selection of the filter type, i.e.
whether an IIR or an FIR filter is to be used. If the requirement is to have linear phase re-
sponse, then an FIR filter should be employed. If the linear phase response is not a require-
ment, then either an IIR or an FIR filter can be used. The IIR filters are computationally
more efficient and require fewer multiplications and additions. Also, for a given response
characteristic, the FIR design requires higher filter order and consequently more memory
elements.
In many practical applications the linearity of the phase response is not a requirement and
this makes the IIR filter preferable because of the lower processor specification require-
ments.
● 157
Practical Audio DSP Projects with the ESP32 - UK.indd 157 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Filter order
The choice of the filter length depends upon the required frequency response specifications.
The easiest method to choose the filter order is by trial and error using a computer-aided
filter design software package (as you shall see in later chapters).
For the design of IIR-type digital filters converted from analog filters, you can estimate the
filter order from the analog design formulas as will be discussed in the section on designing
IIR filters.
There are several estimates of the filter order for the design of FIR filters. A simple formula
often used is:
Example 9.1
It is required to design an FIR-type digital filter with pass-band edge at 200 Hz, stop-band
edge at 400 Hz, pass-band ripple of 0.002 and stop-band ripple of 0.001. Assuming a
sampling rate of 1 kHz, estimate the length of the filter. Use the MATLAB package in this
example.
Solution 9.1
The required MATLAB program is given below
● 158
Practical Audio DSP Projects with the ESP32 - UK.indd 158 06-07-2023 10:40
Chapter 9 • Digital Filters
N = 15.0650
Sampling frequency
According to the sampling theorem, the sampling frequency should be at least twice the
highest frequency in the signal to be sampled. In practice, however, in order to preserve
the fidelity, the sampling frequency is usually (not always) taken to be between 5 to 10
times the highest frequency of the signal to be sampled.
● 159
Practical Audio DSP Projects with the ESP32 - UK.indd 159 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
10.1 Overview
There are several methods leading to practical design of FIR digital filters. Most FIR filter
design methods are based on ideal filter approximation, meaning the resulting filter ap-
proximates the ideal characteristic as the filter order increases, thus making the filter and
its implementation more complex. The filter design process starts with the specifications
and requirements of the desirable FIR filter. Which method is to be used in the filter design
process depends on the filter specifications and implementation. In this chapter, you will be
learning the basic Fourier Transform-based design and the windowing functions. In addi-
tion, computer-aided design techniques using MATLAB and some of the popular FIR digital
design software packages will be discussed with examples.
FIR filters are non-recursive where the output depends only on the present and previous
inputs, and the differential equation describing the output can be written as
M
y[n] = ∑ bk x[n − k ]
k =0
(10.1)
Where bk equals the successive terms in the impulse response of the filter. In practical
applications, between 10 and 100 coefficients are taken.
M
H [ z ] = ∑ bk z − k
k =0
(10.2)
and the corresponding frequency response is given by
(10.3)
When you truncate an infinite-length impulse response, the process is equivalent to mul-
tiplying it by a finite-length window function. The window function determines how many
coefficients of the impulse response should be taken. In other words, the window function
determines how much of the impulse response you can see. By extending the window func-
tion more of the impulse response can be seen and a better approximation is made to the
ideal filter response.
● 160
Practical Audio DSP Projects with the ESP32 - UK.indd 160 06-07-2023 10:40
Chapter 10 • Designing FIR Digital Filters
The windowing operation is performed in the time domain, and the required impulse re-
sponse coefficients are obtained from the multiplication of the ideal impulse response with
the windowing function. i.e.
(10.5)
Where h[n] are the impulse response coefficients, and w[n]are the windowing function
coefficients.
Many windowing functions have been proposed over the years for the design of FIR filters.
The properties of some of the commonly used windowing functions are given in the next
section.
(10.6)
Since the rectangular window has an abrupt transition to zero, it causes oscillatory behavior
in the frequency response of the designed filter (also known as the Gibbs phenomenon).
An example is given below.
Example 10.1
Find the impulse response of a low-pass filter with rectangular windowing where the cut-off
frequency is π/4 and N = 11.
Solution 10.1
Since N = 11, M = (N – 1) / 2 = 5
● 161
Practical Audio DSP Projects with the ESP32 - UK.indd 161 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
h[5] = 0.25
Multiplying by the rectangular windowing functions does not change the impulse response
coefficients.
, n = 0,1,2,…., N-1
Figure 10.1 shows the Hamming window for N = 100, plotted using the following MATLAB
statements:
n=0:99;
w=0.54-0.46*cos(2*pi*n/99);
plot(n,w)
Because the window function is multiplied by the ideal filter impulse response, the impulse
response of the FIR low-pass filter designed using the Hamming window has the following
equation:
● 162
Practical Audio DSP Projects with the ESP32 - UK.indd 162 06-07-2023 10:40
Chapter 10 • Designing FIR Digital Filters
Example 10.2
Find the impulse response of a low-pass filter with Hamming window, where the cut-off
frequency is π/4 and N = 11
Solution 10.2
The impulse response coefficients of the ideal filter are given by:
Since N = 11, M = (N – 1) / 2 = 5
Using the following MATLAB statements, you can find the coefficients of the Hamming win-
dow for the required filter:
>> n=0:10;
>> w=0.54 - 0.46*cos(2*pi*n/10)
w=
Columns 1 through 9
Columns 10 through 11
0.1679 0.0800
Thus,
● 163
Practical Audio DSP Projects with the ESP32 - UK.indd 163 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
The impulse response coefficients are found from the multiplication of h[n] and w[n] and
are:
, n = 0,1,2,…., N-1
, n = 0,1,2,…., N-1
Figure 10.2 shows the Blackman window function plotted with N = 100, using the following
MATLAB statements. Notice that the Blackman window is wider than the Hamming window.
● 164
Practical Audio DSP Projects with the ESP32 - UK.indd 164 06-07-2023 10:40
Chapter 10 • Designing FIR Digital Filters
An example is given below to show how the impulse response of an FIR filter can be com-
puted using the Blackman window.
Example 10.3
Find the impulse response of a low-pass filter with Blackman window, where the cut-off
frequency is π/4 and N = 11. Plot the frequency response using MATLAB.
Solution 10.3
As in Example 10.2, the impulse response coefficients of the ideal filter are given by:
Since N = 11, M = (N – 1) / 2 = 5
Using the following MATLAB statements, you can find the coefficients of the Blackman win-
dow for the required filter:
n=0:10;
w=0.42-0.5*cos(2*pi*n/10)+0.08*cos(4*pi*n/10)
● 165
Practical Audio DSP Projects with the ESP32 - UK.indd 165 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
w=
Columns 1 through 9
Columns 10 through 11
0.0402 -0.0000
Thus,
w[0] = w[10] = 0
w[1] = w[9] = 0.0402
w[2] = w[8] = 0.2008
w[3] = w[7] = 0.5098
w[4] = w[6] = 0.8492
w[5] = 1
The impulse response coefficients are found from the multiplication of h[n] and w[n] and
are:
hd[0] = hd[10] = 0
hd[1] = hd[9] = 0
hd[2] = hd[8] = 0.0151
hd[3] = hd[7] = 0.0816
hd[4] = hd[6] = 0.1911
hd[5] = 0.25
The frequency response is plotted using MATLAB function fvtool(hd, 1) and is shown in Fig-
ure 10.3. Note that the response exhibits a lower ripple than the Hamming window.
● 166
Practical Audio DSP Projects with the ESP32 - UK.indd 166 06-07-2023 10:40
Chapter 10 • Designing FIR Digital Filters
When designing digital FIR filters using window functions it is necessary to specify:
• The window function to be used
• The filter order for the required specifications (selectivity and stop-band
attenuation)
The selected windowing function affects the transition region, the minimum stop-band
attenuation of the used window function, and the minimum stop-band attenuation of the
designed filter. Table 10.1 shows a comparison of some of the windowing functions for an
FIR filter having 20 coefficients.
It is important to see from the table that the minimum attenuation of window function and
that of the filter designed using that function are different for different windows. The differ-
ence is mainly the stop-band attenuation. The minimum stop-band attenuation is fixed for
each windowing function, except for the Kaiser window (described in next section).
Some important response concepts are shown in Figure 10.4, such as the main lobe, main
lobe width, side lobes, transition region, and minimum stop-band attenuation.
● 167
Practical Audio DSP Projects with the ESP32 - UK.indd 167 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
As can be seen from the table above, the stop-band attenuation of the given windows is
not adjustable. Only the transition region can be affected by increasing the filter order.
Therefore, a design should start by specifying the appropriate window function on the basis
of the stop-band attenuation. A window with the least stop-band that satisfies the given
requirements should be chosen. As a result, the designed filter will have the narrowest
transition region.
and many other online design tools and programs that can be found on the Internet. All of
the FIR design software given here are free of charge except the ScopeFIR. ScopeFIR is a
professional FIR filter design tool covering all types of algorithms and window functions with
plots of the impulse response, frequency response and so on. In this section, you will learn
how to design FIR filters using the ScopeFIR software package and the freely available Dr
A R Collins FIR software program.
● 168
Practical Audio DSP Projects with the ESP32 - UK.indd 168 06-07-2023 10:40
Chapter 10 • Designing FIR Digital Filters
10.3.1 ScopeFIR
ScopeFIR software enables you to design many different types of FIR filters, including low-
pass, high-pass, band-pass, and band-stop. In addition, different algorithms can be select-
ed for the design. The impulse response coefficients, plot of the impulse response, and plot
of the frequency response of the designed filter can easily be seen.
Some example FIR filter designs are given below to illustrate the steps involved in the de-
sign. The following examples assume that the ScopeFIR package has already been installed
on the PC. The version of the software used by the author was version 6.0.
Example 10.4
Design an FIR filter with the following specifications using the ScopeFIR software package:
• Low-pass
• Filter order 20 (number of taps = 21)
• Hamming window
• Cut-off frequency 1 kHz
• Sampling frequency 10 kHz
Obtain the impulse filter coefficients and plot the impulse response and the frequency re-
sponse of the designed filter.
Solution 10.4
Step 1: Start the ScopeFIR package.
Step 2: Select the required algorithm (e.g., Windowed Sinc) as shown in Figure 10.5.
● 169
Practical Audio DSP Projects with the ESP32 - UK.indd 169 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Step 3: Enter the cut-off frequency, sampling frequency, number of taps, and select Ham-
ming window and filter type as Low-Pass as shown in Figure 10.6.
Step 4: Click Design. You should see the impulse response parameters in the top right-
hand side of the screen as shown in Figure 10.7.
● 170
Practical Audio DSP Projects with the ESP32 - UK.indd 170 06-07-2023 10:40
Chapter 10 • Designing FIR Digital Filters
The frequency response of the designed filter is shown in Figure 10.8. Notice that the ripple
occurs around the –60 dB line.
Example 10.5
Design an FIR filter with the following specifications using the ScopeFIR software package:
• Low-pass
• Filter order 20 (number of taps = 21)
• Simple Parks-McClellan
• Pass-band upper frequency 1 kHz
• Stop-band lower frequency 1.5kHz
• Sampling frequency 10 kHz
• Pass-band ripple 1 dB
• Stop-band attenuation 80 dB
Obtain the impulse filter coefficients and plot the impulse response and the frequency re-
sponse of the designed filter.
● 171
Practical Audio DSP Projects with the ESP32 - UK.indd 171 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Solution 10.5
Figure 10.10 shows the design parameters entered to the form.
Clicking the Design button designs the filter. The frequency response of the designed filter
is shown in Figure 10.11. Note that the stop-band attenuation is around -60 dB.
You can optimize the design by clicking the Optimize button. This will make sure that the
stop-band attenuation is at least -80 dB as requested, but the number of tappings will in-
crease as shown in Figure 10.12 (it will increase to 57 in this example).
● 172
Practical Audio DSP Projects with the ESP32 - UK.indd 172 06-07-2023 10:40
Chapter 10 • Designing FIR Digital Filters
Example 10.6
Design an FIR filter with the following specifications using the ScopeFIR software package:
• High-pass
• Filter order 30 (number of taps = 31)
• Simple Parks-McClellan
• Pass-band upper frequency 1.5 kHz
• Stop-band lower frequency 2 kHz
• Sampling frequency 10 kHz
• Pass-band ripple 1 dB
• Stop-band attenuation 50 dB
Obtain the impulse filter coefficients and plot the impulse response and the frequency re-
sponse of the designed filter.
● 173
Practical Audio DSP Projects with the ESP32 - UK.indd 173 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Solution 10.6
Figure 10.14 shows the design parameters entered into the form.
Clicking the Design button designs the filter. The frequency response of the designed filter
is shown in Figure 10.15. Note that the stop-band attenuation is around -45 dB.
Example 10.7
Design an FIR filter with the following specifications using the Dr A R Collins FIR program:
• Low-pass
• Filter order 20 (number of taps = 21)
• Kaiser window
• Cut-off frequency 1 kHz
• Sampling frequency 10 kHz
• Stop-band attenuation 60 dB
● 174
Practical Audio DSP Projects with the ESP32 - UK.indd 174 06-07-2023 10:40
Chapter 10 • Designing FIR Digital Filters
Solution 10.7
Start the program and enter the required filter specifications as shown in Figure 10.16.
Click CALCULATE FILTER. The designed filter frequency response, impulse response, and
the filter coefficients will be displayed as shown in the Figure. Notice that the stop-band
attenuation is 60 dB.
Figure 10.17 shows the same design with the stop-band attenuation changed to 80 dB.
● 175
Practical Audio DSP Projects with the ESP32 - UK.indd 175 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Figure 10.18 shows the same design with the stop-band attenuation at 60 dB, but the filter
order increased to 50. Notice the change in the transition region by increasing the filter
order (the transition region became much shorter).
Example 10.8
Design an FIR filter with the following specifications using the Dr A R Collins FIR program:
• and-pass
• Filter order 30 (number of taps = 31)
• Band edges at 1800 Hz and 3000 Hz
• Kaiser window
• Sampling frequency 10 kHz
• Stop-band attenuation 60 dB
Solution 10.8
Start the program and enter the required filter specifications as shown in Figure 10.19. The
frequency response, impulse response, and filter coefficients are all shown in the Figure.
● 176
Practical Audio DSP Projects with the ESP32 - UK.indd 176 06-07-2023 10:40
Chapter 10 • Designing FIR Digital Filters
N −1
y[n] = ∑ h[n] x[n − k ]
k =0
Where y[n] and x[n] are the output and input sequences, respectively.
An FIR filter of length N has N coefficients, and in general requires N multipliers and N-1
adders (two-input) for its implementation. The direct form is realized by expanding and
implementing the difference equation. For example, for N = 5 you have
The direct form of realization for the above example with N = 5 is shown in Figure 10.20.
Notice that in this example there are 5 coefficients, 5 multipliers, and 4 two-input adders.
● 177
Practical Audio DSP Projects with the ESP32 - UK.indd 177 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
● 178
Practical Audio DSP Projects with the ESP32 - UK.indd 178 06-07-2023 10:40
Chapter 11 • Design Of IIR Digital Filters
11.1 Overview
There are several methods available for the design of IIR-type digital filters, such as the im-
pulse invariance method, the bilinear transform method, the analog approximation meth-
od, and others. IIR digital filter design mainly concentrates on the magnitude response
of the filter and regards the phase response as secondary. IIR digital filters are usually
designed via classical analog filter approximations. An analog filter is designed initially and
then it is converted into an equivalent digital filter using transformation methods, such as
the backward difference, or the bilinear transformation. There are several classes of analog
filters, such as Butterworth, Chebyshev, inverse-Chebyshev, Bessel, and elliptic filters.
In this chapter, you will explore some of the analog filter design methods and then see how
digital IIR-type filters can be designed using these methods. In addition, the design of IIR
digital filters using computer software packages will be discussed with example designs. At
the end of the chapter, various IIR digital filter structures will be shown.
∑ a ( k ) y ( n − k ) + ∑ b( k ) x ( n − k )
k =0 k =0 (11.2)
z − k x ( n) = x ( n − k ) (11.3)
Also, with a(0) = 1, from (11.2) and (11.3) you can write the transfer function in terms of
the z-transforms as
∑ b( k ) z −k
H ( z) = k =0
N
∑ a(k ) z
k =0
−k
or,
● 179
Practical Audio DSP Projects with the ESP32 - UK.indd 179 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
(11.5)
Where, N is the filter order and wc is the cut-off frequency, and the filter response decreas-
es monotonically as the frequency is increased.
Similarly, in the stop-band, where i.e. after one decade of the cut-off frequency,
● 180
Practical Audio DSP Projects with the ESP32 - UK.indd 180 06-07-2023 10:40
Chapter 11 • Design Of IIR Digital Filters
Filter order
The filter order for a given specification can be determined from the following equations
(11.6)
where
(11.7)
and
ws f
B= = s
wp fp (11.8)
where, ws and w p are the pass-band and stop-band edge frequencies. K s and K p are the
stop-band attenuation and pass-band ripple respectively (in dB).
Example 11.1
Determine the order of a Butterworth filter that meets the following specifications:
fp = 1 kHz
fs = 5 kHz
Ks = 40 dB
Kp = 1 dB
Solution 11.1
From equations (11.6) to (11.8) you have
5
B= =5
1
● 181
Practical Audio DSP Projects with the ESP32 - UK.indd 181 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
The normalized Butterworth polynomials can be used to determine the transfer function
for any low-pass filter cut-off frequency wc using the bilinear transformation method or
the impulse invariant method, as described below.
z −1
s=
z + 1 (11.9)
After the transformation, the analog critical frequency and digital critical frequency
are related by
(11.10)
The design steps with the bilinear transformation are summarized below:
1.Determine the Butterworth polynomial for the required filter (Table 11.1).
● 182
Practical Audio DSP Projects with the ESP32 - UK.indd 182 06-07-2023 10:40
Chapter 11 • Design Of IIR Digital Filters
Example 11.2
It is required to design a low-pass 2nd-order Butterworth filter with a pass-band edge fre-
quency of 100 Hz. Assume that the sampling rate is 1000 Hz.
Solution 11.2
Step 1:
From Table 11.1, the normalized transfer function of the required 2nd-order analog filter in
the s-plane is given by:
1
H (s) = 2
s + 1.4142 s + 1
Step 2:
The normalized cut-off frequency of the digital filter is given by:
Step 3
The equivalent analog filter cut-off frequency is given by using equation (11.10):
Step 4:
De-normalizing the analog filter transfer function, you have:
1
H (s) = 2
s 1.4142 s
0.325 + 0.325 + 1
Step 5:
z −1
Convert the analog filter into a digital filter by using equation (11.9), i.e., s=
z +1
● 183
Practical Audio DSP Projects with the ESP32 - UK.indd 183 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
This gives
1
H ( z) = 2
1 z − 1 1.4142 z − 1
0.325 2 z + 1 + 0.325 z + 1 + 1
Simplifying,
Step 7:
Comparing with equation (11.4) you have the required filter parameters:
b(0)=0. 067
b(1)=0.135
b(2)=0.067
a(0)=1
a(1)=−1.1429
a(2)=0.4127
MATLAB function butter can be used to design Butterworth-type digital filters. Function
butter is used to determine the filter order. An example is given below.
● 184
Practical Audio DSP Projects with the ESP32 - UK.indd 184 06-07-2023 10:40
Chapter 11 • Design Of IIR Digital Filters
Example 11.3
Find the coefficients of a low-pass Butterworth digital filter with a cut-off frequency of 100
Hz and a sampling frequency of 1000 Hz.
Solution 11.3
The required MATLAB statement is given below
num =
den =
Where num and den are the numerator and denominator coefficients, respectively. Notice
that this result is the same as in Example 11.2.
Example 11.4
Find the coefficients of a 6th-order band-pass Butterworth digital filter with pass-band edg-
es of 0.4 and 0.8, respectively. Plot the frequency response.
Solution 11.4
The required MATLAB statements are:
N = 6;
M = N / 2;
w1 = 0.4;
w2 = 0.8;
wn = [w1 w2];
[num den] = butter(M, wn)
num =
den =
● 185
Practical Audio DSP Projects with the ESP32 - UK.indd 185 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
b(0)=0.0985
b(1)=0
b(2)=−0.2956
b(3)=0
b(4 )=0. 2956
b(5)=0
b(6)=−0.0985
a(0)=1
a(1)=1.3664
a(2)=1.2449
a(3)=0.8777
a(4 )=0. 6537
a(5)=0.2256
a(6)=0.0563
The frequency response can be plotted using the following MATLAB statements and is
shown in Figure 11.3.
w = 0:0.01/pi:pi;
h = freqz(num, den, w);
plot(w/pi, 20*log10(abs(h)));
grid;
xlabel('Normalized frequency ');
ylabel('Gain (dB)');
title('Bandpass Butterworth Filter');
Example 11.5
Write a MATLAB program to design a digital Butterworth band-pass filter. Enter the filter or-
der and the band edge frequencies from the keyboard. Then plot the normalized frequency
response of the filter.
● 186
Practical Audio DSP Projects with the ESP32 - UK.indd 186 06-07-2023 10:40
Chapter 11 • Design Of IIR Digital Filters
Solution 11.5
The required MATLAB program is:
%
% Butterworth IIR band-pass filter design
%
N = input('Enter the filter order: ');
wL = input('Enter the lower pass-band edge frequency: ');
wH = input('Enter the upper pass-band edge frequency: ');
wn = [wL wH];
[num den] = butter(N/2, wn);
disp('Numerator polynomial (b terms): '); disp(num);
disp('Denominator polynomial (a terms): '); disp(den);
wf = 0:0.1/pi:pi;
H = freqz(num, den, wf);
plot(wf/pi, 20*log10(abs(H)));
grid on;
xlabel('Normalized frequency ');
ylabel('Gain (dB) ');
title('Band-pass Butterworth Filter ');
The Chebyshev filters provide higher attenuation in the stop-band but at the same time,
they provide ripples in the pass-band. Thus, if the application can tolerate some ripples in
the pass-band then Chebyshev filters offer higher attenuation in the stop-band than the
Butterworth filters for a given filter order.
(11.11)
Where, N is the filter order, defines the amount of ripple, and TN2 ( w) is an Nth-order
Chebyshev polynomial, given by:
(11.12)
The design of Chebyshev filters involves the determination of both the order and the ripple
parameter.
● 187
Practical Audio DSP Projects with the ESP32 - UK.indd 187 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
(11.13)
Filter order
The filter order for a given specification can be determined from the following equations
cosh −1 A
N≥
cosh −1 B (11.14)
where
(11.15)
and
ws f
B= = s
wp fp
(11.16)
where, ws and w p are the pass-band and stop-band edge frequencies. K s and K p are the
stop-band attenuation and pass-band ripple respectively (in dB).
Example 11.6
Determine the order of a Chebyshev filter that meets the following specifications:
fp = 1 kHz
fs = 5 kHz
Ks = 40 dB
Kp = 1 dB
Solution 11.6
From equations (11.14) to (11.16) you have
5
B= =5
1
● 188
Practical Audio DSP Projects with the ESP32 - UK.indd 188 06-07-2023 10:40
Chapter 11 • Design Of IIR Digital Filters
Therefore, rounding up, you have N = 3. Compared with the Butterworth design with the
same specifications, it is clear that a lower-order Chebyshev filter is required.
The design of Chebyshev digital filters using the bilinear transformation is similar to the
design of Butterworth filters. First, the required normalized Chebyshev polynomial in the
s-plane is obtained for the required filter order and ripple using published tables. Then the
digital filter is designed by following the steps given in section 11.3.1, Example 11.2.
The MATLAB function cheby1 can be used to design Chebyshev type filters.
Example 11.7
Design a 5th-order Chebysev-type high-pass digital filter using MATLAB with a pass-band
ripple of 2 dB and the pass-band edge at 0.8. Then plot the frequency response.
Solution 11.7
The required MATLAB statements are:
N = 5;
e = 2;
wn = 0.8;
[num, den] = cheby1(N, e, wn, 'high')
num =
den =
The statements to plot the frequency response are given below and is shown in Figure 11.4:
w = 0:0.1/pi:pi;
H = freqz(num, den, w);
plot(w/pi, 20*log10(abs(H)));
grid on;
● 189
Practical Audio DSP Projects with the ESP32 - UK.indd 189 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
(11.17)
2
Where, N is the filter order, defines the amount of ripple, and R N ( w) is an Nth-order
polynomial. The design of elliptic filters is much more complex than the design of other
types of filters. There are many books and papers on the design of elliptic filters and inter-
ested readers should consult these sources.
Example 11.8
Design a low-pass digital elliptic filter with an order of 7 and a pass-band edge at 0.5. As-
sume a pass-band ripple of 0.3 dB, and minimum stop-band attenuation of 50 dB. Plot the
frequency response of the filter.
Solution 11.8
The required MATLAB statements are given below:
N = 7;
ep = 0.3;
as = 50;
wn = 0.5;
[num den] = ellip(N, ep, as, wn)
num =
den =
The frequency response can be plotted using the following MATLAB statements, and is
shown in Figure 11.5:
w = 0:0.1/pi:pi;
H = freqz(num, den, w);
plot(w/pi, 20*log10(abs(H)));
grid on;
● 190
Practical Audio DSP Projects with the ESP32 - UK.indd 190 06-07-2023 10:40
Chapter 11 • Design Of IIR Digital Filters
11.7 Computer-aided design tools for the design of IIR digital filters
There are many software packages available on the Internet that help to calculate the IIR
digital filter coefficients. Some popular ones are:
• ScopeIIR (iowegian.com)
• Digital Filter Plus (https://www.numerix-dsp.com/dfplus/)
• FIIIR (https://fiiir.com/)
• IIR Filter Explorer (http://jaggedplanet.com/iir/iir-explorer.asp)
• How to implement IIR Bandpass Butterworth Filter using Scipy – Python?
(https://www.geeksforgeeks.org/how-to-implement-iir-bandpass-butterworth-
filter-using-scipy-python/)
• Digital Filter Analyzer (http://www.digitalfilter.com/products/dfalz/endfalz.html)
• and many others.
Examples are given in the following sections on using the ScopeIIR and the freely available
Digital Filter Analyzer.
Some examples of IIR filter designs are given below to illustrate the steps involved in the
design. The following examples assume that the ScopeIIR package has already been in-
stalled on the PC.
● 191
Practical Audio DSP Projects with the ESP32 - UK.indd 191 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Example 11.9
Design an IIR filter with the following specifications:
• Low-pass
• Butterworth design
• Cut-off frequency = 100 Hz
• Sampling rate = 1000 Hz
• Filter order = 7
Solution 11.9
Figure 11.6 shows the ScopeIIR design window. Clicking the design button designs the filter
and draws the frequency response and the phase response. The frequency response of the
designed filter is shown in Figure 11.7.
The filter coefficients are shown at the bottom left-hand corner of the screen. In addition,
the pole-zero positions of the designed filter are shown on the left-hand side of the screen.
Example 11.10
Design an IIR filter with the following specifications:
• Low-pass
• Chebyshev design
● 192
Practical Audio DSP Projects with the ESP32 - UK.indd 192 06-07-2023 10:40
Chapter 11 • Design Of IIR Digital Filters
Solution 11.10
Select LPF for low-pass filter, click Design and enter the specifications as shown in Figure
11.8. Click OK and then click F-Response and then Coefficients to display the frequency
response and filter coefficients (Figure 11.9).
● 193
Practical Audio DSP Projects with the ESP32 - UK.indd 193 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
N M
y[n] = −∑ a(k ) y (n − k ) + ∑ b(k ) x(n − k )
k =1 k =0
Expanding the above equation, the input and output samples are related by
Figure 11.10 shows the implementation of the above difference equation in direct form.
For example, a third-order filter is implemented from a cascade of a first-order and a sec-
ond-order filter transfer functions as shown below:
● 194
Practical Audio DSP Projects with the ESP32 - UK.indd 194 06-07-2023 10:40
Chapter 11 • Design Of IIR Digital Filters
Solution 11.10
You can factor the transfer function into a second-order and a first-order polynomial:
The above transfer function can easily be implemented as shown in Figure 11.12.
● 195
Practical Audio DSP Projects with the ESP32 - UK.indd 195 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Chapter 12 • D
esigning FIR Digital Filters with the
ESP32 DevKitC
12.1 Overview
In this chapter, you will be learning the design of FIR digital filters. The filter coefficients
will be obtained using the ScopeFIR filter design program described in Chapter 10. After
obtaining the filter coefficients, you will draw the structure of the filter to be implemented.
The actual physical filter will then be realized using the ESP32 DevKitC development board.
Only audio FIR digital filters are considered in this chapter. The frequency response of the
designed filter will be plotted in real-time using the Velleman PCSGU250 digital oscillo-
scope/function generator/Bode plotter device.
Several real-time audio-based projects are given in this chapter using a Pmod I2S2 device
before designing FIR-type digital filters.
Function Generator
• Sweep frequency: 0.005 Hz to 500 kHz
• Amplitude range: 00 mV to 10 V
• Offset voltage: –5 V to +5 V
• Vertical resolution: 8 bits
• Sample rate: 12.5 MHz
Bode Plotter
• Logarithmic plotting
• Automatic sync between input and output
• Volt (V) and decibel (dB) plotting
• Voltage range: 10 mV to 3 V
• Frequency range: 10 Hz to 10 kHz
Oscilloscope
• Bandwidth: DC to 12 MHz (2 channels)
• Input impedance: 1 Mohm
• Maximum input voltage: 39 V
• Timebase: 0.1 μs to 500 ms
• Input range: 10 mV to 3 V per division
• Input sensitivity: 0.3 mV display resolution
● 196
Practical Audio DSP Projects with the ESP32 - UK.indd 196 06-07-2023 10:40
Chapter 12 • Designing FIR Digital Filters with the ESP32 DevKitC
Before using the library, you have to install it in your Arduino IDE. The steps are given
below (you can also see many example files at this link on how to use various tools of the
library):
https://github.com/pschatzmann/arduino-audio-tools
• Click on Code (green tab) and then click Download ZIP (Figure 12.2).
• You should have the following file downloaded to your Downloads folder (this
was the file at the time of authoring this book): arduino-audio-tools-main.
zip.
● 197
Practical Audio DSP Projects with the ESP32 - UK.indd 197 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
• Start your Arduino IDE. Click Sketch Include Library and select Add .ZIP
Library...
• Browse and select the file you just downloaded and click OPEN.
• To verify your installation, click File Examples and scroll down to audio-
tools. You should see many example files listed.
There are many header files with default settings included with the installation. You may
like to look at these files at the above link, or at the following folder (you are advised to
have a look at the sample example files under folder: Examples):
The aim: The aim of this project is to show how the audio tools library can be used to gen-
erate a sinewave with the required frequency. This project should be a good starting point
before you look at the FIR digital filter projects.
The block diagram and circuit diagram of the project are in Figure 6.34 and Figure 6.35, re-
spectively. The generated sinewave is sent to the speaker through the I2S class D amplifier.
Program listing: Figure 12.3 shows the program listing (Program: Sinewave). At the
beginning of the program, the header file AudioTools.h is included in the program. Then
the sample rate is set to 44100 Hz with 1 channel, sine wave generator set to amplitude
32000, which is about the maximum amplitude, and the sound stream is set to sineWave.
https://pschatzmann.github.io/arduino-audio-tools/namespaceaudio__tools.html
https://pschatzmann.github.io/arduino-audio-tools/classaudio__tools_1_1_sine_
wave_generator.html
https://pschatzmann.github.io/arduino-audio-tools/classaudio__tools_1_1_
generated_sound_stream.html
● 198
Practical Audio DSP Projects with the ESP32 - UK.indd 198 06-07-2023 10:40
Chapter 12 • Designing FIR Digital Filters with the ESP32 DevKitC
The sound is generated with 2 bytes (i.e. int16_t). Inside the setup() routine the Serial
Monitor is configured and AudioLogger is started (useful for debugging) so that informa-
tion is displayed on the Serial Monitor. The I2S bus is then configured by specifying the
sample rate, number of channels, amplifier pins, etc. The sine wave is then generated with
the frequency of 2000 Hz using function sineWave().
You should hear the 2 kHz audio sine wave on the speaker.
/****************************************************************
* GENERATE SINEWAVE
* =================
*
* This program uses the audio tools library to generate sinewave
* signal with the frequency of 2 KHz. The generated signal is sent
* to a speaker via an amplifier. Also, a digital oscilloscope is
* used to display the waveform
*
* Author : Dogan Ibrahim
* Program: Sinewave
* Date : April, 2023
**************************************************************/
#include "AudioTools.h"
uint16_t sample_rate=44100;
uint8_t channels = 1;
SineWaveGenerator<int16_t> sineWave(32000); // Amplitude of 32000
GeneratedSoundStream<int16_t> sound(sineWave); // Sine wave
I2SStream out;
StreamCopy copier(out, sound); // Copy sound into i2s
//
// Start Serial Monitor, start AudioLogger, configure I2S, Start sine wave
//
void setup(void)
{
Serial.begin(115200);
AudioLogger::instance().begin(Serial, AudioLogger::Info);
Serial.println("starting I2S...");
auto config = out.defaultConfig(TX_MODE);
config.sample_rate = sample_rate;
config.channels = channels;
config.bits_per_sample = 16;
config.i2s_format = I2S_STD_FORMAT;
config.is_master = true;
config.port_no = 0;
● 199
Practical Audio DSP Projects with the ESP32 - UK.indd 199 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
//
// Start sine wave
//
sineWave.begin(channels, sample_rate, 2000); // 2 kHz sinewave
Serial.println("Sinewave started...");
}
//
// Copy sound to out
//
void loop()
{
copier.copy();
}
In this project, the output waveform is displayed on an Arduino smartphone using the apps
called Audio Frequency Counter, by keuwlsoft (Figure 12.4). Starting the apps and
placing the Android smartphone near the speaker displays the sound frequency as shown
in Figure 12.5. Clearly, the sound frequency is 2000 Hz.
● 200
Practical Audio DSP Projects with the ESP32 - UK.indd 200 06-07-2023 10:40
Chapter 12 • Designing FIR Digital Filters with the ESP32 DevKitC
Figure 12.6 shows the data displayed on the Serial Monitor while the sine wave is gener-
ated.
● 201
Practical Audio DSP Projects with the ESP32 - UK.indd 201 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
The aim: The aim of this project is to show how the Pmod I2S2 can be connected as
two independent I2S ports in ESP32-based signal processing applications.
A Pmod I2S2 device (Figure 12.7) is used as the external interface to the project. This
device includes on-board 24-bit high speed ADC and DAC modules which are used in
this project. An input signal is supplied to the ADC port of this device through a 3.5 mm
blue audio jack. Similarly, the output is taken from the DAC port again through a 3.5
mm green audio jack.
The Pmod I2S2 takes the analog audio signal as input and outputs analog signal through
a standard 3.5 mm stereo headphone jack (labeled Line Out). An ADC converter is
used to input analog audio signals through a 3.5 mm audio jack (labeled Line In). It is
designed to work at a wide variety of standard audio sampling rates.
● 202
Practical Audio DSP Projects with the ESP32 - UK.indd 202 06-07-2023 10:40
Chapter 12 • Designing FIR Digital Filters with the ESP32 DevKitC
https://digilent.com/reference/pmod/pmodi2s2/reference-manual
The line-in converter can be placed in either Master Mode or Slave Mode by setting mode
jumper JP1 to the corresponding position. The position of this jumper should not be changed
while the Pmod I2S2 is powered on. In Slave Mode, LRCK and SCLK must be generated
by the host board. Supported sample rate ranges and their corresponding MCLK/LRCK and
SCLK/LRCK ratios are provided in Table 12.1 below from the CS5343 datasheet. The line-in
converter automatically selects as needed from single- and double-speed modes:
In Master Mode, both LRCK and SCLK are automatically generated by the line-in con-
verter. For Master Mode, the provided MCLK rate must be within the range of 4-54 KHz.
Once the line-in converter has powered up, it automatically selects an MCLK/LRCK ratio of
256×/512× depending on the MCLK rates.
I2S2 has 12 pins. The pin configurations are as in Table 12.2. Pin 1 is marked on the PCB
(see Figure 12.7. Pins run from 1 to 6 on top of the PCB and from 7 to 12 at the bottom,
with pin 7 located under pin 1):
● 203
Practical Audio DSP Projects with the ESP32 - UK.indd 203 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Block diagram: Figure 12.8 shows the block diagram of the project, where the input and
output of the Pmod I2S2 are connected to the PCSGU250 combined function generator/
oscilloscope/Bode plotter.
Circuit diagram: The circuit diagram of the project is shown in Figure 12.9.
The connections between the Pmod I2S2 and the ESP32 DevKitC are given below. Note that
the master clock (MCLK) must be connected to either GPIO0, GPIO1 or GPIO3:
● 204
Practical Audio DSP Projects with the ESP32 - UK.indd 204 06-07-2023 10:40
Chapter 12 • Designing FIR Digital Filters with the ESP32 DevKitC
Note: Pin 4 SDIN is data output from ESP32, pin 10 SDOUT is data input to ESP32. A/D
is the input channel side, and D/A is the output channel side.
Program listing: Figure 12.10 shows the program listing (Program: InOut). At the be-
ginning of the program, AudioTools header file is included, sample_rate is set to 10 kHz
(can be changed as you like), bits_per_sample is set to 16, and two streams named in
and out are defined. You then define using StreamCopy that in will be copied to out.
Inside the setup() function, Serial Monitor and the AudioLogger are initialized, and the
input stream (configin) and output stream (configout) of the I2S ports are configured by
specifying the used GPIO ports. Notice that separate GPIO pins are used for the output and
input I2S ports. Pin pin_ws is the LRCK channel and pin_bck is the SCLK channel. Master
clock (pin_mck) is set to 0 (i.e. GPIO0) for the input and to 1 (i.e. GPIO1) for the output
streams. The remainder of the program runs in the loop() function where the in stream is
copied to the out stream.
/******************************************************************
* USING Pmod I2S2 TO INPUT-OUTPUT A SIGNAL
* ========================================
*
* In this program the Pmod I2S2 module is used. Input signal is
* received from the PCSGU250 function generator.The output signal
* is displayed on the PCSGU250 oscilloscope
*
* Author : Dogan Ibrahim
* Program: InOut
* Date : May, 2023
*
* Note: This program is taken from Phil Schatzmann's stream file
* called i2s-i2s-2.ino and has been modified slightly
*****************************************************************/
#include "AudioTools.h"
uint16_t sample_rate=10000;
uint16_t channels = 2;
uint16_t bits_per_sample = 16;
I2SStream in, out;
● 205
Practical Audio DSP Projects with the ESP32 - UK.indd 205 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
void setup(void)
{
Serial.begin(115200);
AudioLogger::instance().begin(Serial, AudioLogger::Info);
//
// in stream configuration
//
auto configin = in.defaultConfig(RX_MODE); // RX mode
configin.sample_rate = sample_rate;
configin.channels = channels;
configin.bits_per_sample = bits_per_sample;
configin.i2s_format = I2S_STD_FORMAT;
configin.is_master = true;
configin.port_no = 0;
configin.pin_ws = 15; // LRCK pin
configin.pin_bck = 14; // SCLK pin
configin.pin_data = 22; // Data pin
configin.pin_mck=0; // Master clock
in.begin(configin);
//
// out stream configuration
//
auto configout = out.defaultConfig(TX_MODE); // TX mode
configout.sample_rate = sample_rate;
configout.channels = channels;
configout.bits_per_sample = bits_per_sample;
configout.i2s_format = I2S_STD_FORMAT;
configout.is_master = true;
configout.port_no = 1;
configout.pin_ws = 19; // LRCK pin
configout.pin_bck = 18; // SCLK pin
configout.pin_data = 23; // Data pin
configout.pin_mck=1; // Master clock
out.begin(configout);
}
//
// Copy sound to out
//
void loop()
{
● 206
Practical Audio DSP Projects with the ESP32 - UK.indd 206 06-07-2023 10:40
Chapter 12 • Designing FIR Digital Filters with the ESP32 DevKitC
copier.copy();
}
Note that the program in Figure 12.10 is taken from Phil Schatzmann's stream file
called i2s-i2s-2.ino and it has been modified slightly. The original program can be found
at the following website:
https://github.com/pschatzmann/arduino-audio-tools/blob/main/examples/
examples-stream/streams-i2s-i2s-2/streams-i2s-i2s-2.ino
Figure 12.11 shows the input and output waveforms on the oscilloscope (input is the top
waveform). Note that the output signal is similar to the input signal since the input is sent
directly to the output without any processing. In this example, the input was a sinewave
with the frequency of 200 Hz.
The aim: The aim of this project is to show how the Pmod I2S2 can be connected as a
shared I2S port in ESP32-based signal processing applications.
Circuit diagram: The block diagram of the project is as in Figure 12.8. Figure 12.12 shows
the circuit diagram. Notice that a shared I2S port is used in this project where Pmod I2S2
A/D and D/A pins MCLK, LRCK, and SCLK are shared.
● 207
Practical Audio DSP Projects with the ESP32 - UK.indd 207 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
The connections between the Pmod I2S2 and the ESP32 DevKitC are given below:
Program listing: Figure 12.13 shows the program listing (Program: Shared). This pro-
gram is similar to Figure 12.10, but here the I2S port pins are shared. Notice that the I2S
configuration mode is set to RXTX_MODE. The input pin is specified as pin_data_rx and
the output pin simply as pin_data. Here, again, the output waveform is similar to the input
waveform since the input is sent to the output without any processing. In this example,
the sample rate was set to 10 kHz (can be changed if required) and the input was a 200
Hz sinewave.
/****************************************************************
* INPUT-OUTPUT WITH Pmod SHARED PORTS
* ===================================
*
* In this program a Pmod I2S2 module is used. The input signal is
* copied to the output. MCLK, LRCK, SCLK pins of the A/D and D/A
* share the same ESP32 GPIO ports. The data input and output pins
● 208
Practical Audio DSP Projects with the ESP32 - UK.indd 208 06-07-2023 10:40
Chapter 12 • Designing FIR Digital Filters with the ESP32 DevKitC
uint16_t sample_rate=10000;
uint8_t channels = 2;
I2SStream in;
StreamCopy copier(in, in);
//
// Configure the input and output streams
//
void setup(void)
{
Serial.begin(115200);
AudioLogger::instance().begin(Serial, AudioLogger::Info);
//
// Copy in stream to output
//
void loop()
{
copier.copy();
}
● 209
Practical Audio DSP Projects with the ESP32 - UK.indd 209 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
The aim: The aim of this project is to show how FIR low-pass filters can be designed using
the ESP32 and the audio tools library. In this project, you will be using the Dr A R Collin's
FIR design program.
The block diagram and circuit diagram of the project are in Figure 12.8 and Figure 12.9
respectively, except that CH2 of the PCSGU250 is not used and CH1 is connected to the
output of the Pmod I2S2 (green plug).
PCSGU250 generates sine wave signals with varying frequencies at the ADC input of the
Pmod I2S2 ADC/DAC module. At the same time, the signals at the DAC output of Pmod are
plotted in real-time by the Bode plotter of the PCSGU250 device.
● 210
Practical Audio DSP Projects with the ESP32 - UK.indd 210 06-07-2023 10:40
Chapter 12 • Designing FIR Digital Filters with the ESP32 DevKitC
The coefficients can be written as follows. You can see the symmetry in the coefficients:
● 211
Practical Audio DSP Projects with the ESP32 - UK.indd 211 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Program Listing: The Arduino Audio Tools library is used in this project. The program is
called FIR1.C and its listing is shown in Figure 12.17. At the beginning of the program, the
sample time is set to 44100 Hz and the 11 filter coefficients are defined in a floating point
array called Coefficients:
float Coefficients[] =
{
0.037388,
0.040120,
0.042348,
0.043997,
0.045010,
0.045351,
0.045010,
0.043997,
0.042348,
0.040120,
0.037388
};
Inside the setup() function the filter is defined as FIR, and the input and output streams
are configured with the GPIO port numbers of the ESP32 DevKitC.
● 212
Practical Audio DSP Projects with the ESP32 - UK.indd 212 06-07-2023 10:40
Chapter 12 • Designing FIR Digital Filters with the ESP32 DevKitC
/****************************************************************
* FIR LOW-PASS FILTER
* ===================
*
* This is the FIR low-pass filter program using the Pmod I2S2
* module as the ADC/DAC. The specifications of the filter are:
*
* Window Type: Kaiser
* Sampling Frequency: 44100 Hz
* Passband Upper Frequency: 1000 Hz
* Filter Order: 10 (11 taps)
* Pass-band attenuation: 22 dB
*
* Author : Dogan Ibrahim
* Program: FIR1
* Date : May, 2023
**************************************************************/
#include "AudioTools.h"
uint16_t sample_rate=44100;
uint8_t channels = 1;
I2SStream in,out;
FilteredStream <int16_t, float> FIR_Filter(in, channels);
StreamCopy copier(out, FIR_Filter);
//
// FIR low-pass filter coefficients
//
float Coefficients[] =
{
0.037388,
0.040120,
0.042348,
0.043997,
0.045010,
0.045351,
0.045010,
0.043997,
0.042348,
0.040120,
0.037388
};
void setup(void)
{
Serial.begin(115200);
● 213
Practical Audio DSP Projects with the ESP32 - UK.indd 213 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
AudioLogger::instance().begin(Serial, AudioLogger::Info);
//
// Configure out stream
//
auto configout = out.defaultConfig(TX_MODE);
configout.sample_rate = sample_rate;
configout.channels = channels;
configout.bits_per_sample = 16;
configout.i2s_format = I2S_STD_FORMAT;
configout.is_master = true;
configout.port_no = 1;
configout.pin_ws = 19; // LRCK
configout.pin_bck = 18; // SCLK
configout.pin_data = 23; // SDOUT
configout.pin_mck = 1;
out.begin(configout);
//
// Configure in stream
//
auto configin = in.defaultConfig(RX_MODE);
configin.sample_rate = sample_rate;
configin.channels = channels;
configin.bits_per_sample = 16;
configin.i2s_format = I2S_STD_FORMAT;
configin.is_master = true;
configin.port_no = 0;
configin.pin_ws = 15; // LRCK
configin.pin_bck = 14; // SCLK
configin.pin_data = 22; // SDOUT
configin.pin_mck = 0;
in.begin(configin);
}
//
// Copy filtered signal to out
//
void loop()
{
copier.copy();
}
● 214
Practical Audio DSP Projects with the ESP32 - UK.indd 214 06-07-2023 10:40
Chapter 12 • Designing FIR Digital Filters with the ESP32 DevKitC
Figure 12.18 shows the frequency response obtained from the designed filter. Notice in this
figure that the frequency axis is linear.
The instructions to plot the frequency response using the PCSGU250 device are as follows:
• Connect the PCSGU250 function generator output to the input of the Pmod
I2S2 module (blue jack connector).
• Connect the output of the filter (green jack connector of I2S2) to CH1 of the
PCSGU250.
• Connect the PCSGU250 device to the USB port of your PC and power it up
• Click the Start button to draw the frequency response (you may have to adjust
the horizontal and vertical axes scale factors). In this project, the vertical axis
was set to 5 dB/div, the frequency range set to 100 Hz to 100 kHz, and the
signal amplitude was set to 1.6 V on the oscilloscope function generator.
The PCSGU250 device may not give an accurate graph in the stop-band if the input signal
is very small as may be the case in the stop-band of low-pass filters.
● 215
Practical Audio DSP Projects with the ESP32 - UK.indd 215 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
The aim: The aim of this project is to show how FIR band-pass filters can be designed
using the ESP32 and the audio tools library. In this project, you will be using the ScopeFIR
filter design package to get the filter coefficients.
The block diagram and circuit diagram of the project are in Figure 12.8 and Figure 12.9,
respectively.
Figure 12.19 shows the filter specifications entered into the program. The theoretical fre-
quency response and the filter coefficients are displayed in the figure.
● 216
Practical Audio DSP Projects with the ESP32 - UK.indd 216 06-07-2023 10:40
Chapter 12 • Designing FIR Digital Filters with the ESP32 DevKitC
The same program as in Figure 12.17 is used to design the band-pass filter but the filter
coefficients were changed for the band-pass filter. Figure 12.21 shows the frequency re-
sponse of the designed filter, plotted using the PCSU250 function generator/Bode plotter.
The aim: The aim of this project is to show how FIR high-pass filters can be designed using
the ESP32 and the audio tools library. In this project, you will be using the Dr AR Collin's
FIR design program.
The block diagram and circuit diagram of the project are as in Figure 12.8 and Figure 12.9,
respectively.
● 217
Practical Audio DSP Projects with the ESP32 - UK.indd 217 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Figure 12.22 shows the filter specifications entered into the program. Clicking the CALCU-
LATE FILTER button displays the frequency response, impulse response and lists the filter
coefficients.
The same program as in Figure 12.17 is used to design the high-pass filter but the filter
coefficients were changed for the high-pass filter. This is left as an exercise to the readers.
12.10 Design of FIR digital filters from the first principles (without
using a library)
In the previous FIR filter design examples, you have used the Arduino Audio Tools library.
In this section, you will be designing FIR filters without using a library. Here, you will be
using the ESP32 on-chip ADC and DAC converters. It is important to realize that the ESP32
on-chip ADC and DAC converters have very low specifications, and they can only be used in
very low audio DSP applications. The on-chip ADC is 12-bit wide, while the on-chip DAC is
● 218
Practical Audio DSP Projects with the ESP32 - UK.indd 218 06-07-2023 10:40
Chapter 12 • Designing FIR Digital Filters with the ESP32 DevKitC
only 8-bit wide. As a result, the output waveform will not be very accurate representation
if standard 16-bit converters were to be used. But the main aim is here to show FIR filter-
ing can be done using the first principles, without a library. More accurate results can be
obtained by using fast 16-bit external ADC and DAC converters. Additionally, both the ADC
and the DAC are unipolar and they do not accept negative going data. But the sinewave
input has both positive and negative half cycles. The input waveform can be shifted up so
that it is always positive. Modifying the design given in this section to use fast external ADC
and DAC converters should be very easy as it involves modifying the input and output parts
of the hardware and the program.
Designing FIR filters from the first principles requires the use of a timer interrupt of the
ESP32 processor. The operation of the program is such that a timer interrupt is configured
to generate interrupts at the required sample times of the filter. Inside the interrupt service
routine (ISR) data is read from the ADC, processed, and then output to the DAC. Figure
12.24 shows the operation of the program as a PDL (Program Description Language).
BEGIN/MAIN
Configure timer interrupt at the filter sampling time
Store filter coefficients in an array
Configure ADC and DAC
Wait for timer interrupts (ISR)
END/MAIN
BEGIN/ISR
Read a new sample from ADC
Calculate the output sample
Send the output sample to the DAC
Delay the input signals by one sample time
END/TMR
Before writing the filter program, it is worthwhile to review the ESP32 timers and timer
interrupts.
● 219
Practical Audio DSP Projects with the ESP32 - UK.indd 219 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
A timer can trigger an alarm when the timer value matches a preset value. When this
happens, the timer will auto-reload to zero and it will trigger a timer interrupt (if enabled).
As an example, with a prescaler value of 80 and a clock frequency of 80 MHz, the timer
speed will be 1 MHz.
For example,
This function has 3 arguments: The first argument is the timer number (0 to 3), the second
argument is the prescaler value which can have values 2 to 65535. In the above exam-
ple, it is set to 80 so that the timer will count from 0 to 1,000,000 in one second. i.e. each
count will take 1 microsecond. The last argument is a flag where true counts UP and false
counts DOWN.
This function has 3 arguments: the first argument is the pointer as defined in Step 1.
The second argument is the function to be called when the timer interrupt occurs. Note
that the interrupt service routine function cannot have any arguments and it should have
the IRAM_ATTR keyword. When you use the IRAM_ATTR attribute, the compiled code is
placed in the ESP32's Internal RAM (IRAM). Otherwise, the code is kept in Flash memory.
The Flash memory on ESP32 is much slower than internal RAM. If the code you want to run
is an Interrupt Service Routine (ISR), you generally want to execute it as soon as possible.
If you had to wait for the ISR to load from the Flash memory, then the ISR routine could be
very slow. The third argument is a flag set to true to enable the auto-reload.
● 220
Practical Audio DSP Projects with the ESP32 - UK.indd 220 06-07-2023 10:40
Chapter 12 • Designing FIR Digital Filters with the ESP32 DevKitC
for example,
timerAlarmEnable(Timer);
What you are interested to practice is calculating the value to be loaded into the prescaler
in Step 1 and into variable cnt in Step 3 for a required timer interrupt time. This can be
calculated using the following formula:
or,
prescaler * cnt = Timer clock speed (Hz) * T (seconds)
Here, you can choose a value for the prescaler and then calculate the required value of cnt.
Assuming a prescaler value of 80, you have:
cnt = 80,000,000 * T / 80
or
cnt = 1,000,000 * T (seconds)
For example, for a 1-second timer interrupt, you can set cnt as: cnt = 1,000,000. Similarly,
for 1-millisecond timer interrupt you can set cnt as: cnt = 1,000,000 * 0.001 = 1000
The variable manipulated in the interrupt ISR function should be declared with the volatile
keyword.
● 221
Practical Audio DSP Projects with the ESP32 - UK.indd 221 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Some other timer interrupt related functions that may be useful are (see website for the
full list: https://espressif-docs.readthedocs-hosted.com/projects/arduino-esp32/en/latest/
api/timer.html):
A simple example project is given in the next section to show how timer interrupts can be
generated every second and how an LED connected to a GPIO port can be flashed every
second inside the ISR.
The aim: The aim of this project is to show how the timer interrupt can be used in a simple
project.
The block diagram and circuit diagram of the project are as in Figure 4.11 and Figure 4.12,
respectively. The LED is connected to port GPIO23 through a current-limiting resistor.
Program listing: Figure 12.25 shows the program listing (Program: TimerInt). At the be-
ginning of the program, LED is assigned to port GPIO23, and a pointer is created to variable
the named My_timer of type hw_timer_t. Inside the setup routine, the LED port is con-
figured as an output and timer 0 is configured to generated interrupts at every second with
the callback function ISR. The timer is configured with a prescaler value of 80 and a count
value of 1,000,000. Inside the interrupt service routine, the state of the LED is changed.
/****************************************************************
* FLASHING LED IN ISR
* ===================
*
* In this program an LED is connectec to port GPIO23 through a
* current limiting resistor. The LED flashed every second inside
* a timer interrupt service routine called ISR
*
* Program: TimerInt
* Date : May, 2023
**************************************************************/
● 222
Practical Audio DSP Projects with the ESP32 - UK.indd 222 06-07-2023 10:40
Chapter 12 • Designing FIR Digital Filters with the ESP32 DevKitC
#define LED 23
hw_timer_t *My_timer = NULL;
//
// Configure timer 0, prscaler=80, UP count, timer interrupts at
// every second, attach interrupt, callback function ISR
//
void setup()
{
pinMode(LED, OUTPUT);
My_timer = timerBegin(0, 80, true);
timerAttachInterrupt(My_timer, &ISR, true);
timerAlarmWrite(My_timer, 1000000, true);
timerAlarmEnable(My_timer);
}
void loop()
{
}
Using ScopeFIR filter design program (you can use any other design program if you wish),
the specifications of the filter to be designed is shown in Figure 12.26.
● 223
Practical Audio DSP Projects with the ESP32 - UK.indd 223 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
The filter will be implemented using the Direct form of realization (see Chapter 10). The
structure of the filter to be designed has N = 10, having 11 taps.
Circuit diagram: Figure 12.27 shows the circuit diagram. An analog input signal is ap-
plied to analog input GPIO34 (ADC1_CH6). The analog output is taken from port GPIO25
(DAC_CH_1).
● 224
Practical Audio DSP Projects with the ESP32 - UK.indd 224 06-07-2023 10:40
Chapter 12 • Designing FIR Digital Filters with the ESP32 DevKitC
Program listing: Figure 12.28 shows the program listing (Program: FIRInt). At the be-
ginning of the program, the 11 filter coefficients are stored in a floating-point array called
h. Inside the setup() function timer 0 is initialized to generate interrupts at every millisec-
ond (1000 Hz sampling time). Timer 0 prescaler is set to 80 and the counter value is set
to 1000 as described earlier in Section 12.10.1. The timer callback function is named ISR.
This function is called every millisecond. Here, a new input sample is read by the ADC, the
FIR algorithm is applied, and the output is sent to DAC.
The ADC on the ESP32 processor is 12-bits wide, having a range of 0 to 4095. The DAC on
the other hand is only 8-bits wide, having a range of 0 to 255. The map statement is used
to map the received 0 to 4095 into 0 to 255 before the received samples are processed.
Also, the ADC and DAC are unipolar and they do not accept negative data. Because of this,
the input data was shifted up so that it is always positive.
/****************************************************************
* FIR FILTER DESIGN FROM FIRST PRINCIPLES
* =======================================
*
* This is an FIR filter design program. The program is developed
* from first principles and does not use any filter design library
* Timer interrupt is used to read and process the input samples.
* Analog input ADC1_CH6 (GPIO34) is used.
* DAC channel used is DAC_CH_1 (GPIO25).
*
* Program: FIRInt
* Date : May, 2023
* Author : Dogan Ibrahim
**************************************************************/
#define N 10 //Filter order=10,11 taps
#define ADC 34 // ADC channel
#define DAC 25 // DAC channel
hw_timer_t *My_timer = NULL; // Timer pointer
//
// Filter coefficients
//
float h[N+1]={-0.0613461,0.0476723,0.105628,0.1775189,
0.236046,0.258520,0.236046,0.177518,0.105628,0.047672,-0.0613461};
//
// Timer interrupt service routine. Program jumps here
// every 1 ms (sampling time = 1 kHz)
//
● 225
Practical Audio DSP Projects with the ESP32 - UK.indd 225 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
//
// Configure timer 0 to interrupt at every 1 ms
// Prescaler is set to 80, counter is set to 1000
//
void setup()
{
My_timer = timerBegin(0, 80, true);
timerAttachInterrupt(My_timer, &ISR, true); // Attach interrupt
timerAlarmWrite(My_timer, 1000, true); // 1 msec.
timerAlarmEnable(My_timer); // Enable Timer
}
//
// Do nothing, wait for timer interrupts
//
void loop()
{
}
● 226
Practical Audio DSP Projects with the ESP32 - UK.indd 226 06-07-2023 10:40
Chapter 12 • Designing FIR Digital Filters with the ESP32 DevKitC
This method is explained in most DSP books, and the basic operation is explained below by
considering a 3rd-order filter. Figure 12.30 shows a 3rd-order FIR filter where A, B, C and D
are the tapping points. The operations performed are summarized below:
Stage 1:
● 227
Practical Audio DSP Projects with the ESP32 - UK.indd 227 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Stage 2:
Stage 3:
Stage 4:
Stage 5:
The important point to notice here is that the input sample is always multiplied by h0 and
the input values are shifted right by one sample time.
Figure 12.31 shows the filter operation where the variables multiplied by each other are
shown with arrows. On close examination of this figure, it is clear that the filtering operation
can be conducted by making the input array x to be a circular array. The last input samples
are always loaded into the array location which is not needed for the next calculation and
the input array pointer moves up as new samples are received. At the same time, the array
pointer moves down to conduct the multiplication with the filter coefficients.
● 228
Practical Audio DSP Projects with the ESP32 - UK.indd 228 06-07-2023 10:40
Chapter 12 • Designing FIR Digital Filters with the ESP32 DevKitC
The required operations inside the ISR are described by the following PDL. Notice here that
a round bracket means the contents of the array pointed to by the corresponding pointer.
The input pointer (i_pointer) and the x-array pointer (x_pointer) are initialized outside the
ISR:
y = 0
Input to x[i_pointer]
DO for all taps
y = y + h[i] * (x_pointer)
Increment x_pointer and wrap around if > N
ENDDO
Output y to DAC converter
Decrement i_pointer and wrap around if < 0
You will be designing a high-pass filter now as described in the next section using the new
algorithm.
● 229
Practical Audio DSP Projects with the ESP32 - UK.indd 229 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
The ScopeFIR program was used to obtain the filter coefficients and the frequency re-
sponse. The frequency response of the filter is shown in Figure 12.32. The filter coefficients
are shown in Figure 12.33.
● 230
Practical Audio DSP Projects with the ESP32 - UK.indd 230 06-07-2023 10:40
Chapter 12 • Designing FIR Digital Filters with the ESP32 DevKitC
Program Listing: The program listing is shown in Figure 12.34 (Program: FIRCircular).
Most of the code is similar to the one in Figure 12.28, but here a circular buffer is used for
the input samples. The filtering operation is implemented by the following code:
Here, as mentioned earlier, the x_pointer moves down to access the next input sample,
while new input samples are loaded into the array location pointed to by i_pointer.
/****************************************************************
* FIR FILTER DESIGN FROM FIRST PRINCIPLES
* =======================================
*
* This is an FIR filter design program. The program is developed
* from first principles and does not use any filter design library
* Timer interrupt is used to read and process the input samples.
* Analog input ADC1_CH6 (GPIO34) is used.
* DAC channel used is DAC_CH_1 (GPIO25).
*
* This is more efficient algorithm
*
* Program: FIRCircular
* Date : May, 2023
* Author : Dogan Ibrahim
**************************************************************/
● 231
Practical Audio DSP Projects with the ESP32 - UK.indd 231 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
//
// Filter coefficients
//
float h[N+1]={0.02494684, 0.02399362, -0.04291250, -0.01049585,
0.03126108, 0.04482837, -0.04304749, -0.09152983,
0.04515781, 0.31390420, 0.45262051, 0.31390420,
0.04515781,-0.09152983, -0.04304749, 0.04482837,
0.03126108,-0.01049585, -0.04291250, 0.02399362,
0.02494684};
//
// Timer interrupt service routine. Program jumps here
// every 1 ms (sampling time = 1 kHz)
//
void IRAM_ATTR ISR()
{
AnalogIn = analogRead(ADC);
AnalogIn = map(AnalogIn,0,4095,0,255);
x[i_pointer] = AnalogIn;
yN = 0.0;
//
// Calculate a new output yn. This process will also shift the
// input samples as required so that there is no need to move
// the samples around in memory. Index x_pointer is used as the
// pointer and the pointer is initialized outside the loop
//
x_pointer = i_pointer;
//
// Calculate a new output yn
//
for(i = 0; i <= N; i++)
{
yN = yN + h[i] * x[x_pointer];
if(++x_pointer > N)x_pointer = 0;
}
● 232
Practical Audio DSP Projects with the ESP32 - UK.indd 232 06-07-2023 10:40
Chapter 12 • Designing FIR Digital Filters with the ESP32 DevKitC
i_pointer--;
if(i_pointer < 0)i_pointer = N;
//
// Output the new sample via the DAC
//
dacWrite(DAC, (byte)yN);
}
//
// Configure timer 0 to interrupt at every 1 ms
// Prescaler is set to 80, counter is set to 1000
//
void setup()
{
My_timer = timerBegin(0, 80, true);
timerAttachInterrupt(My_timer, &ISR, true); // Attach interrupt
timerAlarmWrite(My_timer, 1000, true); // 1 msec. interrupts
timerAlarmEnable(My_timer); // Enable Timer
}
//
// Do nothing, wait for timer interrupts
//
void loop()
{
}
The frequency response of the designed filter as plotted by the PCSGU250 and is shown in
Figure 12.35.
● 233
Practical Audio DSP Projects with the ESP32 - UK.indd 233 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Notice that the overall filter performance could be improved by using faster ADC and DAC
converters having at least 16-bits word sizes. Figure 12.36 shows the output waveform
from the filter, which is very noisy because of the 8-bit DAC converter.
● 234
Practical Audio DSP Projects with the ESP32 - UK.indd 234 06-07-2023 10:40
Chapter 13 • Designing IIR Digital Filters with the ESP32 DevKitC
Chapter 13 • D
esigning IIR Digital Filters with the
ESP32 DevKitC
13.1 Overview
In this chapter, you will be looking at the design of IIR digital filters using the ESP32
DevKitC. The filter coefficients will be obtained using one of the methods described in earli-
er chapters. The actual physical filter will be realized using the Arduino Audio Tools library.
The frequency response of the designed filter will be plotted in real-time using the Velleman
PCSGU250 plotter device, as has been described in Chapter 12.
Several IIR-type digital filter design examples are given in this chapter, including low-pass
and band-pass filters.
The aim: The aim of this project is to show how an IIR-type Butterworth low-pass filter can
be designed using the ESP32 DevKitC development board.
Design: In this design, the filter coefficients were obtained as described in Chapter 11,
Example 11.2. Here, the filter transfer function was found to be:
(0)=0. 067
b(1)=0.135
b(2)=0.067
a(0)=1
a(1)=−1.1429
a(2)=0.4127
● 235
Practical Audio DSP Projects with the ESP32 - UK.indd 235 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
b0 + b1 z −1 + b2 z −2
H ( z) =
1 + a1 z −1 + a2 z −2
The block diagram and circuit diagram of the filter are in Figure 12.8 and Figure 12.9, re-
spectively.
Program listing: Arduino Audio Tools library is used in this program. Figure 13.2 shows
the filter program (Program: IIR1). At the beginning of the program, the input and out-
put streams are defined, and the filter coefficients are stored in two floating-point arrays
b_coefficients and a_coefficients. Filter coefficients are stored in these two arrays in the
forms b0, b1, b2, b3, b4, etc, and as a0, a1, a2, a3, a4, etc. Inside the setup() function,
the IIR filter is defined, input and output I2S interface is defined for the ESP32 GPIO ports.
/****************************************************************
* IIR LOW-PASS FILTER
* ===================
*
* This is the IIR low-pass filter program using the Pmod I2S2
* module as the ADC/DAC. The specifications of the filter are:
*
* Window Type: Butterworth
* Sampling Frequency: 1000 Hz
* Passband Upper Frequency: 100 Hz
* Filter Order: 2
*
* Author : Dogan Ibrahim
* Program: IIR1
* Date : May, 2023
**************************************************************/
#include "AudioTools.h"
uint16_t sample_rate=1000;
uint8_t channels = 1;
I2SStream in,out;
FilteredStream <int16_t, float> IIR_Filter(in, channels);
StreamCopy copier(out, IIR_Filter);
● 236
Practical Audio DSP Projects with the ESP32 - UK.indd 236 06-07-2023 10:40
Chapter 13 • Designing IIR Digital Filters with the ESP32 DevKitC
//
// IIR low-pass filter coefficients
//
const float b_coefficients[]={0.067,0.135, 0.067};
const float a_coefficients[]={1.0,-1.1429,0.4127};
void setup(void)
{
Serial.begin(115200);
AudioLogger::instance().begin(Serial, AudioLogger::Info);
//
// Configure out stream
//
auto configout = out.defaultConfig(TX_MODE);
configout.sample_rate = sample_rate;
configout.channels = channels;
configout.bits_per_sample = 16;
configout.i2s_format = I2S_STD_FORMAT;
configout.is_master = true;
configout.port_no = 1;
configout.pin_ws = 19; // LRCK
configout.pin_bck = 18; // SCLK
configout.pin_data = 23; // SDOUT
configout.pin_mck = 1;
out.begin(configout);
//
// Configure in stream
//
auto configin = in.defaultConfig(RX_MODE);
configin.sample_rate = sample_rate;
configin.channels = channels;
configin.bits_per_sample = 16;
configin.i2s_format = I2S_STD_FORMAT;
configin.is_master = true;
configin.port_no = 0;
configin.pin_ws = 15; // LRCK
configin.pin_bck = 14; // SCLK
configin.pin_data = 22; // SDOUT
configin.pin_mck = 0;
in.begin(configin);
}
● 237
Practical Audio DSP Projects with the ESP32 - UK.indd 237 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
//
// Copy filtered signal to out
//
void loop()
{
copier.copy();
}
Figure 13.3 shows the frequency response of the designed filter, plotted in real-time using
the PCSGU250 device, as described in Chapter 12.
b0 + b1 z −1
H ( z) =
1 + a1 z −1
The above transfer function can be implemented in cascade form as shown in Figure 13.4.
● 238
Practical Audio DSP Projects with the ESP32 - UK.indd 238 06-07-2023 10:40
Chapter 13 • Designing IIR Digital Filters with the ESP32 DevKitC
x1 = r.z-1
x2 = x1.z-1
r = xn – a1.x1 – a2.x2
yn = r.b0 + b1.x1 + b2.x2
The filter operations are then performed inside the interrupt service routine as shown in
the following steps:
13.4.2 Project 2: Design of IIR low-pass filter from the first principles
Description: A low-pass IIR filter with the same specifications as in the previous project
is used here. i.e.:
● 239
Practical Audio DSP Projects with the ESP32 - UK.indd 239 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
The aim: The aim of this project is to show how an IIR-type Butterworth low-pass filter can
be designed from the first principles without using a filter library.
Program listing: Figure 13.5 shows the program listing (Program: IIRInt). At the begin-
ning of the program, the filter coefficients are defined. The timer is configured to generate
interrupts every milliseconds, so that the sampling time is 1000 Hz. Inside the interrupt
service routine, the IIR filter algorithm is implemented. Notice that since the ADC range is
0 to 4095 and the DAC range is 0 to 255, a map statement is used to map the ADC to the
DAC range.
/****************************************************************
* IIR FILTER DESIGN FROM FIRST PRINCIPLES
* =======================================
*
* This is an IIR filter design program. The program is developed
* from first principles and does not use any filter design library
* Timer interrupt is used to read and process the input samples.
* Analog input ADC1_CH6 (GPIO34) is used.
* DAC channel used is DAC_CH_1 (GPIO25).
*
* Program: IIRInt
* Date : May, 2023
* Author : Dogan Ibrahim
**************************************************************/
#define ADC 34 // ADC channel
#define DAC 25 // DAC channel
hw_timer_t *My_timer = NULL; // Timer pointer
//
// Filter coefficients
//
float IIR_b0 = 0.067;
float IIR_b1 = 0.135;
float IIR_b2 = 0.067;
float IIR_a1 = -1.1429;
float IIR_a2 = 0.4127;
//
// Timer interrupt service routine. Program jumps here
// every 1 ms (sampling time = 1 kHz)
//
● 240
Practical Audio DSP Projects with the ESP32 - UK.indd 240 06-07-2023 10:40
Chapter 13 • Designing IIR Digital Filters with the ESP32 DevKitC
//
// Output the new sample via the DAC
//
dacWrite(DAC, (byte)IIR_yn);
IIR_x2 = IIR_x1;
IIR_x1 = IIR_r;
}
//
// Configure timer 0 to interrupt at every 1 ms
// Prescaler is set to 80, counter is set to 1000
//
void setup()
{
My_timer = timerBegin(0, 80, true);
timerAttachInterrupt(My_timer, &ISR, true);
timerAlarmWrite(My_timer, 1000, true);
timerAlarmEnable(My_timer);
}
//
// Do nothing, wait for timer interrupts
//
void loop()
{
}
Figure 13.6 shows the filter frequency response, plotted using the PSCGU250 device.
● 241
Practical Audio DSP Projects with the ESP32 - UK.indd 241 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
● 242
Practical Audio DSP Projects with the ESP32 - UK.indd 242 06-07-2023 10:40
Chapter 14 • Fast Fourier Transform (FFT)
14.1 Overview
The Fourier transform is one of the important topics in signal processing as a means of
mapping a signal from the time domain into the frequency domain. Any signal of any shape
can be represented by an infinite sum of sine and cosine waveforms. Fourier transform is
used to find the components of these series when analog signals are used. The result is the
frequency spectrum of the input analog signal, where each of its frequency and amplitude
values can be extracted.
The Discrete Fourier Transform (DFT) is a transformation just like the Fourier Transform,
but it is used with digital signals. i.e. DFT is the discrete version of the original Fourier
Transform. The Fast Fourier Transform (FFT) is an algorithm used to compute the DFT fast
and efficiently. i.e. FFT is an implementation of the DFT which produces almost identical
results as the DFT, but it is much more efficient and faster than the DFT.
Both DFT and FFT are complex processes, requiring good mathematics to understand. Al-
though there are several FFT algorithms, one of the most commonly used FFT algorithms
was developed by Cooley-Tukey, which is a divide and conquer type algorithm. This algo-
rithm breaks down the DFT into smaller parts.
Both DFT and FFT are used in many digital DSP applications, including extracting the fre-
quency spectrum, detecting targets from radar echoes, solving complex differential appli-
cations, spectral analysis, acoustic measurements, filtering algorithms, convolutions, image
processing, polynomial multiplication, and many more.
If the input signal is a sine wave, then there is only one spike with the same frequency as
the input signal. If the input signal is a square wave, then a number of spikes with decreas-
ing amplitudes are shown at different frequency points. The FFT algorithm works with a fi-
nite number of input samples (called the length), which need to be multiples of 2 (e.g. 32,
64, 128, 256, etc). In general, the larger the samples, the slower will be the algorithm and
also more memory will be needed as more processing is required. However, larger samples
will give more accurate results.
In this chapter, we will be developing an FFT program using the Arduino Audio Tools library
of Phil Pschatzmann's, which is based on the class AudioRealFFT. The results will be
● 243
Practical Audio DSP Projects with the ESP32 - UK.indd 243 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
displayed on the Serial Monitor with the frequency, magnitude (of the frequency) and the
musical note corresponding to the frequency are all displayed together with the difference
between the frequency and the musical tone frequency. More details are available on the
following website:
https://github.com/pschatzmann/arduino-audio-tools/wiki/FFT
The aim: The aim of this project is to show how the Arduino Audio Tools library can be
used for an FFT application.
Circuit diagram: Figure 14.1 shows the circuit diagram of the project. A Pmod I2S2 mod-
ule receives audio signals from the PCSGU250 device (notice that even though the ADC
part of the Pmod I2S2 is used only, the connections for both the ADC and DAC are shown
in Figure 14.1). The program processes the input samples and displays the results on the
Serial Monitor.
Program listing: Figure 14.2 shows the program listing (Program: FFT). At the beginning
of the program, header files AudioTools.h and AudioLibs/AudioRealFFT.h are included
in the program. Streams fft and in are defined. Inside the setup() function, the I2S stream
in (in RX_MODE) is configured b specifying the ESP32 GPIO ports it is connected to. Also,
the FFT is configured by setting the length to 8192 samples. The callback function is
● 244
Practical Audio DSP Projects with the ESP32 - UK.indd 244 06-07-2023 10:40
Chapter 14 • Fast Fourier Transform (FFT)
given the name fftResult so that the FFT results are available at this function. Function
fftResult() displays the frequency, magnitude, and the musical tone nearest to this
frequency together with the difference between the two frequencies (see website: https://
github.com/pschatzmann/arduino-audio-tools/blob/main/examples/examples-audiokit/
streams-audiokit-fft/streams-audiokit-fft.ino).
/****************************************************************
* FAST FOURIER TRANSFORM
* ======================
*
* This program uses teh Arduino Audio Tools library to display the
* FFT components of an input signal.
*
* Author : Dogan Ibrahim
* Program: FFT
* Date : May, 2023
*
* (This program is a modifed version of the program developed
* by Phil Pschatzmann)
**************************************************************/
#include "AudioTools.h"
#include "AudioLibs/AudioRealFFT.h"
uint16_t sample_rate=44100;
uint8_t channels = 2;
I2SStream in;
AudioRealFFT fft;
StreamCopy copier(fft, in);
//
// Display fft result on Serial Monitor
//
void fftResult(AudioFFTBase &fft)
{
float diff;
auto result = fft.result();
if (result.magnitude>100)
{
Serial.print(result.frequency);
Serial.print(" ");
Serial.print(result.magnitude);
Serial.print(" => ");
Serial.print(result.frequencyAsNote(diff));
Serial.print( " diff: ");
Serial.println(diff);
}
● 245
Practical Audio DSP Projects with the ESP32 - UK.indd 245 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
void setup(void)
{
Serial.begin(115200);
//
// Configure in stream
//
auto configin = in.defaultConfig(RX_MODE);
configin.sample_rate = sample_rate;
configin.channels = channels;
configin.bits_per_sample = 16;
configin.i2s_format = I2S_STD_FORMAT;
configin.is_master = true;
configin.port_no = 0;
configin.pin_ws = 15; // LRCK
configin.pin_bck = 14; // SCLK
configin.pin_data = 22; // SDOUT
configin.pin_mck = 0;
in.begin(configin);
//
// Configure FFT
//
auto tcfg = fft.defaultConfig();
tcfg.length = 8192;
tcfg.channels = channels;
tcfg.sample_rate = sample_rate;
tcfg.bits_per_sample = 16;
tcfg.callback = &fftResult;
fft.begin(tcfg);
}
//
// Copy input signal to fft
//
void loop()
{
copier.copy();
}
● 246
Practical Audio DSP Projects with the ESP32 - UK.indd 246 06-07-2023 10:40
Chapter 14 • Fast Fourier Transform (FFT)
A sample output is shown in Figure 14.3 where the input was a sine wave having a fre-
quency of 440 Hz.
● 247
Practical Audio DSP Projects with the ESP32 - UK.indd 247 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Appendix A
Bill of Materials
Components and modules used for the projects and experiments described in the book.
Qty. Item
8 LED
8 330-ohm resistor
1 100 k-ohm resistor
1 100 k-ohm potentiometer
1 Pushbutton
1 TMP36 temperature sensor
1 I2C LCD
1 microSD card reader module (SPI)
1 4-way, 3.3-V relay module
1 INMP441 digital microphone
1 MAX98357 class-D amplifier module
1 Small loudspeaker, 4-ohm, 3-watt (e.g., CQRobot speaker) (Note 1)
2 Small breadboard (Note 2)
10 Male and female breadboard jumper wires
1 ESP32 DevKitC with microUSB cable
1 Pmod I2S2 module and 2 pcs. 3.5-mm jack audio cables (optional)
Note 1: One project employs two MAX98357 ICs and two loudspeakers.
Note 2: The ESP32 development board is wide and not breadboard friendly. You may need
to use two small breadboards with the power rails removed in order to plug in the ESP32.
● 248
Practical Audio DSP Projects with the ESP32 - UK.indd 248 06-07-2023 10:40
Appendix B
Appendix B
The Audacity program has so many features that arguably the easiest way of
learning to use it is to install the package on your PC and then experiment with it.
The Windows version of the Audacity program can be downloaded from the following web-
site:
https://www.audacityteam.org/download/windows/
At the time of writing this book, the latest version was 3.3.2. Double-click on the program
icon to start it. Figure A.1 shows the startup screen of Audacity.
As an example, let's generate a tone with a frequency of 1000 Hz. Click Generate
Tone… Then select the required frequency as shown in Figure A.2. Figure A.3 shows the
screen after the tone is generated. Click the play button (green arrow) to hear the gener-
ated tone.
● 249
Practical Audio DSP Projects with the ESP32 - UK.indd 249 06-07-2023 10:40
Practical Audio DSP Projects with the ESP32
Now, click Effect Fading Fade In. The screen will change as in Figure A.4 where the
sound amplitude will increase gradually. Click Effect Distortion and Modulation
Tremolo and select the given defaults and click Apply. The screen will change as shown in
Figure A.5. Play the tone and notice the tremolo effect.
● 250
Practical Audio DSP Projects with the ESP32 - UK.indd 250 06-07-2023 10:40
Appendix B
Click Analyze Plot Spectrum… to plot the frequency spectrum of the generated sound
waveform. This is shown in Figure A.6, where the peak of the spectrum is around 1000 Hz.
To export the sound as an MP3 file, click File Export Export as MP3 and assign a
name to your file.
● 251
Practical Audio DSP Projects with the ESP32 - UK.indd 251 06-07-2023 10:41
Practical Audio DSP Projects with the ESP32
B F
b_coefficients 236 FadeLED 38
Bilinear transformation 182 Fast Fourier Transform 243
Bit Clock 83 FAT32 58
Blackman Window 164 FFT) 243
Block diagram 137 FIIIR 168
Block diagram manipulation 138 filter characteristics 156
Bluetooth 18 filter coefficients 210
Bode Plotter 196 Filter order 158
BOOT 21 Filter response 156
Butterworth filters 180 filter structures 177
Button 35 Filter type 157
Finite Impulse Response 154
C FIR 155
CAN bus 13 FIR filter design 174
Cascade FIR structures 178 firmware 22
Cascade structure 194 FLAC 80
Chebyshev filters 187 flash memory 123
Class-D amplifier 94 Format 58
clock generator 14 frequency 76
convolution process 139 Function Generator 196
current capacity 22
G
D GPIOs 16
DAC 17, 51
DAC decoder 94 H
DevKitC 20 Hamming window 162
DFT 243 Hanning Window 164
Digital audio DSP system 83
Digital Filters 154
● 252
Practical Audio DSP Projects with the ESP32 - UK.indd 252 06-07-2023 10:41
Index
I R
I2C 13 Rectangular window 161
I2S 13 ripple effect 162
IIR 155 RTC 13, 16
IIR filter algorithm 239
impulse response 139 S
Infinite Impulse Response 154 Sampling frequency 159
INMP441 87 sampling process 134
Internet radio 110 Sawtooth) 52
Inverse z-transforms 147 ScopeFIR 168
SD card 18
K SD cards 54
Kaiser window 168 SDHC 55
SD pin 95
L SDSC 55
Laplace Transform 146 SDXC 55
LCD 46 Shannon 134
ledcAttachPin 40 shared I2S port 207
ledcSetup 40 Signal input-output 202
ledcWrite 40 Signal to noise ratio 78
longitudinal waves 76 signal volume 119
lossy compression 79 Sine function 144
loudspeaker 93 Sinewave generator 198
L/R output 95 SNR 78
Sound waves 76
M SPI 13
MAX98357A 94 stereo 120
MEMS 87
MP3 80 T
music files 116 temperature sensor 17
Text to speech 114
O TFilter 168
Omnidirectional 87 timer interrupts 219
TMP36 41
P Touch sensor 17
Parks-McClellan 171 transverse waves 76
partial fraction expansion 151 Truncation 160
PCM 79 TTS 114
PCSGU250 196
Phil Schatzmann 197 U
PLAYALL 116 UART 13
Playing an MP3 file 123 Uncompressed audio file 79
Pulse counter 18 Unit ramp function 144
pushbutton 33 Unit step function 143
PWM 13 unit step sequence 135
USB connector 21
● 253
Practical Audio DSP Projects with the ESP32 - UK.indd 253 06-07-2023 10:41
Practical Audio DSP Projects with the ESP32
V
volume control 119
W
watchdog timers 16
WAV 79
wave speed 77
Wi-Fi 18
windowing 160
WMA 80
Word Select 83
Z
z-transform 143
● 254
Practical Audio DSP Projects with the ESP32 - UK.indd 254 06-07-2023 10:41
books
books
> Using an I2S-based digital microphone to capture audio sound Ahmet Ibrahim
> Using an I2S-based class-D audio amplifier and speaker holds BSc
> Playing MP3 music stored on an SD card through an I2S-based (Hons) and
amplifier and speaker MSc degrees
in the fields
> Playing MP3 music files stored in ESP32 flash memory through an
of computing,
I2S-based amplifier and speaker software, and networking. Ahmet
> Mono and stereo Internet radio with I2S-based amplifiers and speakers has held positions in many industries
> Text-to-speech output with an I2S-based amplifier and speaker involved in enterprise computing.
> Using the volume control in I2S-based amplifier and speaker systems He enjoys advising, designing, and
implementing complex cloud and
> A speaking event counter with an I2S-based amplifier and speaker
on-premises computer systems.
> An adjustable sinewave generator with I2S-based amplifier and
speaker
> Using the Pmod I2S2 24-bit fast ADC/DAC module
> Digital low-pass and band-pass real-time FIR filter design with
external and internal A/D and D/A conversion Elektor International Media BV
> Digital low-pass and band-pass real-time IIR filter design with www.elektor.com
external and internal A/D and D/A conversion
> Fast Fourier Transforms (FFT)