source: golgotha/src/i4/loaders/mp3_load.cc @ 80

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