source: golgotha/src/i4/loaders/mp3/common.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: 14.0 KB
RevLine 
[80]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#include <ctype.h>
10#include <stdlib.h>
11#include <signal.h>
12#include "loaders/mp3/mpg123.hh"
13#include "loaders/mp3/tables.hh"
14#include "file/file.hh"
15
16/* max = 1728 */
17#define MAXFRAMESIZE 1792
18
19#define SKIP_JUNK 1
20
21int tabsel_123[2][3][16] = {
22  { {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,},
23    {0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,},
24    {0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,} },
25
26  { {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,},
27    {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,},
28    {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,} }
29};
30
31long freqs[7] = { 44100, 48000, 32000, 22050, 24000, 16000 , 11025 };
32
33static int bitindex;
34static unsigned char *wordpointer;
35
36static int fsize=0,fsizeold=0,ssize;
37static unsigned char bsspace[2][MAXFRAMESIZE+512]; /* MAXFRAMESIZE */
38static unsigned char *bsbuf=bsspace[1],*bsbufold;
39static int bsnum=0;
40
41extern i4_file_class *mp3_out, *mp3_in;
42
43struct ibuf {
44  struct ibuf *next;
45  struct ibuf *prev;
46  unsigned char *buf;
47  unsigned char *pnt;
48  int len;
49  /* skip,time stamp */
50};
51
52struct ibuf ibufs[2];
53struct ibuf *cibuf;
54int ibufnum=0;
55
56unsigned char *pcm_sample;
57int pcm_point = 0;
58int audiobufsize = AUDIOBUFSIZE;
59
60#ifdef VARMODESUPPORT
61/*
62         *   This is a dirty hack!  It might burn your PC and kill your cat!
63         *   When in "loaders/mp3/varmode", specially formatted layer-3 mpeg files arhe
64         *   expected as input -- it will NOT work with standard mpeg files.
65         *   The reason for this:
66         *   Varmode mpeg files enable my own GUI player to perform fast
67         *   forward and backward functions, and to jump to an arbitrary
68         *   timestamp position within the file.  This would be possible
69         *   with standard mpeg files, too, but it would be a lot harder to
70         *   implement.
71         *   A filter for converting standard mpeg to varmode mpeg is
72         *   available on request, but it's really not useful on its own.
73         *
74         *   Oliver Fromme  <oliver.fromme@heim3.tu-clausthal.de>
75         *   Mon Mar 24 00:04:24 MET 1997
76         */
77int varmode = FALSE;
78int playlimit;
79#endif
80
81
82static unsigned long oldhead = 0;
83static unsigned long firsthead=0;
84
85static int halfphase = 0;
86
87static char *lastdir = NULL;
88
89void init_common(void)
90{
91#ifdef VARMODESUPPORT
92  varmode = FALSE;
93#endif
94  pcm_point = 0;
95  audiobufsize = AUDIOBUFSIZE;
96  ibufnum=0;
97  fsize=0;
98  fsizeold=0;
99  bsbuf=bsspace[1];
100  bsnum=0;
101  oldhead = 0;
102  firsthead = 0;
103  halfphase = 0;
104  lastdir = NULL;
105}
106
107static void get_II_stuff(struct frame *fr)
108{
109  static int translate[3][2][16] =
110  { { { 0,2,2,2,2,2,2,0,0,0,1,1,1,1,1,0 } ,
111      { 0,2,2,0,0,0,1,1,1,1,1,1,1,1,1,0 } } ,
112    { { 0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0 } ,
113      { 0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0 } } ,
114    { { 0,3,3,3,3,3,3,0,0,0,1,1,1,1,1,0 } ,
115      { 0,3,3,0,0,0,1,1,1,1,1,1,1,1,1,0 } } };
116
117  int table,sblim;
118  static struct al_table *tables[5] =
119  { alloc_0, alloc_1, alloc_2, alloc_3 , alloc_4 };
120  static int sblims[5] = { 27 , 30 , 8, 12 , 30 };
121
122  if(fr->lsf)
123    table = 4;
124  else
125    table = translate[fr->sampling_frequency][2-fr->stereo][fr->bitrate_index];
126  sblim = sblims[table];
127
128  fr->alloc = tables[table];
129  fr->II_sblimit = sblim;
130}
131
132void audio_flush(int outmode, struct audio_info_struct *ai)
133{
134  if (pcm_point)
135  {
136    mp3_out->write(pcm_sample, pcm_point);
137    pcm_point = 0;
138  }
139}
140
141void read_frame_init (void)
142{
143  oldhead = 0;
144  firsthead = 0;
145}
146
147#define HDRCMPMASK 0xfffffd00
148#if 0
149#define HDRCMPMASK 0xfffffdft
150#endif
151
152/*
153 * HACK,HACK,HACK
154 * step back <num> frames
155 */
156int back_frame(struct frame *fr,int num)
157{
158  long bytes;
159  unsigned char buf[4];
160  unsigned long newhead;
161
162  if(!firsthead)
163    return 0;
164
165  bytes = (fsize+8)*(num+2);
166
167  if(mp3_in->seek(mp3_in->tell()-bytes)<0)
168    return -1;
169
170  if(mp3_in->read(buf,4)!=4)
171    return -1;
172
173  newhead = (buf[0]<<24) + (buf[1]<<16) + (buf[2]<<8) + buf[3];
174       
175  while( (newhead & HDRCMPMASK) != (firsthead & HDRCMPMASK) ) {
176    if(mp3_in->read(buf,1)!=1)
177      return -1;
178    newhead <<= 8;
179    newhead |= buf[0];
180    newhead &= 0xffffffff;
181  }
182
183  if (mp3_in->seek(mp3_in->tell()-4)<0)
184    return -1;
185       
186  read_frame(fr);
187  read_frame(fr);
188
189  if(fr->lay == 3) {
190    set_pointer(512);
191  }
192
193  return 0;
194}
195
196int head_read(unsigned char *hbuf,unsigned long *newhead)
197
198  if (mp3_in->read(hbuf, 4)!=4)
199    return FALSE;
200
201  *newhead = ((unsigned long) hbuf[0] << 24) |
202    ((unsigned long) hbuf[1] << 16) |
203    ((unsigned long) hbuf[2] << 8)  |
204    (unsigned long) hbuf[3];
205
206  return TRUE;
207}
208
209int head_check(unsigned long newhead)
210{
211  if( (newhead & 0xffe00000) != 0xffe00000)
212    return FALSE;
213  if(!((newhead>>17)&3))
214    return FALSE;
215  if( ((newhead>>12)&0xf) == 0xf)
216    return FALSE;
217  if( ((newhead>>10)&0x3) == 0x3 )
218    return FALSE;
219  return TRUE;
220}
221
222
223int read_frame(struct frame *fr)
224{
225  static unsigned long newhead;
226
227  static unsigned char ssave[34];
228  unsigned char hbuf[8];
229  static int framesize;
230  int l;
231  int try_c = 0;
232
233  if (halfspeed)
234    if (halfphase--) {
235      bitindex = 0;
236      wordpointer = (unsigned char *) bsbuf;
237      if (fr->lay == 3)
238        memcpy (bsbuf, ssave, ssize);
239      return 1;
240    }
241    else
242      halfphase = halfspeed - 1;
243
244#ifdef VARMODESUPPORT
245  if (varmode) {
246    if (mp3_in->read(hbuf,8)!=8)
247      return 0;
248  }
249  else
250#endif
251
252    read_again:
253  if(!head_read(hbuf,&newhead))
254    return FALSE;
255
256  if(oldhead != newhead || !oldhead)
257  {
258    fr->header_change = 1;
259
260  init_resync:
261
262#ifdef SKIP_JUNK
263    if(!firsthead && !head_check(newhead) ) {
264      int i;
265
266      /* I even saw RIFF headers at the beginning of MPEG streams ;( */
267
268      if(newhead == ('R'<<24)+('I'<<16)+('F'<<8)+'F') {
269        char buf[40];
270        mp3_in->read(buf,68);
271        goto read_again;
272      }
273      /* search in 32 bit steps through the first 2K */
274      for(i=0;i<512;i++) {
275        if(!head_read(hbuf,&newhead))
276          return 0;
277        if(head_check(newhead))
278          break;
279      }
280      if(i==512) {
281        /* step in byte steps through next 2K */
282        for(i=0;i<2048;i++) {
283          memmove (&hbuf[0], &hbuf[1], 3);
284          if(mp3_in->read(hbuf+3,1) != 1)
285            return 0;
286          newhead <<= 8;
287          newhead |= hbuf[3];
288          newhead &= 0xffffffff;
289          if(head_check(newhead))
290            break;
291        }
292        if(i == 2048) {
293          return 0;
294        }
295      }
296      /*
297       * should we check, whether a new frame starts at the next
298       * expected position? (some kind of read ahead)
299       * We could implement this easily, at least for files.
300       */
301    }
302#endif
303
304    if( (newhead & 0xffe00000) != 0xffe00000) {
305      if (tryresync) {
306        /* Read more bytes until we find something that looks
307           reasonably like a valid header.  This is not a
308           perfect strategy, but it should get us back on the
309           track within a short time (and hopefully without
310           too much distortion in the audio output).  */
311        do {
312          try_c++;
313          memmove (&hbuf[0], &hbuf[1], 7);
314#ifdef VARMODESUPPORT
315          if (mp3_in->read(&hbuf[varmode?7:3],1) != 1)
316#else
317            if (mp3_in->read(&hbuf[3],1) != 1)
318#endif
319              return 0;
320
321          /* This is faster than combining newhead from scratch */
322          newhead = ((newhead << 8) | hbuf[3]) & 0xffffffff;
323
324          if (!oldhead)
325            goto init_resync;       /* "considered harmful", eh? */
326
327        } while ((newhead & HDRCMPMASK) != (oldhead & HDRCMPMASK)
328                 && (newhead & HDRCMPMASK) != (firsthead & HDRCMPMASK));
329      }
330      else
331        return (0);
332    }
333    if (!firsthead)
334      firsthead = newhead;
335
336    if( newhead & (1<<20) ) {
337      fr->lsf = (newhead & (1<<19)) ? 0x0 : 0x1;
338      fr->mpeg25 = 0;
339    }
340    else {
341      fr->lsf = 1;
342      fr->mpeg25 = 1;
343    }
344   
345    if (!tryresync || !oldhead) {
346      /* If "tryresync" is true, assume that certain
347         parameters do not change within the stream! */
348      fr->lay = 4-((newhead>>17)&3);
349      fr->bitrate_index = ((newhead>>12)&0xf);
350      if( ((newhead>>10)&0x3) == 0x3) {
351        exit(1);
352      }
353      if(fr->mpeg25)
354        fr->sampling_frequency = 6;
355      else
356        fr->sampling_frequency = ((newhead>>10)&0x3) + (fr->lsf*3);
357      fr->error_protection = ((newhead>>16)&0x1)^0x1;
358    }
359
360    fr->padding   = ((newhead>>9)&0x1);
361    fr->extension = ((newhead>>8)&0x1);
362    fr->mode      = ((newhead>>6)&0x3);
363    fr->mode_ext  = ((newhead>>4)&0x3);
364    fr->copyright = ((newhead>>3)&0x1);
365    fr->original  = ((newhead>>2)&0x1);
366    fr->emphasis  = newhead & 0x3;
367
368    fr->stereo    = (fr->mode == MPG_MD_MONO) ? 1 : 2;
369
370    oldhead = newhead;
371
372    if(!fr->bitrate_index)
373    {
374      return (0);
375    }
376
377    switch(fr->lay)
378    {
379      case 1:
380        fr->do_layer = do_layer1;
381#ifdef VARMODESUPPORT
382        if (varmode) {
383          return (0);
384        }
385#endif
386        fr->jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ?
387          (fr->mode_ext<<2)+4 : 32;
388        framesize  = (long) tabsel_123[fr->lsf][0][fr->bitrate_index] * 12000;
389        framesize /= freqs[fr->sampling_frequency];
390        framesize  = ((framesize+fr->padding)<<2)-4;
391        break;
392      case 2:
393        fr->do_layer = do_layer2;
394#ifdef VARMODESUPPORT
395        if (varmode) {
396          return (0);
397        }
398#endif
399        get_II_stuff(fr);
400        fr->jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ?
401          (fr->mode_ext<<2)+4 : fr->II_sblimit;
402        framesize = (long) tabsel_123[fr->lsf][1][fr->bitrate_index] * 144000;
403        framesize /= freqs[fr->sampling_frequency];
404        framesize += fr->padding - 4;
405        break;
406      case 3:
407        fr->do_layer = do_layer3;
408        if(fr->lsf)
409          ssize = (fr->stereo == 1) ? 9 : 17;
410        else
411          ssize = (fr->stereo == 1) ? 17 : 32;
412        if(fr->error_protection)
413          ssize += 2;
414#ifdef VARMODESUPPORT
415        if (varmode)
416          playlimit = ((unsigned int) hbuf[6] << 8) | (unsigned int) hbuf[7];
417        framesize = ssize +
418          (((unsigned int) hbuf[4] << 8) | (unsigned int) hbuf[5]);
419        else {
420#endif
421          framesize  = (long) tabsel_123[fr->lsf][2][fr->bitrate_index] * 144000;
422          framesize /= freqs[fr->sampling_frequency]<<(fr->lsf);
423          framesize = framesize + fr->padding - 4;
424#ifdef VARMODESUPPORT
425        }
426#endif
427        break;
428      default:
429        return (0);
430    }
431  }
432  else
433    fr->header_change = 0;
434
435  fsizeold=fsize;       /* for Layer3 */
436  bsbufold = bsbuf;     
437  bsbuf = bsspace[bsnum]+512;
438  bsnum = (bsnum + 1) & 1;
439
440  fsize = framesize;
441 
442  if( (l=mp3_in->read(bsbuf,fsize)) != fsize)
443  {
444    if(l <= 0)
445      return 0;
446    memset(bsbuf+l,0,fsize-l);
447  }
448
449  if (halfspeed && fr->lay == 3)
450    memcpy (ssave, bsbuf, ssize);
451
452  bitindex = 0;
453  wordpointer = (unsigned char *) bsbuf;
454
455  return 1;
456}
457
458/*
459 *   Allocate space for a new string containing the first
460 *   "num" characters of "src".  The resulting string is
461 *   always zero-terminated.  Returns NULL if malloc fails.
462 */
463
464#if 1
465char *strndup (const char *src, int num)
466{
467  char *dst;
468
469  if (!(dst = (char *) malloc(num+1)))
470    return (NULL);
471  dst[num] = '\0';
472  return (strncpy(dst, src, num));
473}
474#endif
475
476/*
477 *   Split "path" into directory and filename components.
478 *
479 *   Return value is 0 if no directory was specified (i.e.
480 *   "path" does not contain a '/'), OR if the directory
481 *   is the same as on the previous call to this function.
482 *
483 *   Return value is 1 if a directory was specified AND it
484 *   is different from the previous one (if any).
485 */
486
487int split_dir_file (const char *path, char **dname, char **fname)
488{
489  char *slashpos;
490
491  if ((slashpos = strrchr(path, '/'))) {
492    *fname = slashpos + 1;
493    *dname = strndup(path, 1 + slashpos - path);
494    if (lastdir && !strcmp(lastdir, *dname)) {
495      /***   same as previous directory   ***/
496      free (*dname);
497      *dname = lastdir;
498      return 0;
499    }
500    else {
501      /***   different directory   ***/
502      if (lastdir)
503        free (lastdir);
504      lastdir = *dname;
505      return 1;
506    }
507  }
508  else {
509    /***   no directory specified   ***/
510    if (lastdir) {
511      free (lastdir);
512      lastdir = NULL;
513    };
514    *dname = NULL;
515    *fname = (char *)path;
516    return 0;
517  }
518}
519
520unsigned int getbits(int number_of_bits)
521{
522  unsigned long rval;
523
524  if(!number_of_bits)
525    return 0;
526
527  {
528    rval = wordpointer[0];
529    rval <<= 8;
530    rval |= wordpointer[1];
531    rval <<= 8;
532    rval |= wordpointer[2];
533    rval <<= bitindex;
534    rval &= 0xffffff;
535
536    bitindex += number_of_bits;
537
538    rval >>= (24-number_of_bits);
539
540    wordpointer += (bitindex>>3);
541    bitindex &= 7;
542  }
543
544  return rval;
545}
546
547unsigned int getbits_fast(int number_of_bits)
548{
549  unsigned long rval;
550
551  {
552    rval = wordpointer[0];
553    rval <<= 8;
554    rval |= wordpointer[1];
555    rval <<= bitindex;
556    rval &= 0xffff;
557    bitindex += number_of_bits;
558
559    rval >>= (16-number_of_bits);
560
561    wordpointer += (bitindex>>3);
562    bitindex &= 7;
563  }
564
565  return rval;
566}
567
568unsigned int get1bit(void)
569{
570  unsigned char rval;
571
572  rval = *wordpointer << bitindex;
573
574  bitindex++;
575  wordpointer += (bitindex>>3);
576  bitindex &= 7;
577
578  return rval>>7;
579}
580
581void set_pointer(long backstep)
582{
583  wordpointer = bsbuf + ssize - backstep;
584  if (backstep)
585    memcpy(wordpointer,bsbufold+fsizeold-backstep,backstep);
586  bitindex = 0;
587}
Note: See TracBrowser for help on using the repository browser.