cancel
Showing results for 
Search instead for 
Did you mean: 

WAV file to c array (audio_sample.c)

dracog71
Associate II
Posted on June 14, 2016 at 23:11

Hi!, i'm trying to recreate the C array of the file ''artofgardens-instr '' that came as example in ''audio_playback_and_record'' files, but with no luck.

Does anyone knows how to do that kind of convertion?   from wav/mp3/ogg  to c array that the I2S can play ?.

The main reason is to play some files in C array stored in the SD. 

(My SD wav/mp3 player doesn't works  taking directly the audio file, so i want to convert it in order to save the file in flash of MCU  D: )
9 REPLIES 9
Posted on June 14, 2016 at 23:27

Can you be a little more specific about what STM32 you are using, and the package you are talking about? Provide a cite

Generally the STM32 examples are going to be PCM data (2-channel 16-bit 22 or 44 KHz), you'd have you use a Codec to get MP3 or OGG decoded.

The 'C' arrays are typically generated using STDIO file handling functions, where the file is loaded, and the bytes output in an ''0x%02X,'' type fashion.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
dracog71
Associate II
Posted on June 14, 2016 at 23:53

Thanks Clive for the respond! , you save me a lot of times before... I'm using STM32F407ZG and STM32F4DISCOVERY.

PCM data (2-channel 16-bit 22 or 44 KHz) it's a good start, i've converted my wav file to PCM data (mono 16-bit 44100). ''The 'C' arrays are typically generated using STDIO file handling functions, where the file is loaded, and the bytes output in an ''0x%02X,'' type fashion.'' That STDIO function that generate the array, whats the name?, i'm reading the file from SD form fat_fs into a buffer of type uint32_t like this with no luck :

memset(&fs32, 0, 
sizeof
(FATFS));
res = f_mount(0, &fs32); printf(
''Value of f_mount %d

''
,res);
res = f_open(&fil, File, FA_READ); printf(
''Value of f_open %d

''
,res); 
f_read (&fil, buffer1_temp, _MAX_SS, &BytesRead);
/* Get Data from SD Key */
if
(res == FR_OK){
while
(WaveDataLength != 0){
XferCplt = 0;
if
(buffer_switch == 0){
/* Play data from buffer1 */
Audio_MAL_Play((
int
)buffer1_temp, _MAX_SS);
/* Store data in buffer2 */
f_read (&fil, buffer2_temp, _MAX_SS, &BytesRead); 
buffer_switch = 1;
}
else
{ 
/* Play data from buffer2 */
Audio_MAL_Play((uint32_t)buffer2_temp, _MAX_SS2);
/* Store data in buffer1 */
f_read (&fil, buffer1_temp, _MAX_SS, &BytesRead);
buffer_switch = 0;
} 
while
(XferCplt == 0) {}
}
}
res = f_close(&fil);

only White noise.... so, i want to convert this WAV files, in audacity or soundforge or even in matlab in ''C array'', and test 4 - 5 sec of the audio directly read from the flash as ''sample_audio.c'' that can be found in stm32f4discovery Firmware package. Any idea of whats going wrong ? any advice?
Posted on June 15, 2016 at 01:02

The ''C'' arrays can be generated on a PC using fopen/fseek/ftell/fread/fclose, a tool to do this from scratch might take 5-10 mins.

Remember .WAV files contain a header, you can process this to determine the data format internally.

You should read both buffers before starting. Not sure of the threaded/blocking nature of Audio_MAL_Play

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on June 15, 2016 at 01:30

512 byte buffers probably aren't going to cut it here, the command/processing overhead is rather high. I'd suggest 8K or 32K aligned blocks.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
AvaTar
Lead
Posted on June 15, 2016 at 07:41

> Remember .WAV files contain a header, you can process this to determine the data format internally.

 

There are several good libraries for reading/creating sound files available, including WAV format. Remember, WAV supports a great variety of sample frequencies and data formats.

These libraries usually come with a ''play'' and a ''record'' example, so it shouldn't take too long to write such a ''WAV-to-C-array'' tool yourself.

dracog71
Associate II
Posted on June 15, 2016 at 18:32 Thank you AvaTar for your time!, i know i'm not the only that wants to play music from SD card, sol, let me make this post as mosrt as usefull for all that people.. first, as avatar says , in this link is the WAV CPM soundformat

http://soundfile.sapp.org/doc/WaveFormat/

and something maybe usefull, as pieznice29 in his youtube account says:

I assume you are looking at 16bit wav files. As FATFS works on bytes you'll need to convert 2 bytes into a value to send to the DAC. I use:
data = (signed)((byteb << 8) | bytea);
I read a chunk of the file through FATFS and loaded that into 2 buffers and then had an interrupt running at 48khz to send the data to the DAC at a regular rate. When the buffer runs out I switch to the second buffer and refill the first using f_read(&file, buffer[currentBuffer], bufferSize, &Pos);
The data must be sent to the DAC at a regular rate to ensure good sound quality and to prevent it from thinking you're done sending data or doing strange things.

At this time, i only hear ''white noise'', not even a single instrument or piece of music D: , if i read directly from SD card , i'm following your advice clive my buffers are 32k, but just in case (maybe something wrong with me?) could you please give all of us an example of a 8k aligned block and 32k aligned block ? By the way, i'm using SDIO to read from the SD card, no SPI as a lot of examples that are in the internet like this

http://www.chibios.com/forum/viewtopic.php?f=4&t=351

i'm gonna continue trying to make this works!
LMI2
Lead
Posted on June 16, 2016 at 16:46

Wav files are very simple, pure audiodata. There is a header but it is very short, two bytes or so. So they probably are already something you call C-arrays.

I have fed wav files directly to DAC and they play fine.  that is, if you have a mono 8 bit file. If you have something else you have think about byte endianess and channels. You can cgange between formats with a suitable audio program or player. Google.

I have no idea what an audio DAC in Discovery card wants.

dracog71
Associate II
Posted on June 16, 2016 at 18:51

Thank you for your time.

Yes, it is pure data, I open it in ''WinHex'', to see the hex files, they are 8bit data.

The audio is taken by the SDIO from the SD card, then converted to 16bit data and given to the DAC by I2S using DMA,  some testing shows that maybe the problem is in the DMA, because the first  second or so can be listened, but ''rare'' maybe the conversion form 8bit to 16bit, maybe the initialization of the I2S.

If I found something usefull i'll post it to help the community, i know here it is plenty of professionals and experts, but for people like me, like us, that are learning you guys are very helpful

Regards to all of you.

AvaTar
Lead
Posted on June 16, 2016 at 20:00

>Wav files are very simple, pure audiodata.

 

No, they are not pure audio data.

The WAV format allows the following data formats (not an exhaustive list):

 - unsigned 8 bit PCM (actually signed)

 - signed 16 bit PCM

 - signed 24 bit PCM

 - signed 32 bit PCM

 - 32 bit float

 - 64 bit float (double)

 - u-law encoding

 - a-law encoding

 - GSM

It supports multiple channels, with sample data interleaved, and sampling frequencies from almost zero right into the MHz range.

In short, nothing you necessarily want do decode yourself.

I would suggest to load your WAV file with

http://www.audacityteam.org/

, and convert / export it as 16-bit PCM with one or two channels.

Writing a WAV-to-C-Array converter for a fixed format is than rather simple.

And with a right-shift of 4 bits (or less, depending on the actual audio level), the data can be fed directly into the DAC.