Mercurial > SDL_sound_CoreAudio
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/decoders/mpglib/interface.c Thu Feb 21 19:46:09 2002 +0000 @@ -0,0 +1,229 @@ + +#include <stdlib.h> +#include <stdio.h> + +#include "mpg123_sdlsound.h" +#include "mpglib_sdlsound.h" + +/* Global mp .. it's a hack */ +struct mpstr *gmp; + + +BOOL InitMP3(struct mpstr *mp) +{ + static int init = 0; + + memset(mp,0,sizeof(struct mpstr)); + + mp->framesize = 0; + mp->fsizeold = -1; + mp->bsize = 0; + mp->head = mp->tail = NULL; + mp->fr.single = -1; + mp->bsnum = 0; + mp->synth_bo = 1; + + if(!init) { + init = 1; + make_decode_tables(32767); + init_layer2(); + init_layer3(SBLIMIT); + } + + return !0; +} + +void ExitMP3(struct mpstr *mp) +{ + struct buf *b,*bn; + + b = mp->tail; + while(b) { + free(b->pnt); + bn = b->next; + free(b); + b = bn; + } +} + +static struct buf *addbuf(struct mpstr *mp,char *buf,int size) +{ + struct buf *nbuf; + + nbuf = malloc( sizeof(struct buf) ); + if(!nbuf) { + fprintf(stderr,"Out of memory!\n"); + return NULL; + } + nbuf->pnt = malloc(size); + if(!nbuf->pnt) { + free(nbuf); + return NULL; + } + nbuf->size = size; + memcpy(nbuf->pnt,buf,size); + nbuf->next = NULL; + nbuf->prev = mp->head; + nbuf->pos = 0; + + if(!mp->tail) { + mp->tail = nbuf; + } + else { + mp->head->next = nbuf; + } + + mp->head = nbuf; + mp->bsize += size; + + return nbuf; +} + +static void remove_buf(struct mpstr *mp) +{ + struct buf *buf = mp->tail; + + mp->tail = buf->next; + if(mp->tail) + mp->tail->prev = NULL; + else { + mp->tail = mp->head = NULL; + } + + free(buf->pnt); + free(buf); + +} + +static int read_buf_byte(struct mpstr *mp) +{ + unsigned int b; + + int pos; + + pos = mp->tail->pos; + while(pos >= mp->tail->size) { + remove_buf(mp); + pos = mp->tail->pos; + if(!mp->tail) { + fprintf(stderr,"Fatal error!\n"); + exit(1); + } + } + + b = mp->tail->pnt[pos]; + mp->bsize--; + mp->tail->pos++; + + + return b; +} + +static void read_head(struct mpstr *mp) +{ + unsigned long head; + + head = read_buf_byte(mp); + head <<= 8; + head |= read_buf_byte(mp); + head <<= 8; + head |= read_buf_byte(mp); + head <<= 8; + head |= read_buf_byte(mp); + + mp->header = head; +} + +int decodeMP3(struct mpstr *mp,char *in,int isize,char *out, + int osize,int *done) +{ + int len; + + gmp = mp; + + if(osize < 4608) { + fprintf(stderr,"To less out space\n"); + return MP3_ERR; + } + + if(in) { + if(addbuf(mp,in,isize) == NULL) { + return MP3_ERR; + } + } + + /* First decode header */ + if(mp->framesize == 0) { + if(mp->bsize < 4) { + return MP3_NEED_MORE; + } + read_head(mp); + decode_header(&mp->fr,mp->header); + mp->framesize = mp->fr.framesize; + } + + if(mp->fr.framesize > mp->bsize) + return MP3_NEED_MORE; + + wordpointer = mp->bsspace[mp->bsnum] + 512; + mp->bsnum = (mp->bsnum + 1) & 0x1; + bitindex = 0; + + len = 0; + while(len < mp->framesize) { + int nlen; + int blen = mp->tail->size - mp->tail->pos; + if( (mp->framesize - len) <= blen) { + nlen = mp->framesize-len; + } + else { + nlen = blen; + } + memcpy(wordpointer+len,mp->tail->pnt+mp->tail->pos,nlen); + len += nlen; + mp->tail->pos += nlen; + mp->bsize -= nlen; + if(mp->tail->pos == mp->tail->size) { + remove_buf(mp); + } + } + + *done = 0; + if(mp->fr.error_protection) + getbits(16); + switch(mp->fr.lay) { + case 1: + do_layer1(&mp->fr,(unsigned char *) out,done); + break; + case 2: + do_layer2(&mp->fr,(unsigned char *) out,done); + break; + case 3: + do_layer3(&mp->fr,(unsigned char *) out,done); + break; + } + + mp->fsizeold = mp->framesize; + mp->framesize = 0; + + return MP3_OK; +} + +int set_pointer(long backstep) +{ + unsigned char *bsbufold; + if(gmp->fsizeold < 0 && backstep > 0) { + fprintf(stderr,"Can't step back %ld!\n",backstep); + return MP3_ERR; + } + bsbufold = gmp->bsspace[gmp->bsnum] + 512; + wordpointer -= backstep; + if (backstep) + memcpy(wordpointer,bsbufold+gmp->fsizeold-backstep,backstep); + bitindex = 0; + return MP3_OK; +} + + + +