Phipps Electronics

Order within the next 

FREE SHIPPING OVER $199

50,000+ ORDERS

WORLDWIDE SHIPPING

SSL SECURED

How to Read a WAV File

Contents

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 OffsetTag NameExample ValueSize in BytesChunk
0ID"RIFF"4"RIFF" chunk
4WAV file Sizexxxxxxxx4
8File Type or Format"WAVE"4
12Format Chunk Start"fmt "4"fmt " (WAVE sub-chunk1)
16Format Size164
20Audio Format (PCM or others12
22No. of Channels22
24Sample Rate441004
28Byte Rate1764004
32Block Align42
34Bits per Sample162
36Data Chunk Start"data"4"data" (WAVE sub-chunk2)
40Data Chunk Sizexxxxxxxx4
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.

Understanding WAV files - sample wav file SD card

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.

SUBSCRIBE FOR NEW POST ALERTS

Subscribe to be the first to know when we publish a new article!
List Subscriptions(Required)

POPULAR POSTS

Scroll to Top