1
/* Geez, why are WAV RIFF headers are so secret? I got something together,
2
but wow... anyway, I hope someone will find this useful.
3
- Samuel Audet <guardia@cam.org> */
5
/* minor simplifications and ugly AU/CDR format stuff by MH */
7
/* It's not a very clean code ... Fix this! */
25
byte SamplesPerSec[4];
26
byte AvgBytesPerSec[4];
28
byte BitsPerSample[2]; /* format specific for PCM */
34
/* from here you insert your PCM data */
38
{ { 'R','I','F','F' } , { sizeof(RIFF.WAVE),0,0,0 } ,
39
{ { 'W','A','V','E','f','m','t',' ' } , { sizeof(RIFF.WAVE.fmt),0,0,0} ,
40
{ {1,0} , {0,0},{0,0,0,0},{0,0,0,0},{0,0},{0,0} } ,
41
{ { 'd','a','t','a' } , {0,0,0,0} }
54
{ 0x2e,0x73,0x6e,0x64 } , { 0x00,0x00,0x00,0x20 } ,
55
{ 0xff,0xff,0xff,0xff } , { 0,0,0,0 } , { 0,0,0,0 } , { 0,0,0,0 } ,
60
static long datalen = 0;
61
static int flipendian=0;
63
/* Convertfunctions: */
64
/* always little endian */
66
static void long2littleendian(long inval,byte *outval,int b)
70
outval[i] = (inval>>(i*8)) & 0xff;
74
/* always big endian */
75
static void long2bigendian(long inval,byte *outval,int b)
79
outval[i] = (inval>>((b-i-1)*8)) & 0xff;
83
static int testEndian(void)
88
for(i=0;i<sizeof(long);i++) {
97
fprintf(stderr,"Strange endianess?? %08lx %08lx %08lx\n",a,b,c);
103
static int open_file(char *filename)
106
setuid(getuid()); /* dunno whether this helps. I'm not a security expert */
108
if(!strcmp("-",filename)) {
112
wavfp = fopen(filename,"w");
120
int au_open(struct audio_info_struct *ai, char *aufilename)
125
case AUDIO_FORMAT_SIGNED_16:
126
flipendian = !testEndian(); /* big end */
127
long2bigendian(3,auhead.encoding,sizeof(auhead.encoding));
129
case AUDIO_FORMAT_UNSIGNED_8:
130
ai->format = AUDIO_FORMAT_ULAW_8;
131
case AUDIO_FORMAT_ULAW_8:
132
long2bigendian(1,auhead.encoding,sizeof(auhead.encoding));
135
fprintf(stderr,"AU output is only a hack. This audio mode isn't supported yet.\n");
139
long2bigendian(0xffffffff,auhead.datalen,sizeof(auhead.datalen));
140
long2bigendian(ai->rate,auhead.rate,sizeof(auhead.rate));
141
long2bigendian(ai->channels,auhead.channels,sizeof(auhead.channels));
143
if(open_file(aufilename) < 0)
146
fwrite(&auhead, sizeof(auhead),1,wavfp);
152
int cdr_open(struct audio_info_struct *ai, char *cdrfilename)
154
param.force_stereo = 0;
155
ai->format = AUDIO_FORMAT_SIGNED_16;
159
if(ai->format != AUDIO_FORMAT_SIGNED_16 || ai->rate != 44100 || ai->channels != 2) {
160
fprintf(stderr,"Oops .. not forced to 16 bit, 44kHz?, stereo\n");
164
flipendian = !testEndian(); /* big end */
167
if(open_file(cdrfilename) < 0)
173
int wav_open(struct audio_info_struct *ai, char *wavfilename)
179
/* standard MS PCM, and its format specific is BitsPerSample */
180
long2littleendian(1,RIFF.WAVE.fmt.FormatTag,sizeof(RIFF.WAVE.fmt.FormatTag));
182
if(ai->format == AUDIO_FORMAT_SIGNED_16) {
183
long2littleendian(bps=16,RIFF.WAVE.fmt.BitsPerSample,sizeof(RIFF.WAVE.fmt.BitsPerSample));
184
flipendian = testEndian();
186
else if(ai->format == AUDIO_FORMAT_UNSIGNED_8)
187
long2littleendian(bps=8,RIFF.WAVE.fmt.BitsPerSample,sizeof(RIFF.WAVE.fmt.BitsPerSample));
190
fprintf(stderr,"Format not supported.");
194
if(ai->rate < 0) ai->rate = 44100;
196
long2littleendian(ai->channels,RIFF.WAVE.fmt.Channels,sizeof(RIFF.WAVE.fmt.Channels));
197
long2littleendian(ai->rate,RIFF.WAVE.fmt.SamplesPerSec,sizeof(RIFF.WAVE.fmt.SamplesPerSec));
198
long2littleendian((int)(ai->channels * ai->rate * bps)>>3,
199
RIFF.WAVE.fmt.AvgBytesPerSec,sizeof(RIFF.WAVE.fmt.AvgBytesPerSec));
200
long2littleendian((int)(ai->channels * bps)>>3,
201
RIFF.WAVE.fmt.BlockAlign,sizeof(RIFF.WAVE.fmt.BlockAlign));
203
if(open_file(wavfilename) < 0)
206
long2littleendian(datalen,RIFF.WAVE.data.datalen,sizeof(RIFF.WAVE.data.datalen));
207
long2littleendian(datalen+sizeof(RIFF.WAVE),RIFF.WAVElen,sizeof(RIFF.WAVElen));
208
fwrite(&RIFF, sizeof(RIFF),1,wavfp);
215
int wav_write(unsigned char *buf,int len)
225
fprintf(stderr,"Odd number of bytes!\n");
228
for(i=0;i<len;i+=2) {
236
temp = fwrite(buf, 1, len, wavfp);
250
if(fseek(wavfp, 0L, SEEK_SET) >= 0) {
251
long2littleendian(datalen,RIFF.WAVE.data.datalen,sizeof(RIFF.WAVE.data.datalen));
252
long2littleendian(datalen+sizeof(RIFF.WAVE),RIFF.WAVElen,sizeof(RIFF.WAVElen));
253
fwrite(&RIFF, sizeof(RIFF),1,wavfp);
256
fprintf(stderr,"Warning can't rewind WAV file. File-format isn't fully conform now.\n");
267
if(fseek(wavfp, 0L, SEEK_SET) >= 0) {
268
long2bigendian(datalen,auhead.datalen,sizeof(auhead.datalen));
269
fwrite(&auhead, sizeof(auhead),1,wavfp);