1 
2 #include <stdlib.h>
3 #include <stdio.h>
4 
5 #include "SDL_sound.h"
6 
7 #define __SDL_SOUND_INTERNAL__
8 #include "SDL_sound_internal.h"
9 
10 #include "mpg123_sdlsound.h"
11 #include "mpglib_sdlsound.h"
12 
13 
InitMP3(struct mpstr * mp)14 BOOL InitMP3(struct mpstr *mp)
15 {
16 	static int init = 0;
17 
18 	memset(mp,0,sizeof(struct mpstr));
19 
20 	mp->framesize = 0;
21 	mp->fsizeold = -1;
22 	mp->bsize = 0;
23 	mp->head = mp->tail = NULL;
24 	mp->fr.single = -1;
25 	mp->bsnum = 0;
26 	mp->synth_bo = 1;
27 
28 	if(!init) {
29 		init = 1;
30 		make_decode_tables(32767);
31 		init_layer2();
32 		init_layer3(SBLIMIT);
33 	}
34 
35 	return !0;
36 }
37 
ExitMP3(struct mpstr * mp)38 void ExitMP3(struct mpstr *mp)
39 {
40 	struct buf *b,*bn;
41 
42 	b = mp->tail;
43 	while(b) {
44 		free(b->pnt);
45 		bn = b->next;
46 		free(b);
47 		b = bn;
48 	}
49 }
50 
addbuf(struct mpstr * mp,char * buf,int size)51 static struct buf *addbuf(struct mpstr *mp,char *buf,int size)
52 {
53 	struct buf *nbuf;
54 
55 	nbuf = malloc( sizeof(struct buf) );
56 	BAIL_IF_MACRO(!nbuf, ERR_OUT_OF_MEMORY, NULL);
57 
58 	nbuf->pnt = malloc(size);
59 	if(!nbuf->pnt) {
60 		free(nbuf);
61 		BAIL_MACRO(ERR_OUT_OF_MEMORY, 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 
remove_buf(struct mpstr * mp)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 
read_buf_byte(struct mpstr * mp,unsigned long * retval)98 static int read_buf_byte(struct mpstr *mp, unsigned long *retval)
99 {
100 	int pos;
101 
102 	pos = mp->tail->pos;
103 	while(pos >= mp->tail->size) {
104 		remove_buf(mp);
105 		pos = mp->tail->pos;
106 		if(!mp->tail) {
107 			BAIL_MACRO("MPGLIB: Short read in read_buf_byte()!", 0);
108 		}
109 	}
110 
111 	if (retval != NULL)
112 		*retval = mp->tail->pnt[pos];
113 
114 	mp->bsize--;
115 	mp->tail->pos++;
116 
117 	return 1;
118 }
119 
read_head(struct mpstr * mp)120 static int read_head(struct mpstr *mp)
121 {
122 	unsigned long val;
123 	unsigned long head;
124 
125 	if (!read_buf_byte(mp, &val))
126 		return 0;
127 
128 	head = val << 8;
129 
130 	if (!read_buf_byte(mp, &val))
131 		return 0;
132 
133 	head |= val;
134 	head <<= 8;
135 
136 	if (!read_buf_byte(mp, &val))
137 		return 0;
138 
139 	head |= val;
140 	head <<= 8;
141 
142 	if (!read_buf_byte(mp, &val))
143 		return 0;
144 
145 	head |= val;
146 	mp->header = head;
147 	return 1;
148 }
149 
decodeMP3(struct mpstr * mp,char * in,int isize,char * out,int osize,int * done)150 int decodeMP3(struct mpstr *mp,char *in,int isize,char *out,
151 		int osize,int *done)
152 {
153 	int len;
154 
155 	BAIL_IF_MACRO(osize < 4608, "MPGLIB: Output buffer too small", MP3_ERR);
156 
157 	if(in) {
158 		if(addbuf(mp,in,isize) == NULL) {
159 			return MP3_ERR;
160 		}
161 	}
162 
163 	/* First decode header */
164 	if(mp->framesize == 0) {
165 		if(mp->bsize < 4) {
166 			return MP3_NEED_MORE;
167 		}
168 
169 		if (!read_head(mp))
170 			return MP3_ERR;
171 
172 		if (!decode_header(&mp->fr,mp->header))
173 			return MP3_ERR;
174 
175 		mp->framesize = mp->fr.framesize;
176 	}
177 
178 	if(mp->fr.framesize > mp->bsize)
179 		return MP3_NEED_MORE;
180 
181 	wordpointer = mp->bsspace[mp->bsnum] + 512;
182 	mp->bsnum = (mp->bsnum + 1) & 0x1;
183 	bitindex = 0;
184 
185 	len = 0;
186 	while(len < mp->framesize) {
187 		int nlen;
188 		int blen = mp->tail->size - mp->tail->pos;
189 		if( (mp->framesize - len) <= blen) {
190                   nlen = mp->framesize-len;
191 		}
192 		else {
193                   nlen = blen;
194                 }
195 		memcpy(wordpointer+len,mp->tail->pnt+mp->tail->pos,nlen);
196                 len += nlen;
197                 mp->tail->pos += nlen;
198 		mp->bsize -= nlen;
199                 if(mp->tail->pos == mp->tail->size) {
200                    remove_buf(mp);
201                 }
202 	}
203 
204 	*done = 0;
205 	if(mp->fr.error_protection)
206            getbits(16);
207         switch(mp->fr.lay) {
208           case 1:
209 	    do_layer1(&mp->fr,(unsigned char *) out,done,mp);
210             break;
211           case 2:
212 	    do_layer2(&mp->fr,(unsigned char *) out,done,mp);
213             break;
214           case 3:
215 	    do_layer3(&mp->fr,(unsigned char *) out,done,mp);
216             break;
217         }
218 
219 	mp->fsizeold = mp->framesize;
220 	mp->framesize = 0;
221 
222 	return MP3_OK;
223 }
224 
set_pointer(long backstep,struct mpstr * mp)225 int set_pointer(long backstep, struct mpstr *mp)
226 {
227   unsigned char *bsbufold;
228   if(mp->fsizeold < 0 && backstep > 0) {
229     char err[128];
230     snprintf(err, sizeof (err), "MPGLIB: Can't step back! %ld!", backstep);
231     BAIL_MACRO(err, MP3_ERR);
232   }
233   bsbufold = mp->bsspace[mp->bsnum] + 512;
234   wordpointer -= backstep;
235   if (backstep)
236     memcpy(wordpointer,bsbufold+mp->fsizeold-backstep,backstep);
237   bitindex = 0;
238   return MP3_OK;
239 }
240 
241 
242 
243 
244