Running AI on Hardware: Implementing Environmental Sound Classification with ESP32

Breaking down auditory perception into data, and letting the ESP32 recognize the sound world! This project fully builds an environmental sound classification system using the ESP32-S2-Mini-1: from microphone audio capture, to window function + RFFT for frequency spectrum transformation, followed by Mel feature extraction and lightweight CNN inference, ultimately displaying scene categories such as “rain sound” and “dog barking” on the onboard OLED. Embedded “auditory intelligence” is at your fingertips, starting with AI from sound.

1

Introduction

Running AI on Hardware: Implementing Environmental Sound Classification with ESP32

1.1 Module/Chip Introduction

This project uses the ESP32-S2-Mini-1 module from Espressif Systems. The ESP32-S2-MINI-1 is a versatile Wi-Fi MCU module with powerful features and rich peripheral interfaces, suitable for applications in wearable electronics, smart homes, and more. The main specifications are as follows:

  • Core: Xtensa® single-core 32-bit LX7 CPU, frequency up to 240MHz

  • Memories:

    • 128 KB of ROM

    • 320 KB of SRAM

    • 16 KB of RTCSRAM

    • 4 MB of Flash memory

For more information, please refer to:

https://www.eetree.cn/doc/detail/2298

1.2 Development Board Introduction

This project uses an audio development board designed with the above module provided by Hehe Academy, integrating the following peripheral circuits and functions:

  • Based on the ESP32-S2 WiFi core module

  • 128*64 OLED display, SPI interface, for displaying information, parameters, and waveforms

  • 4 buttons for parameter control and menu selection

  • 1 Mic audio input – analog circuit, with a potentiometer to adjust gain from 0-40dB, and a bandpass filter

  • 1 headphone jack audio input – analog circuit, with a potentiometer to adjust gain from 0-40dB, and a bandpass filter

  • 2 audio outputs with power amplification, capable of driving speakers and headphone jacks

  • An FM receiver module, with parameters set via I2C interface by the ESP32, to adjust FM stations and volume

  • A switch to toggle between audio generated by the ESP32 and FM output, with the module’s output sent to the speaker or headphone output

For more information, please refer to:

https://www.eetree.cn/project/detail/419

1.3 Task Introduction

Audio Scene Classification (ASC) is a fundamental task in the field of computer acoustics. Its goal is to correctly classify a segment of captured audio into corresponding environmental labels, such as dog barking or rain. This project implements embedded deployment of ASC on the ESP32 platform, allowing it to operate with low power in our daily lives. This project will introduce the various processes involved in implementing audio scene classification using the ESP32, including data collection, feature extraction, neural networks, and implementation methods.

2

Data Collection

Running AI on Hardware: Implementing Environmental Sound Classification with ESP32

Observing the schematic, we can see that the signal received by the Mic is amplified by the operational amplifier U9, and the gain can be adjusted via RV1, ultimately connecting to the ESP32 ADC input. Therefore, the collection part uses DIG ADC1 at a sampling rate of 20kHz to measure the voltage at the pin, and directly copies it to memory via DMA (Direct Memory Access) without CPU processing. The driver for this part directly uses the project-developed code, but due to API updates, I forcibly used deprecated library functions, resulting in warnings during compilation. This part of the driver can be upgraded in the future.

https://www.eetree.cn/project/detail/537

3

Feature Extraction

Running AI on Hardware: Implementing Environmental Sound Classification with ESP32

Feature extraction is the most crucial step for audio perception. The ultimate goal of this part is to convert a segment of audio close to one second into a 30×30 spectrogram. Next, I will explain how to generate a column of data in this spectrogram:

3.1 Window Function

First, we extract 1024 consecutive points from the sampled audio data. These points will subsequently undergo Fourier transformation. Before that, to reduce spectral leakage, we multiply this segment of data by a function that is large in the middle, maximum at 1, and gradually approaches 0 at both ends, known as a “window function.” I used the commonly used Hanning window, which can be referenced here:

https://numpy.org/doc/stable/reference/generated/numpy.hanning.html

3.2 Fast Fourier Transform

Next, we perform a Fast Fourier Transform on these 1024 points. This means that the original signal’s horizontal axis is time, reflecting the signal’s intensity at different times. After transformation, we obtain the distribution of energy of the audio over various frequencies during that time period. As shown in Figure 3.1(a), the left red signal is the time-domain signal before transformation, while the right shows the energy distribution in the frequency domain after transformation. If you are unfamiliar with Fourier transformation, I highly recommend this popular science video:

https://www.bilibili.com/video/av19141078

For the implementation part, I referred to the open-source code for Real FFT (RFFT):https://github.com/willhope/Noise-reduction/blob/master/rfft.c

3.3 Mel Spectrum

Research shows that human perception of frequency is not linear, and we are more sensitive to low-frequency signals than to high-frequency signals. For example, people can easily distinguish between 500 and 1000Hz, but it is quite difficult to notice the difference between 7500 and 8000Hz. However, the horizontal axis of the spectrum after Fourier transformation is linear. At this point, the Mel scale is proposed, which is a nonlinear transformation of Hz. For signals measured in Mel scale, it allows for nearly equal perception of frequency differences. The right side of Figure 1 shows the relationship between human perception of pitch and their actual frequencies. For more information, please refer to:

https://zhuanlan.zhihu.com/p/351956040

In this project, I used 30 sets of filters, so the original array length of 1024 becomes 30 after transformation. During implementation, I referred to and ported the official STM32 audio processing library, which includes common functions for feature extraction, such as Fourier transformation and Mel spectrum. Since ST uses ARM’s DSP to accelerate floating-point operations, when porting to ESP32, I had to replace all with standard mathematical functions, manually adding implementations for missing functions, and finally resolving various compilation issues, which took considerable effort. The address for ST’s audio processing library is:

https://www.st.com/zh/embedded-software/fp-ai-sensing1.html

It is worth mentioning that ESP also has a DSP library, but due to time constraints, I couldn’t study it in detail.

Running AI on Hardware: Implementing Environmental Sound Classification with ESP32

Figure 1 Fourier Transformation and Mel Spectrum

3.4 Program Flow

As shown in Figure 2, to enable the program to implement the above process, I first created 6 DMA receive buffers of length 256 uint16. When an interrupt occurs, the data of the previous 1024 points is extracted and normalized to floating-point numbers, performing a Fast Fourier Transform to obtain the Fourier spectrum. Then, a length of 30 array is calculated as a column of the Mel spectrum. Every 512 sampling points, a column of the Mel spectrum is calculated from the 1024 points. Once 40 columns of results are calculated, this data can be used for subsequent classification.

Running AI on Hardware: Implementing Environmental Sound Classification with ESP32

Figure 2 ESP32 Signal Processing Flowchart

4

Model Training

Running AI on Hardware: Implementing Environmental Sound Classification with ESP32

Model training is completed on a personal computer using Python scripts and the Pytorch deep learning framework.

4.1 Dataset

We used the ESC-10 dataset as training data. ESC stands for Environmental Sound Classification, and ESC10 contains 10 audio categories, each with 40 audio segments. The dataset download link is:

https://dataverse.harvard.edu/dataset.xhtml?persistentId=doi:10.7910/DVN/YDEPUT

Additionally, commonly used datasets include UrbanSound8k, etc. After downloading, we use the aforementioned feature extraction process to obtain the spectrogram for each audio segment. However, in the Python environment, using the librosa library, only two lines of code are needed to perform Fourier transformation and Mel spectrum operations.

4.2 Model Structure

After feature extraction, the audio classification problem is transformed into an image classification problem. We use a relatively simple CNN convolutional neural network for classification. Due to the limited memory on the ESP32 platform and the fact that Hehe uses a chip model without 2M PSRAM, which only has 320k of built-in SRAM, the network size cannot be too large. Generally, in embedded platforms, memory size limits the network scale, while CPU performance determines how fast the network can run. For visualizing the CNN model structure, I recommend referring to the following website:

https://poloclub.github.io/cnn-explainer/

5

Model Deployment

Running AI on Hardware: Implementing Environmental Sound Classification with ESP32

After training the model, the same CNN model structure can be implemented in ESP32 using C language. Then, parameters from the trained Pytorch model can be exported and compiled into the program as arrays, achieving model deployment. The ESP official also launched a more advanced deep learning library that can directly convert and deploy trained models, providing a series of tools. However, due to personal time constraints, I still wrote my own model inference code.

6

Program Flowchart

Running AI on Hardware: Implementing Environmental Sound Classification with ESP32

The program retains functions such as DAC signal generator, as it uses the previous author’s code as a framework. The specific operations are as follows:

Button 1: DAC switch (valid when ADC is off); ADC digital filter parameter settings (valid when ADC is on)Button 2: ADC switch (valid when DAC is off)Button 3: When ADC is on: ADC mode adjustment (detailed in the following text); when DAC is on: DAC volume adjustmentButton 4: DAC frequency switch

Figure 3 focuses on the program logic during ADC mode. When ADC is turned on, the ADC_Task task will start executing and continuously respond to ADC DMA interrupts. Then, it executes the corresponding code based on one of the four modes selected by the ADC button.

Running AI on Hardware: Implementing Environmental Sound Classification with ESP32

Figure 3 Program Execution Flowchart in ADC Mode

7

Key Code

Running AI on Hardware: Implementing Environmental Sound Classification with ESP32

The code for the neural network inference process is as follows, reflecting the structure of the neural network. The functions called in the code are self-implemented C language functions for convolution, pooling, etc.

xSemaphoreTake( xMutexSpec, portMAX_DELAY );conv2d_relu(&spec, 1, 30, 40, feature1, 10, conv1_1_w, conv1_1_b);xSemaphoreGive( xMutexSpec );conv2d_relu(feature1, 10, 28, 38, feature2, 10, conv1_2_w, conv1_2_b);swap_feature(feature1, feature2);max_pool2d(feature1, 10, 26, 36, feature2);swap_feature(feature1, feature2);conv2d_relu(feature1, 10, 13, 18, feature2, 10, conv2_1_w, conv2_1_b);swap_feature(feature1, feature2);conv2d_relu(feature1, 10, 11, 16, feature2, 10, conv2_2_w, conv2_2_b);swap_feature(feature1, feature2);max_pool2d(feature1, 10, 9, 14, feature2);swap_feature(feature1, feature2);flatten_fc(feature1, 10, 4, 7, out_neurons, 10, fc_w, fc_b);

The neural network inference code trains for 10 epochs, with about 2000 one-second sound segments per epoch, and a batch_size of 10.

for epoch in range(num_epochs):  # loop over the dataset multiple times    running_loss = 0.0    correct = 0    for i, data in enumerate(asc_dataloader, 0):        # get the inputs; data is a list of [inputs, labels]        inputs, labels = data        labels = torch.tensor(labels, dtype=torch.long)        # zero the parameter gradients        optimizer.zero_grad()        # forward + backward + optimize        outputs = model(inputs)        loss = criterion(outputs, labels)        loss.backward()        optimizer.step()        _, preds = torch.max(outputs, 1)        # show_images(inputs[:6], labels[:6], preds[:6])        correct += (preds == labels).sum()        # print statistics        running_loss += loss.item()        if i % 1 == 0:    # print every 2000 mini-batches            print('Epoch [{}/{}], Step [{}/{}], Loss(Avg): {:.3f}'                  .format(epoch + 1, num_epochs, i + 1, len(asc_dataloader), running_loss / 1))            running_loss = 0.0    print("Epoch {}, Acc: {}/{}".format(epoch + 1, correct, asc_dataset.__len__()))    correct = 0

8

Results

Running AI on Hardware: Implementing Environmental Sound Classification with ESP32

The final experimental phenomenon is that after powering on the board, it continuously collects audio data, and then displays the classification results and probabilities on the OLED screen, as shown in Figure 4.

Running AI on Hardware: Implementing Environmental Sound Classification with ESP32

Figure 4 Physical Result DisplayThis audio classification case is entirely based on the ESP32-S2-Mini-1 implementation. If you want to explore embedded AI at home, you might as well start with this small board.Running AI on Hardware: Implementing Environmental Sound Classification with ESP32It is already available in the Little Footstep Enterprise Store, interested students can directly purchase it and learn while practicing.Running AI on Hardware: Implementing Environmental Sound Classification with ESP32Running AI on Hardware: Implementing Environmental Sound Classification with ESP32

Click “Read the original text” to view the project

Leave a Comment