1 /* WaveGain - Filename: AUDIO.C
2  *
3  * Function: Essentially provides all the wave input and output routines.
4  *
5  *   Copyright (c) 2002 - 2005 John Edwards <john.edwards33@ntlworld.com>
6  *
7  *   This library is free software; you can redistribute it and/or
8  *   modify it under the terms of the GNU Library General Public
9  *   License as published by the Free Software Foundation; either
10  *   version 2 of the License, or (at your option) any later version.
11  *
12  *   This library is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  *   Library General Public License for more details.
16  *
17  *   You should have received a copy of the GNU Library General Public
18  *   License along with this library; if not, write to the Free Software
19  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  * Portions, (c) Michael Smith <msmith@labyrinth.net.au>
22  * Portions from Vorbize, (c) Kenneth Arnold <kcarnold@yahoo.com>
23  * and libvorbis examples, (c) Monty <monty@xiph.org>
24  *
25  * AIFF/AIFC support from OggSquish, (c) 1994-1996 Monty <xiphmont@xiph.org>
26  */
27 
28 
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <sys/types.h>
33 #include <math.h>
34 
35 #include <fcntl.h>
36 
37 #include "config.h"
38 #include "audio.h"
39 #include "i18n.h"
40 #include "misc.h"
41 
42 /* Macros to read header data */
43 #define READ_U32_LE(buf) \
44 	(((buf)[3]<<24)|((buf)[2]<<16)|((buf)[1]<<8)|((buf)[0]&0xff))
45 
46 #define READ_U16_LE(buf) \
47 	(((buf)[1]<<8)|((buf)[0]&0xff))
48 
49 #define READ_U32_BE(buf) \
50 	(((buf)[0]<<24)|((buf)[1]<<16)|((buf)[2]<<8)|((buf)[3]&0xff))
51 
52 #define READ_U16_BE(buf) \
53 	(((buf)[0]<<8)|((buf)[1]&0xff))
54 
55 #ifdef __MACOSX__
56 	#define READ_D64	read_d64_be
57 	#define WRITE_D64	write_d64_be
58 #else
59 	#define READ_D64	read_d64_le
60 	#define WRITE_D64	write_d64_le
61 #endif
62 
63 /* Define the supported formats here */
64 input_format formats[] = {
65 	{wav_id, 12, wav_open, wav_close, "wav", N_("WAV file reader")},
66 	{aiff_id, 12, aiff_open, wav_close, "aiff", N_("AIFF/AIFC file reader")},
67 	{NULL, 0, NULL, NULL, NULL, NULL}
68 };
69 
70 #if (defined (WIN32) || defined (_WIN32))
71 extern int __cdecl _fseeki64(FILE *, Int64_t, int);
72 extern Int64_t __cdecl _ftelli64(FILE *);
73 
74 	#define FSEEK64		_fseeki64
75 	#define FTELL64		_ftelli64
76 #else
77 	#define FSEEK64		fseeko
78 	#define FTELL64		ftello
79 #endif
80 
81 /* Global */
82 Int64_t current_pos_t;
83 
84 #if (defined (WIN32) || defined (_WIN32))
lrint(double flt)85 __inline long int lrint(double flt)
86 {
87 	int intgr;
88 
89 	_asm {
90 		fld flt
91 		fistp intgr
92 	}
93 
94 	return intgr;
95 }
96 #elif (defined (__MACOSX__))
97 #define lrint	double2int
98 inline static long
double2int(register double in)99 double2int (register double in)
100 {	int res [2] ;
101 
102 	__asm__ __volatile__
103 	(	"fctiw	%1, %1\n\t"
104 		"stfd	%1, %0"
105 		: "=m" (res)	/* Output */
106 		: "f" (in)		/* Input */
107 		: "memory"
108 		) ;
109 
110 	return res [1] ;
111 }
112 #else
113 #define	lrint	double2int
double2int(double in)114 static inline long double2int (double in)
115 {	long retval ;
116 
117 	__asm__ __volatile__
118 	(	"fistpl %0"
119 		: "=m" (retval)
120 		: "t" (in)
121 		: "st"
122 		) ;
123 
124 	return retval ;
125 }
126 #endif
127 
read_d64_be(unsigned char * cptr)128 double read_d64_be(unsigned char *cptr)
129 {
130 	int	exponent, negative;
131 	double	dvalue;
132 
133 	negative = (cptr [0] & 0x80) ? 1 : 0;
134 	exponent = ((cptr [0] & 0x7F) << 4) | ((cptr [1] >> 4) & 0xF);
135 
136 	/* Might not have a 64 bit long, so load the mantissa into a double. */
137 	dvalue = (((cptr [1] & 0xF) << 24) | (cptr [2] << 16) | (cptr [3] << 8) | cptr [4]);
138 	dvalue += ((cptr [5] << 16) | (cptr [6] << 8) | cptr [7]) / ((double) 0x1000000);
139 
140 	if (exponent == 0 && dvalue == 0.0)
141 		return 0.0;
142 
143 	dvalue += 0x10000000;
144 
145 	exponent = exponent - 0x3FF;
146 
147 	dvalue = dvalue / ((double) 0x10000000);
148 
149 	if (negative)
150 		dvalue *= -1;
151 
152 	if (exponent > 0)
153 		dvalue *= (1 << exponent);
154 	else if (exponent < 0)
155 		dvalue /= (1 << abs (exponent));
156 
157 	return dvalue;
158 }
159 
read_d64_le(unsigned char * cptr)160 double read_d64_le(unsigned char *cptr)
161 {
162 	int	exponent, negative;
163 	double	dvalue;
164 
165 	negative = (cptr [7] & 0x80) ? 1 : 0;
166 	exponent = ((cptr [7] & 0x7F) << 4) | ((cptr [6] >> 4) & 0xF);
167 
168 	/* Might not have a 64 bit long, so load the mantissa into a double. */
169 	dvalue = (((cptr [6] & 0xF) << 24) | (cptr [5] << 16) | (cptr [4] << 8) | cptr [3]);
170 	dvalue += ((cptr [2] << 16) | (cptr [1] << 8) | cptr [0]) / ((double) 0x1000000);
171 
172 	if (exponent == 0 && dvalue == 0.0)
173 		return 0.0;
174 
175 	dvalue += 0x10000000;
176 
177 	exponent = exponent - 0x3FF;
178 
179 	dvalue = dvalue / ((double) 0x10000000);
180 
181 	if (negative)
182 		dvalue *= -1;
183 
184 	if (exponent > 0)
185 		dvalue *= (1 << exponent);
186 	else if (exponent < 0)
187 		dvalue /= (1 << abs (exponent));
188 
189 	return dvalue;
190 }
191 
write_d64_be(unsigned char * out,double in)192 void write_d64_be(unsigned char *out, double in)
193 {
194 	int	exponent, mantissa;
195 
196 	memset (out, 0, sizeof (double));
197 
198 	if (in == 0.0)
199 		return;
200 
201 	if (in < 0.0) {
202 		in *= -1.0;
203 		out [0] |= 0x80;
204 	}
205 
206 	in = frexp (in, &exponent);
207 
208 	exponent += 1022;
209 
210 	out [0] |= (exponent >> 4) & 0x7F;
211 	out [1] |= (exponent << 4) & 0xF0;
212 
213 	in *= 0x20000000;
214 	mantissa = lrint (floor (in));
215 
216 	out [1] |= (mantissa >> 24) & 0xF;
217 	out [2] = (mantissa >> 16) & 0xFF;
218 	out [3] = (mantissa >> 8) & 0xFF;
219 	out [4] = mantissa & 0xFF;
220 
221 	in = fmod (in, 1.0);
222 	in *= 0x1000000;
223 	mantissa = lrint (floor (in));
224 
225 	out [5] = (mantissa >> 16) & 0xFF;
226 	out [6] = (mantissa >> 8) & 0xFF;
227 	out [7] = mantissa & 0xFF;
228 
229 	return;
230 }
231 
write_d64_le(unsigned char * out,double in)232 void write_d64_le(unsigned char *out, double in)
233 {
234 	int	exponent, mantissa;
235 
236 	memset (out, 0, sizeof (double));
237 
238 	if (in == 0.0)
239 		return;
240 
241 	if (in < 0.0) {
242 		in *= -1.0;
243 		out [7] |= 0x80;
244 	}
245 
246 	in = frexp (in, &exponent);
247 
248 	exponent += 1022;
249 
250 	out [7] |= (exponent >> 4) & 0x7F;
251 	out [6] |= (exponent << 4) & 0xF0;
252 
253 	in *= 0x20000000;
254 	mantissa = lrint (floor (in));
255 
256 	out [6] |= (mantissa >> 24) & 0xF;
257 	out [5] = (mantissa >> 16) & 0xFF;
258 	out [4] = (mantissa >> 8) & 0xFF;
259 	out [3] = mantissa & 0xFF;
260 
261 	in = fmod (in, 1.0);
262 	in *= 0x1000000;
263 	mantissa = lrint (floor (in));
264 
265 	out [2] = (mantissa >> 16) & 0xFF;
266 	out [1] = (mantissa >> 8) & 0xFF;
267 	out [0] = mantissa & 0xFF;
268 
269 	return;
270 }
271 
open_audio_file(FILE * in,wavegain_opt * opt)272 input_format *open_audio_file(FILE *in, wavegain_opt *opt)
273 {
274 	int j = 0;
275 	unsigned char *buf = NULL;
276 	int buf_size=0, buf_filled = 0;
277 	int size, ret;
278 
279 	while (formats[j].id_func) {
280 		size = formats[j].id_data_len;
281 		if (size >= buf_size) {
282 			buf = realloc(buf, size);
283 			buf_size = size;
284 		}
285 
286 		if (size > buf_filled) {
287 			ret = fread(buf+buf_filled, 1, buf_size-buf_filled, in);
288 			buf_filled += ret;
289 
290 			if (buf_filled < size) {
291 				/* File truncated */
292 				j++;
293 				continue;
294 			}
295 		}
296 
297 		if (formats[j].id_func(buf, buf_filled)) {
298 			/* ok, we now have something that can handle the file */
299 			if (formats[j].open_func(in, opt, buf, buf_filled)) {
300 				free(buf);
301 				return &formats[j];
302 			}
303 		}
304 		j++;
305 	}
306 
307 	free(buf);
308 
309 	return NULL;
310 }
311 
seek_forward(FILE * in,Int64_t length)312 static int seek_forward(FILE *in, Int64_t length)
313 {
314 	if (FSEEK64(in, length, SEEK_CUR)) {
315 		/* Failed. Do it the hard way. */
316 		unsigned char buf[1024];
317 		int seek_needed = length, seeked;
318 		while (seek_needed > 0) {
319 			seeked = fread(buf, 1, seek_needed > 1024 ? 1024:seek_needed, in);
320 			if (!seeked)
321 				return 0; /* Couldn't read more, can't read file */
322 			else
323 				seek_needed -= seeked;
324 		}
325 	}
326 	return 1;
327 }
328 
329 
find_wav_chunk(FILE * in,char * type,Int64_t * len)330 static int find_wav_chunk(FILE *in, char *type, Int64_t *len)
331 {
332 	unsigned char buf[8];
333 
334 	while (1) {
335 		if (fread(buf,1,8,in) < 8) {
336 			/* Suck down a chunk specifier */
337 			if (memcmp(type, "gain", 4))
338 				fprintf(stderr, "Warning: Unexpected EOF in reading WAV header (1)\n");
339 			return 0; /* EOF before reaching the appropriate chunk */
340 		}
341 
342 		if (memcmp(buf, type, 4)) {
343 			*len = READ_U32_LE(buf+4);
344 			if (!seek_forward(in, *len))
345 				return 0;
346 
347 			buf[4] = 0;
348 		}
349 		else {
350 			*len = READ_U32_LE(buf+4);
351 			return 1;
352 		}
353 	}
354 }
355 
find_gain_chunk(FILE * in,Int64_t * len)356 static int find_gain_chunk(FILE *in, Int64_t *len)
357 {
358 	unsigned char buf[8];
359 
360 	if (fread(buf,1,8,in) < 8) {
361 		/* Suck down a chunk specifier */
362 			fprintf(stderr, "Warning: Unexpected EOF in reading WAV header (3)\n");
363 		return 0; /* EOF before reaching the appropriate chunk */
364 	}
365 
366 	if (!memcmp(buf, "gain", 4)) {
367 		*len = READ_U32_LE(buf+4);
368 		return 1;
369 	}
370 	else {
371 		return 0;
372 	}
373 }
374 
find_aiff_chunk(FILE * in,char * type,unsigned int * len)375 static int find_aiff_chunk(FILE *in, char *type, unsigned int *len)
376 {
377 	unsigned char buf[8];
378 
379 	while (1) {
380 		if (fread(buf,1,8,in) <8) {
381 			fprintf(stderr, "Warning: Unexpected EOF in AIFF chunk\n");
382 			return 0;
383 		}
384 
385 		*len = READ_U32_BE(buf+4);
386 
387 		if (memcmp(buf,type,4)) {
388 			if ((*len) & 0x1)
389 				(*len)++;
390 
391 			if (!seek_forward(in, *len))
392 				return 0;
393 		}
394 		else
395 			return 1;
396 	}
397 }
398 
399 
400 
read_IEEE80(unsigned char * buf)401 double read_IEEE80(unsigned char *buf)
402 {
403 	int s = buf[0] & 0xff;
404 	int e = ((buf[0] & 0x7f) <<8) | (buf[1] & 0xff);
405 	double f = ((unsigned long)(buf[2] & 0xff) << 24)|
406 		((buf[3] & 0xff) << 16)|
407 		((buf[4] & 0xff) << 8) |
408 		 (buf[5] & 0xff);
409 
410 	if (e == 32767) {
411 		if (buf[2] & 0x80)
412 			return HUGE_VAL; /* Really NaN, but this won't happen in reality */
413 		else {
414 			if (s)
415 				return -HUGE_VAL;
416 			else
417 				return HUGE_VAL;
418 		}
419 	}
420 
421 	f = ldexp(f, 32);
422 	f += ((buf[6] & 0xff) << 24)|
423 		((buf[7] & 0xff) << 16)|
424 		((buf[8] & 0xff) << 8) |
425 		 (buf[9] & 0xff);
426 
427 	return ldexp(f, e-16446);
428 }
429 
430 /* AIFF/AIFC support adapted from the old OggSQUISH application */
aiff_id(unsigned char * buf,int len)431 int aiff_id(unsigned char *buf, int len)
432 {
433 	if (len < 12) return 0; /* Truncated file, probably */
434 
435 	if (memcmp(buf, "FORM", 4))
436 		return 0;
437 
438 	if (memcmp(buf + 8, "AIF",3))
439 		return 0;
440 
441 	if (buf[11] != 'C' && buf[11] != 'F')
442 		return 0;
443 
444 	return 1;
445 }
446 
aiff_open(FILE * in,wavegain_opt * opt,unsigned char * buf,int buflen)447 int aiff_open(FILE *in, wavegain_opt *opt, unsigned char *buf, int buflen)
448 {
449 	int aifc; /* AIFC or AIFF? */
450 	unsigned int len;
451 	unsigned char *buffer;
452 	unsigned char buf2[8];
453 	aiff_fmt format;
454 	aifffile *aiff = malloc(sizeof(aifffile));
455 
456 	if (buf[11] == 'C')
457 		aifc = 1;
458 	else {
459 		aifc = 0;
460 		opt->format = WAV_FMT_AIFF;
461 	}
462 
463 	if (!find_aiff_chunk(in, "COMM", &len)) {
464 		fprintf(stderr, "Warning: No common chunk found in AIFF file\n");
465 		return 0; /* EOF before COMM chunk */
466 	}
467 
468 	if (len < 18) {
469 		fprintf(stderr, "Warning: Truncated common chunk in AIFF header\n");
470 		return 0; /* Weird common chunk */
471 	}
472 
473 	buffer = alloca(len);
474 
475 	if (fread(buffer, 1, len, in) < len) {
476 		fprintf(stderr, "Warning: Unexpected EOF in reading AIFF header\n");
477 		return 0;
478 	}
479 
480 	format.channels = READ_U16_BE(buffer);
481 	format.totalframes = READ_U32_BE(buffer + 2);
482 	format.samplesize = READ_U16_BE(buffer + 6);
483 	format.rate = (int)read_IEEE80(buffer + 8);
484 
485 	aiff->bigendian = BIG;
486 	opt->endianness = BIG;
487 
488 	if (aifc) {
489 		if (len < 22) {
490 			fprintf(stderr, "Warning: AIFF-C header truncated.\n");
491 			return 0;
492 		}
493 
494 		if (!memcmp(buffer + 18, "NONE", 4)) {
495 			aiff->bigendian = BIG;
496 			opt->endianness = BIG;
497 		}
498 		else if (!memcmp(buffer + 18, "sowt", 4)) {
499 			aiff->bigendian = LITTLE;
500 			opt->endianness = LITTLE;
501 		}
502 		else {
503 			fprintf(stderr, "Warning: Can't handle compressed AIFF-C (%c%c%c%c)\n", *(buffer+18), *(buffer+19), *(buffer+20), *(buffer+21));
504 			return 0; /* Compressed. Can't handle */
505 		}
506 	}
507 
508 	if (!find_aiff_chunk(in, "SSND", &len)) {
509 		fprintf(stderr, "Warning: No SSND chunk found in AIFF file\n");
510 		return 0; /* No SSND chunk -> no actual audio */
511 	}
512 
513 	if (len < 8) {
514 		fprintf(stderr, "Warning: Corrupted SSND chunk in AIFF header\n");
515 		return 0;
516 	}
517 
518 	if (fread(buf2, 1, 8, in) < 8) {
519 		fprintf(stderr, "Warning: Unexpected EOF reading AIFF header\n");
520 		return 0;
521 	}
522 
523 	format.offset = READ_U32_BE(buf2);
524 	format.blocksize = READ_U32_BE(buf2+4);
525 
526 	if ( format.blocksize == 0 && (format.samplesize == 16 || format.samplesize == 8)) {
527 		/* From here on, this is very similar to the wav code. Oh well. */
528 
529 		opt->rate = format.rate;
530 		opt->channels = format.channels;
531 		opt->read_samples = wav_read; /* Similar enough, so we use the same */
532 		opt->total_samples_per_channel = format.totalframes;
533 		opt->samplesize = format.samplesize;
534 		if (aifc && format.samplesize == 8)
535 			opt->format = WAV_FMT_AIFC8;
536 		else if (aifc && format.samplesize == 16)
537 			opt->format = WAV_FMT_AIFC16;
538 		opt->header_size = 0;
539 		opt->header = NULL;
540 		opt->rate = format.rate;
541 		aiff->f = in;
542 		aiff->samplesread = 0;
543 		aiff->channels = format.channels;
544 		aiff->samplesize = format.samplesize;
545 		aiff->totalsamples = format.totalframes;
546 
547 		opt->readdata = (void *)aiff;
548 
549 		seek_forward(in, format.offset); /* Swallow some data */
550 		return 1;
551 	}
552 	else {
553 		fprintf(stderr, "Warning: WaveGain does not support this type of AIFF/AIFC file\n"
554 				" Must be 8 or 16 bit PCM.\n");
555 		return 0;
556 	}
557 }
558 
wav_id(unsigned char * buf,int len)559 int wav_id(unsigned char *buf, int len)
560 {
561 	unsigned int flen;
562 
563 	if (len < 12) return 0; /* Something screwed up */
564 
565 	if (memcmp(buf, "RIFF", 4))
566 		return 0; /* Not wave */
567 
568 	flen = READ_U32_LE(buf + 4); /* We don't use this */
569 
570 	if (memcmp(buf + 8, "WAVE",4))
571 		return 0; /* RIFF, but not wave */
572 
573 	return 1;
574 }
575 
wav_open(FILE * in,wavegain_opt * opt,unsigned char * oldbuf,int buflen)576 int wav_open(FILE *in, wavegain_opt *opt, unsigned char *oldbuf, int buflen)
577 {
578 	unsigned char buf[16];
579 	Int64_t len;
580 	Int64_t current_pos;
581 	int samplesize;
582 	wav_fmt format;
583 	wavfile *wav = malloc(sizeof(wavfile));
584 
585 	/* Ok. At this point, we know we have a WAV file. Now we have to detect
586 	 * whether we support the subtype, and we have to find the actual data
587 	 * We don't (for the wav reader) need to use the buffer we used to id this
588 	 * as a wav file (oldbuf)
589 	 */
590 
591 	if (!find_wav_chunk(in, "fmt ", &len)) {
592 		fprintf(stderr, "Warning: Failed to find fmt chunk in reading WAV header\n");
593 		return 0; /* EOF */
594 	}
595 
596 	if (len < 16) {
597 		fprintf(stderr, "Warning: Unrecognised format chunk in WAV header\n");
598 		return 0; /* Weird format chunk */
599 	}
600 
601 	/* A common error is to have a format chunk that is not 16 or 18 bytes
602 	 * in size.  This is incorrect, but not fatal, so we only warn about
603 	 * it instead of refusing to work with the file.  Please, if you
604 	 * have a program that's creating format chunks of sizes other than
605 	 * 16 or 18 bytes in size, report a bug to the author.
606 	 */
607 	if (len != 16 && len != 18)
608 		fprintf(stderr, "Warning: INVALID format chunk in wav header.\n"
609 				" Trying to read anyway (may not work)...\n");
610 
611 	if (fread(buf, 1, 16, in) < 16) {
612 		fprintf(stderr, "Warning: Unexpected EOF in reading WAV header (2)\n");
613 		return 0;
614 	}
615 
616 	/* Deal with stupid broken apps. Don't use these programs.
617 	 */
618 	if (len - 16 > 0 && !seek_forward(in, len - 16))
619 	    return 0;
620 
621 	format.format =      READ_U16_LE(buf);
622 	format.channels =    READ_U16_LE(buf+2);
623 	format.samplerate =  READ_U32_LE(buf+4);
624 	format.bytespersec = READ_U32_LE(buf+8);
625 	format.align =       READ_U16_LE(buf+12);
626 	format.samplesize =  READ_U16_LE(buf+14);
627 
628 	if (!opt->std_in) {
629 		current_pos = FTELL64(in);
630 		if (!find_gain_chunk(in, &len))
631 			FSEEK64(in, current_pos, SEEK_SET);
632 		else {
633 			unsigned char buf_double[8];
634 			opt->gain_chunk = 1;
635 			fread(buf_double, 1, 8, in);
636 			opt->gain_scale = READ_D64(buf_double);
637 		}
638 	}
639 
640 	if (!find_wav_chunk(in, "data", &len)) {
641 		fprintf(stderr, "Warning: Failed to find data chunk in reading WAV header\n");
642 		return 0; /* EOF */
643 	}
644 
645 	if (opt->apply_gain) {
646 		current_pos = FTELL64(in);
647 		current_pos_t = current_pos + len;
648 		FSEEK64(in, 0, SEEK_SET);
649 		if ((opt->header = malloc(sizeof(char) * current_pos)) == NULL)
650 			fprintf(stderr, "Error: unable to allocate memory for header\n");
651 		else {
652 			opt->header_size = current_pos;
653 			fread(opt->header, 1, opt->header_size, in);
654 		}
655 		FSEEK64(in, current_pos, SEEK_SET);
656 	}
657 
658 	if (format.format == 1) {
659 		samplesize = format.samplesize / 8;
660 		opt->read_samples = wav_read;
661 		/* works with current enum */
662 		opt->format = samplesize;
663 	}
664 	else if (format.format == 3) {
665 		samplesize = 4;
666 		opt->read_samples = wav_ieee_read;
667 		opt->endianness = LITTLE;
668 		opt->format = WAV_FMT_FLOAT;
669 	}
670 	else {
671 		fprintf(stderr, "ERROR: Wav file is unsupported type (must be standard PCM\n"
672 				" or type 3 floating point PCM)\n");
673 		return 0;
674 	}
675 
676 	opt->samplesize = format.samplesize;
677 
678 	if ( format.align == format.channels * samplesize &&
679 			format.samplesize == samplesize * 8 &&
680 			(format.samplesize == 32 || format.samplesize == 24 ||
681 			 format.samplesize == 16 || format.samplesize == 8)) {
682 		/* OK, good - we have the one supported format,
683 		   now we want to find the size of the file */
684 		opt->rate = format.samplerate;
685 		opt->channels = format.channels;
686 
687 		wav->f = in;
688 		wav->samplesread = 0;
689 		wav->bigendian = 0;
690 		opt->endianness = LITTLE;
691 		wav->channels = format.channels; /* This is in several places. The price
692 							of trying to abstract stuff. */
693 		wav->samplesize = format.samplesize;
694 
695 		if (len)
696 			opt->total_samples_per_channel = len/(format.channels*samplesize);
697 		else {
698 			Int64_t pos;
699 			pos = FTELL64(in);
700 			if (FSEEK64(in, 0, SEEK_END) == -1)
701 				opt->total_samples_per_channel = 0; /* Give up */
702 			else {
703 				opt->total_samples_per_channel = (FTELL64(in) - pos)/(format.channels * samplesize);
704 				FSEEK64(in, pos, SEEK_SET);
705 			}
706 		}
707 		wav->totalsamples = opt->total_samples_per_channel;
708 
709 		opt->readdata = (void *)wav;
710 		return 1;
711 	}
712 	else {
713 		fprintf(stderr, "ERROR: Wav file is unsupported subformat (must be 8, 16, 24 or 32 bit PCM\n"
714 				"or floating point PCM)\n");
715 		return 0;
716 	}
717 }
718 
wav_read(void * in,double ** buffer,int samples,int fast,int chunk)719 long wav_read(void *in, double **buffer, int samples, int fast, int chunk)
720 {
721 	wavfile *f = (wavfile *)in;
722 	int sampbyte = f->samplesize / 8;
723 	signed char *buf = alloca(samples*sampbyte*f->channels);
724 	long bytes_read;
725 	int i, j;
726 	long realsamples;
727 
728 	if (fast) {
729 		chunk /= (sampbyte * f->channels);
730 		chunk *= (sampbyte * f->channels);
731 		FSEEK64(f->f, chunk, SEEK_SET);
732 	}
733 
734 	bytes_read = fread(buf, 1, samples * sampbyte * f->channels, f->f);
735 
736 	if (f->totalsamples && f->samplesread + bytes_read / (sampbyte * f->channels) > f->totalsamples) {
737 		bytes_read = sampbyte * f->channels * (f->totalsamples - f->samplesread);
738 	}
739 
740 	realsamples = bytes_read / (sampbyte * f->channels);
741 	f->samplesread += realsamples;
742 
743 	if (f->samplesize == 8) {
744 		unsigned char *bufu = (unsigned char *)buf;
745 		for (i = 0; i < realsamples; i++) {
746 			for (j = 0; j < f->channels; j++)
747 				buffer[j][i] = ((int)(bufu[i * f->channels + j]) - 128) / 128.0;
748 		}
749 	}
750 	else if (f->samplesize==16) {
751 #ifdef __MACOSX__
752 		if (f->bigendian != machine_endianness) {
753 #else
754 		if (f->bigendian == machine_endianness) {
755 #endif
756 			for (i = 0; i < realsamples; i++) {
757 				for (j = 0; j < f->channels; j++)
758 					buffer[j][i] = ((buf[i * 2 * f->channels + 2 * j + 1] <<8) |
759 							        (buf[i * 2 * f->channels + 2 * j] & 0xff)) / 32768.0;
760 			}
761 		}
762 		else {
763 			for (i = 0; i < realsamples; i++) {
764 				for (j = 0; j < f->channels; j++)
765 					buffer[j][i]=((buf[i * 2 * f->channels + 2 * j] << 8) |
766 							      (buf[i * 2 * f->channels + 2 * j + 1] & 0xff)) / 32768.0;
767 			}
768 		}
769 	}
770 	else if (f->samplesize == 24) {
771 #ifdef __MACOSX__
772 		if (f->bigendian != machine_endianness) {
773 #else
774 		if (f->bigendian == machine_endianness) {
775 #endif
776 			for (i = 0; i < realsamples; i++) {
777 				for (j = 0; j < f->channels; j++)
778 					buffer[j][i] = ((buf[i * 3 * f->channels + 3 * j + 2] << 16) |
779 						(((unsigned char *)buf)[i * 3 * f->channels + 3 * j + 1] << 8) |
780 						(((unsigned char *)buf)[i * 3 * f->channels + 3 * j] & 0xff))
781 						/ 8388608.0;
782 			}
783 		}
784 		else {
785 			fprintf(stderr, "Big endian 24 bit PCM data is not currently "
786 					"supported, aborting.\n");
787 			return 0;
788 		}
789 	}
790 	else if (f->samplesize == 32) {
791 #ifdef __MACOSX__
792 		if (f->bigendian != machine_endianness) {
793 #else
794 		if (f->bigendian == machine_endianness) {
795 #endif
796 			for (i = 0; i < realsamples; i++) {
797 				for (j = 0; j < f->channels; j++)
798 					buffer[j][i] = ((buf[i * 4 * f->channels + 4 * j + 3] << 24) |
799 						(((unsigned char *)buf)[i * 4 * f->channels + 4 * j + 2] << 16) |
800 						(((unsigned char *)buf)[i * 4 * f->channels + 4 * j + 1] << 8) |
801 						(((unsigned char *)buf)[i * 4 * f->channels + 4 * j] & 0xff))
802 						/ 2147483648.0;
803 			}
804 		}
805 		else {
806 			fprintf(stderr, "Big endian 32 bit PCM data is not currently "
807 					"supported, aborting.\n");
808 			return 0;
809 		}
810 	}
811 	else {
812 		fprintf(stderr, "Internal error: attempt to read unsupported "
813 				"bitdepth %d\n", f->samplesize);
814 		return 0;
815 	}
816 
817 	return realsamples;
818 }
819 
820 long wav_ieee_read(void *in, double **buffer, int samples, int fast, int chunk)
821 {
822 	wavfile *f = (wavfile *)in;
823 	float *buf = alloca(samples * 4 * f->channels); /* de-interleave buffer */
824 	long bytes_read;
825 	int i,j;
826 	long realsamples;
827 
828 	if (fast) {
829 		chunk /= (sizeof(float) * f->channels);
830 		chunk *= (sizeof(float) * f->channels);
831 		FSEEK64(f->f, chunk, SEEK_SET);
832 	}
833 
834 	bytes_read = fread(buf, 1, samples * 4 * f->channels, f->f);
835 
836 	if (f->totalsamples && f->samplesread + bytes_read / (4 * f->channels) > f->totalsamples)
837 		bytes_read = 4 * f->channels * (f->totalsamples - f->samplesread);
838 	realsamples = bytes_read / (4 * f->channels);
839 	f->samplesread += realsamples;
840 
841 	for (i = 0; i < realsamples; i++)
842 		for (j = 0; j < f->channels; j++)
843 			buffer[j][i] = buf[i * f->channels + j];
844 
845 	return realsamples;
846 }
847 
848 
849 void wav_close(void *info)
850 {
851 	wavfile *f = (wavfile *)info;
852 
853 	free(f);
854 }
855 
856 int raw_open(FILE *in, wavegain_opt *opt)
857 {
858 	wav_fmt format; /* fake wave header ;) */
859 	wavfile *wav = malloc(sizeof(wavfile));
860 
861 	/* construct fake wav header ;) */
862 	format.format =      2;
863 	format.channels =    opt->channels;
864 	format.samplerate =  opt->rate;
865 	format.samplesize =  opt->samplesize;
866 	format.bytespersec = opt->channels * opt->rate * opt->samplesize / 8;
867 	format.align =       format.bytespersec;
868 	wav->f =             in;
869 	wav->samplesread =   0;
870 	wav->bigendian =     opt->endianness;
871 	wav->channels =      format.channels;
872 	wav->samplesize =    opt->samplesize;
873 	wav->totalsamples =  0;
874 
875 	opt->read_samples = wav_read;
876 	opt->readdata = (void *)wav;
877 	opt->total_samples_per_channel = 0; /* raw mode, don't bother */
878 	return 1;
879 }
880 
881 /*
882  * W A V E   O U T P U T
883  */
884 
885 audio_file *open_output_audio_file(char *infile, wavegain_opt *opt)
886 {
887 	audio_file *aufile = malloc(sizeof(audio_file));
888 
889 	aufile->outputFormat = opt->format;
890 
891 	aufile->samplerate = opt->rate;
892 	aufile->channels = opt->channels;
893 	aufile->samples = 0;
894 	aufile->endianness = opt->endianness;
895 	aufile->bits_per_sample = opt->samplesize;
896 
897 	if (opt->std_out) {
898 		aufile->sndfile = stdout;
899 #ifdef _WIN32
900 		_setmode( _fileno(stdout), _O_BINARY );
901 #endif
902 	}
903 	else
904 		aufile->sndfile = fopen(infile, "wb");
905 
906 	if (aufile->sndfile == NULL) {
907 		if (aufile)
908 			free(aufile);
909 		return NULL;
910 	}
911 
912 	switch (aufile->outputFormat) {
913 		case WAV_FMT_AIFF:
914 			write_aiff_header(aufile);
915 			break;
916 		case WAV_FMT_8BIT:
917 		case WAV_FMT_16BIT:
918 		case WAV_FMT_24BIT:
919 		case WAV_FMT_32BIT:
920 		case WAV_FMT_FLOAT: {
921 			unsigned int file_size = 0xffffffff;
922 			write_wav_header(aufile, opt, file_size);
923 			}
924 			break;
925 	}
926 
927 	return aufile;
928 }
929 
930 int write_audio_file(audio_file *aufile, void *sample_buffer, int samples)
931 {
932 	switch (aufile->outputFormat) {
933 		case WAV_FMT_8BIT:
934 			return write_audio_8bit(aufile, sample_buffer, samples);
935 		case WAV_FMT_16BIT:
936 		case WAV_FMT_AIFF:
937 			return write_audio_16bit(aufile, sample_buffer, samples);
938 		case WAV_FMT_24BIT:
939 			return write_audio_24bit(aufile, sample_buffer, samples);
940 		case WAV_FMT_32BIT:
941 			return write_audio_32bit(aufile, sample_buffer, samples);
942 		case WAV_FMT_FLOAT:
943 			return write_audio_float(aufile, sample_buffer, samples);
944 		default:
945 			return 0;
946 	}
947 
948 	return 0;
949 }
950 
951 void close_audio_file( FILE *in, audio_file *aufile, wavegain_opt *opt)
952 {
953 	unsigned char *ch;
954 	Int64_t pos;
955 
956 	if (!opt->std_out) {
957 
958 		switch (aufile->outputFormat) {
959 			case WAV_FMT_AIFF:
960 				FSEEK64(aufile->sndfile, 0, SEEK_SET);
961 				write_aiff_header(aufile);
962 				break;
963 			case WAV_FMT_8BIT:
964 			case WAV_FMT_16BIT:
965 			case WAV_FMT_24BIT:
966 			case WAV_FMT_32BIT:
967 			case WAV_FMT_FLOAT: {
968 				FSEEK64(in, 0, SEEK_END);
969 				pos = FTELL64 (in);
970 				if ((pos - current_pos_t) > 0) {
971 					FSEEK64 (in, current_pos_t, SEEK_SET);
972 					ch = malloc (sizeof(char) * (pos - current_pos_t));
973 
974 					fread (ch, 1, pos - current_pos_t, in);
975 					fwrite (ch, pos - current_pos_t, 1, aufile->sndfile);
976 
977 					if (ch)
978 						free (ch);
979 				}
980 				FSEEK64(aufile->sndfile, 0, SEEK_END);
981 				pos = FTELL64 (aufile->sndfile);
982 				FSEEK64(aufile->sndfile, 0, SEEK_SET);
983 				write_wav_header(aufile, opt, pos - 8);
984 				break;
985 			}
986 		}
987 	}
988 
989 	if(opt->header)
990 		free(opt->header);
991 	if(opt)
992 		free(opt);
993 
994 	fclose(aufile->sndfile);
995 
996 	if (aufile)
997 		free(aufile);
998 }
999 
1000 #define WRITE_U32(buf, x) *(buf)     = (unsigned char)((x)&0xff);\
1001                           *((buf)+1) = (unsigned char)(((x)>>8)&0xff);\
1002                           *((buf)+2) = (unsigned char)(((x)>>16)&0xff);\
1003                           *((buf)+3) = (unsigned char)(((x)>>24)&0xff);
1004 
1005 #define WRITE_U16(buf, x) *(buf)     = (unsigned char)((x)&0xff);\
1006                           *((buf)+1) = (unsigned char)(((x)>>8)&0xff);
1007 
1008 static int write_wav_header(audio_file *aufile, wavegain_opt *opt, Int64_t file_size)
1009 {
1010 	unsigned short channels    = opt->channels;
1011 	unsigned long samplerate   = opt->rate;
1012 	unsigned long bytespersec  = opt->channels * opt->rate * opt->samplesize / 8;
1013 	unsigned short align       = opt->channels * opt->samplesize / 8;
1014 	unsigned short samplesize  = opt->samplesize;
1015 	unsigned long size         = file_size;
1016 	unsigned long data_size    = aufile->samples * (opt->samplesize / 8) < 0xffffffff ?
1017 					aufile->samples * (opt->samplesize / 8) : 0xffffffff;
1018 
1019 	unsigned long sz_fmt;
1020 	unsigned char *p = opt->header;
1021 	unsigned char *q;
1022 	unsigned char *r;
1023 //	unsigned char buf[8];
1024 	unsigned long chunks_to_process;
1025 	unsigned long no_of_chunks_processed = 0;
1026 
1027 	if ((opt->force || opt->undo) && opt->gain_chunk)
1028 		chunks_to_process = 3;
1029 	else
1030 		chunks_to_process = 2;
1031 
1032 	for (;;) {
1033 		if (!memcmp(p, "RIFF", 4)) {
1034 			p += 4;
1035 			WRITE_U32(p, size);
1036 			p += 4;
1037 			no_of_chunks_processed++;
1038 		}
1039 		if (!memcmp(p, "fmt ", 4)) {
1040 			unsigned long fmt_length = 0;
1041 			p += 4;
1042 			sz_fmt = READ_U32_LE(p);
1043 			p += 4;
1044 			if (aufile->outputFormat == WAV_FMT_FLOAT) {
1045 				WRITE_U16(p, 3);
1046 			}
1047 			else {
1048 				WRITE_U16(p, 1);
1049 			}
1050 			p += 2;
1051 			fmt_length += 2;
1052 			WRITE_U16(p, channels);
1053 			p += 2;
1054 			fmt_length += 2;
1055 			WRITE_U32(p, samplerate);
1056 			p += 4;
1057 			fmt_length += 4;
1058 			WRITE_U32(p, bytespersec);
1059 			p += 4;
1060 			fmt_length += 4;
1061 			WRITE_U16(p, align);
1062 			p += 2;
1063 			fmt_length += 2;
1064 			WRITE_U16(p, samplesize);
1065 			p += 2;
1066 			fmt_length += 2;
1067 			p += sz_fmt - fmt_length;
1068 			no_of_chunks_processed++;
1069 		}
1070 		if (chunks_to_process == 3) {
1071 			if (!memcmp(p, "gain", 4)) {
1072 				p += 8;
1073 				WRITE_D64(p, opt->gain_scale);
1074 				p += 8;
1075 				no_of_chunks_processed++;
1076 			}
1077 		}
1078 		if (no_of_chunks_processed == chunks_to_process)
1079 			break;
1080 		else
1081 			p++;
1082 	}
1083 
1084 	if (opt->write_chunk == 1 && !opt->gain_chunk) {
1085 		if ((q = malloc(sizeof(char) * (opt->header_size + 16))) == NULL)
1086 			fprintf(stderr, "Error: unable to allocate memory for header\n");
1087 		else {
1088 			r = q;
1089 			memcpy(r, opt->header, p - opt->header);
1090 			r += (p - opt->header);
1091 			memcpy(r, "gain", 4);
1092 			r += 4;
1093 			WRITE_U32(r, 8);
1094 			r += 4;
1095 //			buf = (unsigned char *)&opt->gain_scale;
1096 			WRITE_D64(r, opt->gain_scale);
1097 			r += 8;
1098 		}
1099 
1100 		memcpy(r, p, (opt->header_size - (p - opt->header)));
1101 
1102 		r = q + opt->header_size + 16 - 8;
1103 		if (!memcmp(r, "data", 4)) {
1104 			r += 4;
1105 			WRITE_U32(r, data_size);
1106 			r += 4;
1107 			fwrite(q, opt->header_size + 16, 1, aufile->sndfile);
1108 		}
1109 		else
1110 			fprintf(stderr, "Error: unable to write header\n");
1111 		if(q) free(q);
1112 	}
1113 	else {
1114 		p = opt->header + opt->header_size - 8;
1115 		if (!memcmp(p, "data", 4)) {
1116 			p += 4;
1117 			WRITE_U32(p, data_size);
1118 			p += 4;
1119 			fwrite(opt->header, opt->header_size, 1, aufile->sndfile);
1120 		}
1121 	}
1122 
1123 	return 1;
1124 }
1125 
1126 /*
1127  *  Write a 80 bit IEEE854 big endian number as 10 octets. Destination is passed as pointer,
1128  *  End of destination (p+10) is returned.
1129  */
1130 
1131 static unsigned char* Convert_to_80bit_BE_IEEE854_Float(unsigned char* p, long double val )
1132 {
1133     unsigned long  word32 = 0x401E;
1134 
1135     if (val > 0.L)
1136         while (val < (long double)0x80000000)                    // scales value in the range 2^31...2^32
1137             word32--, val *= 2.L;                              // so you have the exponent
1138 
1139     *p++   = (unsigned char)(word32 >>  8);
1140     *p++   = (unsigned char)(word32 >>  0);                          // write exponent, sign is assumed as '+'
1141     word32 = (unsigned long) val;
1142     *p++   = (unsigned char)(word32 >> 24);
1143     *p++   = (unsigned char)(word32 >> 16);
1144     *p++   = (unsigned char)(word32 >>  8);
1145     *p++   = (unsigned char)(word32 >>  0);                          // write the upper 32 bit of the mantissa
1146     word32 = (unsigned long) ((val - word32) * 4294967296.L);
1147     *p++   = (unsigned char)(word32 >> 24);
1148     *p++   = (unsigned char)(word32 >> 16);
1149     *p++   = (unsigned char)(word32 >>  8);
1150     *p++   = (unsigned char)(word32 >>  0);                          // write the lower 32 bit of the mantissa
1151 
1152     return p;
1153 }
1154 
1155 static int write_aiff_header(audio_file *aufile)
1156 {
1157 	unsigned char   header[54],
1158 	                        *p = header;
1159 	unsigned int         bytes = (aufile->bits_per_sample + 7) / 8;
1160 	unsigned long    data_size = aufile->samples * bytes;
1161 	unsigned long       word32;
1162 
1163 	// FORM chunk
1164 	*p++ = 'F';
1165 	*p++ = 'O';
1166 	*p++ = 'R';
1167 	*p++ = 'M';
1168 
1169 	word32 = data_size + 0x2E;  // size of the AIFF chunk
1170 	*p++ = (unsigned char)(word32 >> 24);
1171 	*p++ = (unsigned char)(word32 >> 16);
1172 	*p++ = (unsigned char)(word32 >>  8);
1173 	*p++ = (unsigned char)(word32 >>  0);
1174 
1175 	*p++ = 'A';
1176 	*p++ = 'I';
1177 	*p++ = 'F';
1178 	*p++ = 'F';
1179 	// end of FORM chunk
1180 
1181 	// COMM chunk
1182 	*p++ = 'C';
1183 	*p++ = 'O';
1184 	*p++ = 'M';
1185 	*p++ = 'M';
1186 
1187 	word32 = 0x12;                             // size of this chunk
1188 	*p++ = (unsigned char)(word32 >> 24);
1189 	*p++ = (unsigned char)(word32 >> 16);
1190 	*p++ = (unsigned char)(word32 >>  8);
1191 	*p++ = (unsigned char)(word32 >>  0);
1192 
1193 	word32 = aufile->channels;                 // channels
1194 	*p++ = (unsigned char)(word32 >>  8);
1195 	*p++ = (unsigned char)(word32 >>  0);
1196 
1197 	word32 = aufile->samples / aufile->channels;       // no. of sample frames
1198 	*p++ = (unsigned char)(word32 >> 24);
1199 	*p++ = (unsigned char)(word32 >> 16);
1200 	*p++ = (unsigned char)(word32 >>  8);
1201 	*p++ = (unsigned char)(word32 >>  0);
1202 
1203 	word32 = aufile->bits_per_sample;           // bits
1204 	*p++ = (unsigned char)(word32 >>  8);
1205 	*p++ = (unsigned char)(word32 >>  0);
1206 
1207 	p = Convert_to_80bit_BE_IEEE854_Float (p, (long double)aufile->samplerate);  // sample frequency as big endian 80 bit IEEE854 float
1208 	// End of COMM chunk
1209 
1210 	// SSND chunk
1211 	*p++ = 'S';
1212 	*p++ = 'S';
1213 	*p++ = 'N';
1214 	*p++ = 'D';
1215 
1216 	word32 = data_size + 0x08;  // chunk length
1217 	*p++ = (unsigned char)(word32 >> 24);
1218 	*p++ = (unsigned char)(word32 >> 16);
1219 	*p++ = (unsigned char)(word32 >>  8);
1220 	*p++ = (unsigned char)(word32 >>  0);
1221 
1222 	*p++ = 0;                                  // offset
1223 	*p++ = 0;
1224 	*p++ = 0;
1225 	*p++ = 0;
1226 
1227 	*p++ = 0;                                  // block size
1228 	*p++ = 0;
1229 	*p++ = 0;
1230 	*p++ = 0;
1231 
1232 	return fwrite(header, sizeof(header), 1, aufile->sndfile);
1233 }
1234 
1235 static int write_audio_8bit(audio_file *aufile, void *sample_buffer, unsigned int samples)
1236 {
1237 	int              ret;
1238 	unsigned int     i;
1239 	unsigned char    *sample_buffer8 = (unsigned char*)sample_buffer;
1240 	unsigned char    *data = malloc(samples*aufile->bits_per_sample*sizeof(char)/8);
1241 
1242 	aufile->samples += samples;
1243 
1244 	for (i = 0; i < samples; i++)
1245 		data[i] = (sample_buffer8[i]+128) & 0xFF;
1246 
1247 	ret = fwrite(data, samples*aufile->bits_per_sample/8, 1, aufile->sndfile);
1248 
1249 	if (data)
1250 		free(data);
1251 
1252 	return ret;
1253 }
1254 
1255 static int write_audio_16bit(audio_file *aufile, void *sample_buffer, unsigned int samples)
1256 {
1257 	int          ret;
1258 	unsigned int i;
1259 	short        *sample_buffer16 = (short*)sample_buffer;
1260 	char         *data = malloc(samples*aufile->bits_per_sample*sizeof(char)/8);
1261 
1262 	aufile->samples += samples;
1263 
1264 #ifdef __MACOSX__
1265 		if (aufile->endianness != machine_endianness) {
1266 #else
1267 		if (aufile->endianness == machine_endianness) {
1268 #endif
1269 		for (i = 0; i < samples; i++) {
1270 			data[i*2] = (char)(sample_buffer16[i] & 0xFF);
1271 			data[i*2+1] = (char)((sample_buffer16[i] >> 8) & 0xFF);
1272 		}
1273 	}
1274 	else {
1275 		for (i = 0; i < samples; i++) {
1276 			data[i*2+1] = (char)(sample_buffer16[i] & 0xFF);
1277 			data[i*2] = (char)((sample_buffer16[i] >> 8) & 0xFF);
1278 		}
1279 	}
1280 
1281 	ret = fwrite(data, samples*aufile->bits_per_sample/8, 1, aufile->sndfile);
1282 
1283 	if (data)
1284 		free(data);
1285 
1286 	return ret;
1287 }
1288 
1289 static int write_audio_24bit(audio_file *aufile, void *sample_buffer, unsigned int samples)
1290 {
1291 	int          ret;
1292 	unsigned int i;
1293 	long         *sample_buffer24 = (long*)sample_buffer;
1294 	char         *data = malloc(samples*aufile->bits_per_sample*sizeof(char)/8);
1295 
1296 	aufile->samples += samples;
1297 
1298 	for (i = 0; i < samples; i++) {
1299 		data[i*3] = (char)(sample_buffer24[i] & 0xFF);
1300 		data[i*3+1] = (char)((sample_buffer24[i] >> 8) & 0xFF);
1301 		data[i*3+2] = (char)((sample_buffer24[i] >> 16) & 0xFF);
1302 	}
1303 
1304 	ret = fwrite(data, samples*aufile->bits_per_sample/8, 1, aufile->sndfile);
1305 
1306 	if (data)
1307 		free(data);
1308 
1309 	return ret;
1310 }
1311 
1312 static int write_audio_32bit(audio_file *aufile, void *sample_buffer, unsigned int samples)
1313 {
1314 	int          ret;
1315 	unsigned int i;
1316 	long         *sample_buffer32 = (long*)sample_buffer;
1317 	char         *data = malloc(samples*aufile->bits_per_sample*sizeof(char)/8);
1318 
1319 	aufile->samples += samples;
1320 
1321 	for (i = 0; i < samples; i++) {
1322 		data[i*4] = (char)(sample_buffer32[i] & 0xFF);
1323 		data[i*4+1] = (char)((sample_buffer32[i] >> 8) & 0xFF);
1324 		data[i*4+2] = (char)((sample_buffer32[i] >> 16) & 0xFF);
1325 		data[i*4+3] = (char)((sample_buffer32[i] >> 24) & 0xFF);
1326 	}
1327 
1328 	ret = fwrite(data, samples*aufile->bits_per_sample/8, 1, aufile->sndfile);
1329 
1330 	if (data)
1331 		free(data);
1332 
1333 	return ret;
1334 }
1335 
1336 static int write_audio_float(audio_file *aufile, void *sample_buffer, unsigned int samples)
1337 {
1338 	int           ret;
1339 	unsigned int  i;
1340 	float         *sample_buffer_f = (float*)sample_buffer;
1341 	unsigned char *data = malloc(samples*aufile->bits_per_sample*sizeof(char)/8);
1342 
1343 	aufile->samples += samples;
1344 
1345 	for (i = 0; i < samples; i++) {
1346 		int   exponent,
1347 		      mantissa,
1348 		      negative = 0;
1349 		float in = sample_buffer_f[i];
1350 
1351 		data[i*4] = 0;
1352 		data[i*4+1] = 0;
1353 		data[i*4+2] = 0;
1354 		data[i*4+3] = 0;
1355 		if (in == 0.f)
1356 			continue;
1357 
1358 		if (in < 0.0) {
1359 			in *= -1.0;
1360 			negative = 1;
1361 		}
1362 		in = (float)frexp(in, &exponent);
1363 		exponent += 126;
1364 		in *= (float)0x1000000;
1365 		mantissa = (((int)in) & 0x7FFFFF);
1366 
1367 		if (negative)
1368 			data[i*4+3] |= 0x80;
1369 
1370 		if (exponent & 0x01)
1371 			data[i*4+2] |= 0x80;
1372 
1373 		data[i*4] = mantissa & 0xFF;
1374 		data[i*4+1] = (mantissa >> 8) & 0xFF;
1375 		data[i*4+2] |= (mantissa >> 16) & 0x7F;
1376 		data[i*4+3] |= (exponent >> 1) & 0x7F;
1377 	}
1378 
1379 	ret = fwrite(data, samples*aufile->bits_per_sample/8, 1, aufile->sndfile);
1380 
1381 	if (data)
1382 		free(data);
1383 
1384 	return ret;
1385 }
1386 
1387 void* output_to_PCM(double **input, void *sample_buffer, int channels,
1388                     int samples, int format)
1389 {
1390 	unsigned char   ch;
1391 	int             i;
1392 
1393 	char             *char_sample_buffer = (char*)sample_buffer;
1394 	short           *short_sample_buffer = (short*)sample_buffer;
1395 	int               *int_sample_buffer = (int*)sample_buffer;
1396 	float           *float_sample_buffer = (float*)sample_buffer;
1397 
1398 	/*
1399 	 * Copy output to a standard PCM buffer
1400 	 */
1401 	switch (format) {
1402 	case WAV_FMT_8BIT:
1403 		for (ch = 0; ch < channels; ch++) {
1404 			for (i = 0; i < samples; i++) {
1405 				char_sample_buffer[(i*channels)+ch] = (char)input[ch][i];
1406 			}
1407 		}
1408 		break;
1409 	case WAV_FMT_AIFF:
1410 	case WAV_FMT_16BIT:
1411 		for (ch = 0; ch < channels; ch++) {
1412 			for (i = 0; i < samples; i++) {
1413 				short_sample_buffer[(i*channels)+ch] = (short)input[ch][i];
1414 			}
1415 		}
1416 		break;
1417 	case WAV_FMT_24BIT:
1418 	case WAV_FMT_32BIT:
1419 		for (ch = 0; ch < channels; ch++) {
1420 			for (i = 0; i < samples; i++) {
1421 				int_sample_buffer[(i*channels)+ch] = (int)input[ch][i];
1422 			}
1423 		}
1424 		break;
1425 	case WAV_FMT_FLOAT:
1426 		for (ch = 0; ch < channels; ch++) {
1427 			for (i = 0; i < samples; i++) {
1428 				float_sample_buffer[(i*channels)+ch] = (float)input[ch][i];
1429 			}
1430 		}
1431 		break;
1432 	}
1433 
1434 	return sample_buffer;
1435 }
1436 
1437 /*
1438  * end of audio.c
1439  */
1440