]> 4ch.mooo.com Git - 16.git/blob - src/lib/dl/ext/vorbtool/audio.c
cleaned up the repo from debugging watcom2 ^^
[16.git] / src / lib / dl / ext / vorbtool / audio.c
1 /* OggEnc
2  **
3  ** This program is distributed under the GNU General Public License, version 2.
4  ** A copy of this license is included with this source.
5  **
6  ** Copyright 2000-2002, Michael Smith <msmith@xiph.org>
7  **           2010, Monty <monty@xiph.org>
8  **
9  ** AIFF/AIFC support from OggSquish, (c) 1994-1996 Monty <xiphmont@xiph.org>
10  **/
11
12 #ifdef HAVE_CONFIG_H
13 #include "config.h"
14 #endif
15
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include <sys/types.h>
20 #include <math.h>
21
22 #include "audio.h"
23 #include "platform.h"
24 #include "i18n.h"
25 #include "resample.h"
26
27 #ifdef HAVE_LIBFLAC
28 #include "flac.h"
29 #endif
30
31 /* Macros to read header data */
32 #define READ_U32_LE(buf) \
33     (((buf)[3]<<24)|((buf)[2]<<16)|((buf)[1]<<8)|((buf)[0]&0xff))
34
35 #define READ_U16_LE(buf) \
36     (((buf)[1]<<8)|((buf)[0]&0xff))
37
38 #define READ_U32_BE(buf) \
39     (((buf)[0]<<24)|((buf)[1]<<16)|((buf)[2]<<8)|((buf)[3]&0xff))
40
41 #define READ_U16_BE(buf) \
42     (((buf)[0]<<8)|((buf)[1]&0xff))
43
44 /* Define the supported formats here */
45 input_format formats[] = {
46     {wav_id, 12, wav_open, wav_close, "wav", N_("WAV file reader")},
47     {aiff_id, 12, aiff_open, wav_close, "aiff", N_("AIFF/AIFC file reader")},
48 #ifdef HAVE_LIBFLAC
49     {flac_id,     4, flac_open, flac_close, "flac", N_("FLAC file reader")},
50     {oggflac_id, 32, flac_open, flac_close, "ogg", N_("Ogg FLAC file reader")},
51 #endif
52     {NULL, 0, NULL, NULL, NULL, NULL}
53 };
54
55 input_format *open_audio_file(FILE *in, oe_enc_opt *opt)
56 {
57     int j=0;
58     unsigned char *buf=NULL;
59     int buf_size=0, buf_filled=0;
60     int size,ret;
61
62     while(formats[j].id_func)
63     {
64         size = formats[j].id_data_len;
65         if(size >= buf_size)
66         {
67             buf = realloc(buf, size);
68             buf_size = size;
69         }
70
71         if(size > buf_filled)
72         {
73             ret = fread(buf+buf_filled, 1, buf_size-buf_filled, in);
74             buf_filled += ret;
75
76             if(buf_filled < size)
77             { /* File truncated */
78                 j++;
79                 continue;
80             }
81         }
82
83         if(formats[j].id_func(buf, buf_filled))
84         {
85             /* ok, we now have something that can handle the file */
86             if(formats[j].open_func(in, opt, buf, buf_filled)) {
87                 free(buf);
88                 return &formats[j];
89             }
90         }
91         j++;
92     }
93
94     free(buf);
95
96     return NULL;
97 }
98
99 static int seek_forward(FILE *in, unsigned int length)
100 {
101     if(fseek(in, length, SEEK_CUR))
102     {
103         /* Failed. Do it the hard way. */
104         unsigned char buf[1024];
105         unsigned int seek_needed = length;
106         int seeked;
107         while(seek_needed > 0)
108         {
109             seeked = fread(buf, 1, seek_needed>1024?1024:seek_needed, in);
110             if(!seeked)
111                 return 0; /* Couldn't read more, can't read file */
112             else
113                 seek_needed -= seeked;
114         }
115     }
116     return 1;
117 }
118
119
120 static int find_wav_chunk(FILE *in, char *type, unsigned int *len)
121 {
122     unsigned char buf[8];
123
124     while(1)
125     {
126         if(fread(buf,1,8,in) < 8) /* Suck down a chunk specifier */
127         {
128             fprintf(stderr, _("Warning: Unexpected EOF in reading WAV header\n"));
129             return 0; /* EOF before reaching the appropriate chunk */
130         }
131
132         if(memcmp(buf, type, 4))
133         {
134             *len = READ_U32_LE(buf+4);
135             if(!seek_forward(in, *len))
136                 return 0;
137
138             buf[4] = 0;
139             fprintf(stderr, _("Skipping chunk of type \"%s\", length %d\n"), buf, *len);
140         }
141         else
142         {
143             *len = READ_U32_LE(buf+4);
144             return 1;
145         }
146     }
147 }
148
149 static int find_aiff_chunk(FILE *in, char *type, unsigned int *len)
150 {
151     unsigned char buf[8];
152     int restarted = 0;
153
154     while(1)
155     {
156         if(fread(buf,1,8,in) <8)
157         {
158             if(!restarted) {
159                 /* Handle out of order chunks by seeking back to the start
160                  * to retry */
161                 restarted = 1;
162                 fseek(in, 12, SEEK_SET);
163                 continue;
164             }
165             fprintf(stderr, _("Warning: Unexpected EOF in AIFF chunk\n"));
166             return 0;
167         }
168
169         *len = READ_U32_BE(buf+4);
170
171         if(memcmp(buf,type,4))
172         {
173             if((*len) & 0x1)
174                 (*len)++;
175
176             if(!seek_forward(in, *len))
177                 return 0;
178         }
179         else
180             return 1;
181     }
182 }
183
184
185
186 double read_IEEE80(unsigned char *buf)
187 {
188     int s=buf[0]&0xff;
189     int e=((buf[0]&0x7f)<<8)|(buf[1]&0xff);
190     double f=((unsigned long)(buf[2]&0xff)<<24)|
191         ((buf[3]&0xff)<<16)|
192         ((buf[4]&0xff)<<8) |
193          (buf[5]&0xff);
194
195     if(e==32767)
196     {
197         if(buf[2]&0x80)
198             return HUGE_VAL; /* Really NaN, but this won't happen in reality */
199         else
200         {
201             if(s)
202                 return -HUGE_VAL;
203             else
204                 return HUGE_VAL;
205         }
206     }
207
208     f=ldexp(f,32);
209     f+= ((buf[6]&0xff)<<24)|
210         ((buf[7]&0xff)<<16)|
211         ((buf[8]&0xff)<<8) |
212          (buf[9]&0xff);
213
214     return ldexp(f, e-16446);
215 }
216
217 /* AIFF/AIFC support adapted from the old OggSQUISH application */
218 int aiff_id(unsigned char *buf, int len)
219 {
220     if(len<12) return 0; /* Truncated file, probably */
221
222     if(memcmp(buf, "FORM", 4))
223         return 0;
224
225     if(memcmp(buf+8, "AIF",3))
226         return 0;
227
228     if(buf[11]!='C' && buf[11]!='F')
229         return 0;
230
231     return 1;
232 }
233
234 static int aiff_permute_matrix[6][6] = 
235 {
236   {0},              /* 1.0 mono   */
237   {0,1},            /* 2.0 stereo */
238   {0,2,1},          /* 3.0 channel ('wide') stereo */
239   {0,1,2,3},        /* 4.0 discrete quadraphonic (WARN) */
240   {0,2,1,3,4},      /* 5.0 surround (WARN) */
241   {0,1,2,3,4,5},    /* 5.1 surround (WARN)*/
242 };
243
244
245 int aiff_open(FILE *in, oe_enc_opt *opt, unsigned char *buf, int buflen)
246 {
247     int aifc; /* AIFC or AIFF? */
248     unsigned int len;
249     unsigned char *buffer;
250     unsigned char buf2[8];
251     aiff_fmt format;
252     aifffile *aiff = malloc(sizeof(aifffile));
253     int i;
254
255     if(buf[11]=='C')
256         aifc=1;
257     else
258         aifc=0;
259
260     if(!find_aiff_chunk(in, "COMM", &len))
261     {
262         fprintf(stderr, _("Warning: No common chunk found in AIFF file\n"));
263         return 0; /* EOF before COMM chunk */
264     }
265
266     if(len < 18) 
267     {
268         fprintf(stderr, _("Warning: Truncated common chunk in AIFF header\n"));
269         return 0; /* Weird common chunk */
270     }
271
272     buffer = alloca(len);
273
274     if(fread(buffer,1,len,in) < len)
275     {
276         fprintf(stderr, _("Warning: Unexpected EOF in reading AIFF header\n"));
277         return 0;
278     }
279
280     format.channels = READ_U16_BE(buffer);
281     format.totalframes = READ_U32_BE(buffer+2);
282     format.samplesize = READ_U16_BE(buffer+6);
283     format.rate = (int)read_IEEE80(buffer+8);
284
285     aiff->bigendian = 1;
286
287     if(aifc)
288     {
289         if(len < 22)
290         {
291             fprintf(stderr, _("Warning: AIFF-C header truncated.\n"));
292             return 0;
293         }
294
295         if(!memcmp(buffer+18, "NONE", 4)) 
296         {
297             aiff->bigendian = 1;
298         }
299         else if(!memcmp(buffer+18, "sowt", 4)) 
300         {
301             aiff->bigendian = 0;
302         }
303         else
304         {
305             fprintf(stderr, _("Warning: Can't handle compressed AIFF-C (%c%c%c%c)\n"), *(buffer+18), *(buffer+19), *(buffer+20), *(buffer+21));
306             return 0; /* Compressed. Can't handle */
307         }
308     }
309
310     if(!find_aiff_chunk(in, "SSND", &len))
311     {
312         fprintf(stderr, _("Warning: No SSND chunk found in AIFF file\n"));
313         return 0; /* No SSND chunk -> no actual audio */
314     }
315
316     if(len < 8) 
317     {
318         fprintf(stderr, _("Warning: Corrupted SSND chunk in AIFF header\n"));
319         return 0; 
320     }
321
322     if(fread(buf2,1,8, in) < 8)
323     {
324         fprintf(stderr, _("Warning: Unexpected EOF reading AIFF header\n"));
325         return 0;
326     }
327
328     format.offset = READ_U32_BE(buf2);
329     format.blocksize = READ_U32_BE(buf2+4);
330
331     if( format.blocksize == 0 &&
332         (format.samplesize == 16 || format.samplesize == 8))
333     {
334         /* From here on, this is very similar to the wav code. Oh well. */
335         
336         opt->rate = format.rate;
337         opt->channels = format.channels;
338         opt->read_samples = wav_read; /* Similar enough, so we use the same */
339         opt->total_samples_per_channel = format.totalframes;
340
341         aiff->f = in;
342         aiff->samplesread = 0;
343         aiff->channels = format.channels;
344         aiff->samplesize = format.samplesize;
345         aiff->totalsamples = format.totalframes;
346
347         if(aiff->channels>3)
348           fprintf(stderr,"WARNING: AIFF[-C] files with greater than three channels use\n"
349                   "speaker locations incompatable with Vorbis suppound definitions.\n"
350                   "Not performaing channel location mapping.\n");
351
352         opt->readdata = (void *)aiff;
353
354         aiff->channel_permute = malloc(aiff->channels * sizeof(int));
355         if (aiff->channels <= 6)
356             /* Where we know the mappings, use them. */
357             memcpy(aiff->channel_permute, aiff_permute_matrix[aiff->channels-1], 
358                     sizeof(int) * aiff->channels);
359         else
360             /* Use a default 1-1 mapping */
361             for (i=0; i < aiff->channels; i++)
362                 aiff->channel_permute[i] = i;
363
364         seek_forward(in, format.offset); /* Swallow some data */
365         return 1;
366     }
367     else
368     {
369         fprintf(stderr, 
370                 _("Warning: OggEnc does not support this type of AIFF/AIFC file\n"
371                 " Must be 8 or 16 bit PCM.\n"));
372         return 0;
373     }
374 }
375
376
377 int wav_id(unsigned char *buf, int len)
378 {
379     unsigned int flen;
380     
381     if(len<12) return 0; /* Something screwed up */
382
383     if(memcmp(buf, "RIFF", 4))
384         return 0; /* Not wave */
385
386     flen = READ_U32_LE(buf+4); /* We don't use this */
387
388     if(memcmp(buf+8, "WAVE",4))
389         return 0; /* RIFF, but not wave */
390
391     return 1;
392 }
393
394 static int wav_permute_matrix[8][8] = 
395 {
396   {0},              /* 1.0 mono   */
397   {0,1},            /* 2.0 stereo */
398   {0,2,1},          /* 3.0 channel ('wide') stereo */
399   {0,1,2,3},        /* 4.0 discrete quadraphonic */
400   {0,2,1,3,4},      /* 5.0 surround */
401   {0,2,1,4,5,3},    /* 5.1 surround */
402   {0,2,1,4,5,6,3},  /* 6.1 surround */
403   {0,2,1,6,7,4,5,3} /* 7.1 surround (classic theater 8-track) */
404 };
405
406
407 int wav_open(FILE *in, oe_enc_opt *opt, unsigned char *oldbuf, int buflen)
408 {
409     unsigned char buf[40];
410     unsigned int len;
411     int samplesize;
412     wav_fmt format;
413     wavfile *wav = malloc(sizeof(wavfile));
414     int i;
415
416     /* Ok. At this point, we know we have a WAV file. Now we have to detect
417      * whether we support the subtype, and we have to find the actual data
418      * We don't (for the wav reader) need to use the buffer we used to id this
419      * as a wav file (oldbuf)
420      */
421
422     if(!find_wav_chunk(in, "fmt ", &len))
423         return 0; /* EOF */
424
425     if(len < 16) 
426     {
427         fprintf(stderr, _("Warning: Unrecognised format chunk in WAV header\n"));
428         return 0; /* Weird format chunk */
429     }
430
431     /* A common error is to have a format chunk that is not 16, 18 or
432      * 40 bytes in size.  This is incorrect, but not fatal, so we only
433      * warn about it instead of refusing to work with the file.
434      * Please, if you have a program that's creating format chunks of
435      * sizes other than 16 or 18 bytes in size, report a bug to the
436      * author.
437      */
438     if(len!=16 && len!=18 && len!=40)
439         fprintf(stderr, 
440                 _("Warning: INVALID format chunk in wav header.\n"
441                 " Trying to read anyway (may not work)...\n"));
442
443     if(len>40)len=40;
444
445     if(fread(buf,1,len,in) < len)
446     {
447         fprintf(stderr, _("Warning: Unexpected EOF in reading WAV header\n"));
448         return 0;
449     }
450
451     format.format =      READ_U16_LE(buf);
452     format.channels =    READ_U16_LE(buf+2);
453     format.samplerate =  READ_U32_LE(buf+4);
454     format.bytespersec = READ_U32_LE(buf+8);
455     format.align =       READ_U16_LE(buf+12);
456     format.samplesize =  READ_U16_LE(buf+14);
457
458     if(format.format == -2) /* WAVE_FORMAT_EXTENSIBLE */
459     {
460       if(len<40)
461       {
462         fprintf(stderr,"ERROR: Extended WAV format header invalid (too small)\n");
463         return 0;
464       }
465
466       format.mask = READ_U32_LE(buf+20);
467       /* warn the user if the format mask is not a supported/expected type */
468       switch(format.mask){
469       case 1539: /* 4.0 using side surround instead of back */
470         fprintf(stderr,"WARNING: WAV file uses side surround instead of rear for quadraphonic;\n"
471                 "remapping side speakers to rear in encoding.\n");
472         break;
473       case 1551: /* 5.1 using side instead of rear */
474         fprintf(stderr,"WARNING: WAV file uses side surround instead of rear for 5.1;\n"
475                 "remapping side speakers to rear in encoding.\n");
476         break;
477       case 319:  /* 6.1 using rear instead of side */
478         fprintf(stderr,"WARNING: WAV file uses rear surround instead of side for 6.1;\n"
479                 "remapping rear speakers to side in encoding.\n");
480         break;
481       case 255:  /* 7.1 'Widescreen' */
482         fprintf(stderr,"WARNING: WAV file is a 7.1 'Widescreen' channel mapping;\n"
483                 "remapping speakers to Vorbis 7.1 format.\n");
484         break;
485       case 0:    /* default/undeclared */
486       case 1:    /* mono */
487       case 3:    /* stereo */
488       case 51:   /* quad */
489       case 55:   /* 5.0 */
490       case 63:   /* 5.1 */
491       case 1807: /* 6.1 */
492       case 1599: /* 7.1 */
493         break;
494       default:
495         fprintf(stderr,"WARNING: Unknown WAV surround channel mask: %d\n"
496                 "blindly mapping speakers using default SMPTE/ITU ordering.\n",
497                 format.mask);
498         break;
499       }
500       format.format = READ_U16_LE(buf+24);
501     }
502
503     if(!find_wav_chunk(in, "data", &len))
504         return 0; /* EOF */
505
506     if(format.format == 1)
507     {
508         samplesize = format.samplesize/8;
509         opt->read_samples = wav_read;
510     }
511     else if(format.format == 3)
512     {
513         samplesize = 4;
514         opt->read_samples = wav_ieee_read;
515     }
516     else
517     {
518         fprintf(stderr, 
519                 _("ERROR: Wav file is unsupported type (must be standard PCM\n"
520                 " or type 3 floating point PCM\n"));
521         return 0;
522     }
523
524     if(format.align != format.channels * samplesize) {
525         /* This is incorrect according to the spec. Warn loudly, then ignore
526          * this value.
527          */
528         fprintf(stderr, _("Warning: WAV 'block alignment' value is incorrect, "
529                     "ignoring.\n" 
530                     "The software that created this file is incorrect.\n"));
531     }
532
533     if(format.samplesize == samplesize*8 && 
534             (format.samplesize == 24 || format.samplesize == 16 || 
535              format.samplesize == 8 ||
536          (format.samplesize == 32 && format.format == 3)))
537     {
538         /* OK, good - we have the one supported format,
539            now we want to find the size of the file */
540         opt->rate = format.samplerate;
541         opt->channels = format.channels;
542
543         wav->f = in;
544         wav->samplesread = 0;
545         wav->bigendian = 0;
546         wav->channels = format.channels; /* This is in several places. The price
547                                             of trying to abstract stuff. */
548         wav->samplesize = format.samplesize;
549
550         if(len)
551         {
552             opt->total_samples_per_channel = len/(format.channels*samplesize);
553         }
554         else
555         {
556             long pos;
557             pos = ftell(in);
558             if(fseek(in, 0, SEEK_END) == -1)
559             {
560                 opt->total_samples_per_channel = 0; /* Give up */
561             }
562             else
563             {
564                 opt->total_samples_per_channel = (ftell(in) - pos)/
565                     (format.channels*samplesize);
566                 fseek(in,pos, SEEK_SET);
567             }
568         }
569         wav->totalsamples = opt->total_samples_per_channel;
570
571         opt->readdata = (void *)wav;
572
573         wav->channel_permute = malloc(wav->channels * sizeof(int));
574         if (wav->channels <= 8)
575             /* Where we know the mappings, use them. */
576             memcpy(wav->channel_permute, wav_permute_matrix[wav->channels-1], 
577                     sizeof(int) * wav->channels);
578         else
579             /* Use a default 1-1 mapping */
580             for (i=0; i < wav->channels; i++)
581                 wav->channel_permute[i] = i;
582
583         return 1;
584     }
585     else
586     {
587         fprintf(stderr, 
588                 _("ERROR: Wav file is unsupported subformat (must be 8,16, or 24 bit PCM\n"
589                 "or floating point PCM\n"));
590         return 0;
591     }
592 }
593
594 long wav_read(void *in, float **buffer, int samples)
595 {
596     wavfile *f = (wavfile *)in;
597     int sampbyte = f->samplesize / 8;
598     signed char *buf = alloca(samples*sampbyte*f->channels);
599     long bytes_read = fread(buf, 1, samples*sampbyte*f->channels, f->f);
600     int i,j;
601     long realsamples;
602     int *ch_permute = f->channel_permute;
603
604     if(f->totalsamples && f->samplesread + 
605             bytes_read/(sampbyte*f->channels) > f->totalsamples) {
606         bytes_read = sampbyte*f->channels*(f->totalsamples - f->samplesread);
607     }
608
609     realsamples = bytes_read/(sampbyte*f->channels);
610     f->samplesread += realsamples;
611
612     if(f->samplesize==8)
613     {
614         unsigned char *bufu = (unsigned char *)buf;
615         for(i = 0; i < realsamples; i++)
616         {
617             for(j=0; j < f->channels; j++)
618             {
619                 buffer[j][i]=((int)(bufu[i*f->channels + ch_permute[j]])-128)/128.0f;
620             }
621         }
622     }
623     else if(f->samplesize==16)
624     {
625         if(!f->bigendian)
626         {
627             for(i = 0; i < realsamples; i++)
628             {
629                 for(j=0; j < f->channels; j++)
630                 {
631                     buffer[j][i] = ((buf[i*2*f->channels + 2*ch_permute[j] + 1]<<8) |
632                                     (buf[i*2*f->channels + 2*ch_permute[j]] & 0xff))/32768.0f;
633                 }
634             }
635         }
636         else
637         {
638             for(i = 0; i < realsamples; i++)
639             {
640                 for(j=0; j < f->channels; j++)
641                 {
642                     buffer[j][i]=((buf[i*2*f->channels + 2*ch_permute[j]]<<8) |
643                                   (buf[i*2*f->channels + 2*ch_permute[j] + 1] & 0xff))/32768.0f;
644                 }
645             }
646         }
647     }
648     else if(f->samplesize==24) 
649     {
650         if(!f->bigendian) {
651             for(i = 0; i < realsamples; i++)
652             {
653                 for(j=0; j < f->channels; j++) 
654                 {
655                     buffer[j][i] = ((buf[i*3*f->channels + 3*ch_permute[j] + 2] << 16) |
656                       (((unsigned char *)buf)[i*3*f->channels + 3*ch_permute[j] + 1] << 8) |
657                       (((unsigned char *)buf)[i*3*f->channels + 3*ch_permute[j]] & 0xff)) 
658                         / 8388608.0f;
659
660                 }
661             }
662         }
663         else {
664             fprintf(stderr, _("Big endian 24 bit PCM data is not currently "
665                               "supported, aborting.\n"));
666             return 0;
667         }
668     }
669     else {
670         fprintf(stderr, _("Internal error: attempt to read unsupported "
671                           "bitdepth %d\n"), f->samplesize);
672         return 0;
673     }
674
675     return realsamples;
676 }
677
678 long wav_ieee_read(void *in, float **buffer, int samples)
679 {
680     wavfile *f = (wavfile *)in;
681     float *buf = alloca(samples*4*f->channels); /* de-interleave buffer */
682     long bytes_read = fread(buf,1,samples*4*f->channels, f->f);
683     int i,j;
684     long realsamples;
685
686
687     if(f->totalsamples && f->samplesread +
688             bytes_read/(4*f->channels) > f->totalsamples)
689         bytes_read = 4*f->channels*(f->totalsamples - f->samplesread);
690     realsamples = bytes_read/(4*f->channels);
691     f->samplesread += realsamples;
692
693     for(i=0; i < realsamples; i++)
694         for(j=0; j < f->channels; j++)
695             buffer[j][i] = buf[i*f->channels + f->channel_permute[j]];
696
697     return realsamples;
698 }
699
700
701 void wav_close(void *info)
702 {
703     wavfile *f = (wavfile *)info;
704     free(f->channel_permute);
705
706     free(f);
707 }
708
709 int raw_open(FILE *in, oe_enc_opt *opt, unsigned char *buf, int buflen)
710 {
711     wav_fmt format; /* fake wave header ;) */
712     wavfile *wav = malloc(sizeof(wavfile));
713     int i;
714
715     /* construct fake wav header ;) */
716     format.format =      2; 
717     format.channels =    opt->channels;
718     format.samplerate =  opt->rate;
719     format.samplesize =  opt->samplesize;
720     format.bytespersec = opt->channels * opt->rate * opt->samplesize / 8;
721     format.align =       format.bytespersec;
722     wav->f =             in;
723     wav->samplesread =   0;
724     wav->bigendian =     opt->endianness;
725     wav->channels =      format.channels;
726     wav->samplesize =    opt->samplesize;
727     wav->totalsamples =  0;
728     wav->channel_permute = malloc(wav->channels * sizeof(int));
729     for (i=0; i < wav->channels; i++)
730       wav->channel_permute[i] = i;
731
732     opt->read_samples = wav_read;
733     opt->readdata = (void *)wav;
734     opt->total_samples_per_channel = 0; /* raw mode, don't bother */
735     return 1;
736 }
737
738 typedef struct {
739     res_state resampler;
740     audio_read_func real_reader;
741     void *real_readdata;
742     float **bufs;
743     int channels;
744     int bufsize;
745     int done;
746 } resampler;
747
748 static long read_resampled(void *d, float **buffer, int samples)
749 {
750     resampler *rs = d;
751     long in_samples;
752     int out_samples;
753
754     in_samples = res_push_max_input(&rs->resampler, samples);
755     if(in_samples > rs->bufsize)
756         in_samples = rs->bufsize;
757
758     in_samples = rs->real_reader(rs->real_readdata, rs->bufs, in_samples);
759
760     if(in_samples <= 0) {
761         if(!rs->done) {
762             rs->done = 1;
763             out_samples = res_drain(&rs->resampler, buffer);
764             return out_samples;
765         }
766         return 0;
767     }
768
769     out_samples = res_push(&rs->resampler, buffer, (float const **)rs->bufs, in_samples);
770
771     if(out_samples <= 0) {
772         fprintf(stderr, _("BUG: Got zero samples from resampler: your file will be truncated. Please report this.\n"));
773     }
774
775     return out_samples;
776 }
777
778 int setup_resample(oe_enc_opt *opt) {
779     resampler *rs = calloc(1, sizeof(resampler));
780     int c;
781
782     rs->bufsize = 4096; /* Shrug */
783     rs->real_reader = opt->read_samples;
784     rs->real_readdata = opt->readdata;
785     rs->bufs = malloc(sizeof(float *) * opt->channels);
786     rs->channels = opt->channels;
787     rs->done = 0;
788     if(res_init(&rs->resampler, rs->channels, opt->resamplefreq, opt->rate, RES_END))
789     {
790         fprintf(stderr, _("Couldn't initialise resampler\n"));
791         return -1;
792     }
793
794     for(c=0; c < opt->channels; c++)
795         rs->bufs[c] = malloc(sizeof(float) * rs->bufsize);
796
797     opt->read_samples = read_resampled;
798     opt->readdata = rs;
799     if(opt->total_samples_per_channel)
800         opt->total_samples_per_channel = (int)((float)opt->total_samples_per_channel * 
801             ((float)opt->resamplefreq/(float)opt->rate));
802     opt->rate = opt->resamplefreq;
803
804     return 0;
805 }
806
807 void clear_resample(oe_enc_opt *opt) {
808     resampler *rs = opt->readdata;
809     int i;
810
811     opt->read_samples = rs->real_reader;
812     opt->readdata = rs->real_readdata;
813     res_clear(&rs->resampler);
814
815     for(i = 0; i < rs->channels; i++)
816         free(rs->bufs[i]);
817
818     free(rs->bufs);
819
820     free(rs);
821 }
822
823 typedef struct {
824     audio_read_func real_reader;
825     void *real_readdata;
826     int channels;
827     float scale_factor;
828 } scaler;
829
830 static long read_scaler(void *data, float **buffer, int samples) {
831     scaler *d = data;
832     long in_samples = d->real_reader(d->real_readdata, buffer, samples);
833     int i,j;
834
835     for(i=0; i < d->channels; i++) {
836         for(j=0; j < in_samples; j++) {
837             buffer[i][j] *= d->scale_factor;
838         }
839     }
840
841     return in_samples;
842 }
843
844
845 void setup_scaler(oe_enc_opt *opt, float scale) {
846     scaler *d = calloc(1, sizeof(scaler));
847
848     d->real_reader = opt->read_samples;
849     d->real_readdata = opt->readdata;
850
851     opt->read_samples = read_scaler;
852     opt->readdata = d;
853     d->channels = opt->channels;
854     d->scale_factor = scale;
855 }
856
857 void clear_scaler(oe_enc_opt *opt) {
858     scaler *d = opt->readdata;
859
860     opt->read_samples = d->real_reader;
861     opt->readdata = d->real_readdata;
862
863     free(d);
864 }
865
866 typedef struct {
867     audio_read_func real_reader;
868     void *real_readdata;
869     float **bufs;
870 } downmix;
871
872 static long read_downmix(void *data, float **buffer, int samples)
873 {
874     downmix *d = data;
875     long in_samples = d->real_reader(d->real_readdata, d->bufs, samples);
876     int i;
877
878     for(i=0; i < in_samples; i++) {
879         buffer[0][i] = (d->bufs[0][i] + d->bufs[1][i])*0.5f;
880     }
881
882     return in_samples;
883 }
884
885 void setup_downmix(oe_enc_opt *opt) {
886     downmix *d = calloc(1, sizeof(downmix));
887
888     if(opt->channels != 2) {
889         fprintf(stderr, "Internal error! Please report this bug.\n");
890         return;
891     }
892     
893     d->bufs = malloc(2 * sizeof(float *));
894     d->bufs[0] = malloc(4096 * sizeof(float));
895     d->bufs[1] = malloc(4096 * sizeof(float));
896     d->real_reader = opt->read_samples;
897
898     d->real_readdata = opt->readdata;
899
900     opt->read_samples = read_downmix;
901     opt->readdata = d;
902
903     opt->channels = 1;
904 }
905 void clear_downmix(oe_enc_opt *opt) {
906     downmix *d = opt->readdata;
907
908     opt->read_samples = d->real_reader;
909     opt->readdata = d->real_readdata;
910     opt->channels = 2; /* other things in cleanup rely on this */
911
912     free(d->bufs[0]);
913     free(d->bufs[1]);
914     free(d->bufs);
915     free(d);
916 }
917