Subversion Repositories Games.Descent

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 pmbaty 1
/*
2
    SMPEG - SDL MPEG Player Library
3
    Copyright (C) 1999  Loki Entertainment Software
4
 
5
    - Modified by Michel Darricau from eProcess <mdarricau@eprocess.fr>  for popcorn -
6
 
7
    This library is free software; you can redistribute it and/or
8
    modify it under the terms of the GNU Library General Public
9
    License as published by the Free Software Foundation; either
10
    version 2 of the License, or (at your option) any later version.
11
 
12
    This library is distributed in the hope that it will be useful,
13
    but WITHOUT ANY WARRANTY; without even the implied warranty of
14
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
    Library General Public License for more details.
16
 
17
    You should have received a copy of the GNU Library General Public
18
    License along with this library; if not, write to the Free
19
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
*/
21
 
22
/* A class based on the MPEG stream class, used to parse and play audio */
23
 
24
#ifndef _MPEGAUDIO_H_
25
#define _MPEGAUDIO_H_
26
 
27
#include "SDL.h"
28
#include "MPEGerror.h"
29
#include "MPEGaction.h"
30
 
31
#ifdef THREADED_AUDIO
32
#include "MPEGring.h"
33
#endif
34
 
35
void Play_MPEGaudioSDL(void *udata, Uint8 *stream, int len);
36
#ifdef THREADED_AUDIO
37
    int Decode_MPEGaudio(void *udata);
38
#endif
39
 
40
class MPEGstream;
41
 
42
/* MPEG/WAVE Sound library
43
   (C) 1997 by Woo-jae Jung */
44
 
45
/**************************/
46
/* Define values for MPEG */
47
/**************************/
48
#define SCALEBLOCK     12
49
#define CALCBUFFERSIZE 512
50
#define MAXSUBBAND     32
51
#define MAXCHANNEL     2
52
#define MAXTABLE       2
53
#define SCALE          32768
54
#define MAXSCALE       (SCALE-1)
55
#define MINSCALE       (-SCALE)
56
#define RAWDATASIZE    (2*2*32*SSLIMIT)
57
 
58
#define LS 0
59
#define RS 1
60
 
61
#define SSLIMIT      18
62
#define SBLIMIT      32
63
 
64
#define WINDOWSIZE    4096
65
 
66
// Huffmancode
67
#define HTN 34
68
 
69
/********************/
70
/* Type definitions */
71
/********************/
72
typedef float REAL;
73
 
74
typedef struct
75
{
76
  bool         generalflag;
77
  unsigned int part2_3_length;
78
  unsigned int big_values;
79
  unsigned int global_gain;
80
  unsigned int scalefac_compress;
81
  unsigned int window_switching_flag;
82
  unsigned int block_type;
83
  unsigned int mixed_block_flag;
84
  unsigned int table_select[3];
85
  unsigned int subblock_gain[3];
86
  unsigned int region0_count;
87
  unsigned int region1_count;
88
  unsigned int preflag;
89
  unsigned int scalefac_scale;
90
  unsigned int count1table_select;
91
}layer3grinfo;
92
 
93
typedef struct
94
{
95
  unsigned main_data_begin;
96
  unsigned private_bits;
97
  struct
98
  {
99
    unsigned scfsi[4];
100
    layer3grinfo gr[2];
101
  }ch[2];
102
}layer3sideinfo;
103
 
104
typedef struct
105
{
106
  int l[23];            /* [cb] */
107
  int s[3][13];         /* [window][cb] */
108
}layer3scalefactor;     /* [ch] */
109
 
110
typedef struct
111
{
112
  int tablename;
113
  unsigned int xlen,ylen;
114
  unsigned int linbits;
115
  unsigned int treelen;
116
  const unsigned int (*val)[2];
117
}HUFFMANCODETABLE;
118
 
119
 
120
// Class for Mpeg layer3
121
class Mpegbitwindow
122
{
123
public:
124
  Mpegbitwindow(){bitindex=point=0;};
125
 
126
  void initialize(void)  {bitindex=point=0;};
127
  int  gettotalbit(void) const {return bitindex;};
128
  void putbyte(int c)    {buffer[point&(WINDOWSIZE-1)]=c;point++;};
129
  void wrap(void);
130
  void rewind(int bits)  {bitindex-=bits;};
131
  void forward(int bits) {bitindex+=bits;};
132
  int getbit(void) {
133
      register int r=(buffer[bitindex>>3]>>(7-(bitindex&7)))&1;
134
      bitindex++;
135
      return r;
136
  }
137
  int getbits9(int bits)
138
  {
139
      register unsigned short a;
140
      { int offset=bitindex>>3;
141
 
142
        a=(((unsigned char)buffer[offset])<<8) | ((unsigned char)buffer[offset+1]);
143
      }
144
      a<<=(bitindex&7);
145
      bitindex+=bits;
146
      return (int)((unsigned int)(a>>(16-bits)));
147
  }
148
  int  getbits(int bits);
149
 
150
private:
151
  int  point,bitindex;
152
  char buffer[2*WINDOWSIZE];
153
};
154
 
155
/* The actual MPEG audio class */
156
class MPEGaudio : public MPEGerror, public MPEGaudioaction {
157
 
158
public:
159
    MPEGaudio(MPEGstream *stream, bool initSDL = true);
160
    virtual ~MPEGaudio();
161
 
162
    /* MPEG actions */
163
    bool GetAudioInfo(MPEG_AudioInfo *info);
164
    double Time(void);
165
    void Play(void);
166
    void Stop(void);
167
    void Rewind(void);
168
    void ResetSynchro(double time);
169
    void Skip(float seconds);
170
    void Volume(int vol);
171
                /* Michel Darricau from eProcess <mdarricau@eprocess.fr> conflict name in popcorn */
172
    MPEGstatus GetStatus(void);
173
 
174
    /* Returns the desired SDL audio spec for this stream */
175
    bool WantedSpec(SDL_AudioSpec *wanted);
176
 
177
    /* Inform SMPEG of the actual audio format if configuring SDL
178
       outside of this class */
179
    void ActualSpec(SDL_AudioSpec *actual);
180
 
181
protected:
182
    bool sdl_audio;
183
    MPEGstream *mpeg;
184
    int valid_stream;
185
    bool stereo;
186
    double rate_in_s;
187
    Uint32 frags_playing;
188
    Uint32 frag_time;
189
#ifdef THREADED_AUDIO
190
    bool decoding;
191
    SDL_Thread *decode_thread;
192
 
193
    void StartDecoding(void);
194
    void StopDecoding(void);
195
#endif
196
 
197
/* Code from splay 1.8.2 */
198
 
199
  /*****************************/
200
  /* Constant tables for layer */
201
  /*****************************/
202
private:
203
  static const int bitrate[2][3][15],frequencies[2][3];
204
  static const REAL scalefactorstable[64];
205
  static const HUFFMANCODETABLE ht[HTN];
206
  static const REAL filter[512];
207
  static REAL hcos_64[16],hcos_32[8],hcos_16[4],hcos_8[2],hcos_4;
208
 
209
  /*************************/
210
  /* MPEG header variables */
211
  /*************************/
212
private:
213
  int last_speed;
214
  int layer,protection,bitrateindex,padding,extendedmode;
215
  enum _mpegversion  {mpeg1,mpeg2}                               version;
216
  enum _mode    {fullstereo,joint,dual,single}                   mode;
217
  enum _frequency {frequency44100,frequency48000,frequency32000} frequency;
218
 
219
  /***************************************/
220
  /* Interface for setting music quality */
221
  /***************************************/
222
private:
223
  bool forcetomonoflag;
224
  bool forcetostereoflag;
225
  bool swapendianflag;
226
  int  downfrequency;
227
 
228
public:
229
  void setforcetomono(bool flag);
230
  void setdownfrequency(int value);
231
 
232
  /******************************/
233
  /* Frame management variables */
234
  /******************************/
235
private:
236
  int decodedframe,currentframe,totalframe;
237
 
238
  /***************************************/
239
  /* Variables made by MPEG-Audio header */
240
  /***************************************/
241
private:
242
  int tableindex,channelbitrate;
243
  int stereobound,subbandnumber,inputstereo,outputstereo;
244
  REAL scalefactor;
245
  int framesize;
246
 
247
  /*******************/
248
  /* Mpegtoraw class */
249
  /*******************/
250
public:
251
  void initialize();
252
  bool run(int frames, double *timestamp = NULL);
253
  void clearbuffer(void);
254
 
255
  /*****************************/
256
  /* Loading MPEG-Audio stream */
257
  /*****************************/
258
private:
259
  Uint8 _buffer[4096];
260
  Uint32 _buffer_pos;
261
  int  bitindex;
262
  bool fillbuffer(int size);
263
  void sync(void);
264
  bool issync(void);
265
  int getbyte(void);
266
  int getbit(void);
267
  int getbits8(void);
268
  int getbits9(int bits);
269
  int getbits(int bits);
270
 
271
 
272
  /********************/
273
  /* Global variables */
274
  /********************/
275
private:
276
  int lastfrequency,laststereo;
277
 
278
  // for Layer3
279
  int layer3slots,layer3framestart,layer3part2start;
280
  REAL prevblck[2][2][SBLIMIT][SSLIMIT];
281
  int currentprevblock;
282
  layer3sideinfo sideinfo;
283
  layer3scalefactor scalefactors[2];
284
 
285
  Mpegbitwindow bitwindow;
286
  int wgetbit  (void)    {return bitwindow.getbit  ();    }
287
  int wgetbits9(int bits){return bitwindow.getbits9(bits);}
288
  int wgetbits (int bits){return bitwindow.getbits (bits);}
289
 
290
 
291
  /*************************************/
292
  /* Decoding functions for each layer */
293
  /*************************************/
294
private:
295
  bool loadheader(void);
296
 
297
  //
298
  // Subbandsynthesis
299
  //
300
  REAL calcbufferL[2][CALCBUFFERSIZE],calcbufferR[2][CALCBUFFERSIZE];
301
  int  currentcalcbuffer,calcbufferoffset;
302
 
303
  void computebuffer(REAL *fraction,REAL buffer[2][CALCBUFFERSIZE]);
304
  void generatesingle(void);
305
  void generate(void);
306
  void subbandsynthesis(REAL *fractionL,REAL *fractionR);
307
 
308
  void computebuffer_2(REAL *fraction,REAL buffer[2][CALCBUFFERSIZE]);
309
  void generatesingle_2(void);
310
  void generate_2(void);
311
  void subbandsynthesis_2(REAL *fractionL,REAL *fractionR);
312
 
313
  // Extarctor
314
  void extractlayer1(void);    // MPEG-1
315
  void extractlayer2(void);
316
  void extractlayer3(void);
317
  void extractlayer3_2(void);  // MPEG-2
318
 
319
 
320
  // Functions for layer 3
321
  void layer3initialize(void);
322
  bool layer3getsideinfo(void);
323
  bool layer3getsideinfo_2(void);
324
  void layer3getscalefactors(int ch,int gr);
325
  void layer3getscalefactors_2(int ch);
326
  void layer3huffmandecode(int ch,int gr,int out[SBLIMIT][SSLIMIT]);
327
  REAL layer3twopow2(int scale,int preflag,int pretab_offset,int l);
328
  REAL layer3twopow2_1(int a,int b,int c);
329
  void layer3dequantizesample(int ch,int gr,int   in[SBLIMIT][SSLIMIT],
330
                                REAL out[SBLIMIT][SSLIMIT]);
331
  void layer3fixtostereo(int gr,REAL  in[2][SBLIMIT][SSLIMIT]);
332
  void layer3reorderandantialias(int ch,int gr,REAL  in[SBLIMIT][SSLIMIT],
333
                               REAL out[SBLIMIT][SSLIMIT]);
334
 
335
  void layer3hybrid(int ch,int gr,REAL in[SBLIMIT][SSLIMIT],
336
                          REAL out[SSLIMIT][SBLIMIT]);
337
 
338
  void huffmandecoder_1(const HUFFMANCODETABLE *h,int *x,int *y);
339
  void huffmandecoder_2(const HUFFMANCODETABLE *h,int *x,int *y,int *v,int *w);
340
 
341
  /********************/
342
  /* Playing raw data */
343
  /********************/
344
private:
345
  int     samplesperframe;
346
  int     rawdatareadoffset, rawdatawriteoffset;
347
  Sint16 *rawdata;
348
#ifdef THREADED_AUDIO
349
  MPEG_ring *ring;
350
#else
351
  Sint16  spillover[ RAWDATASIZE ];
352
#endif
353
  int volume;
354
 
355
  void clearrawdata(void)    {
356
        rawdatareadoffset=0;
357
        rawdatawriteoffset=0;
358
        rawdata=NULL;
359
  }
360
  void putraw(short int pcm) {rawdata[rawdatawriteoffset++]=pcm;}
361
 
362
  /********************/
363
  /* Timestamp sync   */
364
  /********************/
365
public:
366
#define N_TIMESTAMPS 5
367
 
368
  double timestamp[N_TIMESTAMPS];
369
 
370
  /* Functions which access MPEGaudio internals */
371
  friend void Play_MPEGaudioSDL(void *udata, Uint8 *stream, int len);
372
  friend int Play_MPEGaudio(MPEGaudio *audio, Uint8 *stream, int len);
373
#ifdef THREADED_AUDIO
374
  friend int Decode_MPEGaudio(void *udata);
375
#endif
376
};
377
 
378
/* Need to duplicate the prototypes, this is not a typo :) */
379
void Play_MPEGaudioSDL(void *udata, Uint8 *stream, int len);
380
int Play_MPEGaudio(MPEGaudio *audio, Uint8 *stream, int len);
381
#ifdef THREADED_AUDIO
382
int Decode_MPEGaudio(void *udata);
383
#endif
384
 
385
#endif /* _MPEGAUDIO_H_ */