~ubuntu-branches/debian/sid/vorbis-tools/sid

« back to all changes in this revision

Viewing changes to oggenc/audio.c

  • Committer: Bazaar Package Importer
  • Author(s): Jesus Climent
  • Date: 2005-04-10 09:22:24 UTC
  • mfrom: (2.1.1 warty)
  • Revision ID: james.westby@ubuntu.com-20050410092224-xtukpa3qghghhjje
Tags: 1.0.1-1.3
* Authorized NMU.
* Modified alsa to mention alsa09 (although the device might be nowadays
  alsa, back, since alsa1.0 has been already released). (Closes: #258286)
* Modified the manpage/help message for vorbiscomment to make it a bit more
  userfiendly: Closes: #252531.
* Added oggdec to the long description field, so that it triggers apt-cache
  searches: Closes: #274894.
* Typos in manpages: Closes: #302150.
* Escaped dashes in manpage: Closes: #264365.
* Quiet option is actually with -Q, not -q (Closes: #211289) Reported
  upstream but patched for Debian.
* Change input.wav with inputfile, since we accept flac-formated files:
  Closes: #262509.
* Translation bits:
  * Updated translation hu.po: Closes: #272037.
  * French translation correction: Encodage -> Codage (Closes: #248431).
  * debian/rules: remove .gmo's to avoid clash with uploaded tarball.

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
 ** This program is distributed under the GNU General Public License, version 2.
4
4
 ** A copy of this license is included with this source.
5
5
 **
6
 
 ** Copyright 2000, Michael Smith <msmith@labyrinth.net.au>
 
6
 ** Copyright 2000-2002, Michael Smith <msmith@xiph.org>
7
7
 **
8
8
 ** AIFF/AIFC support from OggSquish, (c) 1994-1996 Monty <xiphmont@xiph.org>
9
9
 **/
16
16
#include <math.h>
17
17
#include "audio.h"
18
18
#include "platform.h"
 
19
#include "i18n.h"
 
20
#include "resample.h"
 
21
 
 
22
#ifdef HAVE_LIBFLAC
 
23
#include "flac.h"
 
24
#endif
19
25
 
20
26
#define WAV_HEADER_SIZE 44
21
27
 
34
40
 
35
41
/* Define the supported formats here */
36
42
input_format formats[] = {
37
 
        {wav_id, 12, wav_open, wav_close, "wav", "WAV file reader"},
38
 
        {aiff_id, 12, aiff_open, wav_close, "aiff", "AIFF/AIFC file reader"},
 
43
        {wav_id, 12, wav_open, wav_close, "wav", N_("WAV file reader")},
 
44
        {aiff_id, 12, aiff_open, wav_close, "aiff", N_("AIFF/AIFC file reader")},
 
45
#ifdef HAVE_LIBFLAC
 
46
        {flac_id,     4, flac_open, flac_close, "flac", N_("FLAC file reader")},
 
47
        {oggflac_id, 32, flac_open, flac_close, "ogg", N_("Ogg FLAC file reader")},
 
48
#endif
39
49
        {NULL, 0, NULL, NULL, NULL, NULL}
40
50
};
41
51
 
55
65
                        buf_size = size;
56
66
                }
57
67
 
58
 
                if(buf_size > buf_filled)
 
68
                if(size > buf_filled)
59
69
                {
60
70
                        ret = fread(buf+buf_filled, 1, buf_size-buf_filled, in);
61
71
                        buf_filled += ret;
62
72
 
63
 
                        if(buf_filled != buf_size)
 
73
                        if(buf_filled < size)
64
74
                        { /* File truncated */
65
 
                                buf_size = buf_filled;
66
75
                                j++;
67
76
                                continue;
68
77
                        }
69
78
                }
70
79
 
71
 
                if(formats[j].id_func(buf, size))
 
80
                if(formats[j].id_func(buf, buf_filled))
72
81
                {
73
82
                        /* ok, we now have something that can handle the file */
74
 
                        if(formats[j].open_func(in, opt, buf, size))
 
83
                        if(formats[j].open_func(in, opt, buf, buf_filled)) {
 
84
                free(buf);
75
85
                                return &formats[j];
 
86
            }
76
87
                }
77
88
                j++;
78
89
        }
79
90
 
 
91
    free(buf);
 
92
 
80
93
        return NULL;
81
94
}
82
95
 
108
121
        {
109
122
                if(fread(buf,1,8,in) < 8) /* Suck down a chunk specifier */
110
123
                {
111
 
                        fprintf(stderr, "Warning: Unexpected EOF in reading WAV header\n");
 
124
                        fprintf(stderr, _("Warning: Unexpected EOF in reading WAV header\n"));
112
125
                        return 0; /* EOF before reaching the appropriate chunk */
113
126
                }
114
127
 
119
132
                                return 0;
120
133
 
121
134
                        buf[4] = 0;
122
 
                        fprintf(stderr, "Skipping chunk of type \"%s\", length %d\n", buf, *len);
 
135
                        fprintf(stderr, _("Skipping chunk of type \"%s\", length %d\n"), buf, *len);
123
136
                }
124
137
                else
125
138
                {
137
150
        {
138
151
                if(fread(buf,1,8,in) <8)
139
152
                {
140
 
                        fprintf(stderr, "Warning: Unexpected EOF in AIFF chunk\n");
 
153
                        fprintf(stderr, _("Warning: Unexpected EOF in AIFF chunk\n"));
141
154
                        return 0;
142
155
                }
143
156
 
222
235
 
223
236
        if(!find_aiff_chunk(in, "COMM", &len))
224
237
        {
225
 
                fprintf(stderr, "Warning: No common chunk found in AIFF file\n");
 
238
                fprintf(stderr, _("Warning: No common chunk found in AIFF file\n"));
226
239
                return 0; /* EOF before COMM chunk */
227
240
        }
228
241
 
229
242
        if(len < 18) 
230
243
        {
231
 
                fprintf(stderr, "Warning: Truncated common chunk in AIFF header\n");
 
244
                fprintf(stderr, _("Warning: Truncated common chunk in AIFF header\n"));
232
245
                return 0; /* Weird common chunk */
233
246
        }
234
247
 
236
249
 
237
250
        if(fread(buffer,1,len,in) < len)
238
251
        {
239
 
                fprintf(stderr, "Warning: Unexpected EOF in reading AIFF header\n");
 
252
                fprintf(stderr, _("Warning: Unexpected EOF in reading AIFF header\n"));
240
253
                return 0;
241
254
        }
242
255
 
245
258
        format.samplesize = READ_U16_BE(buffer+6);
246
259
        format.rate = (int)read_IEEE80(buffer+8);
247
260
 
 
261
    aiff->bigendian = 1;
 
262
 
248
263
        if(aifc)
249
264
        {
250
265
                if(len < 22)
251
266
                {
252
 
                        fprintf(stderr, "Warning: AIFF-C header truncated.\n");
 
267
                        fprintf(stderr, _("Warning: AIFF-C header truncated.\n"));
253
268
                        return 0;
254
269
                }
255
 
                else if(memcmp(buffer+18, "NONE", 4)) 
256
 
                {
257
 
                        fprintf(stderr, "Warning: Can't handle compressed AIFF-C\n");
 
270
 
 
271
                if(!memcmp(buffer+18, "NONE", 4)) 
 
272
                {
 
273
                        aiff->bigendian = 1;
 
274
                }
 
275
                else if(!memcmp(buffer+18, "sowt", 4)) 
 
276
                {
 
277
                        aiff->bigendian = 0;
 
278
                }
 
279
                else
 
280
                {
 
281
                        fprintf(stderr, _("Warning: Can't handle compressed AIFF-C (%c%c%c%c)\n"), *(buffer+18), *(buffer+19), *(buffer+20), *(buffer+21));
258
282
                        return 0; /* Compressed. Can't handle */
259
283
                }
260
284
        }
261
285
 
262
286
        if(!find_aiff_chunk(in, "SSND", &len))
263
287
        {
264
 
                fprintf(stderr, "Warning: No SSND chunk found in AIFF file\n");
 
288
                fprintf(stderr, _("Warning: No SSND chunk found in AIFF file\n"));
265
289
                return 0; /* No SSND chunk -> no actual audio */
266
290
        }
267
291
 
268
292
        if(len < 8) 
269
293
        {
270
 
                fprintf(stderr, "Warning: Corrupted SSND chunk in AIFF header\n");
 
294
                fprintf(stderr, _("Warning: Corrupted SSND chunk in AIFF header\n"));
271
295
                return 0; 
272
296
        }
273
297
 
274
298
        if(fread(buf2,1,8, in) < 8)
275
299
        {
276
 
                fprintf(stderr, "Warning: Unexpected EOF reading AIFF header\n");
 
300
                fprintf(stderr, _("Warning: Unexpected EOF reading AIFF header\n"));
277
301
                return 0;
278
302
        }
279
303
 
285
309
        {
286
310
                /* From here on, this is very similar to the wav code. Oh well. */
287
311
                
288
 
                if(format.rate != 44100 && format.rate != 48000)
289
 
                        fprintf(stderr, "Warning: Vorbis is not currently tuned for this input (%.3f kHz).\n"
290
 
                                " At other than 44.1/48 kHz quality will be degraded.\n",
291
 
                                (float)format.rate * 1.0e-3);
292
 
 
293
312
                opt->rate = format.rate;
294
313
                opt->channels = format.channels;
295
314
                opt->read_samples = wav_read; /* Similar enough, so we use the same */
300
319
                aiff->channels = format.channels;
301
320
                aiff->samplesize = format.samplesize;
302
321
                aiff->totalsamples = format.totalframes;
303
 
                aiff->bigendian = 1;
304
322
 
305
323
                opt->readdata = (void *)aiff;
306
324
 
310
328
        else
311
329
        {
312
330
                fprintf(stderr, 
313
 
                                "Warning: OggEnc does not support this type of AIFF/AIFC file\n"
314
 
                                " Must be 8 or 16 bit PCM.\n");
 
331
                                _("Warning: OggEnc does not support this type of AIFF/AIFC file\n"
 
332
                                " Must be 8, 16, or 24 bit PCM.\n"));
315
333
                return 0;
316
334
        }
317
335
}
353
371
 
354
372
        if(len < 16) 
355
373
        {
356
 
                fprintf(stderr, "Warning: Unrecognised format chunk in WAV header\n");
 
374
                fprintf(stderr, _("Warning: Unrecognised format chunk in WAV header\n"));
357
375
                return 0; /* Weird format chunk */
358
376
        }
359
377
 
365
383
         */
366
384
        if(len!=16 && len!=18)
367
385
                fprintf(stderr, 
368
 
                                "Warning: INVALID format chunk in wav header.\n"
369
 
                                " Trying to read anyway (may not work)...\n");
 
386
                                _("Warning: INVALID format chunk in wav header.\n"
 
387
                                " Trying to read anyway (may not work)...\n"));
370
388
 
371
389
        if(fread(buf,1,16,in) < 16)
372
390
        {
373
 
                fprintf(stderr, "Warning: Unexpected EOF in reading WAV header\n");
 
391
                fprintf(stderr, _("Warning: Unexpected EOF in reading WAV header\n"));
374
392
                return 0;
375
393
        }
376
394
 
402
420
        else
403
421
        {
404
422
                fprintf(stderr, 
405
 
                                "ERROR: Wav file is unsupported type (must be standard PCM\n"
406
 
                                " or type 3 floating point PCM\n");
 
423
                                _("ERROR: Wav file is unsupported type (must be standard PCM\n"
 
424
                                " or type 3 floating point PCM\n"));
407
425
                return 0;
408
426
        }
409
427
 
410
428
 
411
429
 
412
430
        if( format.align == format.channels*samplesize &&
413
 
                        format.samplesize == samplesize*8)
 
431
                        format.samplesize == samplesize*8 && 
 
432
                (format.samplesize == 24 || format.samplesize == 16 || 
 
433
             format.samplesize == 8 ||
 
434
             (format.samplesize == 32 && format.format == 3)))
414
435
        {
415
 
                if(format.samplerate != 44100 && format.samplerate != 48000)
416
 
                        fprintf(stderr, "Warning: Vorbis is not currently tuned for this input (%.3f kHz).\n"
417
 
                                        " At other than 44.1/48 kHz quality will be degraded.\n",
418
 
                                        (float)format.samplerate * 1.0e-3);
419
 
 
420
436
                /* OK, good - we have the one supported format,
421
437
                   now we want to find the size of the file */
422
438
                opt->rate = format.samplerate;
456
472
        else
457
473
        {
458
474
                fprintf(stderr, 
459
 
                                "ERROR: Wav file is unsupported subformat (must be 16 bit PCM\n"
460
 
                                "or floating point PCM\n");
 
475
                                _("ERROR: Wav file is unsupported subformat (must be 8,16, or 24 bit PCM\n"
 
476
                                "or floating point PCM\n"));
461
477
                return 0;
462
478
        }
463
479
}
472
488
        long realsamples;
473
489
 
474
490
        if(f->totalsamples && f->samplesread + 
475
 
                        bytes_read/(sampbyte*f->channels) > f->totalsamples) 
 
491
                        bytes_read/(sampbyte*f->channels) > f->totalsamples) {
476
492
                bytes_read = sampbyte*f->channels*(f->totalsamples - f->samplesread);
 
493
    }
477
494
 
478
495
        realsamples = bytes_read/(sampbyte*f->channels);
479
496
        f->samplesread += realsamples;
489
506
                        }
490
507
                }
491
508
        }
492
 
        else
 
509
        else if(f->samplesize==16)
493
510
        {
494
511
                if(!f->bigendian)
495
512
                {
514
531
                        }
515
532
                }
516
533
        }
 
534
    else if(f->samplesize==24) 
 
535
    {
 
536
        if(!f->bigendian) {
 
537
            for(i = 0; i < realsamples; i++)
 
538
            {
 
539
                for(j=0; j < f->channels; j++) 
 
540
                {
 
541
                    buffer[j][i] = ((buf[i*3*f->channels + 3*j + 2] << 16) |
 
542
                      (((unsigned char *)buf)[i*3*f->channels + 3*j + 1] << 8) |
 
543
                      (((unsigned char *)buf)[i*3*f->channels + 3*j] & 0xff)) 
 
544
                        / 8388608.0f;
 
545
 
 
546
                }
 
547
            }
 
548
        }
 
549
        else {
 
550
            fprintf(stderr, _("Big endian 24 bit PCM data is not currently "
 
551
                              "supported, aborting.\n"));
 
552
            return 0;
 
553
        }
 
554
    }
 
555
    else {
 
556
        fprintf(stderr, _("Internal error: attempt to read unsupported "
 
557
                          "bitdepth %d\n"), f->samplesize);
 
558
        return 0;
 
559
    }
517
560
 
518
561
        return realsamples;
519
562
}
553
596
        wav_fmt format; /* fake wave header ;) */
554
597
        wavfile *wav = malloc(sizeof(wavfile));
555
598
 
556
 
        if(opt->rate != 44100 && opt->rate != 48000)
557
 
                fprintf(stderr, "Warning: Vorbis is not currently tuned for this input (%.3f kHz).\n"
558
 
                                " At other than 44.1/48 kHz quality will be significantly degraded.\n",
559
 
                                (float)opt->rate * 1.0e-3);
560
 
 
561
599
        /* construct fake wav header ;) */
562
600
        format.format =      2; 
563
601
        format.channels =    opt->channels;
567
605
        format.align =       format.bytespersec;
568
606
        wav->f =             in;
569
607
        wav->samplesread =   0;
570
 
        wav->bigendian =     0;
 
608
        wav->bigendian =     opt->endianness;
571
609
        wav->channels =      format.channels;
572
610
        wav->samplesize =    opt->samplesize;
 
611
    wav->totalsamples =  0;
573
612
 
574
613
        opt->read_samples = wav_read;
575
614
        opt->readdata = (void *)wav;
576
615
        opt->total_samples_per_channel = 0; /* raw mode, don't bother */
577
616
        return 1;
578
617
}
 
618
 
 
619
typedef struct {
 
620
    res_state resampler;
 
621
    audio_read_func real_reader;
 
622
    void *real_readdata;
 
623
    float **bufs;
 
624
    int channels;
 
625
    int bufsize;
 
626
    int done;
 
627
} resampler;
 
628
 
 
629
static long read_resampled(void *d, float **buffer, int samples)
 
630
{
 
631
    resampler *rs = d;
 
632
    long in_samples;
 
633
    int out_samples;
 
634
 
 
635
    in_samples = res_push_max_input(&rs->resampler, samples);
 
636
    if(in_samples > rs->bufsize)
 
637
        in_samples = rs->bufsize;
 
638
 
 
639
    in_samples = rs->real_reader(rs->real_readdata, rs->bufs, in_samples);
 
640
 
 
641
    if(in_samples <= 0) {
 
642
        if(!rs->done) {
 
643
            rs->done = 1;
 
644
            out_samples = res_drain(&rs->resampler, buffer);
 
645
            return out_samples;
 
646
        }
 
647
        return 0;
 
648
    }
 
649
 
 
650
    out_samples = res_push(&rs->resampler, buffer, (float const **)rs->bufs, in_samples);
 
651
 
 
652
    if(out_samples <= 0) {
 
653
        fprintf(stderr, _("BUG: Got zero samples from resampler: your file will be truncated. Please report this.\n"));
 
654
    }
 
655
 
 
656
    return out_samples;
 
657
}
 
658
 
 
659
int setup_resample(oe_enc_opt *opt) {
 
660
    resampler *rs = calloc(1, sizeof(resampler));
 
661
    int c;
 
662
 
 
663
    rs->bufsize = 4096; /* Shrug */
 
664
    rs->real_reader = opt->read_samples;
 
665
    rs->real_readdata = opt->readdata;
 
666
    rs->bufs = malloc(sizeof(float *) * opt->channels);
 
667
    rs->channels = opt->channels;
 
668
    rs->done = 0;
 
669
    if(res_init(&rs->resampler, rs->channels, opt->resamplefreq, opt->rate, RES_END))
 
670
    {
 
671
        fprintf(stderr, _("Couldn't initialise resampler\n"));
 
672
        return -1;
 
673
    }
 
674
 
 
675
    for(c=0; c < opt->channels; c++)
 
676
        rs->bufs[c] = malloc(sizeof(float) * rs->bufsize);
 
677
 
 
678
    opt->read_samples = read_resampled;
 
679
    opt->readdata = rs;
 
680
    if(opt->total_samples_per_channel)
 
681
        opt->total_samples_per_channel = (int)((float)opt->total_samples_per_channel * 
 
682
            ((float)opt->resamplefreq/(float)opt->rate));
 
683
    opt->rate = opt->resamplefreq;
 
684
 
 
685
    return 0;
 
686
}
 
687
 
 
688
void clear_resample(oe_enc_opt *opt) {
 
689
    resampler *rs = opt->readdata;
 
690
    int i;
 
691
 
 
692
    opt->read_samples = rs->real_reader;
 
693
    opt->readdata = rs->real_readdata;
 
694
    res_clear(&rs->resampler);
 
695
 
 
696
    for(i = 0; i < rs->channels; i++)
 
697
        free(rs->bufs[i]);
 
698
 
 
699
    free(rs->bufs);
 
700
 
 
701
    free(rs);
 
702
}
 
703
 
 
704
typedef struct {
 
705
    audio_read_func real_reader;
 
706
    void *real_readdata;
 
707
    int channels;
 
708
    float scale_factor;
 
709
} scaler;
 
710
 
 
711
static long read_scaler(void *data, float **buffer, int samples) {
 
712
    scaler *d = data;
 
713
    long in_samples = d->real_reader(d->real_readdata, buffer, samples);
 
714
    int i,j;
 
715
 
 
716
    for(i=0; i < d->channels; i++) {
 
717
        for(j=0; j < in_samples; j++) {
 
718
            buffer[i][j] *= d->scale_factor;
 
719
        }
 
720
    }
 
721
 
 
722
    return in_samples;
 
723
}
 
724
 
 
725
 
 
726
void setup_scaler(oe_enc_opt *opt, float scale) {
 
727
    scaler *d = calloc(1, sizeof(scaler));
 
728
 
 
729
    d->real_reader = opt->read_samples;
 
730
    d->real_readdata = opt->readdata;
 
731
 
 
732
    opt->read_samples = read_scaler;
 
733
    opt->readdata = d;
 
734
    d->channels = opt->channels;
 
735
    d->scale_factor = scale;
 
736
}
 
737
 
 
738
void clear_scaler(oe_enc_opt *opt) {
 
739
    scaler *d = opt->readdata;
 
740
 
 
741
    opt->read_samples = d->real_reader;
 
742
    opt->readdata = d->real_readdata;
 
743
 
 
744
    free(d);
 
745
}
 
746
 
 
747
typedef struct {
 
748
    audio_read_func real_reader;
 
749
    void *real_readdata;
 
750
    float **bufs;
 
751
} downmix;
 
752
 
 
753
static long read_downmix(void *data, float **buffer, int samples)
 
754
{
 
755
    downmix *d = data;
 
756
    long in_samples = d->real_reader(d->real_readdata, d->bufs, samples);
 
757
    int i;
 
758
 
 
759
    for(i=0; i < in_samples; i++) {
 
760
        buffer[0][i] = (d->bufs[0][i] + d->bufs[1][i])*0.5f;
 
761
    }
 
762
 
 
763
    return in_samples;
 
764
}
 
765
 
 
766
void setup_downmix(oe_enc_opt *opt) {
 
767
    downmix *d = calloc(1, sizeof(downmix));
 
768
 
 
769
    if(opt->channels != 2) {
 
770
        fprintf(stderr, "Internal error! Please report this bug.\n");
 
771
        return;
 
772
    }
 
773
    
 
774
    d->bufs = malloc(2 * sizeof(float *));
 
775
    d->bufs[0] = malloc(4096 * sizeof(float));
 
776
    d->bufs[1] = malloc(4096 * sizeof(float));
 
777
    d->real_reader = opt->read_samples;
 
778
 
 
779
    d->real_readdata = opt->readdata;
 
780
 
 
781
    opt->read_samples = read_downmix;
 
782
    opt->readdata = d;
 
783
 
 
784
    opt->channels = 1;
 
785
}
 
786
void clear_downmix(oe_enc_opt *opt) {
 
787
    downmix *d = opt->readdata;
 
788
 
 
789
    opt->read_samples = d->real_reader;
 
790
    opt->readdata = d->real_readdata;
 
791
    opt->channels = 2; /* other things in cleanup rely on this */
 
792
 
 
793
    free(d->bufs[0]);
 
794
    free(d->bufs[1]);
 
795
    free(d->bufs);
 
796
    free(d);
 
797
}
 
798