Sign in

username:

password:



Not a member?

Search compdsp



Search tips

comp.dsp by Keywords

Adaptive Filter | ADPCM | ADSP | ADSP-2181 | Aliasing | AMR | Anti-Aliasing | ARMA | Autocorrelation | AutoCovariance | Beamforming | Bessel | Blackfin | Butterworth | C6713 | CCS | Chebyshev | CIC Filter | Circular Convolution | Code Composer Studio | Comb Filter | Compression | Convolution | Cross Correlation | DCT | Decimation | Deconvolution | Demodulation | DM642 | DSP Boards | DSP/BIOS | DTMF | Echo Cancellation | Equalization | Equalizer | ETSI | EZLITE (Ez-kit Lite) | FFT | FFTW | FIR Filter | Fixed Point | FSK | G.711 | G.723 | G.729 | Gaussian Noise | Goertzel | GPIO | Hilbert Transform | IFFT | IIR Filter | Interpolation | Invariance | JTAG | Kalman | Laplace Transform | Levinson | LPC | McBSP | MIPS | Modulation | MPEG | Multirate | Notch Filter | Nyquist | OFDM | Oversampling | Pink Noise | Pitch | PLL | Polyphase | QAM | QDMA | Quantization | Quantizer | Radar | Random Noise | Reed Solomon | Remez | Resampling | RTDX | Sampling | Sharc | TI C6711 | Undersampling | Viterbi | Wavelets | White Noise | Wiener Filter | Windowing | XDS510PP | Z Transform


Discussion Groups

Free Online Books

See Also

Embedded SystemsFPGAElectronics

Discussion Groups | Comp.DSP | Audio programming - WAV data chunk format issues

There are 8 messages in this thread.

You are currently looking at messages 0 to 8.


Audio programming - WAV data chunk format issues - 2006-05-16 14:02:00

Hi list,
I am developing a new algorithm and I just translated the Matlab code
in ANSI C. The problem is that I get a strange behaviour doing trivial
sample-level computations. Basically the program should create a new
file with the same lenght and properties as the input one, so the
operations are:
- read the original 44 bytes WAV header and I copy it to the output
file
- read the original 2 bytes a time (signed short) and I put it in a
double array converting every   sample to -1--1 range(float)
- process the array and put the processed samples in another one
- copy the requantized samples to the output file
- copy the remaining header

The issue happens in the processing stage: if I do nothing or just
memcpy the input array to the output array everything goes fine. If I
process the array or if I just multiply it by a constant or set
everything to 0 wavelab won't recognize it anymore as a valid wav nor
other audio apps.
here's a short example code:

x_array = (double *) calloc(n_samples,sizeof(double)); // input array
out_array = (double *) calloc(n_samples,sizeof(double));
for(i = 0;i<n_samples;i++)
{
	fread(&data,hdr.bytes_per_samp,1,wavIn);
	x_array[i] = (double)data/(double)resolution;  //res is 2^15
}

///////////////////////////////////////////////////////////////// THIS
gives error
for(i = 0; i < n_samples; i++)
   out_array [i] = x_array [i]*1.1f;
///////////////////////////////////////////////////////////////

for(i = 0;i<n_samples;i++)
{
	data = out_array[i]*resolution;
	fwrite(&data,hdr.bytes_per_samp,1,wavOut);
}
while(fread(&data,1,1,wavIn))         //  Grumble, RIFF tail
	 fwrite(&data,1,1,wavOut);
--------------------------------------------------------------------------------------------

If I substitute the
out_array [i] = x_array [i]*1.1f;
with
out_array [i] = x_array [i]*1.0f;

the resutling wav is OK.
Any suggestion? I'm stuck on this.
Alessandro

______________________________
New DSP Code Snippets Section now Live.   Learn more about the reward program for contributors here.

Re: Audio programming - WAV data chunk format issues - Phil Frisbie, Jr. - 2006-05-16 14:33:00



a...@gmail.com wrote:

> Hi list,
> I am developing a new algorithm and I just translated the Matlab code
> in ANSI C. The problem is that I get a strange behaviour doing trivial
> sample-level computations. Basically the program should create a new
> file with the same lenght and properties as the input one, so the
> operations are:
> - read the original 44 bytes WAV header and I copy it to the output
> file

Are you sure the wave files are 16 bit PCM and the total header is 44 bytes?

It is better to actually parse the original wave file and copy everything up to 
and including the data chunk ID and length.

> - read the original 2 bytes a time (signed short) and I put it in a
> double array converting every   sample to -1--1 range(float)
> - process the array and put the processed samples in another one
> - copy the requantized samples to the output file
> - copy the remaining header

What do you mean by remaining header?

-- 
Phil Frisbie, Jr.
Hawk Software
http://www.hawksoft.com
______________________________
New DSP Code Snippets Section now Live.   Learn more about the reward program for contributors here.

Re: Audio programming - WAV data chunk format issues - 2006-05-16 14:43:00

> > - read the original 44 bytes WAV header and I copy it to the output
> > file
>
> Are you sure the wave files are 16 bit PCM and the total header is 44 bytes?

Yes I am. Here you go

/*********     WAV BigEndian File Version ***********************/

struct soundhdr {
  char  riff[4];        /* "RIFF"                                  */
  long  flength;        /* file length in bytes                    */
  char  wave[4];        /* "WAVE"                                  */
  char  fmt[4];         /* "fmt "                                  */
  long  block_size;     /* in bytes (generally 16)                 */
  short format_tag;     /* 1=PCM, 257=Mu-Law, 258=A-Law, 259=ADPCM */
  short num_chans;      /* 1=mono, 2=stereo                        */
  long  srate;          /* Sampling rate in samples per second     */
  long  bytes_per_sec;  /* bytes per second                        */
  short bytes_per_samp; /* 2=16-bit mono, 4=16-bit stereo          */
  short bits_per_samp;  /* Number of bits per sample               */
  char  data[4];        /* "data"                                  */
  long  dlength;        /* data length in bytes (filelength - 44)  */
};

The problem is that everyhing is good and already tested but only god
knows why I am getting this issue converting to double and going back
to short. I always used this header thingie and it always working doing
integer processing. Now I am using floating point computations and...
doesn't work well. The problem is not even casting back to short
because multiplying by 1.0f (i.e. leaving the samples untouched) works.

> > - copy the remaining header
>
> What do you mean by remaining header?

I mean the RIFF tail of the file.

Chers
Ale

______________________________
New DSP Code Snippets Section now Live.   Learn more about the reward program for contributors here.

Re: Audio programming - WAV data chunk format issues - BobF - 2006-05-16 15:41:00

On 16 May 2006 11:43:30 -0700, a...@gmail.com wrote:

>>> - read the original 44 bytes WAV header and I copy it to the output
>>> file
>>
>> Are you sure the wave files are 16 bit PCM and the total header is 44 bytes?
> 
> Yes I am. Here you go
> 
> /*********     WAV BigEndian File Version ***********************/
> 
> struct soundhdr {
>   char  riff[4];        /* "RIFF"                                  */
>   long  flength;        /* file length in bytes                    */
>   char  wave[4];        /* "WAVE"                                  */
>   char  fmt[4];         /* "fmt "                                  */
>   long  block_size;     /* in bytes (generally 16)                 */
>   short format_tag;     /* 1=PCM, 257=Mu-Law, 258=A-Law, 259=ADPCM */
>   short num_chans;      /* 1=mono, 2=stereo                        */
>   long  srate;          /* Sampling rate in samples per second     */
>   long  bytes_per_sec;  /* bytes per second                        */
>   short bytes_per_samp; /* 2=16-bit mono, 4=16-bit stereo          */
>   short bits_per_samp;  /* Number of bits per sample               */
>   char  data[4];        /* "data"                                  */
>   long  dlength;        /* data length in bytes (filelength - 44)  */
> };
> 
> The problem is that everyhing is good and already tested but only god
> knows why I am getting this issue converting to double and going back
> to short. I always used this header thingie and it always working doing
> integer processing. Now I am using floating point computations and...
> doesn't work well. The problem is not even casting back to short
> because multiplying by 1.0f (i.e. leaving the samples untouched) works.
> 
>>> - copy the remaining header
>>
>> What do you mean by remaining header?
> 
> I mean the RIFF tail of the file.
> 
> Chers
> Ale

There can be multiple data chunks with other chunk types interspersed in a
WAV file.

datalength for the first data chunk isn't guaranteed to be filelength -
headersize. 
______________________________
New DSP Code Snippets Section now Live.   Learn more about the reward program for contributors here.

Re: Audio programming - WAV data chunk format issues - Phil Frisbie, Jr. - 2006-05-16 16:44:00

a...@gmail.com wrote:

>>>- read the original 44 bytes WAV header and I copy it to the output
>>>file
>>
>>Are you sure the wave files are 16 bit PCM and the total header is 44 bytes?
> 
> Yes I am. Here you go
> 
> /*********     WAV BigEndian File Version ***********************/
> 
> struct soundhdr {
>   char  riff[4];        /* "RIFF"                                  */
>   long  flength;        /* file length in bytes                    */
>   char  wave[4];        /* "WAVE"                                  */
>   char  fmt[4];         /* "fmt "                                  */
>   long  block_size;     /* in bytes (generally 16)                 */
>   short format_tag;     /* 1=PCM, 257=Mu-Law, 258=A-Law, 259=ADPCM */
>   short num_chans;      /* 1=mono, 2=stereo                        */
>   long  srate;          /* Sampling rate in samples per second     */
>   long  bytes_per_sec;  /* bytes per second                        */
>   short bytes_per_samp; /* 2=16-bit mono, 4=16-bit stereo          */
>   short bits_per_samp;  /* Number of bits per sample               */
>   char  data[4];        /* "data"                                  */
>   long  dlength;        /* data length in bytes (filelength - 44)  */
> };

That is only one possible type of wave header. Windows Media Player does not 
play many PCM files unless they have another 2 bytes padding after bits_per_samp 
and block_size is bumped up to 18...

Also, you should have a 'fact' chunk between the 'fmt' chunk and the 'data' 
chunk to tell the media player how many samples long the file is. They use that 
to display the length in time of the file.

> The problem is that everyhing is good and already tested but only god
> knows why I am getting this issue converting to double and going back
> to short. I always used this header thingie and it always working doing
> integer processing. Now I am using floating point computations and...
> doesn't work well. The problem is not even casting back to short
> because multiplying by 1.0f (i.e. leaving the samples untouched) works.

Think about it. If multiplying by 1.0 works, then you are likely processing 
bytes that are NOT PCM data. The 'fact' chunk is a good possibility, and the 
reason I said you should parse the chunks and not assume what is there. Look at 
your code real well and you will find your error.

-- 
Phil Frisbie, Jr.
Hawk Software
http://www.hawksoft.com
______________________________
New DSP Code Snippets Section now Live.   Learn more about the reward program for contributors here.

Re: Audio programming - WAV data chunk format issues - BobF - 2006-05-16 17:24:00

On Tue, 16 May 2006 13:44:05 -0700, Phil Frisbie, Jr. wrote:

> a...@gmail.com wrote:
> 
>>>>- read the original 44 bytes WAV header and I copy it to the output
>>>>file
>>>
>>>Are you sure the wave files are 16 bit PCM and the total header is 44 bytes?
>> 
>> Yes I am. Here you go
>> 
>> /*********     WAV BigEndian File Version ***********************/
>> 
>> struct soundhdr {
>>   char  riff[4];        /* "RIFF"                                  */
>>   long  flength;        /* file length in bytes                    */
>>   char  wave[4];        /* "WAVE"                                  */
>>   char  fmt[4];         /* "fmt "                                  */
>>   long  block_size;     /* in bytes (generally 16)                 */
>>   short format_tag;     /* 1=PCM, 257=Mu-Law, 258=A-Law, 259=ADPCM */
>>   short num_chans;      /* 1=mono, 2=stereo                        */
>>   long  srate;          /* Sampling rate in samples per second     */
>>   long  bytes_per_sec;  /* bytes per second                        */
>>   short bytes_per_samp; /* 2=16-bit mono, 4=16-bit stereo          */
>>   short bits_per_samp;  /* Number of bits per sample               */
>>   char  data[4];        /* "data"                                  */
>>   long  dlength;        /* data length in bytes (filelength - 44)  */
>> };
> 
> That is only one possible type of wave header. Windows Media Player does not 
> play many PCM files unless they have another 2 bytes padding after bits_per_samp 
> and block_size is bumped up to 18...
> 
> Also, you should have a 'fact' chunk between the 'fmt' chunk and the 'data' 
> chunk to tell the media player how many samples long the file is. They use that 
> to display the length in time of the file.
> 
>> The problem is that everyhing is good and already tested but only god
>> knows why I am getting this issue converting to double and going back
>> to short. I always used this header thingie and it always working doing
>> integer processing. Now I am using floating point computations and...
>> doesn't work well. The problem is not even casting back to short
>> because multiplying by 1.0f (i.e. leaving the samples untouched) works.
> 
> Think about it. If multiplying by 1.0 works, then you are likely processing 
> bytes that are NOT PCM data. The 'fact' chunk is a good possibility, and the 
> reason I said you should parse the chunks and not assume what is there. Look at 
> your code real well and you will find your error.

An anecdotal example from a PCM WAV library I built a while back.  I was
grabbing WAV files from everywhere to test the lib.  This output is from a
WAV file produced by a popular multi-tracking studio application.  The
point of this is that you can't count on all of the data being in a single
chunk immediately following the WAVPCM header.

D:\xpDSPLib\libtest\libtest\Debug>libtest dm.wav

RIFF Chunk ID:   RIFF
RIFF Chunk Size: 10166264
Wave ID:         WAVE

FMT Chunk ID:    fmt
FMT Chunk Size:  18

Format:          PCM
Num channels:    2
Samples/sec:     44100
Bytes/sec:       264600
Block Align:     6
Bits per sample: 24
cb size:         0

DATA Chunk ID:   PAD
DATA Chunk Size: 4042


DATA Chunk ID:   data
DATA Chunk Size: 10160640


DATA Chunk ID:   PAD
DATA Chunk Size: 1528

______________________________
New DSP Code Snippets Section now Live.   Learn more about the reward program for contributors here.

Re: Audio programming - WAV data chunk format issues - 2006-05-16 19:44:00

Thanks a lot. So this is what I think I have to do, please correct me
if I'm wrong: malloc a big array as the whole file was "data", then
parse the file for the first "data" chunk, write this chunk it in the
array, then look if I get a "pad" or "data" chunk, if it's data add it
to the end of the array and so on... eventually writing an output file
with just one big "data" chunk that would be the sum of just the input
data chunks?
Consider that I need to access a window of many samples after and
before the sample I am processing so I can't process the data chunks
separately. Thanks,
Ale

______________________________
New DSP Code Snippets Section now Live.   Learn more about the reward program for contributors here.

Re: Audio programming - WAV data chunk format issues - Andreas Huennebeck - 2006-05-17 05:48:00

a...@gmail.com wrote:

> Thanks a lot. So this is what I think I have to do, please correct me
> if I'm wrong: malloc a big array as the whole file was "data", then
> parse the file for the first "data" chunk, write this chunk it in the
> array, then look if I get a "pad" or "data" chunk, if it's data add it
> to the end of the array and so on... eventually writing an output file
> with just one big "data" chunk that would be the sum of just the input
> data chunks?

In principle yes, but it might be much easier if you use an existing
library like libsndfile: http://www.mega-nerd.com/libsndfile/

Another caveat in you copde may be the declaration of your struct soundhdr.
This works as expected only if the compiler does not create any padding holes,
otherwise a (compiler dependend) packed array must be used, or another
way (define all components as char arrays and convert into int/short/double
where appropriate).

Bye
Andreas
--
Andreas Hünnebeck | email: a...@gmx.de
----- privat ---- | www  : http://www.huennebeck-online.de
Fax/Anrufbeantworter: 0721/151-284301
GPG-Key: http://www.huennebeck-online.de/public_keys/andreas.asc
PGP-Key: http://www.huennebeck-online.de/public_keys/pgp_andreas.asc

______________________________
New DSP Code Snippets Section now Live.   Learn more about the reward program for contributors here.