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