cancel
Showing results for 
Search instead for 
Did you mean: 

I2S Data stored in .wav file not playing correctly!

Niyathi Shenoy
Associate II

Hi I have ADAU1978 which is a quad ADC that gives I2S data which im trying to store in a SD card under .wav extension. When i do this i get a .wav file of size 8kB. When i try to play it with windows media player, it doesnt throw any error,but doesnt play as well. I have attached the .wav file here. Also my code is as follows:

uint8_t pHeader[44]={0x00};

/*************WAVE Header FORMAT*************/

/* Write chunkID, must be 'RIFF' ------------------------------------------*/

 pHeader[0] = 'R';

 pHeader[1] = 'I';

 pHeader[2] = 'F';

 pHeader[3] = 'F';

  

 /* Write the file length ----------------------------------------------------*/

 /* The sampling time: this value will be be written back at the end of the 

   recording opearation. Example: 661500 Btyes = 0x000A17FC, byte[7]=0x00, byte[4]=0xFC */

pHeader[4] = 0x24;

 pHeader[5] = 0x65;

 pHeader[6] = 0x04;

 pHeader[7] = 0x00;

  

 /* Write the file format, must be 'WAVE' -----------------------------------*/

 pHeader[8] = 'W';

 pHeader[9] = 'A';

 pHeader[10] = 'V';

 pHeader[11] = 'E';

  

 /* Write the format chunk, must be'fmt ' -----------------------------------*/

 pHeader[12] = 'f';

 pHeader[13] = 'm';

 pHeader[14] = 't';

 pHeader[15] = ' ';

  

 /* Write the length of the 'fmt' data, must be 0x10 ------------------------*/

 pHeader[16] = 0x10;

 pHeader[17] = 0x00;

 pHeader[18] = 0x00;

 pHeader[19] = 0x00;

  

 /* Write the audio format, must be 0x01 (PCM) ------------------------------*/

 pHeader[20] = 0x01;

 pHeader[21] = 0x00;

  

 /* Write the number of channels, ie. 0x01 (Mono) ---------------------------*/

 // pHeader[22] = pWaveFormatStruct->NbrChannels;

 //pHeader[22] = 0x01;

pHeader[22] = 0x02;

 pHeader[23] = 0x00;

  

 /* Write the Sample Rate in Hz ---------------------------------------------*/

 /* Write Little Endian ie. 8000 = 0x00001F40 => byte[24]=0x40, byte[27]=0x00*/

pHeader[24] = 0x80;

 pHeader[25] = 0xBB;

 pHeader[26] = 0x00;

 pHeader[27] = 0x00;

  

 /* Write the Byte Rate -----------------------------------------------------*/

 pHeader[28] =0x00;

pHeader[29]=0x65;

pHeader[30] = 0x04;

pHeader[31]=0x00;

 /* Write the block alignment -----------------------------------------------*/

pHeader[32] = 0x06;

 pHeader[33] = 0x00;

  

 /* Write the number of bits per sample -------------------------------------*/

pHeader[34] = 0x18;

 pHeader[35] = 0x00;

  

 /* Write the Data chunk, must be 'data' ------------------------------------*/

 pHeader[36] = 'd';

 pHeader[37] = 'a';

 pHeader[38] = 't';

 pHeader[39] = 'a';

  

 /* Write the number of sample data -----------------------------------------*/

 /* This variable will be written back at the end of the recording operation */

 pHeader[40] = 0x00;

 pHeader[41] = 0x65;

 pHeader[42] = 0x04;

 pHeader[43] = 0x00;

/**************End of WAVE Format************/

/***********SD Card mount**********/

if(f_mount(&myFATAFS,SD_Path,1)==FR_OK)

{

HAL_GPIO_TogglePin(GPIOD,GPIO_PIN_12);

char myPath[]="0:rec.wav"; 

if(f_open(&myFILE,myPath,FA_WRITE | FA_CREATE_ALWAYS)== FR_OK)

{

HAL_GPIO_TogglePin(GPIOD,GPIO_PIN_14);

}

}

/* USER CODE BEGIN 3 */

/*********Write the wave header file*************/

if(f_write(&myFILE,(void*)pHeader,44,&testByte)==FR_OK)

{

HAL_GPIO_TogglePin(GPIOD,GPIO_PIN_15);

}

for(int i=0;i<2048;i++)

{

HAL_I2S_Receive_DMA(&hi2s2,i2s_rcvbf,2);

//HAL_I2S_Receive_DMA(&hi2s2,i2s_rcvbf1,2);

i2s_final= (i2s_rcvbf[0]<<16)+ i2s_rcvbf[1];

HAL_Delay(500);

if(f_write(&myFILE,(void*)&i2s_final,sizeof(i2s_final),&testByte)==FR_OK)

{

HAL_GPIO_TogglePin(GPIOD,GPIO_PIN_15);

}

}

f_close(&myFILE);

i2s_final=0x00000000;

HAL_Delay(1000);

}

7 REPLIES 7

> HAL_Delay(500);

So you've taken samples 500ms apart, and expect to play back correctly?

(I also suspect that your i2s_rcvbf is uint8_t, as each other byte in the given file is 0x00).

JW

Niyathi Shenoy
Associate II

i2s_rcvbf is uint16_t not uint8_t. I have tried without the delay part too...

A couple of bytes at a time?!

You're going to want two much larger buffers, switching them seamlessly and managing the write to a file in another thread to avoid blocking.​

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Niyathi Shenoy
Associate II

Hi Clive,

The API, HAL_I2S_Receive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size), Receives an amount of data in non-blocking mode with DMA and here pData is a 16 bit pointer to the receive data buffer. Also,When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S configuration phase, the Size parameter means the number of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data frame is selected the Size parameter means the number of 16-bit data length.

Do you have a sample code for I2S demonstration or I2S documentation. I have checked the Technical reference manual of stm32f407. Also i have checked the audio record and playback example code,but here the the output data is PCM.

If it were non-blocking it would return immediately, you don't look to be catching a completion interrupt or anything.

Doing a pair of words at a time is going to have an awfully large overhead, as is writing them to a file 4 bytes at a time is also going to be brutal.

In a CD application the audio data consists of 2352 byte sectors, each 16-bit left/right PCM sample pair taking 4 bytes.

Audio CODECs expect a continuous stream of data, usually synchronous with the audio clock.

I can't provide you with examples, or sample code, I'm working on different things.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Niyathi Shenoy
Associate II

Hi Clive,

I am already receiving data in two different buffers. As you can see above in my code, HAL_I2S_Receive_DMA(&hi2s2,i2s_rcvbf,2); receives 16 bit samples in i2s_rcvbf[0] and another 16 bit of samples in i2s_rcvbf[1]. Also, HAL_I2S_Receive_DMA receives an amount of data in non-blocking mode with DMA.

Niyathi Shenoy
Associate II

Hi,

Is there any sample code for I2S DMA receive. How is it done and how not to lose samples? I am stuck at this.