Lesson 12: Playing Local WAV Files from the SD Card¶
Applicable development board: CrowPanel Advanced 7 / 9 / 10.1-inch ESP32-P4 HMI AI Display development board
Model compatibility: The 7-inch, 9-inch, and 10.1-inch models are fully interchangeable in terms of hardware interfaces and software code; only their physical dimensions differ. Please select a model based on your actual display size and use case. No code modifications are required for this lesson.
1. Course Introduction¶
This lesson uses the Arduino IDE programming approach to read a WAV audio file from the SD card and play it through the speaker. After the program is flashed, when the development board is powered on and reset, the SD card will be mounted to the /sdcard directory, and the I2S audio output and amplifier will be initialized simultaneously. The program then automatically opens the /sdcard/huahai.wav file, validates the WAV file header, and performs streaming playback, outputting music through the speaker. This lesson integrates the SD card functionality from Lesson 08 and the I2S audio output from Lesson 11, and introduces WAV file format parsing for the first time. Through this experiment, learners will complete a full audio playback workflow validation, covering SD card file reading, WAV header information verification, and streaming playback of PCM data.
2. Learning Objectives¶
Upon completing this lesson, you should be able to:
- Be able to explain the structure of the WAV file header (RIFF/WAVE/fmt/data) and the significance of validating it.
- Be able to explain the workflow of streaming playback (chunked reading → amplification → I2S write).
- Be able to complete compilation and flashing, and hear the WAV file from the SD card playing.
- Be able to determine whether SD card reading and the audio chain are functioning properly based on the presence of playback logs and audio output.
3. Preparation¶
- Hardware: One CrowPanel Advanced 7 / 9 / 10.1-inch ESP32-P4 HMI AI Display development board (with onboard SD card slot, I2S audio output and amplifier, and speaker); one MicroSD card formatted as FAT32, with
huahai.wav(16 kHz, 16-bit, mono PCM WAV) placed in its root directory; one USB Type-C data cable supporting data transfer. - Prepare a microSD card and the onboard speaker.
- Recommended WAV format: PCM, 16 kHz, 16-bit, mono or stereo.
Code reference: https://github.com/Elecrow-RD/CrowPanel-Advanced-7inch-ESP32-P4-HMI-AI-Display-1024x600-IPS-Touch-Screen/tree/master/example
4. Software Operation Steps¶
Double-click to open the Lesson 12 code (.ino file).
Configure the options below.
- Board:
ESP32P4 Dev Module - Core Debug Level:
Info - Flash Frequency / Mode / Size:
80MHz/QIO/16MB (128Mb) - Partition Scheme:
16M Flash (3MB APP/9.9MB FATFS) - PSRAM:
Enabled - USB Mode:
Hardware CDC and JTAG - Port: After connecting the USB data cable to the board's UART0, select the newly appeared COM port under "Tools → Port".
Following the library import steps explained in detail in Lesson 1, import the library files required by this project into the development environment to ensure that the relevant dependencies can be correctly located during compilation, thereby guaranteeing normal program operation.
5. Hardware Operation Steps¶
Now that the code is ready, we need to flash the ESP32-P4 to see the results in action.
First, connect the Advance-P4 device to your computer host via a USB cable.
Copy the WAV audio file to the root directory of the SD card, and ensure that the audio file's encoding format matches the playback format supported by the program; otherwise, it will not play correctly.
Insert the SD card with the power off; verify that the onboard speaker and card slot orientation are correct.
Before uploading the code, first select the upload configuration by following "4. Software Operation Steps".
Connect to UART0 and upload using the general configuration. Open the serial monitor to observe the mounting and validation logs, and wait for playback after confirming the file exists.
After the code is uploaded:
6. Key Code Explanation¶
6.1 WAV Header Validation¶
fseek(file, 0, SEEK_SET);
fread(header, 1, 44, file);
if (memcmp(header, "RIFF", 4) != 0) return false;
if (memcmp(header + 8, "WAVE", 4) != 0) return false;
The function saves the original file pointer, checks the standard identifiers and audio parameters; if any check fails, it restores the pointer and returns false, preventing non-PCM files from being sent to the I2S.
6.2 Chunked Playback¶
fseek(fh, 44, SEEK_SET);
while (1) {
samples_read = fread(input_buf, sizeof(int16_t),
SAMPLES_PER_BUFFER, fh);
if (samples_read == 0) break;
i2s_spk.write((uint8_t*)output_buf, bytes_to_write);
}
After skipping the header, it reads in fixed buffer sizes, converts samples, and accumulates the playback amount; at the end of the loop, it closes the file and releases the buffer and audio power.
7. Experimental Observations¶
- No format error logs appear on the serial monitor, and the speaker plays the WAV file from the SD card.
8. Common Issues and Troubleshooting¶
- When the
Invalid RIFF/WAVE headererror is reported, reconvert the file to a PCM WAV. - When there is no sound, check the file path, SD card mounting, AUDIO_GPIO_CTRL, and I2S pins.








