## C5505 eZdsp - reproducing wav file

Started by 3 years ago6 replieslatest reply 3 years ago94 views

Hi,

on my c5505 eZdsp i have configured the codec at 192 Khz recording / playback frequency.

I'd like to reproduce a 8 Khz wav file, saved in 16 bit PCM format with Audacity.

I done this:

with Scilab, i have printed the values of the file.

then I have converted them in Q15 format.

In my DSP code, i created an array with these values.

The problem is that when i try to reproduce it, i hear only bad noise, not the sound.

What should I do?

PMartin

[ - ]
Reply by November 29, 2017

Signed / unsigned ?

Big endian / little endian ?

Do you mean Q1.15 ? Is it the format expected by the codec on output ?

It's very hard to tell from the information you provide, but most of the time, the symptoms you report come from a different signal representation

Benoit

[ - ]
Reply by November 29, 2017

Hi Benoit,

thanks a lot for your suggestions.

For example, i haven't considered the data endianity, but i created a tone signal (1Khz sine wave) and it is emitted correctly. However i have created it not with Audacity, but computing sines and converting every single entry in Q1.15.

Q15 if the codec data format (signed 16 bit data, Q1.15 - 1 sign bit, 15 bits for -1 < x < 1 data representation).

What do you mean with 'different signal representation'?

Could WAV 8 Khz 16 bit a wrong format?

Thanks a lot

PMartin

[ - ]
Reply by November 29, 2017
Reading and writing .wav files is rather straightforward in C or C++, you don't need any special libraries. There are a couple of header blocks that hold the configuration data and then the raw data itself. The headers can be combined into a single struct. It is possible for the data to be chunked, but this is rarely done.

Here is some excerpted code that will hopefully help you out.

Ced

struct WaveFile
{
char     RiffID[4];
int      RiffLength;
char     Wave[4];
char     FormatID[4];
int      FormatLength;
short    Always0x01;
short    TrackCount;
int      SamplesPerSecond;
int      BytesPerSecond;
short    BytesPerSample;
char     DataID[4];
int      DataLength;
};

...

//--- Stock the Wave File Header

int theBytesPerSample = 2 * sizeof( short );

memcpy( theHeader.RiffID,   "RIFF", 4 );

memcpy( theHeader.Wave,     "WAVE", 4 );
memcpy( theHeader.FormatID, "fmt ", 4 );

theHeader.BytesPerSecond    = theBytesPerSample * theExactRate;
theHeader.BitsPerReading    = 8 * sizeof( short );

memcpy( theHeader.DataID, "data", 4 );

...

//--- Update the Header

theHeader.RiffLength = theDataLength + 36;

lseek( theFD, 0, SEEK_SET );
write( theFD, &theHeader, sizeof( theHeader ) );


[ - ]
Reply by November 29, 2017

Thanks a lot Cedron,

this is very helpful!

Best Regards

PMartin

[ - ]
Reply by November 29, 2017
You're welcome.

A few notes:

1) This code is for a stereo file.  If you want to produce a mono file the track count should be one.  This also affects the 'theBytesPerSample' calculation.

2) You can hard code a value of 2 instead of 'sizeof( short )' because it depends on the wave file specification, not the platform you are running on.  I should have changed this for this example, sorry.

3) The PCM sound data should be two byte little endian integers.  For stereo files, L and R are interweaved.

4) If you write code to read .wav files, you need to process the header pieces individually because not all software uses the same sizes.

5) If you know the size of your file ahead of time, you can stock the header the first time you write it.
[ - ]
Reply by November 29, 2017

Thank you Cedron.

My file is Mono mode. It is very interesting what you say.

The problem i think is endianity. Wav data is stored in little endian format and my machine is Big endian.

Maybe it is not the only problem, but i start fixing this.

Thanks you so much

Martin