261
|
1
|
|
2 #include <stdlib.h>
|
|
3 #include <stdio.h>
|
|
4
|
|
5 #include "mpg123_sdlsound.h"
|
|
6 #include "mpglib_sdlsound.h"
|
|
7
|
|
8 /* Global mp .. it's a hack */
|
|
9 struct mpstr *gmp;
|
|
10
|
|
11
|
|
12 BOOL InitMP3(struct mpstr *mp)
|
|
13 {
|
|
14 static int init = 0;
|
|
15
|
|
16 memset(mp,0,sizeof(struct mpstr));
|
|
17
|
|
18 mp->framesize = 0;
|
|
19 mp->fsizeold = -1;
|
|
20 mp->bsize = 0;
|
|
21 mp->head = mp->tail = NULL;
|
|
22 mp->fr.single = -1;
|
|
23 mp->bsnum = 0;
|
|
24 mp->synth_bo = 1;
|
|
25
|
|
26 if(!init) {
|
|
27 init = 1;
|
|
28 make_decode_tables(32767);
|
|
29 init_layer2();
|
|
30 init_layer3(SBLIMIT);
|
|
31 }
|
|
32
|
|
33 return !0;
|
|
34 }
|
|
35
|
|
36 void ExitMP3(struct mpstr *mp)
|
|
37 {
|
|
38 struct buf *b,*bn;
|
|
39
|
|
40 b = mp->tail;
|
|
41 while(b) {
|
|
42 free(b->pnt);
|
|
43 bn = b->next;
|
|
44 free(b);
|
|
45 b = bn;
|
|
46 }
|
|
47 }
|
|
48
|
|
49 static struct buf *addbuf(struct mpstr *mp,char *buf,int size)
|
|
50 {
|
|
51 struct buf *nbuf;
|
|
52
|
|
53 nbuf = malloc( sizeof(struct buf) );
|
|
54 if(!nbuf) {
|
|
55 fprintf(stderr,"Out of memory!\n");
|
|
56 return NULL;
|
|
57 }
|
|
58 nbuf->pnt = malloc(size);
|
|
59 if(!nbuf->pnt) {
|
|
60 free(nbuf);
|
|
61 return NULL;
|
|
62 }
|
|
63 nbuf->size = size;
|
|
64 memcpy(nbuf->pnt,buf,size);
|
|
65 nbuf->next = NULL;
|
|
66 nbuf->prev = mp->head;
|
|
67 nbuf->pos = 0;
|
|
68
|
|
69 if(!mp->tail) {
|
|
70 mp->tail = nbuf;
|
|
71 }
|
|
72 else {
|
|
73 mp->head->next = nbuf;
|
|
74 }
|
|
75
|
|
76 mp->head = nbuf;
|
|
77 mp->bsize += size;
|
|
78
|
|
79 return nbuf;
|
|
80 }
|
|
81
|
|
82 static void remove_buf(struct mpstr *mp)
|
|
83 {
|
|
84 struct buf *buf = mp->tail;
|
|
85
|
|
86 mp->tail = buf->next;
|
|
87 if(mp->tail)
|
|
88 mp->tail->prev = NULL;
|
|
89 else {
|
|
90 mp->tail = mp->head = NULL;
|
|
91 }
|
|
92
|
|
93 free(buf->pnt);
|
|
94 free(buf);
|
|
95
|
|
96 }
|
|
97
|
|
98 static int read_buf_byte(struct mpstr *mp)
|
|
99 {
|
|
100 unsigned int b;
|
|
101
|
|
102 int pos;
|
|
103
|
|
104 pos = mp->tail->pos;
|
|
105 while(pos >= mp->tail->size) {
|
|
106 remove_buf(mp);
|
|
107 pos = mp->tail->pos;
|
|
108 if(!mp->tail) {
|
|
109 fprintf(stderr,"Fatal error!\n");
|
|
110 exit(1);
|
|
111 }
|
|
112 }
|
|
113
|
|
114 b = mp->tail->pnt[pos];
|
|
115 mp->bsize--;
|
|
116 mp->tail->pos++;
|
|
117
|
|
118
|
|
119 return b;
|
|
120 }
|
|
121
|
|
122 static void read_head(struct mpstr *mp)
|
|
123 {
|
|
124 unsigned long head;
|
|
125
|
|
126 head = read_buf_byte(mp);
|
|
127 head <<= 8;
|
|
128 head |= read_buf_byte(mp);
|
|
129 head <<= 8;
|
|
130 head |= read_buf_byte(mp);
|
|
131 head <<= 8;
|
|
132 head |= read_buf_byte(mp);
|
|
133
|
|
134 mp->header = head;
|
|
135 }
|
|
136
|
|
137 int decodeMP3(struct mpstr *mp,char *in,int isize,char *out,
|
|
138 int osize,int *done)
|
|
139 {
|
|
140 int len;
|
|
141
|
|
142 gmp = mp;
|
|
143
|
|
144 if(osize < 4608) {
|
|
145 fprintf(stderr,"To less out space\n");
|
|
146 return MP3_ERR;
|
|
147 }
|
|
148
|
|
149 if(in) {
|
|
150 if(addbuf(mp,in,isize) == NULL) {
|
|
151 return MP3_ERR;
|
|
152 }
|
|
153 }
|
|
154
|
|
155 /* First decode header */
|
|
156 if(mp->framesize == 0) {
|
|
157 if(mp->bsize < 4) {
|
|
158 return MP3_NEED_MORE;
|
|
159 }
|
|
160 read_head(mp);
|
|
161 decode_header(&mp->fr,mp->header);
|
|
162 mp->framesize = mp->fr.framesize;
|
|
163 }
|
|
164
|
|
165 if(mp->fr.framesize > mp->bsize)
|
|
166 return MP3_NEED_MORE;
|
|
167
|
|
168 wordpointer = mp->bsspace[mp->bsnum] + 512;
|
|
169 mp->bsnum = (mp->bsnum + 1) & 0x1;
|
|
170 bitindex = 0;
|
|
171
|
|
172 len = 0;
|
|
173 while(len < mp->framesize) {
|
|
174 int nlen;
|
|
175 int blen = mp->tail->size - mp->tail->pos;
|
|
176 if( (mp->framesize - len) <= blen) {
|
|
177 nlen = mp->framesize-len;
|
|
178 }
|
|
179 else {
|
|
180 nlen = blen;
|
|
181 }
|
|
182 memcpy(wordpointer+len,mp->tail->pnt+mp->tail->pos,nlen);
|
|
183 len += nlen;
|
|
184 mp->tail->pos += nlen;
|
|
185 mp->bsize -= nlen;
|
|
186 if(mp->tail->pos == mp->tail->size) {
|
|
187 remove_buf(mp);
|
|
188 }
|
|
189 }
|
|
190
|
|
191 *done = 0;
|
|
192 if(mp->fr.error_protection)
|
|
193 getbits(16);
|
|
194 switch(mp->fr.lay) {
|
|
195 case 1:
|
|
196 do_layer1(&mp->fr,(unsigned char *) out,done);
|
|
197 break;
|
|
198 case 2:
|
|
199 do_layer2(&mp->fr,(unsigned char *) out,done);
|
|
200 break;
|
|
201 case 3:
|
|
202 do_layer3(&mp->fr,(unsigned char *) out,done);
|
|
203 break;
|
|
204 }
|
|
205
|
|
206 mp->fsizeold = mp->framesize;
|
|
207 mp->framesize = 0;
|
|
208
|
|
209 return MP3_OK;
|
|
210 }
|
|
211
|
|
212 int set_pointer(long backstep)
|
|
213 {
|
|
214 unsigned char *bsbufold;
|
|
215 if(gmp->fsizeold < 0 && backstep > 0) {
|
|
216 fprintf(stderr,"Can't step back %ld!\n",backstep);
|
|
217 return MP3_ERR;
|
|
218 }
|
|
219 bsbufold = gmp->bsspace[gmp->bsnum] + 512;
|
|
220 wordpointer -= backstep;
|
|
221 if (backstep)
|
|
222 memcpy(wordpointer,bsbufold+gmp->fsizeold-backstep,backstep);
|
|
223 bitindex = 0;
|
|
224 return MP3_OK;
|
|
225 }
|
|
226
|
|
227
|
|
228
|
|
229
|