Use "local" instead of "system" header file inclusion.
[asterisk/asterisk.git] / addons / mp3 / interface.c
1 #include "asterisk.h"
2 #include "asterisk/logger.h"
3
4 #include <stdlib.h>
5 #include <stdio.h>
6
7 #include "mpg123.h"
8 #include "mpglib.h"
9
10
11 void InitMP3Constants(void)
12 {
13         init_layer3_const();
14         make_decode_tables_const();
15         
16 }
17
18
19 BOOL InitMP3(struct mpstr *mp, long outscale) 
20 {
21         /* quiet 4096 med 8192 */
22
23         memset(mp,0,sizeof(struct mpstr));
24
25         mp->framesize = 0;
26         mp->fsizeold = -1;
27         mp->bsize = 0;
28         mp->head = mp->tail = NULL;
29         mp->fr.single = 3; /* force mono */
30         mp->bsnum = 0;
31         mp->synth_bo = 1;
32         mp->outsamplerate = 8000;
33
34         make_decode_tables_scale(mp, outscale);
35
36         init_layer3_sample_limits(mp, SBLIMIT);
37
38         return !0;
39 }
40
41 void ExitMP3(struct mpstr *mp)
42 {
43         struct buf *b,*bn;
44         
45         b = mp->tail;
46         while(b) {
47                 free(b->pnt);
48                 bn = b->next;
49                 free(b);
50                 b = bn;
51         }
52 }
53
54 static struct buf *addbuf(struct mpstr *mp,char *buf,int size)
55 {
56         struct buf *nbuf;
57
58         nbuf = malloc( sizeof(struct buf) );
59         if(!nbuf) {
60                 ast_log(LOG_WARNING,"Out of memory!\n");
61                 return NULL;
62         }
63         nbuf->pnt = malloc(size);
64         if(!nbuf->pnt) {
65                 free(nbuf);
66                 return NULL;
67         }
68         nbuf->size = size;
69         memcpy(nbuf->pnt,buf,size);
70         nbuf->next = NULL;
71         nbuf->prev = mp->head;
72         nbuf->pos = 0;
73
74         if(!mp->tail) {
75                 mp->tail = nbuf;
76         }
77         else {
78           mp->head->next = nbuf;
79         }
80
81         mp->head = nbuf;
82         mp->bsize += size;
83
84         return nbuf;
85 }
86
87 static void remove_buf(struct mpstr *mp)
88 {
89   struct buf *buf = mp->tail;
90   
91   mp->tail = buf->next;
92   if(mp->tail)
93     mp->tail->prev = NULL;
94   else {
95     mp->tail = mp->head = NULL;
96   }
97   
98   free(buf->pnt);
99   free(buf);
100
101 }
102
103 static int read_buf_byte(int *error, struct mpstr *mp)
104 {
105         unsigned int b;int pos;
106
107         pos = mp->tail->pos;
108         while(pos >= mp->tail->size) {
109                 remove_buf(mp);
110                 pos = mp->tail->pos;
111                 if(!mp->tail) {
112                         /* We may pick up this error a few times*/
113                         /* But things have gone pear shaped */
114                         ast_log(LOG_WARNING,"Fatal Buffer error!\n");
115                         *error = 1;
116                         return (0);             
117                 }
118         }
119
120         b = mp->tail->pnt[pos];
121         mp->bsize--;
122         mp->tail->pos++;
123         
124
125         return b;
126 }
127
128 static int  read_head(struct mpstr *mp)
129 {
130         unsigned long head;
131         int error=0;
132         
133
134         head = read_buf_byte(&error, mp);
135         head <<= 8;
136         head |= read_buf_byte(&error, mp);
137         head <<= 8;
138         head |= read_buf_byte(&error, mp);
139         head <<= 8;
140         head |= read_buf_byte(&error, mp);
141
142         mp->header = head;
143
144         if(error){
145                 return (1);
146         }else
147                 return (0);
148                 
149 }
150
151 static int head_check(unsigned long head)
152 {
153     if( (head & 0xffe00000) != 0xffe00000)
154         return FALSE;
155     if(!((head>>17)&3))
156         return FALSE;
157     if( ((head>>12)&0xf) == 0xf || ((head>>12)&0xf) == 0)
158         return FALSE;
159     if( ((head>>10)&0x3) == 0x3 )
160         return FALSE;
161     if ((head & 0xffff0000) == 0xfffe0000)
162       return FALSE;
163
164     return TRUE;
165 }
166
167 static int head_shift(struct mpstr *mp)
168 {
169         unsigned long head;
170         int error = 0;
171         
172         head = mp->header;
173         
174         head <<= 8;
175         head |= read_buf_byte(&error, mp);
176         
177         mp->header = head;
178
179         if (error){
180                 return (1);
181         }else
182                 return (0);
183         
184 }
185
186
187 int decodeMP3(struct mpstr *mp,char *in,int isize,char *out,
188                 int osize,int *done)
189 {
190         int len;
191         long n,m;
192         int down_sample_sblimit;
193
194         if(osize < 4608) {
195                 ast_log(LOG_WARNING,"To less out space\n");
196                 return MP3_ERR;
197         }
198
199         if(in) {
200                 if(addbuf(mp,in,isize) == NULL) {
201                         return MP3_ERR;
202                 }
203         }
204
205         /* First decode header */
206         if(mp->framesize == 0) {
207                 if(mp->bsize < 4) {
208                         return MP3_NEED_MORE;
209                 }
210                 if (read_head(mp))
211                         return MP3_ERR;
212                 
213                 if(!head_check(mp->header) ) {
214                         int i;
215
216                         ast_log(LOG_WARNING,"Junk at the beginning of frame %08lx\n",mp->header);
217                         
218                         /* step in byte steps through next 64K */
219                         for(i=0;i<65536;i++) {
220                                 if(!mp->bsize)
221                                         return MP3_NEED_MORE;
222                                 
223                                 if(head_shift(mp))
224                                         return MP3_ERR;
225                                 
226                                 if(head_check(mp->header))
227                                         break;
228                         }
229                         if(i == 65536) {
230                                 ast_log(LOG_WARNING,"Giving up searching valid MPEG header\n");
231                                 return MP3_ERR;
232                         }
233                 }
234
235                 decode_header(&mp->fr,mp->header);
236                 mp->framesize = mp->fr.framesize;
237
238                 if (!mp->initmp3){
239                         mp->initmp3 = 1;
240                         
241                         n = freqs[mp->fr.sampling_frequency];
242                         if (mp->outsamplerate) {
243                                 m = mp->outsamplerate;
244                         }
245                         else {
246                                 m =n;
247                         }
248                 
249                         if (synth_ntom_set_step(n,m))
250                                 return MP3_ERR;
251                         
252                         
253                         if(n>m) {
254                                 down_sample_sblimit = SBLIMIT * m;
255                                 down_sample_sblimit /= n;
256                         }
257                         else {
258                                 down_sample_sblimit = SBLIMIT;
259                         }
260                         
261                         init_layer3_sample_limits(mp, down_sample_sblimit);
262         
263                 }
264         }
265         
266
267         if(mp->fr.framesize > mp->bsize)
268                 return MP3_NEED_MORE;
269
270         (mp->worksample).wordpointer = mp->bsspace[mp->bsnum] + 512;
271         mp->bsnum = (mp->bsnum + 1) & 0x1;
272         (mp->worksample).bitindex = 0;
273
274         len = 0;
275         while(len < mp->framesize) {
276                 int nlen;
277                 int blen = mp->tail->size - mp->tail->pos;
278                 if( (mp->framesize - len) <= blen) {
279                   nlen = mp->framesize-len;
280                 }
281                 else {
282                   nlen = blen;
283                 }
284                 memcpy((mp->worksample).wordpointer+len,mp->tail->pnt+mp->tail->pos,nlen);
285                 len += nlen;
286                 mp->tail->pos += nlen;
287                 mp->bsize -= nlen;
288                 if(mp->tail->pos == mp->tail->size) {
289                    remove_buf(mp);
290                 }
291         }
292
293         *done = 0;
294         if(mp->fr.error_protection)
295            getbits(mp, 16);
296         
297         if (do_layer3(mp,(unsigned char *) out,done))
298                 return MP3_ERR;
299
300         mp->fsizeold = mp->framesize;
301         mp->framesize = 0;
302
303         return MP3_OK;
304 }
305
306 int set_pointer(struct mpstr *mp, long backstep)
307 {
308   unsigned char *bsbufold;
309   if(mp->fsizeold < 0 && backstep > 0) {
310     ast_log(LOG_WARNING,"Can't step back %ld!\n",backstep);
311     return MP3_ERR;
312   }
313   bsbufold = mp->bsspace[mp->bsnum] + 512;
314   (mp->worksample).wordpointer -= backstep;
315   if (backstep)
316     memcpy((mp->worksample).wordpointer,bsbufold+mp->fsizeold-backstep,backstep);
317   (mp->worksample).bitindex = 0;
318   return MP3_OK;
319 }
320
321
322
323