1 /*____________________________________________________________________________
2 
3         FreeAmp - The Free MP3 Player
4 
5         MP3 Decoder originally Copyright (C) 1995-1997 Xing Technology
6         Corp.  http://www.xingtech.com
7 
8         Portions Copyright (C) 1998-1999 EMusic.com
9 
10         This program is free software; you can redistribute it and/or modify
11         it under the terms of the GNU General Public License as published by
12         the Free Software Foundation; either version 2 of the License, or
13         (at your option) any later version.
14 
15         This program is distributed in the hope that it will be useful,
16         but WITHOUT ANY WARRANTY; without even the implied warranty of
17         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18         GNU General Public License for more details.
19 
20         You should have received a copy of the GNU General Public License
21         along with this program; if not, write to the Free Software
22         Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 
24         $Id: towave.c,v 1.8 2001/01/05 06:40:07 robert Exp $
25 ____________________________________________________________________________*/
26 
27 /* ------------------------------------------------------------------------
28 
29       NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
30 
31         This file exists for reference only. It is not actually used
32         in the FreeAmp project. There is no need to mess with this
33         file. There is no need to flatten the beavers, either.
34 
35       NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
36 */
37 /*---- towave.c --------------------------------------------
38   32 bit version only
39 
40 decode mpeg Layer I/II/III file using portable ANSI C decoder,
41 output to pcm wave file.
42 
43 mod 8/19/98 decode 22 sf bands
44 
45 mod 5/14/98  allow mpeg25 (dec8 not supported for mpeg25 samp rate)
46 
47 mod 3/4/98 bs_trigger  bs_bufbytes  made signed, unsigned may
48             not terminate properly.  Also extra test in bs_fill.
49 
50 mod 8/6/96 add 8 bit output to standard decoder
51 
52 ver 1.4 mods 7/18/96 32 bit and add asm option
53 
54 mods 6/29/95  allow MS wave file for u-law.  bugfix u-law table dec8.c
55 
56 mods 2/95 add sample rate reduction, freq_limit and conversions.
57           add _decode8 for 8Ks output, 16bit 8bit, u-law output.
58           add additional control parameters to init.
59           add _info function
60 
61 mod 5/12/95 add quick window cwinq.c
62 
63 mod 5/19/95 change from stream io to handle io
64 
65 mod 11/16/95 add Layer I
66 
67 mod 1/5/95   integer overflow mod iup.c
68 
69 ver 1.3
70 mod 2/5/96   portability mods
71              drop Tom and Gloria pcm file types
72 
73 ver 2.0
74 mod 1/7/97   Layer 3 (float mpeg-1 only)
75     2/6/97   Layer 3 MPEG-2
76 
77 ver 3.01     Layer III bugfix crc problem 8/18/97
78 ver 3.02     Layer III fix wannabe.mp3 problem 10/9/97
79 ver 3.03     allow mpeg 2.5  5/14/98
80 
81 Decoder functions for _decode8 are defined in dec8.c.  Useage
82 is same as regular decoder.
83 
84 Towave illustrates use of decoder.  Towave converts
85 mpeg audio files to 16 bit (short) pcm.  Default pcm file
86 format is wave. Other formats can be accommodated by
87 adding alternative write_pcm_header and write_pcm_tailer
88 functions.  The functions kbhit and getch used in towave.c
89 may not port to other systems.
90 
91 The decoder handles all mpeg1 and mpeg2 Layer I/II  bitstreams.
92 
93 For compatability with the asm decoder and future C versions,
94 source code users are discouraged from making modifications
95 to the decoder proper.  MS Windows applications can use wrapper
96 functions in a separate module if decoder functions need to
97 be exported.
98 
99 NOTE additional control parameters.
100 
101 mod 8/6/96 standard decoder adds 8 bit output
102 
103 decode8 (8Ks output) convert_code:
104    convert_code = 4*bit_code + chan_code
105        bit_code:   1 = 16 bit linear pcm
106                    2 =  8 bit (unsigned) linear pcm
107                    3 = u-law (8 bits unsigned)
108        chan_code:  0 = convert two chan to mono
109                    1 = convert two chan to mono
110                    2 = convert two chan to left chan
111                    3 = convert two chan to right chan
112 
113 decode (standard decoder) convert_code:
114              0 = two chan output
115              1 = convert two chan to mono
116              2 = convert two chan to left chan
117              3 = convert two chan to right chan
118      or with 8 = 8 bit output
119           (other bits ignored)
120 
121 decode (standard decoder) reduction_code:
122              0 = full sample rate output
123              1 = half rate
124              2 = quarter rate
125 
126 -----------------------------------------------------------*/
127 #include <stdlib.h>
128 #include <stdio.h>
129 #include <float.h>
130 #include <math.h>
131 #include <string.h>
132 #include <errno.h>
133 #include <unistd.h>
134 #ifdef WIN32
135 #include <io.h>
136 #endif
137 #include <fcntl.h>              /* file open flags */
138 #include <sys/types.h>          /* someone wants for port */
139 #include <sys/stat.h>           /* forward slash for portability */
140 #include "mhead.h"              /* mpeg header structure, decode protos */
141 
142 #define NEED_KBHIT
143 
144 #include "port.h"
145 
146 /* time test Pentium only */
147 //#define TIME_TEST
148 
149 static char default_file[] = "TEST.MP3";
150 static char default_outfile[] = "TEST.WAV";
151 
152 /*---- timing test ---*/
153 #ifdef TIME_TEST
154 static double tot_cycles;
155 static int tot_cycles_n;
156 unsigned int set_clock(void);
157 unsigned int get_clock(void);
158 extern unsigned int global_cycles;
159 
160 #endif
161 
162 float     equalizer[32] = {
163    1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
164    1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
165    1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
166    1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
167 };
168 int       enableEQ = 0;
169 float     EQ_gain_adjust = 1.0;
170 
171 /*********  bitstream buffer */
172 #define BS_BUFBYTES 60000U
173 static unsigned char *bs_buffer = NULL;
174 static unsigned char *bs_bufptr;
175 static int bs_trigger;
176 static int bs_bufbytes;
177 static int handle = -1;
178 
179 /********************** */
180 
181 /********  pcm buffer ********/
182 #define PCM_BUFBYTES  60000U
183 static char *pcm_buffer;
184 static unsigned int pcm_bufbytes;
185 static unsigned int pcm_trigger = (PCM_BUFBYTES - 2500 * sizeof(short));
186 static int handout = -1;
187 
188 /****************************/
189 static int bs_fill();
190 
191 static int out_help();
192 static int out_mpeg_info(MPEG_HEAD * h, int bitrate_arg);
193 int       ff_decode(char *filename,
194 
195                     char *fileout,
196                     int reduction_code,
197                     int convert_code,
198                     int decode8_flag, int freq_limit, int integer_decode);
199 int       cvt_to_wave_test();
200 int       write_pcm_header_wave(int handout,
201                                 int samprate, int channels, int bits, int type);
202 int       write_pcm_tailer_wave(int handout, unsigned int pcm_bytes);
203 
204 /*------------------------------------------*/
205 int
main(int argc,char * argv[])206 main(int argc, char *argv[])
207 {
208    int       i, k;
209    char     *filename;
210    char     *fileout;
211    int       convert_code;
212    int       reduction_code;
213    int       freq_limit;
214    int       integer_decode;
215    int       decode8_flag;      /* decode to 8KHz */
216 
217    printf("\n  file-file MPEG Layer I/II/III audio decode v3.04/32"
218           "\n Copyright 1995-98 Xing Technology Corp."
219           "\n"
220           "\n useage: towave mpeg_file pcm_file -Cconvert_code -Rreduction_code"
221           "\n                 -I -D8 -HELP ");
222 
223 /****** process command line args */
224    filename = default_file;
225    fileout = default_outfile;
226    convert_code = 0;
227    reduction_code = 0;
228    freq_limit = 24000;
229    integer_decode = 0;
230    decode8_flag = 0;            /* decode to 8KHz */
231    for (k = 0, i = 1; i < argc; i++)
232    {
233       if (argv[i][0] != '-')
234       {
235          if (k == 0)
236             filename = argv[i];
237          if (k == 1)
238             fileout = argv[i];
239          k++;
240          continue;
241       }
242       switch (argv[i][1])
243       {
244       case 'h':
245       case 'H':
246          out_help();
247          return 0;
248       case 'c':
249       case 'C':
250          convert_code = atoi(argv[i] + 2);
251          break;
252       case 'r':
253       case 'R':
254          reduction_code = atoi(argv[i] + 2);
255          break;
256       case 'f':
257       case 'F':
258          freq_limit = atoi(argv[i] + 2);
259          break;
260       case 'i':
261       case 'I':
262          integer_decode = 1;
263          break;
264       case 'd':
265       case 'D':
266          if (atoi(argv[i] + 2) == 8)
267             decode8_flag = 1;
268          break;
269       }
270    }
271 
272    printf("\n  <press any key to stop decoder>");
273 
274 /******** decode *********/
275    ff_decode(filename, fileout,
276              reduction_code, convert_code, decode8_flag,
277              freq_limit, integer_decode);
278 /*************************/
279 
280 /*---- timing test --------*/
281 #ifdef TIME_TEST
282    if (tot_cycles_n)
283    {
284       // ms per frame
285       tot_cycles = (1.0 / 266000.0) * tot_cycles / tot_cycles_n;
286       if (tot_cycles > 5.0)
287          printf("\n ave frame time ms = %8.1lf", tot_cycles);
288       else
289          printf("\n ave frame time ms = %8.2lf", tot_cycles);
290    }
291 #endif
292 
293    printf("\n");
294    return 0;
295 }
296 
297 /*-------------------------------------------------------------*/
298 static int
out_help()299 out_help()
300 {
301 
302    printf("\n"
303           "\n -D8 option decode8 (8Ks output) convert_code:"
304           "\n    convert_code = 4*bit_code + chan_code"
305           "\n        bit_code:   1 = 16 bit linear pcm"
306           "\n                    2 =  8 bit (unsigned) linear pcm"
307           "\n                    3 = u-law (8 bits unsigned)"
308           "\n        chan_code:  0 = convert two chan to mono"
309           "\n                    1 = convert two chan to mono"
310           "\n                    2 = convert two chan to left chan"
311           "\n                    3 = convert two chan to right chan"
312           "\n decode (standard decoder) convert_code:"
313           "\n              0 = two chan output"
314           "\n              1 = convert two chan to mono"
315           "\n              2 = convert two chan to left chan"
316           "\n              3 = convert two chan to right chan"
317           "\n              (higher bits ignored)"
318           "\n decode (standard decoder) reduction_code:"
319           "\n              0 = full sample rate output"
320           "\n              1 = half rate"
321           "\n              2 = quarter rate"
322           "\n -I  option selects integer decoder");
323 
324    return 1;
325 }
326 
327 /*-------------------------------------------------------------*/
328 int
ff_decode(char * filename,char * fileout,int reduction_code,int convert_code,int decode8_flag,int freq_limit,int integer)329 ff_decode(char *filename, char *fileout,
330           int reduction_code, int convert_code, int decode8_flag,
331           int freq_limit, int integer)
332 {
333    int       framebytes;
334    int       u;
335    MPEG_HEAD head;
336    MPEG      m;
337    unsigned int nwrite;
338    IN_OUT    x;
339    int       in_bytes, out_bytes;
340    DEC_INFO  decinfo;
341    int       bitrate;
342 
343 /*------------------------------------------*/
344 /*   typedef struct
345    {
346       int (*decode_init) (MPEG_HEAD * h, int framebytes_arg,
347                           int reduction_code, int transform_code,
348                           int convert_code, int freq_limit);
349       void (*decode_info) (DEC_INFO * info);
350         IN_OUT(*decode) (unsigned char *bs, short *pcm);
351    }
352    AUDIO;
353    static AUDIO audio;
354    static AUDIO audio_table[2][2] =
355    {
356       {
357          {audio_decode_init, audio_decode_info, audio_decode},
358          {audio_decode8_init, audio_decode8_info, audio_decode8},
359       },
360       {
361          {i_audio_decode_init, i_audio_decode_info, i_audio_decode},
362          {audio_decode8_init, audio_decode8_info, audio_decode8},
363       }
364    };
365 */
366 /*------------------------------------------*/
367 
368 /*-----------------------*/
369    printf("\nMPEG input file: %s", filename);
370    printf("\n    output file: %s", fileout);
371 /*-----------------------*/
372 /*-----select decoder --------------*/
373 /*   if (decode8_flag && (convert_code >= 4))
374       audio = audio_table[integer & 1][1];
375    else
376       audio = audio_table[integer & 1][0]; */
377 /*-----------------------*/
378 
379    mpeg_init(&m, 1);
380    in_bytes = out_bytes = 0;
381 /*-----------------------*/
382    handout = -1;
383    pcm_buffer = NULL;
384    pcm_bufbytes = 0;
385 /*-----------------------*/
386    bs_buffer = NULL;
387    handle = -1;
388    bs_bufbytes = 0;
389    bs_bufptr = bs_buffer;
390    bs_trigger = 2500;
391 /*--- test for valid cvt_to_wave compile ---*/
392    if (cvt_to_wave_test() != 0)
393    {
394       printf("\n INVALID CVT_TO_WAVE COMPILE");
395       goto abort;
396    }
397 /*------ open mpeg file --------*/
398    handle = open(filename, O_RDONLY | O_BINARY);
399    if (handle < 0)
400    {
401       printf("\n CANNOT_OPEN_INPUT_FILE\n");
402       goto abort;
403    }
404 /*--- allocate bs buffer ----*/
405    bs_buffer = malloc(BS_BUFBYTES);
406    if (bs_buffer == NULL)
407    {
408       printf("\n CANNOT_ALLOCATE_BUFFER\n");
409       goto abort;
410    }
411 /*--- fill bs buffer ----*/
412    if (!bs_fill())
413       goto abort;
414 /*---- parse mpeg header  -------*/
415    framebytes = head_info2(bs_buffer, bs_bufbytes, &head, &bitrate);
416    if (framebytes == 0)
417    {
418       printf("\n BAD OR UNSUPPORTED MPEG FILE\n");
419       goto abort;
420    }
421 /*--- display mpeg info --*/
422    out_mpeg_info(&head, bitrate);
423 
424 /*---- create pcm file ------*/
425    handout =
426       open(fileout, O_RDWR | O_BINARY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
427    handout = open(fileout, O_WRONLY | O_BINARY);
428 /*
429    {
430        int fd;
431        int channels = 2;
432        int play_precision = 16;
433        int play_stereo = channels-1;
434        int play_sample_rate = 44100; //info->samples_per_second;
435        int junkvar = 0;
436        int flags;
437        if ((fd = open("/dev/dsp", O_WRONLY | O_SYNC, 0)) < 0) {
438            if (errno == EBUSY) {
439                printf("Audio device busy!\n");
440                exit(1);
441            } else {
442                printf("Can't open /dev/dsp for writing");
443                exit(1);
444            }
445        }
446 
447        if ((flags = fcntl(fd,F_GETFL,0)) < 0) {
448            printf("fcntl F_GETFL on /dev/audio failed");
449            exit(1);
450        }
451        flags &= ~O_NDELAY;
452 
453        if (fcntl(fd, F_SETFL, flags) < 0) {
454            printf("fcntl F_SETFL on /dev/audio failed");
455            exit(1);
456        }
457 
458        handout = fd;
459 
460 
461        if (handout < 0) {
462            printf ("Internal error, LinuxObuffer::handout has to be initialized\nby LinuxObuffer::class_suitable()!\n");
463            exit (1);
464        }
465 
466        // configure the device:
467        //int play_precision = 16;
468        //int play_stereo = channels-1;
469        //int play_sample_rate = info->samples_per_second;
470        //int junkvar = 0;
471        if (ioctl(handout, SNDCTL_DSP_RESET, &junkvar) == -1) {
472            printf("hosed during ioctl reset\n");
473            exit(1);
474        }
475 
476        if(ioctl(handout, SNDCTL_DSP_SAMPLESIZE, &play_precision) == -1) {
477            printf("config of samplesize failed");
478            exit(1);
479        }
480        if(ioctl(handout, SNDCTL_DSP_STEREO, &play_stereo) == -1) {
481            printf("config of stereo failed");
482            exit(1);
483        }
484        if (ioctl(handout, SNDCTL_DSP_SPEED, &play_sample_rate) == -1) {
485            printf("config of speed failed");
486            exit(1);
487        }
488 
489    }
490 */
491    if (handout < 0)
492    {
493       printf("\n CANNOT CREATE OUTPUT FILE\n");
494       goto abort;
495    }
496 /*---- allocate pcm buffer --------*/
497    pcm_buffer = malloc(PCM_BUFBYTES);
498    if (pcm_buffer == NULL)
499    {
500       printf("\n CANNOT ALLOCATE PCM BUFFER\n");
501       goto abort;
502    }
503 
504 /*---- init decoder -------*/
505    if (!audio_decode_init(&m, &head, framebytes,
506                           reduction_code, 0, convert_code, freq_limit))
507    {
508       printf("\n DECODER INIT FAIL \n");
509       goto abort;
510    }
511 /*---- get info -------*/
512    audio_decode_info(&m, &decinfo);
513 /*---- info display -------*/
514    printf("\n output samprate = %6ld", decinfo.samprate);
515    printf("\n output channels = %6d", decinfo.channels);
516    printf("\n output bits     = %6d", decinfo.bits);
517    printf("\n output type     = %6d", decinfo.type);
518 
519 /*---- write pcm header -------*/
520    if (!write_pcm_header_wave(handout,
521                               decinfo.samprate, decinfo.channels, decinfo.bits,
522                               decinfo.type))
523    {
524       printf("\n FILE WRITE ERROR\n");
525       goto abort;
526    }
527 
528 /*--- init wave converter ---*/
529    cvt_to_wave_init(decinfo.bits);
530 
531    printf("\n");
532 /*----- DECODE -----*/
533 
534    for (u = 0;;)
535    {
536       if (!bs_fill())
537          break;
538       if (bs_bufbytes < framebytes)
539          break;                 /* end of file */
540 #ifdef TIME_TEST
541       set_clock();
542 #endif
543       x = audio_decode(&m, bs_bufptr, (short *) (pcm_buffer + pcm_bufbytes));
544 #ifdef TIME_TEST
545       get_clock();
546       tot_cycles += global_cycles;
547       tot_cycles_n++;
548 #endif
549       if (x.in_bytes <= 0)
550       {
551          printf("\n BAD SYNC IN MPEG FILE\n");
552          break;
553       }
554       bs_bufptr += x.in_bytes;
555       bs_bufbytes -= x.in_bytes;
556       pcm_bufbytes += x.out_bytes;
557       u++;
558       if (pcm_bufbytes > pcm_trigger)
559       {
560          pcm_bufbytes = cvt_to_wave(pcm_buffer, pcm_bufbytes);
561          do
562          {
563             nwrite = write(handout, pcm_buffer, pcm_bufbytes);
564             usleep(10000);
565          }
566          while (errno == EAGAIN);
567          if (nwrite != pcm_bufbytes)
568          {
569             printf("\n FILE WRITE ERROR\n");
570             break;
571          }
572          out_bytes += pcm_bufbytes;
573          pcm_bufbytes = 0;
574       }
575       if (kbhit())
576          break;
577       in_bytes += x.in_bytes;
578       if ((u & 63) == 1)
579          printf("\r frames %6ld   bytes in %6ld    bytes out %6ld",
580                 u, in_bytes, out_bytes);
581    }
582 /*---------------*/
583 
584    if (pcm_bufbytes > 0)
585    {
586       pcm_bufbytes = cvt_to_wave(pcm_buffer, pcm_bufbytes);
587       nwrite = write(handout, pcm_buffer, pcm_bufbytes);
588       if (nwrite != pcm_bufbytes)
589       {
590          printf("\n FILE WRITE ERROR\n");
591       }
592       out_bytes += pcm_bufbytes;
593       pcm_bufbytes = 0;
594    }
595    printf("\n frames %6ld   bytes in %6ld    bytes out %6ld",
596           u, in_bytes, out_bytes);
597 
598 /*---- write pcm tailer -------*/
599    write_pcm_tailer_wave(handout, out_bytes);
600 
601    printf("\n    output file: %s", fileout);
602 
603  abort:
604    mpeg_cleanup(&m);
605    close(handle);
606    close(handout);
607    free(bs_buffer);
608    free(pcm_buffer);
609    while (kbhit())
610       getch();                  /* purge key board */
611    return 1;
612 }
613 
614 /*-------------------------------------------------------------*/
615 static int
bs_fill()616 bs_fill()
617 {
618    unsigned int nread;
619 
620    if (bs_bufbytes < 0)
621       bs_bufbytes = 0;          // signed var could be negative
622 
623    if (bs_bufbytes < bs_trigger)
624    {
625       memmove(bs_buffer, bs_bufptr, bs_bufbytes);
626       nread = read(handle, bs_buffer + bs_bufbytes, BS_BUFBYTES - bs_bufbytes);
627       if ((nread + 1) == 0)
628       {
629 /*-- test for -1 = error --*/
630          bs_trigger = 0;
631          printf("\n FILE_READ_ERROR\n");
632          return 0;
633       }
634       bs_bufbytes += nread;
635       bs_bufptr = bs_buffer;
636    }
637 
638    return 1;
639 }
640 
641 /*------------------------------------------------------------------*/
642 static int
out_mpeg_info(MPEG_HEAD * h,int bitrate_arg)643 out_mpeg_info(MPEG_HEAD * h, int bitrate_arg)   /* info only */
644 {
645    int       bitrate;
646    int       samprate;
647    static char *Layer_msg[] = { "INVALID", "III", "II", "I" };
648    static char *mode_msg[] = { "STEREO", "JOINT", "DUAL", "MONO" };
649    static int sr_table[8] = { 22050L, 24000L, 16000L, 1L,
650       44100L, 48000L, 32000L, 1L
651    };
652 
653    bitrate = bitrate_arg / 1000;
654    printf("\n Layer %s ", Layer_msg[h->option]);
655 
656    printf("  %s ", mode_msg[h->mode]);
657    samprate = sr_table[4 * h->id + h->sr_index];
658    if ((h->sync & 1) == 0)
659       samprate = samprate / 2;  // mpeg25
660 
661    printf(" %d ", samprate);
662    printf("  %dKb ", bitrate);
663    if ((h->mode == 1) && (h->option != 1))
664       printf("  %d stereo bands ", 4 + 4 * h->mode_ext);
665    if (h->prot == 0)
666       printf(" (CRC)");
667 
668    return 0;
669 }
670 
671 /*------------------------------------------------------------------*/
672 int
dummy()673 dummy()
674 {
675    return 0;
676 }
677