Crazy, how to convert the PCM raw data into wav?

PCM data format 44.1khz, 16bit, stereo->wave format 8000 hz, 8bit, mono.
which library can help me? or is there any code having this function?
thank u very much!!!!
[175 byte] By [Wenming] at [2007-11-19 4:19:27]
# 1 Re: Crazy, how to convert the PCM raw data into wav?
I know this two libs
http://www.fmod.org/
http://www.un4seen.com/
I think both are for personal use and for freewares.

But I'm sure that there is a way to do it with DirectSound also.
blueday54555 at 2007-11-11 0:39:47 >
# 2 Re: Crazy, how to convert the PCM raw data into wav?
The DirectSound examples have a class in DSUtil.cpp which'll write a WAV file given PCM data.

Darwen.
darwen at 2007-11-11 0:40:50 >
# 3 Re: Crazy, how to convert the PCM raw data into wav?
thank u, additionally, does it support 8bit 8khz mono wav?
Wenming at 2007-11-11 0:41:43 >
# 4 Re: Crazy, how to convert the PCM raw data into wav?
i use madplay to convert PCM into a wave file in the format 8khz 8bit mono, the wave file works fine on the pc, but it didn't work on the cellphone which supports the wave file. but other wave with the same format converted by another software(dBpowerAMP Music Converter) works fine on both pc and cell phone
Wenming at 2007-11-11 0:42:48 >
# 5 Re: Crazy, how to convert the PCM raw data into wav?
Use this struct I wrote if you like....You just need to fill in the info for your PCM data i.e.

riff riff1;

riff1.BitsPerSample = 8;
.
.
.

Then use WriteFile() to write the RIFF struct followed immediately by your data buffer. I personaly find this a lot simpler than using someone elses library. Any questions you might have about filling this stuct in should be answered on MSDN if you look for RIFF or WAVEFORMATEX.

struct riff //Bytes Total
{
char chunkID[4]; //"RIFF" 4 4

DWORD riffSize; //file size - 8 4 8

char typeID[4]; //"WAVE" 4 12

char formatChunkID[4]; //"fmt " 4 16

DWORD formatChunkSize; //16 bytes 4 20

WORD FormatTag; // 2 22

WORD NoOfChannels; // 2 24

DWORD SamplesPerSec; // 4 28

DWORD BytesPerSec; // 4 32

WORD BlockAlign; // 2 34

WORD BitsPerSample; // 2 36

char dataChunkID[4]; //"data" 4 40

DWORD dataChunkSize; //not fixed 4 44
};

Hope that helps.
ggmn at 2007-11-11 0:43:50 >
# 6 Re: Crazy, how to convert the PCM raw data into wav?
i use libmad to help work. but it doesn't support 8bit 8khz mono wav format.
most of coders know it well, i think.
the main code shows as below:
/* WAV structure
* Used in CbMpegAudioDecoder when instructed to write a
* WAV header to the output file.
*/
struct WAV_HEADER {
int RIFF; // 'R','I','F','F'
int size; // size of wave file from here on
int WAVE; // 'W','A','V','E'
int fmt; //'f','m','t',' '
int wFormatLength; // The length of the TAG format
short wFormatTag; // should be 1 for PCM type data
short nChannels; // Mono = 1, Stereo = 2, etc.
int nSampleRate; // 8000, 44100, etc.
int nAvgBytesPerSec; // Average Data Rate
short nBlockAlign; // 1 for 8 bit data, 2 for 16 bit
short wBitsPerSample; // 8 for 8 bit data, 16 for 16 bit
int data; // 'd','a','t','a'
int datasize; // size of data from here on
};
WAV_HEADER wav_header; /* my WAV header */
... ...
wav_header.nChannels = 1;
wav_header.nSampleRate = 8000;

/* Once decoded the frame is synthesized to PCM samples. No errors
* are reported by mad_synth_frame();
*/
mad_synth_frame(&Synth, &Frame);

/* Synthesized samples must be converted from libmad's fixed
* point number to the consumer format. Here we use unsigned
* 16 bit big endian integers on two channels. Integer samples
* are temporarily stored in a buffer that is flushed when
* full.
*/
for(i=0; i < Synth.pcm.length; i++)
{
signed short Sample;

/* Left channel */
Sample=Scale(Synth.pcm.samples[0][i], &gRand);

/* output in 16 bit little-endian */
/*
*(OutputPtr++)=Sample>>8; //Originally big-endian
*(OutputPtr++)=Sample&0xff;
*/
*(OutputPtr++)=((Sample>>0) & 0xff);
*(OutputPtr++)=((Sample>>8) & 0xff);

//char leftsample = Sample && 0xff;

/* Right channel. If the decoded stream is monophonic then
* the right output channel is the same as the left one.
*/
if(MAD_NCHANNELS(&Frame.header)==2)
Sample=Scale(Synth.pcm.samples[1][i], &gRand);

/* output in 16 bit little-endian */
/*
*(OutputPtr++)=Sample>>8; //Originally big-endian
*(OutputPtr++)=Sample&0xff;
*/
*(OutputPtr++)=((Sample>>0) & 0xff);
*(OutputPtr++)=((Sample>>8) & 0xff);

/* Flush the output buffer if it is full. */
if(OutputPtr == OutputBufferEnd)
{
if(fwrite(OutputBuffer, 1, OUTPUT_BUFFER_SIZE,
OutputFp)!=OUTPUT_BUFFER_SIZE)
{
sprintf(StatMsg, "PCM write error (%s).\n",
strerror(errno));
Status=2;
break;
}
OutputPtr=OutputBuffer;
}
}

}while(1);

and the Scale() is as following:
/***************************************************************************
*
* A little more advanced scaling routine based on madplay's
* audio_linear_dither() function. Rather than simply rounding the 24 bit
* number down to 16 bits (as MadFixedToSshort() in madlld does), it
performs
* dithering, which is the addition of a random number to the least
* significant bits (LSB) of the sample that targets the LSB at the 16 bit
* mark. CbMpegAudioDecoder() uses this to perform its scaling before
output.

****************************************************************************
/
static inline signed short Scale(mad_fixed_t sample, mad_fixed_t *gRandom)
{
unsigned int scalebits;
mad_fixed_t output, mask, rnd;

/* bias */
output = sample + (1L << (MAD_F_FRACBITS + 1 - 16 - 1));
//output = sample + (1L << (MAD_F_FRACBITS + 1 - 8 - 1));

scalebits = MAD_F_FRACBITS + 1 - 16;
//scalebits = MAD_F_FRACBITS + 1 - 8;
mask = (1L << scalebits) - 1;

/* dither */
rnd = Prng(*gRandom);
output += (rnd & mask) - (*gRandom & mask);
*gRandom = rnd;

/* clip */
if (output >= MAD_F_ONE)
output = MAD_F_ONE - 1;
else if (output < -MAD_F_ONE)
output = -MAD_F_ONE;

/* quantize */
output &= ~mask;

/* scale */
return output >> scalebits;
}

i'm new to audio programming, i don't know how to resample, worse, i haven't
found any stuff about
audio conversation in converting other format into 8bit 8000hz mono wav
format.
i think, it would fit my need if modifying the above code properly.
i tried for many times, unfortunately, it sounds strange:-(
how to modify the code to fit my need?
thank you very much.
Wenming at 2007-11-11 0:44:49 >