comparison decoders/mpglib/interface.c @ 261:9b6e82f7c853

Initial add.
author Ryan C. Gordon <icculus@icculus.org>
date Thu, 21 Feb 2002 19:46:09 +0000
parents
children e1429f96aded
comparison
equal deleted inserted replaced
260:44a4730a1e6f 261:9b6e82f7c853
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