2018-11-18 11:40 PM
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);
}
2018-11-19 01:29 AM
> 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
2018-11-19 04:49 AM
i2s_rcvbf is uint16_t not uint8_t. I have tried without the delay part too...
2018-11-19 05:22 AM
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.
2018-11-19 08:21 PM
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.
2018-11-19 09:10 PM
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.
2018-11-28 11:34 PM
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.
2019-01-07 01:06 AM
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.