1 //
2 //	MP3 decoding using libMAD
3 //
4 //      (c) 1999-2004 Jim Peters <jim@uazu.net>.  All Rights Reserved.
5 //      For latest version see http://sbagen.sf.net/ or
6 //      http://uazu.net/sbagen/.  Released under the GNU GPL version 2.
7 //
8 
9 #include "libs/mad.h"
10 
11 extern FILE *mix_in;
12 extern void *Alloc(size_t);
13 extern void error(char *fmt, ...);
14 
15 int mp3_read(int *dst, int dlen);
16 
17 static struct mad_stream stream;
18 static struct mad_frame frame;
19 static struct mad_synth synth;
20 static char *mp3_buf;
21 static int mp3_len;
22 static int synth_extra;		// Extra samples carried over from previous frame
23 
24 void
mp3_init()25 mp3_init() {
26    mp3_len= 32768;
27    mp3_buf= (char*)Alloc(mp3_len);
28 
29    // Setup MAD decoder
30    mad_stream_init(&stream);
31    mad_frame_init(&frame);
32    mad_synth_init(&synth);
33    mad_stream_options(&stream, 0);
34 
35    // Force first data read
36    stream.error= MAD_ERROR_BUFLEN;
37    synth_extra= 0;
38 
39    inbuf_start(mp3_read, 256*1024);	// 1024K buffer: 3s@44.1kHz
40 }
41 
42 void
mp3_term()43 mp3_term() {
44    mad_synth_finish(&synth);
45    mad_frame_finish(&frame);
46    mad_stream_finish(&stream);
47    free(mp3_buf);
48 }
49 
50 
51 // Limiting and truncation to 20 bits
52 #define ROUND(xx) ((((xx)<-MAD_F_ONE) ? -MAD_F_ONE : 	\
53 		    ((xx)>=MAD_F_ONE) ? MAD_F_ONE-1 : 	\
54 		    (xx)) >> (MAD_F_FRACBITS-15-4))
55 
56 int
mp3_read(int * dst,int dlen)57 mp3_read(int *dst, int dlen) {
58    int *dst0= dst;
59    int cnt, a, val;
60 
61    //debug("mp3_read %d", dlen);
62 
63    while (dlen > 0) {
64       // First use up any samples from previous synth frame
65       if (synth_extra > 0) {
66 	 cnt= dlen/2;
67 	 if (cnt > synth_extra) cnt= synth_extra;
68 	 for (a= 0; a<cnt; a++) {
69 	    int ii= synth.pcm.length - synth_extra--;
70 	    val= synth.pcm.samples[0][ii]; *dst++= ROUND(val);
71 	    val= synth.pcm.samples[1][ii]; *dst++= ROUND(val);
72 	    dlen -= 2;
73 	 }
74 	 continue;
75       }
76 
77       // Load up more MP3 data from disk if required
78       if (stream.error == MAD_ERROR_BUFLEN) {
79 	 char *rp= mp3_buf;
80 
81 	 // Preserve start of last frame
82 	 if (stream.next_frame) {
83 	    cnt= stream.bufend - stream.next_frame;
84 	    memmove(mp3_buf, stream.next_frame, cnt);
85 	    rp += cnt;
86 	 }
87 
88 	 // Fill buffer
89 	 cnt= fread(rp, 1, mp3_buf + mp3_len - rp, mix_in);
90 	 if (cnt == 0) {
91 	    if (feof(mix_in))
92 	       return dst-dst0;
93 	    error("Read error on MP3 input stream:\n  %s", strerror(errno));
94 	 }
95 	 rp += cnt;
96 
97 	 mad_stream_buffer(&stream, (const unsigned char*)mp3_buf, rp - mp3_buf);
98 	 stream.error= 0;
99       }
100 
101       // Decode frame
102       if (mad_frame_decode(&frame, &stream)) {
103 	 if (MAD_RECOVERABLE(stream.error)) {
104 	    warn("MAD recoverable error: %s", mad_stream_errorstr(&stream));
105 	    continue;
106 	 }
107 	 if (stream.error == MAD_ERROR_BUFLEN)
108 	    continue;
109 	 error("Fatal error decoding MP3 stream: %s",
110 	       mad_stream_errorstr(&stream));
111       }
112 
113       // Pickup sampling rate if not picked up yet
114       if (out_rate_def) {
115 	 out_rate= frame.header.samplerate;
116 	 out_rate_def= 0;
117       }
118 
119       // Synthesize frame into samples
120       mad_synth_frame(&synth, &frame);
121       synth_extra= synth.pcm.length;
122    }
123    return dst-dst0;
124 }
125 
126 // END //
127