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