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