xref: /plan9/sys/src/games/mp3enc/mpglib_interface.c (revision 8f5875f3e9b20916b4c52ad4336922bc8653eb7b)
1 /* $Id: mpglib_interface.c,v 1.18 2001/01/06 01:00:33 markt Exp $ */
2 
3 #ifdef HAVE_CONFIG_H
4 # include <config.h>
5 #endif
6 
7 #ifdef HAVE_MPGLIB
8 
9 #include <limits.h>
10 #include <stdlib.h>
11 #include <assert.h>
12 
13 #include "interface.h"
14 #include "lame.h"
15 
16 #ifdef WITH_DMALLOC
17 #include <dmalloc.h>
18 #endif
19 
20 
21 MPSTR           mp;
22 plotting_data*  mpg123_pinfo = NULL;
23 
24 
lame_decode_init(void)25 int lame_decode_init( void )
26 {
27     InitMP3 ( &mp );
28     return 0;
29 }
30 
31 /*
32  * For lame_decode:  return code
33  * -1     error
34  *  0     ok, but need more data before outputing any samples
35  *  n     number of samples output.  either 576 or 1152 depending on MP3 file.
36  */
37 
lame_decode1_headers(unsigned char * buffer,int len,short pcm_l[],short pcm_r[],mp3data_struct * mp3data)38 int lame_decode1_headers(
39         unsigned char*   buffer,
40         int              len,
41         short            pcm_l [],
42         short            pcm_r [],
43         mp3data_struct*  mp3data )
44 {
45     static const int smpls [2] [4] = {
46     /* Layer   I    II   III */
47         { 0, 384, 1152, 1152 }, /* MPEG-1     */
48         { 0, 384, 1152,  576 }  /* MPEG-2(.5) */
49     };
50     static char        out  [8192];
51     signed short int*  p = (signed short int*) out;
52     int                processed_bytes;
53     int                processed_samples;  // processed samples per channel
54     int                ret;
55     int                i;
56 
57     mp3data->header_parsed = 0;
58 
59     ret = decodeMP3 ( &mp, buffer, len, (char*)p, sizeof(out), &processed_bytes );
60 
61     if ( mp.header_parsed ) {
62         mp3data->header_parsed = 1;
63         mp3data->stereo        = mp.fr.stereo;
64         mp3data->samplerate    = freqs [mp.fr.sampling_frequency];
65         mp3data->mode          = mp.fr.mode;
66         mp3data->mode_ext      = mp.fr.mode_ext;
67         mp3data->framesize     = smpls [mp.fr.lsf] [mp.fr.lay];
68 
69         if (mp.fsizeold > 0)      /* works for free format and fixed, no overrun, temporal results are < 400.e6 */
70             mp3data->bitrate   = 8 * (4 + mp.fsizeold) * mp3data->samplerate /
71 	                         ( 1.e3 * mp3data->framesize ) + 0.5;
72         else
73             mp3data->bitrate   = tabsel_123 [mp.fr.lsf] [mp.fr.lay-1] [mp.fr.bitrate_index];
74 
75         if (mp.num_frames>0) {
76 	  /* Xing VBR header found and num_frames was set */
77 	  mp3data->totalframes = mp.num_frames;
78           mp3data->nsamp=mp3data->framesize * mp.num_frames;
79 	}
80     }
81 
82     switch ( ret ) {
83     case MP3_OK:
84         switch ( mp.fr.stereo ) {
85 	case 1:
86             processed_samples = processed_bytes >> 1;
87             for ( i = 0; i < processed_samples; i++ )
88 	        pcm_l [i] = *p++;
89 	    break;
90 	case 2:
91             processed_samples = processed_bytes >> 2;
92             for ( i = 0; i < processed_samples; i++ ) {
93 	        pcm_l [i] = *p++;
94 		pcm_r [i] = *p++;
95 	    }
96 	    break;
97 	default:
98             processed_samples = -1;
99 	    assert (0);
100 	    break;
101         }
102 	break;
103 
104     case MP3_NEED_MORE:
105         processed_samples = 0;
106 	break;
107 
108     default:
109         assert (0);
110     case MP3_ERR:
111         processed_samples = -1;
112 	break;
113 
114     }
115 
116     //  printf ( "ok, more, err:  %i %i %i\n", MP3_OK, MP3_NEED_MORE, MP3_ERR );
117     //  printf ( "ret = %i out=%i\n", ret, totsize );
118     return processed_samples;
119 }
120 
121 
122 /*
123  * For lame_decode:  return code
124  *  -1     error
125  *   0     ok, but need more data before outputing any samples
126  *   n     number of samples output.  Will be at most one frame of
127  *         MPEG data.
128  */
129 
lame_decode1(unsigned char * buffer,int len,short pcm_l[],short pcm_r[])130 int lame_decode1(
131         unsigned char*  buffer,
132 	int    len,
133 	short  pcm_l [],
134 	short  pcm_r [] )
135 {
136   mp3data_struct mp3data;
137 
138   return lame_decode1_headers ( buffer, len, pcm_l, pcm_r, &mp3data );
139 }
140 
141 
142 /*
143  * For lame_decode:  return code
144  *  -1     error
145  *   0     ok, but need more data before outputing any samples
146  *   n     number of samples output.  a multiple of 576 or 1152 depending on MP3 file.
147  */
148 
lame_decode_headers(unsigned char * buffer,int len,short pcm_l[],short pcm_r[],mp3data_struct * mp3data)149 int lame_decode_headers(
150         unsigned char*   buffer,
151 	int              len,
152 	short            pcm_l [],
153 	short            pcm_r [],
154         mp3data_struct*  mp3data )
155 {
156     int  ret;
157     int  totsize = 0;   // number of decoded samples per channel
158 
159     while (1) {
160         switch ( ret = lame_decode1_headers ( buffer, len, pcm_l+totsize, pcm_r+totsize, mp3data ) ) {
161         case -1: return ret;
162         case  0: return totsize;
163         default: totsize += ret;
164                  len      = 0;  /* future calls to decodeMP3 are just to flush buffers */
165                  break;
166         }
167     }
168 }
169 
170 
lame_decode(unsigned char * buffer,int len,short pcm_l[],short pcm_r[])171 int lame_decode(
172         unsigned char*  buffer,
173 	int    len,
174 	short  pcm_l [],
175 	short  pcm_r [] )
176 {
177     mp3data_struct  mp3data;
178 
179     return lame_decode_headers ( buffer, len, pcm_l, pcm_r, &mp3data );
180 }
181 
182 
183 #endif
184 
185 /* end of mpglib_interface.c */
186