Stereo Wave Data

Mar 07, 2008 7 Replies

Hi,



I'm trying to read a PCM wave file from an MMC to a 16 bit DAC with an AVR. The audio file format: 44100 Hz, 16 bit, stereo. I found a lot of stuff on the web but not all pages says the same thing...



I want to know how the audio data is stored into the file.



I know this:



#1 Ch Left / Low Byte #2 Ch Left / High Byte #3 Ch right / Low Byte #4 Ch right / High Byte . . .


1) The most significant *bit* is the 8th in the byte, isn't it? So 0x80 = 128 = 0b10000000


2) What's the number format (int16 or uint16) ? I have a DAC: could I send out the Low Byte on the low-byte-port and the High Byte on the high-byte-port directly or should I do something before?



Thanks! Marco / iw2nzm


On a sunny day (Fri, 07 Mar 2008 15:24:57 GMT) it happened Marco Trapanese wrote in :

That is actually the sign bit.

Here is a piece of C code to get those low and high bytes and make an unsigned number from it.

int cm; double dm; unsigned long p = 1

Jan Panteltje ha scritto:

Ok, that was just an example. Anyway, I found the data is stored as unsigned int.

Thanks.

I solved quickly inverting the most significant bit. It works!

Marco / iw2nzm

On a sunny day (Fri, 07 Mar 2008 17:01:50 GMT) it happened Marco Trapanese wrote in :

Yes, possible, but normally in wave files sound is stored as 16 bit signed

2 complements's, see:
formatting link

Actually the C code I showed, was code that converted the 16 bit sample to a double, with range from -1.0 to + 1.0. That allows all sorts of math to be done with it. You can then convert it back with: /* double data to output buffer */ ll = floor(dout * p); if( dout < 0) ll += 2 * p; //fprintf(stderr, "new ll=%lu\\n", ll);

*pobptr = ll % 256; *(pobptr + 1) = ll / 256;

If you want to look up that code, it is from 'substract_wave', a GPL program I wrote, it can substract 2 wave files (to cancel background noise).

formatting link

Be very careful, sometimes audio PCM may SEEM to work as unsigned, but of course it will be distorted and not usable.

Jan Panteltje ha scritto:

You're right, it's a 16 bit signed 2 complement's. I was wrong when I wrote the post. However this short code works fine:

ad5547_output(audio[idxR], audio[idxR+1] ^ _BV(7)); ad5547_output(audio[idxR+2], audio[idxR+3] ^ _BV(7));

The first line is for left channel, the second for the right one. The first parameter is the low byte, the second the high byte with MSB flipped.

audioB[] is the 1024-bytes buffer loaded by audio data.

Using a 8 bit MCU (ATmega644 @ 20 MHz) I can't do some math in the interrupt routine so I just send out the values to the DAC.

Bye! Marco / iw2nzm

now that you have that under your belt..

just remember that 16 bit cross over point is

0 value in value.. 0..$7FFF is the positive value of the sine and $FFFF..$8000 is the negative range of the sine..

for 8 bit. the cross over of the sine is at $7F.

http://webpages.charter.net/jamie_5"

2.5V.

Not that i am want to sound overly critical but, in standard "C" double is a 64-bit floating point number. I see no value in doing the conversions.

Wav files on X86 machines are int 16, little endian. The MSB of the

16-bit integer is the sign bit, not the MSB of just any byte in the file.

On a sunny day (Sat, 08 Mar 2008 19:07:40 GMT) it happened JosephKK wrote in :

Actually, as I pointed out in the next posting as correction, dm is range -1.0 to +1.0. The conversion was done in my program to be able to work with -1.0 to +1.0 signals, and do all math in type double. This code is part of a program I wrote to cancel background sound in a translation channel.

p = 1

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required