Curious to know what’s inside a WAV file? Want to work with this kind of file? Read along to find out how to read a WAV file.
INtroduction
The WAV file format was already popular even before the other file formats, such as MP3, M4P, AAC, FLAC, and Ogg Vorbis, were embraced by the masses. IBM and Microsoft introduced WAV files during the 1990s, which were meant to carry uncompressed audio data. Even Microsoft Windows used WAV files for most of its system sounds during those times. Here, you’ll learn specifically how to read a wav file.
WAV is short for Waveform Audio File. This format is an audio container containing chunks of data, including the header and the audio bitstream. The header contains data such as audio format and encoding schemes. The bitstream part contains the actual sound data that can be interleaved through different channels.Â
A WAV file is an example of a RIFF (or Resource Interchange File Format), which was similarly developed by IBM and Microsoft. RIFF files are mostly used for storing data meant for multi-media applications.
What's Inside a WAV FIle
As previously discussed, WAV files contain both format data (called a header) and the actual audio data (in bitstream form). The WAV file header format is seen in the table below.
| Byte Offset | Tag Name | Example Value | Size in Bytes | Chunk |
|---|---|---|---|---|
| 0 | ID | "RIFF" | 4 | "RIFF" chunk |
| 4 | WAV file Size | xxxxxxxx | 4 | |
| 8 | File Type or Format | "WAVE" | 4 | |
| 12 | Format Chunk Start | "fmt " | 4 | "fmt " (WAVE sub-chunk1) |
| 16 | Format Size | 16 | 4 | |
| 20 | Audio Format (PCM or others | 1 | 2 | |
| 22 | No. of Channels | 2 | 2 | |
| 24 | Sample Rate | 44100 | 4 | |
| 28 | Byte Rate | 176400 | 4 | |
| 32 | Block Align | 4 | 2 | |
| 34 | Bits per Sample | 16 | 2 | |
| 36 | Data Chunk Start | "data" | 4 | "data" (WAVE sub-chunk2) |
| 40 | Data Chunk Size | xxxxxxxx | 4 | |
| 44 | {Start of Audio Data} | ---- | ---- |
Referring to the Chunk column, the first chunk of data is the “RIFF” chunk. Along this chunk is the WAV file size (where this is the size of the rest of this WAV file after this point, in bytes) and the “WAVE” File Format. Additionally, there are sub-chunks of the “WAVE” File Format which include both the “fmt ” sub-chunk (at byte offset 12) and the “data sub-chunk (at byte offset 44).
The “fmt ” sub-chunk should have complete details for parsing information for the player to play the wave file successfully. This includes the length of the “fmt ” section (Format Size), the Audio Format (1- PCM), Sample Rate (in HZ), Byte Rate (as (Sample Rate * BitsPerSample * Channels)/8), Block Align (as Bits per Sample * Channels)/8, and Bits per Sample.
Finally, the “data” sub-chunk at byte offset 44 carries the Data Size and the audio bitstream data.
PArsing the Contents of a WAV File Using an MCU
To better understand the structure of a WAV file, here is an example code parsing the contents of a WAV file stored on an SD Card on an STM32F4XX series device that you can try.
Last time, you were able to Interface an SD Card through SDIO. This time, you can continue reading the contents of a file such as a WAV file.
Before continuing, you may want to review STM32CubeIDE Tutorial and Debug an STM32 using printf using only an ST-Link so you could find your way around STM32CubeIDE.
Download a sample audio file and Save it on an SD card
You should be able to find a sample wave audio file then save it on an SD card through a PC. If you’d like to play this file later on your STM32F4, choose a non-compressed PCM WAV file type.
Create a struct for the Wav Header Components
Creating a structure makes parsing the contents of the WAV file orderly.
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
typedef struct {
uint32_t ChunkID; // "RIFF"
uint32_t ChunkSize;
uint32_t Format; // "WAVE"
uint32_t Subchunk1ID; // "fmt "
uint32_t Subchunk1Size; // 16 for PCM
uint16_t AudioFormat; // 1 = PCM
uint16_t NumChannels;
uint32_t SampleRate;
uint32_t ByteRate;
uint16_t BlockAlign;
uint16_t BitsPerSample;
uint32_t Subchunk2ID; // "data"
uint32_t Subchunk2Size; // size of data
} WAV_Header;
Create the Private variables
As before, create the necessary private variables for SD card access. Add the wav header variable.
/* USER CODE BEGIN PV */
FRESULT ret; /* Return value for SD */
FATFS fs; /* File system object for SD logical drive */
FIL fil; /* File object for SD */
UINT bw; /* Number of Bytes Written */
UINT br; /* Number of Bytes Read */
FILINFO file_info; /* File info structure */
WAV_Header header;
Main code
Here is the rest of the code to be able to parse the header of the WAV file. With this, you should be able to configure your I2S/DAC correctly.
// Initialize your Board
uint8_t bsp_r = BSP_SD_Init();
if(bsp_r != 0){
Error_Handler();
}
// Mount the filesystem
ret = f_mount(&fs,"", 1);
if(ret != FR_OK){
Error_Handler();
}
// Open the audio wav file
ret = f_open(&fil, "audio_sampler.wav", FA_READ);
if (ret != FR_OK) {
Error_Handler();
}
// Check file and info
ret = f_stat("audio_sampler.wav", &file_info);
if (ret != FR_OK) {
printf("File not found\n");
Error_Handler();
}else{
printf("File audio_sampler.wav exists, size = %lu bytes\n", file_info.fsize);
}
// Parse the contents of WAV header
if(f_read(&fil, &header, sizeof(WAV_Header), &br) == FR_OK)
{
// Now you can configure I2S/DAC
printf("SampleRate: %lu Hz\n", header.SampleRate);
printf("Channels: %u\n", header.NumChannels);
printf("Bits: %u\n", header.BitsPerSample);
// Seek to start of PCM data
f_lseek(&SDFile, sizeof(WAV_Header));
}
else
{
printf("Error reading WAV header\r\n");
Error_Handler();
}
// Close the File
ret = f_close(&SDFile);
The SD card functions are initialized through BSP_SD_Init() (don’t forget to initialize SDIO bus width to 1 bit in MX_SDIO_SD_Init() initially). After that, you can mount the FATFS file system through f_mount(). Open the audio file through f_open() and then check the file info through f_stat(). Continue to parse and read the contents of the WAV header through f_read() and f_lseek().
Code Output
Here is the video of parsing the contents of a WAV file on an SD card.
This ends the article on how to read a wav file. Your next step should be knwoing how to play the contents of your audio file.
SHOP THIS PROJECT
-
Digital LCD Thermometer Temperature Gauge with Probe
$15.95Original price was: $15.95.$14.95Current price is: $14.95. Add to cart