source: golgotha/src/i4/loaders/mp3/mpg123.cc @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 11 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 10.1 KB
Line 
1/********************************************************************** <BR>
2  This file is part of Crack dot Com's free source code release of
3  Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
4  information about compiling & licensing issues visit this URL</a>
5  <PRE> If that doesn't help, contact Jonathan Clark at
6  golgotha_source@usa.net (Subject should have "GOLG" in it)
7***********************************************************************/
8
9/*
10 * Mpeg Layer audio decoder (see version.h for version number)
11 * ------------------------
12 * copyright (c) 1995,1996,1997 by Michael Hipp, All rights reserved.
13 * See also 'README' !
14 *
15 * Moved all staticly initialized variables to top and added init_variables()
16 * so I can restart this monster.
17 *
18 */
19
20#include <stdlib.h>
21#include <sys/types.h>
22
23/* #define SET_PRIO */
24
25#include "loaders/mp3/mpg123.hh"
26#include "loaders/mp3/getlopt.hh"
27
28#include "loaders/mp3/version.hh"
29
30extern int mp3_endfile;
31
32static long rates[3][3] = {
33  { 32000,44100,48000 } ,
34  { 16000,22050,24000 } ,
35  {  8000,11025,12000 }
36};
37
38struct flags flags = { 0 , 0 };
39
40int supported_rates = 0;
41
42int outmode = DECODE_AUDIO;
43
44char *listname = NULL;
45long outscale  = 32768;
46int checkrange = FALSE;
47int tryresync  = TRUE;
48int quiet      = FALSE;
49int verbose    = 0;
50int doublespeed= 0;
51int halfspeed  = 0;
52int change_always = 1;
53int force_8bit = 0;
54int force_frequency = -1;
55int force_mono = 0;
56long numframes = -1;
57long startFrame= 0;
58int usebuffer  = 0;
59int buffer_fd[2];
60int buffer_pid;
61
62static struct frame fr;
63static struct audio_info_struct ai;
64#define FRAMEBUFUNIT (18 * 64 * 4)
65
66static int init_output_done = FALSE;
67
68static FILE *listfile = NULL;
69
70static void *synth_funcs[2][2][3][2] = {
71  { { { synth_1to1 , synth_1to1_mono2stereo } ,
72      { synth_2to1 , synth_2to1_mono2stereo } ,
73      { synth_4to1 , synth_4to1_mono2stereo } } ,
74    { { synth_1to1_8bit , synth_1to1_8bit_mono2stereo } ,
75      { synth_2to1_8bit , synth_2to1_8bit_mono2stereo } ,
76      { synth_4to1_8bit , synth_4to1_8bit_mono2stereo } } } ,
77  { { { synth_1to1_mono , synth_1to1_mono } ,
78      { synth_2to1_mono , synth_2to1_mono } ,
79      { synth_4to1_mono , synth_4to1_mono } } ,
80    { { synth_1to1_8bit_mono , synth_1to1_8bit_mono } ,
81      { synth_2to1_8bit_mono , synth_2to1_8bit_mono } ,
82      { synth_4to1_8bit_mono , synth_4to1_8bit_mono } } }
83};
84
85void init_mpg123(void)
86{
87
88  rates[0][0] = 32000;
89  rates[0][1] = 44100;
90  rates[0][2] = 48000;
91  rates[1][0] = 16000;
92  rates[1][1] = 22050;
93  rates[1][2] = 24000;
94  rates[2][0] = 8000;
95  rates[2][1] = 11025;
96  rates[2][2] = 12000;
97
98  flags.equalizer = 0;
99  flags.aggressive = 0;
100
101  supported_rates = 0;
102
103  outmode = DECODE_AUDIO;
104
105  listname = NULL;
106  outscale  = 32768;
107  checkrange = FALSE;
108  tryresync  = TRUE;
109  quiet      = FALSE;
110  verbose    = 0;
111  doublespeed= 0;
112  halfspeed  = 0;
113  change_always = 1;
114  force_8bit = 0;
115  /*    force_frequency = -1; */
116  force_mono = 1;
117  numframes = -1;
118  startFrame= 0;
119  usebuffer  = 0;
120
121  init_output_done = FALSE;
122
123  listfile = NULL;
124
125}
126
127void audio_info_struct_init(struct audio_info_struct *ai)
128{
129  ai->rate = -1;
130  ai->gain = -1;
131  ai->output = -1;
132  ai->device = NULL;
133  ai->channels = -1;
134  ai->format = -1;
135}
136
137void print_rheader(struct frame *fr);
138
139void init_output(void)
140{
141
142  if (init_output_done)
143    return;
144  init_output_done = TRUE;
145  if (!(pcm_sample = (unsigned char *) malloc(audiobufsize * 2))) {
146    perror ("malloc()");
147    exit (1);
148  }
149
150}
151
152char *get_next_file (int argc, char *argv[])
153{
154  static char line[1024];
155
156  if (listname || listfile) {
157    if (!listfile) {
158      if (!*listname || !strcmp(listname, "-")) {
159        listfile = stdin;
160        listname = NULL;
161      }
162      else if (!(listfile = fopen(listname, "rb"))) {
163        perror (listname);
164        exit (1);
165      }
166    }
167    do {
168      if (fgets(line, 1023, listfile)) {
169        line[strcspn(line, "\t\n\r")] = '\0';
170        if (line[0]=='\0' || line[0]=='#')
171          continue;
172        return (line);
173      }
174      else {
175        if (*listname)
176          fclose (listfile);
177        listname = NULL;
178        listfile = NULL;
179      }
180    } while (listfile);
181  }
182
183  if (loptind < argc)
184    return (argv[loptind++]);
185  return (NULL);
186}
187
188void set_synth (char *arg)
189{
190  if (*arg == '2') {
191    fr.down_sample = 1;
192  }
193  else {
194    fr.down_sample = 2;
195  }
196}
197
198#ifdef VARMODESUPPORT
199void set_varmode (char *arg)
200{
201  audiobufsize = ((audiobufsize >> 1) + 63) & 0xffffc0;
202}
203#endif
204
205void set_verbose (char *arg)
206{
207  verbose++;
208}
209
210topt opts[] = {
211  {'k', "skip",        GLO_ARG | GLO_NUM,  0, &startFrame, 0},
212  {'a', "audiodevice", GLO_ARG | GLO_CHAR, 0, &ai.device,  0},
213  {'2', "2to1",        0,          set_synth, 0,           0},
214  {'4', "4to1",        0,          set_synth, 0,           0},
215  {'t', "test",        0,                  0, &outmode, DECODE_TEST},
216  {'s', "stdout",      0,                  0, &outmode, DECODE_STDOUT},
217  {'c', "check",       0,                  0, &checkrange, TRUE},
218  {'v', "verbose",     0,        set_verbose, 0,           0},
219  {'q', "quiet",       0,                  0, &quiet,      TRUE},
220  {'y', "resync",      0,                  0, &tryresync,  FALSE},
221  {'0', "single0",     0,                  0, &fr.single,  0},
222  {0,   "left",        0,                  0, &fr.single,  0},
223  {'1', "single1",     0,                  0, &fr.single,  1},
224  {0,   "right",       0,                  0, &fr.single,  1},
225  {'m', "singlemix",   0,                  0, &fr.single,  3},
226  {0,   "mix",         0,                  0, &fr.single,  3},
227  {'g', "gain",        GLO_ARG | GLO_NUM,  0, &ai.gain,    0},
228  {'r', "rate",        GLO_ARG | GLO_NUM,  0, &force_frequency,  0},
229  {0,   "8bit",        0,                  0, &force_8bit, 1},
230  {'f', "scale",       GLO_ARG | GLO_NUM,  0, &outscale,   0},
231  {'n', "frames",      GLO_ARG | GLO_NUM,  0, &numframes,  0},
232#ifdef VARMODESUPPORT
233  {'v', "var",         0,        set_varmode, &varmode,    TRUE},
234#endif
235  {'b', "buffer",      GLO_ARG | GLO_NUM,  0, &usebuffer,  0},
236  {'d', "doublespeed", GLO_ARG | GLO_NUM,  0, &doublespeed,0},
237  {'h', "halfspeed",   GLO_ARG | GLO_NUM,  0, &halfspeed,  0},
238  {'@', "list",        GLO_ARG | GLO_CHAR, 0, &listname,   0},
239  {0,   "equalizer",    0,                              0, &flags.equalizer,1},
240  {0,   "aggressive",   0,                              0, &flags.aggressive,2},
241  {0, 0, 0, 0, 0, 0}
242};
243
244/*
245 *   Change the playback sample rate.
246 */
247void reset_audio_samplerate(void)
248{
249}
250
251/*
252 * play a frame read read_frame();
253 * (re)initialize audio if necessary.
254 */
255void play_frame(int init,struct frame *fr)
256{
257  int clip;
258
259  if((fr->header_change && change_always) || init) {
260    int reset_audio = 0;
261
262    if(force_frequency < 0) {
263      if(ai.rate != freqs[fr->sampling_frequency]>>(fr->down_sample)) {
264        ai.rate = freqs[fr->sampling_frequency]>>(fr->down_sample);
265        reset_audio = 1;
266      }
267    }
268    else if(ai.rate != force_frequency) {
269      ai.rate = force_frequency;
270      reset_audio = 1;
271    }
272    init_output();
273    if(reset_audio) {
274      reset_audio_samplerate();
275    }
276  }
277
278  if (fr->error_protection) {
279    getbits(16); /* crc */
280  }
281
282  clip = (fr->do_layer)(fr,outmode,&ai);
283
284  /*
285    if(clip > 0 && checkrange)
286    fprintf(stderr,"%d samples clipped\n", clip);
287    */
288}
289
290void set_synth_functions(struct frame *fr)
291{
292
293  *((void **)(&fr->synth)) = synth_funcs[force_mono][force_8bit][fr->down_sample][0];
294  *((void **)(&fr->synth_mono)) = synth_funcs[force_mono][force_8bit][fr->down_sample][1];
295  fr->block_size = 128 >> (force_mono+force_8bit+fr->down_sample);
296
297  if(force_8bit) {
298    ai.format = AUDIO_FORMAT_ULAW_8;
299    make_conv16to8_table(ai.format);
300  }
301}
302
303int mpg123_main(int argc, char *argv[])
304{
305  int result;
306  long frameNum = 0;
307  char *fname;
308  int init;
309
310  extern void init_mpg123(void);
311  extern void init_common(void);
312  extern void init_decode(void);
313  extern void init_decode_2to1(void);
314  extern void init_decode_4to1(void);
315  extern void init_getlopt(void);
316  extern void show_progress(void);
317
318  init_mpg123();
319  init_common();
320  init_decode();
321  init_decode_2to1();
322  init_decode_4to1();
323  /*            init_decode_i386(); */
324  init_getlopt();
325
326  fr.single = -1; /* both channels */
327  fr.synth = synth_1to1;
328  fr.down_sample = 0;
329
330  ai.format = AUDIO_FORMAT_SIGNED_16;
331  ai.gain = ai.rate = ai.output = -1;
332  ai.device = NULL;
333  ai.channels = 2;
334
335  (prgName = strrchr(argv[0], '/')) ? prgName++ : (prgName = argv[0]);
336
337  while ((result = getlopt(argc, argv, opts))) ;
338
339  if(fr.single >= 0)
340    force_mono = 1;
341  if(force_mono) {
342    if(fr.single < 0)
343      fr.single = 3;
344    ai.channels = 1;
345  }
346
347  {
348    int fmts;
349    int i,j;
350
351    struct audio_info_struct ai;
352
353    audio_info_struct_init(&ai);
354    fmts = AUDIO_FORMAT_SIGNED_16;
355
356    supported_rates = 0;
357    for(i=0;i<3;i++) {
358      for(j=0;j<3;j++) {
359        ai.rate = rates[i][j];
360        /* allow about 2% difference */
361        if( ((rates[i][j]*98) < (ai.rate*100)) &&
362           ((rates[i][j]*102) > (ai.rate*100)) )
363          supported_rates |= 1<<(i*3+j);
364      }
365    }
366
367    if(!force_8bit && !(fmts & AUDIO_FORMAT_SIGNED_16))
368      force_8bit = 1;
369
370    if(force_8bit && !(fmts & AUDIO_FORMAT_ULAW_8)) {
371      exit(1);
372    }
373  }
374
375
376  set_synth_functions(&fr);
377
378  make_decode_tables(outscale);
379  init_layer2(); /* inits also shared tables with layer1 */
380  init_layer3(fr.down_sample);
381
382  while ((fname = get_next_file(argc, argv)))
383  {
384    if(!*fname || !strcmp(fname, "-"))
385      fname = NULL;
386     
387    read_frame_init();
388
389    init = 1;
390    for(frameNum=0;ftell(filept)!=mp3_endfile && read_frame(&fr) && numframes ;frameNum++) {
391      if(frameNum < startFrame || (doublespeed && (frameNum % doublespeed))) {
392        if(fr.lay == 3)
393          set_pointer(512);
394        continue;
395      }
396
397      show_progress();
398
399      numframes--;
400      play_frame(init,&fr);
401      init = 0;
402
403    }
404
405  }
406  audio_flush(outmode, &ai);
407  free (pcm_sample);
408  return 0;
409
410}
411
412
Note: See TracBrowser for help on using the repository browser.