diff options
author | Monty <xiphmont@xiph.org> | 2003-04-22 09:00:49 +0000 |
---|---|---|
committer | Monty <xiphmont@xiph.org> | 2003-04-22 09:00:49 +0000 |
commit | 84f5ba9c21fdbdd3e4ff68938601dc99d78fa1a2 (patch) | |
tree | 325d681b9bd66a12aa0b7cd8ff0b7e286546be88 | |
parent | 1ab220015dda5e647a4ba23858d4b0c3c7c98136 (diff) | |
download | tremor-84f5ba9c21fdbdd3e4ff68938601dc99d78fa1a2.tar.gz |
Scary data flow rearrangement with mdct refolding
git-svn-id: https://svn.xiph.org/branches/lowmem-branch/Tremor@4624 0101bb08-14d6-0310-b084-bc0e0c8e3800
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | block.c | 394 | ||||
-rw-r--r-- | codec_internal.h | 57 | ||||
-rw-r--r-- | floor0.c | 30 | ||||
-rw-r--r-- | floor1.c | 34 | ||||
-rw-r--r-- | info.c | 2 | ||||
-rw-r--r-- | ivorbiscodec.h | 101 | ||||
-rw-r--r-- | ivorbisfile.h | 3 | ||||
-rw-r--r-- | mapping0.c | 110 | ||||
-rw-r--r-- | mdct.c | 4 | ||||
-rw-r--r-- | res012.c | 18 | ||||
-rw-r--r-- | synthesis.c | 119 | ||||
-rw-r--r-- | vorbisfile.c | 96 |
13 files changed, 149 insertions, 822 deletions
diff --git a/Makefile.am b/Makefile.am index 0c8b7af..d6e0dbc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,8 +4,7 @@ INCLUDES = -I./ lib_LTLIBRARIES = libvorbisidec.la -libvorbisidec_la_SOURCES = mdct.c block.c \ - synthesis.c info.c misc.c \ +libvorbisidec_la_SOURCES = mdct.c dsp.c info.c misc.c \ floor1.c floor0.c vorbisfile.c \ res012.c mapping0.c codebook.c \ framing.c bitwise.c \ diff --git a/block.c b/block.c deleted file mode 100644 index 6cbd7ec..0000000 --- a/block.c +++ /dev/null @@ -1,394 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * - * * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 * - * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * - * * - ******************************************************************** - - function: PCM data vector blocking, windowing and dis/reassembly - - ********************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "ogg.h" -#include "ivorbiscodec.h" -#include "codec_internal.h" -#include "misc.h" - -/* pcm accumulator examples (not exhaustive): - - <-------------- lW ----------------> - <--------------- W ----------------> -: .....|..... _______________ | -: .''' | '''_--- | |\ | -:.....''' |_____--- '''......| | \_______| -:.................|__________________|_______|__|______| - |<------ Sl ------>| > Sr < |endW - |beginSl |endSl | |endSr - |beginW |endlW |beginSr - - - |< lW >| - <--------------- W ----------------> - | | .. ______________ | - | | ' `/ | ---_ | - |___.'___/`. | ---_____| - |_______|__|_______|_________________| - | >|Sl|< |<------ Sr ----->|endW - | | |endSl |beginSr |endSr - |beginW | |endlW - mult[0] |beginSl mult[n] - - <-------------- lW -----------------> - |<--W-->| -: .............. ___ | | -: .''' |`/ \ | | -:.....''' |/`....\|...| -:.........................|___|___|___| - |Sl |Sr |endW - | | |endSr - | |beginSr - | |endSl - |beginSl - |beginW -*/ - -/* block abstraction setup *********************************************/ - -#ifndef WORD_ALIGN -#define WORD_ALIGN 8 -#endif - -vorbis_block *vorbis_block_create(vorbis_dsp_state *v){ - vorbis_block *vb=_ogg_calloc(1,sizeof(*vb)); - vb->vd=v; - vb->localalloc=0; - vb->localstore=NULL; - - return vb; -} - -void *_vorbis_block_alloc(vorbis_block *vb,long bytes){ - bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1); - if(bytes+vb->localtop>vb->localalloc){ - /* can't just _ogg_realloc... there are outstanding pointers */ - if(vb->localstore){ - struct alloc_chain *link=(struct alloc_chain *)_ogg_malloc(sizeof(*link)); - vb->totaluse+=vb->localtop; - link->next=vb->reap; - link->ptr=vb->localstore; - vb->reap=link; - } - /* highly conservative */ - vb->localalloc=bytes; - vb->localstore=_ogg_malloc(vb->localalloc); - vb->localtop=0; - } - { - void *ret=(void *)(((char *)vb->localstore)+vb->localtop); - vb->localtop+=bytes; - return ret; - } -} - -/* reap the chain, pull the ripcord */ -void _vorbis_block_ripcord(vorbis_block *vb){ - /* reap the chain */ - struct alloc_chain *reap=vb->reap; - while(reap){ - struct alloc_chain *next=reap->next; - _ogg_free(reap->ptr); - memset(reap,0,sizeof(*reap)); - _ogg_free(reap); - reap=next; - } - /* consolidate storage */ - if(vb->totaluse){ - vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc); - vb->localalloc+=vb->totaluse; - vb->totaluse=0; - } - - /* pull the ripcord */ - vb->localtop=0; - vb->reap=NULL; -} - -int vorbis_block_destroy(vorbis_block *vb){ - _vorbis_block_ripcord(vb); - if(vb->localstore)_ogg_free(vb->localstore); - _ogg_free(vb); - return 0; -} - -static int _vds_init(vorbis_dsp_state *v,vorbis_info *vi){ - int i; - codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; - memset(v,0,sizeof(*v)); - - v->vi=vi; - - v->pcm_storage=ci->blocksizes[1]; - v->pcm=(ogg_int32_t **)_ogg_malloc(vi->channels*sizeof(*v->pcm)); - v->pcmret=(ogg_int32_t **)_ogg_malloc(vi->channels*sizeof(*v->pcmret)); - for(i=0;i<vi->channels;i++) - v->pcm[i]=(ogg_int32_t *)_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i])); - - /* all 1 (large block) or 0 (small block) */ - /* explicitly set for the sake of clarity */ - v->lW=0; /* previous window size */ - v->W=0; /* current window size */ - - return(0); -} - -int vorbis_synthesis_restart(vorbis_dsp_state *v){ - if(!v)return -1; - { - vorbis_info *vi=v->vi; - codec_setup_info *ci; - - if(!vi)return -1; - ci=vi->codec_setup; - if(!ci)return -1; - - v->centerW=ci->blocksizes[1]/2; - v->pcm_current=v->centerW; - - v->pcm_returned=-1; - v->granulepos=-1; - v->sequence=-1; - v->sample_count=-1; - } - return 0; -} - -vorbis_dsp_state *vorbis_dsp_create(vorbis_info *vi){ - vorbis_dsp_state *v=_ogg_calloc(1,sizeof(*v)); - _vds_init(v,vi); - vorbis_synthesis_restart(v); - return v; -} - -void vorbis_dsp_destroy(vorbis_dsp_state *v){ - int i; - if(v){ - vorbis_info *vi=v->vi; - codec_setup_info *ci=(codec_setup_info *)(vi?vi->codec_setup:NULL); - - if(v->pcm){ - for(i=0;i<vi->channels;i++) - if(v->pcm[i])_ogg_free(v->pcm[i]); - _ogg_free(v->pcm); - if(v->pcmret)_ogg_free(v->pcmret); - } - - _ogg_free(v); - } -} - -/* Unlike in analysis, the window is only partially applied for each - block. The time domain envelope is not yet handled at the point of - calling (as it relies on the previous block). */ - -int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){ - vorbis_info *vi=v->vi; - codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; - int i,j; - - if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL); - - v->lW=v->W; - v->W=vb->W; - v->nW=-1; - - if((v->sequence==-1)|| - (v->sequence+1 != vb->sequence)){ - v->granulepos=-1; /* out of sequence; lose count */ - v->sample_count=-1; - } - - v->sequence=vb->sequence; - - if(vb->pcm){ /* no pcm to process if vorbis_synthesis_trackonly - was called on block */ - int n=ci->blocksizes[v->W]/2; - int n0=ci->blocksizes[0]/2; - int n1=ci->blocksizes[1]/2; - - int thisCenter; - int prevCenter; - - if(v->centerW){ - thisCenter=n1; - prevCenter=0; - }else{ - thisCenter=0; - prevCenter=n1; - } - - /* v->pcm is now used like a two-stage double buffer. We don't want - to have to constantly shift *or* adjust memory usage. Don't - accept a new block until the old is shifted out */ - - /* overlap/add PCM */ - - for(j=0;j<vi->channels;j++){ - /* the overlap/add section */ - if(v->lW){ - if(v->W){ - /* large/large */ - ogg_int32_t *pcm=v->pcm[j]+prevCenter; - ogg_int32_t *p=vb->pcm[j]; - for(i=0;i<n1;i++) - pcm[i]+=p[i]; - }else{ - /* large/small */ - ogg_int32_t *pcm=v->pcm[j]+prevCenter+n1/2-n0/2; - ogg_int32_t *p=vb->pcm[j]; - for(i=0;i<n0;i++) - pcm[i]+=p[i]; - } - }else{ - if(v->W){ - /* small/large */ - ogg_int32_t *pcm=v->pcm[j]+prevCenter; - ogg_int32_t *p=vb->pcm[j]+n1/2-n0/2; - for(i=0;i<n0;i++) - pcm[i]+=p[i]; - for(;i<n1/2+n0/2;i++) - pcm[i]=p[i]; - }else{ - /* small/small */ - ogg_int32_t *pcm=v->pcm[j]+prevCenter; - ogg_int32_t *p=vb->pcm[j]; - for(i=0;i<n0;i++) - pcm[i]+=p[i]; - } - } - - /* the copy section */ - { - ogg_int32_t *pcm=v->pcm[j]+thisCenter; - ogg_int32_t *p=vb->pcm[j]+n; - for(i=0;i<n;i++) - pcm[i]=p[i]; - } - } - - if(v->centerW) - v->centerW=0; - else - v->centerW=n1; - - /* deal with initial packet state; we do this using the explicit - pcm_returned==-1 flag otherwise we're sensitive to first block - being short or long */ - - if(v->pcm_returned==-1){ - v->pcm_returned=thisCenter; - v->pcm_current=thisCenter; - }else{ - v->pcm_returned=prevCenter; - v->pcm_current=prevCenter+ - ci->blocksizes[v->lW]/4+ - ci->blocksizes[v->W]/4; - } - - } - - /* track the frame number... This is for convenience, but also - making sure our last packet doesn't end with added padding. If - the last packet is partial, the number of samples we'll have to - return will be past the vb->granulepos. - - This is not foolproof! It will be confused if we begin - decoding at the last page after a seek or hole. In that case, - we don't have a starting point to judge where the last frame - is. For this reason, vorbisfile will always try to make sure - it reads the last two marked pages in proper sequence */ - - if(v->sample_count==-1){ - v->sample_count=0; - }else{ - v->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4; - } - - if(v->granulepos==-1){ - if(vb->granulepos!=-1){ /* only set if we have a position to set to */ - - v->granulepos=vb->granulepos; - - /* is this a short page? */ - if(v->sample_count>v->granulepos){ - /* corner case; if this is both the first and last audio page, - then spec says the end is cut, not beginning */ - if(vb->eofflag){ - /* trim the end */ - /* no preceeding granulepos; assume we started at zero (we'd - have to in a short single-page stream) */ - /* granulepos could be -1 due to a seek, but that would result - in a long coun`t, not short count */ - - v->pcm_current-=(v->sample_count-v->granulepos); - }else{ - /* trim the beginning */ - v->pcm_returned+=(v->sample_count-v->granulepos); - if(v->pcm_returned>v->pcm_current) - v->pcm_returned=v->pcm_current; - } - - } - - } - }else{ - v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4; - if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){ - - if(v->granulepos>vb->granulepos){ - long extra=v->granulepos-vb->granulepos; - - if(extra) - if(vb->eofflag){ - /* partial last frame. Strip the extra samples off */ - v->pcm_current-=extra; - } /* else {Shouldn't happen *unless* the bitstream is out of - spec. Either way, believe the bitstream } */ - } /* else {Shouldn't happen *unless* the bitstream is out of - spec. Either way, believe the bitstream } */ - v->granulepos=vb->granulepos; - } - } - - return(0); -} - -/* pcm==NULL indicates we just want the pending samples, no more */ -int vorbis_synthesis_pcmout(vorbis_dsp_state *v,ogg_int32_t ***pcm){ - vorbis_info *vi=v->vi; - if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){ - if(pcm){ - int i; - for(i=0;i<vi->channels;i++) - v->pcmret[i]=v->pcm[i]+v->pcm_returned; - *pcm=v->pcmret; - } - return(v->pcm_current-v->pcm_returned); - } - return(0); -} - -int vorbis_synthesis_read(vorbis_dsp_state *v,int bytes){ - if(bytes && v->pcm_returned+bytes>v->pcm_current)return(OV_EINVAL); - v->pcm_returned+=bytes; - return(0); -} - diff --git a/codec_internal.h b/codec_internal.h index 7100786..bd7dd47 100644 --- a/codec_internal.h +++ b/codec_internal.h @@ -30,19 +30,45 @@ typedef void vorbis_info_floor; +/* vorbis_dsp_state buffers the current vorbis audio + analysis/synthesis state. The DSP state belongs to a specific + logical bitstream ****************************************************/ +struct vorbis_dsp_state{ + vorbis_info *vi; + oggpack_buffer opb; + + ogg_int32_t **work; + ogg_int32_t **mdctright; + int out_begin; + int out_end; + + long lW; + long W; + + ogg_int64_t granulepos; + ogg_int64_t sequence; + ogg_int64_t sample_count; + +}; + + /* Floor backend generic *****************************************/ extern vorbis_info_floor *floor0_info_unpack(vorbis_info *,oggpack_buffer *); extern void floor0_free_info(vorbis_info_floor *); -extern void *floor0_inverse1(struct vorbis_block *,vorbis_info_floor *); -extern int floor0_inverse2 (struct vorbis_block *,vorbis_info_floor *, - void *buffer,ogg_int32_t *); +extern int floor0_memosize(vorbis_info_floor *); +extern ogg_int32_t *floor0_inverse1(struct vorbis_dsp_state *, + vorbis_info_floor *,ogg_int32_t *); +extern int floor0_inverse2 (struct vorbis_dsp_state *,vorbis_info_floor *, + ogg_int32_t *buffer,ogg_int32_t *); extern vorbis_info_floor *floor1_info_unpack(vorbis_info *,oggpack_buffer *); extern void floor1_free_info(vorbis_info_floor *); -extern void *floor1_inverse1(struct vorbis_block *,vorbis_info_floor *); -extern int floor1_inverse2 (struct vorbis_block *,vorbis_info_floor *, - void *buffer,ogg_int32_t *); +extern int floor1_memosize(vorbis_info_floor *); +extern ogg_int32_t *floor1_inverse1(struct vorbis_dsp_state *, + vorbis_info_floor *,ogg_int32_t *); +extern int floor1_inverse2 (struct vorbis_dsp_state *,vorbis_info_floor *, + ogg_int32_t *buffer,ogg_int32_t *); typedef struct{ int order; @@ -99,7 +125,7 @@ typedef struct vorbis_info_residue{ extern void res_clear_info(vorbis_info_residue *info); extern int res_unpack(vorbis_info_residue *info, vorbis_info *vi,oggpack_buffer *opb); -extern int res_inverse(vorbis_block *vb,vorbis_info_residue *info, +extern int res_inverse(vorbis_dsp_state *,vorbis_info_residue *info, ogg_int32_t **in,int *nonzero,int ch); /* mode ************************************************************/ @@ -132,7 +158,7 @@ typedef struct vorbis_info_mapping{ extern int mapping_info_unpack(vorbis_info_mapping *,vorbis_info *, oggpack_buffer *); extern void mapping_clear_info(vorbis_info_mapping *); -extern int mapping_inverse(struct vorbis_block *vb,vorbis_info_mapping *); +extern int mapping_inverse(struct vorbis_dsp_state *,vorbis_info_mapping *); /* codec_setup_info contains all the setup information specific to the specific compression/decompression mode in progress (eg, @@ -167,4 +193,19 @@ typedef struct codec_setup_info { } codec_setup_info; +extern vorbis_dsp_state *vorbis_dsp_create(vorbis_info *vi); +extern void vorbis_dsp_destroy(vorbis_dsp_state *v); +extern int vorbis_dsp_headerin(vorbis_info *vi,vorbis_comment *vc, + ogg_packet *op); + +extern int vorbis_dsp_restart(vorbis_dsp_state *v); +extern int vorbis_dsp_synthesis(vorbis_dsp_state *vd, + ogg_packet *op,int decodep); +extern int vorbis_dsp_pcmout(vorbis_dsp_state *v, + ogg_int16_t *pcm,int samples); +extern int vorbis_dsp_read(vorbis_dsp_state *v,int samples); +extern long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op); + + + #endif @@ -365,25 +365,29 @@ vorbis_info_floor *floor0_info_unpack (vorbis_info *vi,oggpack_buffer *opb){ return(NULL); } -void *floor0_inverse1(vorbis_block *vb,vorbis_info_floor *i){ +int floor0_memosize(vorbis_info_floor *i){ + vorbis_info_floor0 *info=(vorbis_info_floor0 *)i; + return info->order+1; +} + +ogg_int32_t *floor0_inverse1(vorbis_dsp_state *vd,vorbis_info_floor *i, + ogg_int32_t *lsp){ vorbis_info_floor0 *info=(vorbis_info_floor0 *)i; int j,k; - int ampraw=oggpack_read(&vb->opb,info->ampbits); + int ampraw=oggpack_read(&vd->opb,info->ampbits); if(ampraw>0){ /* also handles the -1 out of data case */ long maxval=(1<<info->ampbits)-1; int amp=((ampraw*info->ampdB)<<4)/maxval; - int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks)); + int booknum=oggpack_read(&vd->opb,_ilog(info->numbooks)); if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */ - codec_setup_info *ci=(codec_setup_info *)vb->vd->vi->codec_setup; + codec_setup_info *ci=(codec_setup_info *)vd->vi->codec_setup; codebook *b=ci->book_param+info->books[booknum]; ogg_int32_t last=0; - ogg_int32_t *lsp= - (ogg_int32_t *)_vorbis_block_alloc(vb,sizeof(*lsp)*(info->order+1)); for(j=0;j<info->order;j+=b->dim) - if(vorbis_book_decodev_set(b,lsp+j,&vb->opb,b->dim,-24)==-1)goto eop; + if(vorbis_book_decodev_set(b,lsp+j,&vd->opb,b->dim,-24)==-1)goto eop; for(j=0;j<info->order;){ for(k=0;k<b->dim;k++,j++)lsp[j]+=last; last=lsp[j-1]; @@ -397,21 +401,21 @@ void *floor0_inverse1(vorbis_block *vb,vorbis_info_floor *i){ return(NULL); } -int floor0_inverse2(vorbis_block *vb,vorbis_info_floor *i, - void *memo,ogg_int32_t *out){ +int floor0_inverse2(vorbis_dsp_state *vd,vorbis_info_floor *i, + ogg_int32_t *lsp,ogg_int32_t *out){ vorbis_info_floor0 *info=(vorbis_info_floor0 *)i; + codec_setup_info *ci=(codec_setup_info *)vd->vi->codec_setup; - if(memo){ - ogg_int32_t *lsp=(ogg_int32_t *)memo; + if(lsp){ ogg_int32_t amp=lsp[info->order]; /* take the coefficients back to a spectral envelope curve */ - vorbis_lsp_to_curve(out,vb->pcmend/2,info->barkmap, + vorbis_lsp_to_curve(out,ci->blocksizes[vd->W]/2,info->barkmap, lsp,info->order,amp,info->ampdB, info->rate>>1); return(1); } - memset(out,0,sizeof(*out)*vb->pcmend/2); + memset(out,0,sizeof(*out)*ci->blocksizes[vd->W]/2); return(0); } @@ -269,23 +269,26 @@ static void render_line(int x0,int x1,int y0,int y1,ogg_int32_t *d){ } } +int floor1_memosize(vorbis_info_floor *i){ + vorbis_info_floor1 *info=(vorbis_info_floor1 *)i; + return info->posts; +} + static int quant_look[4]={256,128,86,64}; -void *floor1_inverse1(vorbis_block *vb,vorbis_info_floor *in){ +ogg_int32_t *floor1_inverse1(vorbis_dsp_state *vd,vorbis_info_floor *in, + ogg_int32_t *fit_value){ vorbis_info_floor1 *info=(vorbis_info_floor1 *)in; - codec_setup_info *ci=(codec_setup_info *)vb->vd->vi->codec_setup; + codec_setup_info *ci=(codec_setup_info *)vd->vi->codec_setup; int i,j,k; codebook *books=ci->book_param; int quant_q=quant_look[info->mult-1]; /* unpack wrapped/predicted values from stream */ - if(oggpack_read(&vb->opb,1)==1){ - int *fit_value= - (int *)_vorbis_block_alloc(vb,(info->posts)*sizeof(*fit_value)); - - fit_value[0]=oggpack_read(&vb->opb,ilog(quant_q-1)); - fit_value[1]=oggpack_read(&vb->opb,ilog(quant_q-1)); + if(oggpack_read(&vd->opb,1)==1){ + fit_value[0]=oggpack_read(&vd->opb,ilog(quant_q-1)); + fit_value[1]=oggpack_read(&vd->opb,ilog(quant_q-1)); /* partition by partition */ /* partition by partition */ @@ -298,7 +301,7 @@ void *floor1_inverse1(vorbis_block *vb,vorbis_info_floor *in){ /* decode the partition's first stage cascade value */ if(csubbits){ - cval=vorbis_book_decode(books+info->class[classv].class_book,&vb->opb); + cval=vorbis_book_decode(books+info->class[classv].class_book,&vd->opb); if(cval==-1)goto eop; } @@ -307,7 +310,7 @@ void *floor1_inverse1(vorbis_block *vb,vorbis_info_floor *in){ int book=info->class[classv].class_subbook[cval&(csub-1)]; cval>>=csubbits; if(book!=0xff){ - if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1) + if((fit_value[j+k]=vorbis_book_decode(books+book,&vd->opb))==-1) goto eop; }else{ fit_value[j+k]=0; @@ -359,17 +362,16 @@ void *floor1_inverse1(vorbis_block *vb,vorbis_info_floor *in){ return(NULL); } -int floor1_inverse2(vorbis_block *vb,vorbis_info_floor *in,void *memo, - ogg_int32_t *out){ +int floor1_inverse2(vorbis_dsp_state *vd,vorbis_info_floor *in, + ogg_int32_t *fit_value,ogg_int32_t *out){ vorbis_info_floor1 *info=(vorbis_info_floor1 *)in; - codec_setup_info *ci=(codec_setup_info *)vb->vd->vi->codec_setup; - int n=ci->blocksizes[vb->W]/2; + codec_setup_info *ci=(codec_setup_info *)vd->vi->codec_setup; + int n=ci->blocksizes[vd->W]/2; int j; - if(memo){ + if(fit_value){ /* render the lines */ - int *fit_value=(int *)memo; int hx=0; int lx=0; int ly=fit_value[0]*info->mult; @@ -284,7 +284,7 @@ static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){ with bitstream comments and a third packet that holds the codebook. */ -int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op){ +int vorbis_dsp_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op){ oggpack_buffer opb; if(op){ diff --git a/ivorbiscodec.h b/ivorbiscodec.h index 5a76dbf..0eea9eb 100644 --- a/ivorbiscodec.h +++ b/ivorbiscodec.h @@ -25,6 +25,9 @@ extern "C" #include "ogg.h" +struct vorbis_dsp_state; +typedef struct vorbis_dsp_state vorbis_dsp_state; + typedef struct vorbis_info{ int version; int channels; @@ -53,76 +56,7 @@ typedef struct vorbis_info{ void *codec_setup; } vorbis_info; -/* vorbis_dsp_state buffers the current vorbis audio - analysis/synthesis state. The DSP state belongs to a specific - logical bitstream ****************************************************/ -typedef struct vorbis_dsp_state{ - vorbis_info *vi; - - ogg_int32_t **pcm; - ogg_int32_t **pcmret; - int pcm_storage; - int pcm_current; - int pcm_returned; - - long lW; - long W; - long nW; - long centerW; - - ogg_int64_t granulepos; - ogg_int64_t sequence; - ogg_int64_t sample_count; - -} vorbis_dsp_state; - -typedef struct vorbis_block{ - /* necessary stream state for linking to the framing abstraction */ - ogg_int32_t **pcm; /* this is a pointer into local storage */ - oggpack_buffer opb; - - long lW; - long W; - long nW; - int pcmend; - int mode; - - int eofflag; - ogg_int64_t granulepos; - ogg_int64_t sequence; - vorbis_dsp_state *vd; /* For read-only access of configuration */ - - /* local storage to avoid remallocing; it's up to the mapping to - structure it */ - void *localstore; - long localtop; - long localalloc; - long totaluse; - struct alloc_chain *reap; - -} vorbis_block; - -/* vorbis_block is a single block of data to be processed as part of -the analysis/synthesis stream; it belongs to a specific logical -bitstream, but is independant from other vorbis_blocks belonging to -that logical bitstream. *************************************************/ - -struct alloc_chain{ - void *ptr; - struct alloc_chain *next; -}; - -/* vorbis_info contains all the setup information specific to the - specific compression/decompression mode in progress (eg, - psychoacoustic settings, channel setup, options, codebook - etc). vorbis_info and substructures are in backends.h. -*********************************************************************/ - -/* the comments are not part of vorbis_info so that vorbis_info can be - static storage */ typedef struct vorbis_comment{ - /* unlimited user comment fields. libvorbis writes 'libvorbis' - whatever vendor is set to in encode */ char **user_comments; int *comment_lengths; int comments; @@ -131,18 +65,6 @@ typedef struct vorbis_comment{ } vorbis_comment; -/* libvorbis encodes in two abstraction layers; first we perform DSP - and produce a packet (see docs/analysis.txt). The packet is then - coded into a framed OggSquish bitstream by the second layer (see - docs/framing.txt). Decode is the reverse process; we sync/frame - the bitstream and extract individual packets, then decode the - packet back into PCM audio. - - The extra framing/packetizing is used in streaming formats, such as - files. Over the net (such as with UDP), the framing and - packetization aren't necessary as they're provided by the transport - and the streaming layer is not used */ - /* Vorbis PRIMITIVES: general ***************************************/ extern void vorbis_info_init(vorbis_info *vi); @@ -156,23 +78,6 @@ extern char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count); extern int vorbis_comment_query_count(vorbis_comment *vc, char *tag); extern void vorbis_comment_clear(vorbis_comment *vc); -extern vorbis_block *vorbis_block_create(vorbis_dsp_state *v); -extern int vorbis_block_destroy(vorbis_block *vb); - -extern vorbis_dsp_state *vorbis_dsp_create(vorbis_info *vi); -extern void vorbis_dsp_destroy(vorbis_dsp_state *v); - -/* Vorbis PRIMITIVES: synthesis layer *******************************/ -extern int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc, - ogg_packet *op); - -extern int vorbis_synthesis_restart(vorbis_dsp_state *v); -extern int vorbis_synthesis(vorbis_block *vb,ogg_packet *op,int decodep); -extern int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb); -extern int vorbis_synthesis_pcmout(vorbis_dsp_state *v,ogg_int32_t ***pcm); -extern int vorbis_synthesis_read(vorbis_dsp_state *v,int samples); -extern long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op); - /* Vorbis ERRORS and return codes ***********************************/ #define OV_FALSE -1 diff --git a/ivorbisfile.h b/ivorbisfile.h index e01afe0..50f4f5e 100644 --- a/ivorbisfile.h +++ b/ivorbisfile.h @@ -79,7 +79,6 @@ typedef struct OggVorbis_File { ogg_stream_state *os; /* take physical pages, weld into a logical stream of packets */ vorbis_dsp_state *vd; /* central working state for the packet->PCM decoder */ - vorbis_block *vb; /* local working space for packet->PCM decode */ ov_callbacks callbacks; @@ -118,7 +117,7 @@ extern ogg_int64_t ov_time_tell(OggVorbis_File *vf); extern vorbis_info *ov_info(OggVorbis_File *vf,int link); extern vorbis_comment *ov_comment(OggVorbis_File *vf,int link); -extern long ov_read(OggVorbis_File *vf,char *buffer,int length, +extern long ov_read(OggVorbis_File *vf,void *buffer,int length, int *bitstream); #ifdef __cplusplus @@ -25,63 +25,6 @@ #include "codec_internal.h" #include "codebook.h" #include "misc.h" -#include "window_lookup.h" - -static const void *_vorbis_window(int left){ - switch(left){ - case 32: - return vwin64; - case 64: - return vwin128; - case 128: - return vwin256; - case 256: - return vwin512; - case 512: - return vwin1024; - case 1024: - return vwin2048; - case 2048: - return vwin4096; - case 4096: - return vwin8192; - default: - return(0); - } -} - -static void _vorbis_apply_window(ogg_int32_t *d, - long *blocksizes, - int lW,int W,int nW){ - - LOOKUP_T *window[2]; - long n=blocksizes[W]; - long ln=blocksizes[lW]; - long rn=blocksizes[nW]; - - long leftbegin=n/4-ln/4; - long leftend=leftbegin+ln/2; - - long rightbegin=n/2+n/4-rn/4; - long rightend=rightbegin+rn/2; - - int i,p; - - window[0]=_vorbis_window(blocksizes[0]>>1); - window[1]=_vorbis_window(blocksizes[1]>>1); - - for(i=0;i<leftbegin;i++) - d[i]=0; - - for(p=0;i<leftend;i++,p++) - d[i]=MULT31(d[i],window[lW][p]); - - for(i=rightbegin,p=rn/2-1;i<rightend;i++,p--) - d[i]=MULT31(d[i],window[nW][p]); - - for(;i<n;i++) - d[i]=0; -} void mapping_clear_info(vorbis_info_mapping *info){ if(info){ @@ -158,13 +101,12 @@ int mapping_info_unpack(vorbis_info_mapping *info,vorbis_info *vi, return -1; } -int mapping_inverse(vorbis_block *vb,vorbis_info_mapping *info){ - vorbis_dsp_state *vd=vb->vd; +int mapping_inverse(vorbis_dsp_state *vd,vorbis_info_mapping *info){ vorbis_info *vi=vd->vi; codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; int i,j; - long n=vb->pcmend=ci->blocksizes[vb->W]; + long n=ci->blocksizes[vd->W]; ogg_int32_t **pcmbundle= (ogg_int32_t **)alloca(sizeof(*pcmbundle)*vi->channels); @@ -172,7 +114,7 @@ int mapping_inverse(vorbis_block *vb,vorbis_info_mapping *info){ (int *)alloca(sizeof(*zerobundle)*vi->channels); int *nonzero= (int *)alloca(sizeof(*nonzero)*vi->channels); - void **floormemo= + ogg_int32_t **floormemo= (void **)alloca(sizeof(*floormemo)*vi->channels); /* recover the spectral envelope; store it in the PCM vector for now */ @@ -186,17 +128,21 @@ int mapping_inverse(vorbis_block *vb,vorbis_info_mapping *info){ if(ci->floor_type[floorno]){ /* floor 1 */ - floormemo[i]=floor1_inverse1(vb,ci->floor_param[floorno]); + floormemo[i]=alloca(sizeof(*floormemo[i])* + floor1_memosize(ci->floor_param[floorno])); + floormemo[i]=floor1_inverse1(vd,ci->floor_param[floorno],floormemo[i]); }else{ /* floor 0 */ - floormemo[i]=floor0_inverse1(vb,ci->floor_param[floorno]); + floormemo[i]=alloca(sizeof(*floormemo[i])* + floor0_memosize(ci->floor_param[floorno])); + floormemo[i]=floor0_inverse1(vd,ci->floor_param[floorno],floormemo[i]); } - + if(floormemo[i]) nonzero[i]=1; else nonzero[i]=0; - memset(vb->pcm[i],0,sizeof(*vb->pcm[i])*n/2); + memset(vd->work[i],0,sizeof(*vd->work[i])*n/2); } /* channel coupling can 'dirty' the nonzero listing */ @@ -217,11 +163,11 @@ int mapping_inverse(vorbis_block *vb,vorbis_info_mapping *info){ zerobundle[ch_in_bundle]=1; else zerobundle[ch_in_bundle]=0; - pcmbundle[ch_in_bundle++]=vb->pcm[j]; + pcmbundle[ch_in_bundle++]=vd->work[j]; } } - res_inverse(vb,ci->residue_param+info->submaplist[i].residue, + res_inverse(vd,ci->residue_param+info->submaplist[i].residue, pcmbundle,zerobundle,ch_in_bundle); } @@ -230,8 +176,8 @@ int mapping_inverse(vorbis_block *vb,vorbis_info_mapping *info){ /* channel coupling */ for(i=info->coupling_steps-1;i>=0;i--){ - ogg_int32_t *pcmM=vb->pcm[info->coupling[i].mag]; - ogg_int32_t *pcmA=vb->pcm[info->coupling[i].ang]; + ogg_int32_t *pcmM=vd->work[info->coupling[i].mag]; + ogg_int32_t *pcmA=vd->work[info->coupling[i].ang]; for(j=0;j<n/2;j++){ ogg_int32_t mag=pcmM[j]; @@ -261,7 +207,7 @@ int mapping_inverse(vorbis_block *vb,vorbis_info_mapping *info){ /* compute and apply spectral envelope */ for(i=0;i<vi->channels;i++){ - ogg_int32_t *pcm=vb->pcm[i]; + ogg_int32_t *pcm=vd->work[i]; int submap=0; int floorno; @@ -271,10 +217,10 @@ int mapping_inverse(vorbis_block *vb,vorbis_info_mapping *info){ if(ci->floor_type[floorno]){ /* floor 1 */ - floor1_inverse2(vb,ci->floor_param[floorno],floormemo[i],pcm); + floor1_inverse2(vd,ci->floor_param[floorno],floormemo[i],pcm); }else{ /* floor 0 */ - floor0_inverse2(vb,ci->floor_param[floorno],floormemo[i],pcm); + floor0_inverse2(vd,ci->floor_param[floorno],floormemo[i],pcm); } } @@ -283,28 +229,12 @@ int mapping_inverse(vorbis_block *vb,vorbis_info_mapping *info){ /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */ /* only MDCT right now.... */ - for(i=0;i<vi->channels;i++){ - ogg_int32_t *pcm=vb->pcm[i]; - mdct_backward(n,pcm,pcm); - } + for(i=0;i<vi->channels;i++) + mdct_backward(n,vd->work[i]); //for(j=0;j<vi->channels;j++) //_analysis_output("imdct",seq+j,vb->pcm[j],-24,n,0,0); - /* window the data */ - for(i=0;i<vi->channels;i++){ - ogg_int32_t *pcm=vb->pcm[i]; - if(nonzero[i]) - _vorbis_apply_window(pcm,ci->blocksizes,vb->lW,vb->W,vb->nW); - else - for(j=0;j<n;j++) - pcm[j]=0; - - } - - //for(j=0;j<vi->channels;j++) - //_analysis_output("window",seq+j,vb->pcm[j],-24,n,0,0); - /* all done! */ return(0); } @@ -13,7 +13,7 @@ function: normalized modified discrete cosine transform power of two length transform only [64 <= n ] - last mod: $Id: mdct.c,v 1.9.6.3 2003/04/22 06:58:24 xiphmont Exp $ + last mod: $Id: mdct.c,v 1.9.6.4 2003/04/22 09:00:49 xiphmont Exp $ Original algorithm adapted long ago from _The use of multirate filter banks for coding of high quality digital audio_, by T. Sporer, @@ -434,7 +434,7 @@ void mdct_unroll_lap(int n0,int n1, start -= off; end -= n; while(r>post){ - out++ = CLIP_TO_15((*--r)>>9); + *out = CLIP_TO_15((*--r)>>9); out+=step; } } @@ -88,11 +88,11 @@ int res_unpack(vorbis_info_residue *info, return 1; } -int res_inverse(vorbis_block *vb,vorbis_info_residue *info, +int res_inverse(vorbis_dsp_state *vd,vorbis_info_residue *info, ogg_int32_t **in,int *nonzero,int ch){ int i,j,k,s,used=0; - codec_setup_info *ci=(codec_setup_info *)vb->vd->vi->codec_setup; + codec_setup_info *ci=(codec_setup_info *)vd->vi->codec_setup; codebook *phrasebook=ci->book_param+info->groupbook; int samples_per_partition=info->grouping; int partitions_per_word=phrasebook->dim; @@ -128,8 +128,8 @@ int res_inverse(vorbis_block *vb,vorbis_info_residue *info, partword[j][i+k]=partword[j-1][i+k]; for(j=0;j<ch;j++){ - int temp=vorbis_book_decode(phrasebook,&vb->opb); - if(oggpack_eop(&vb->opb))goto eopbreak; + int temp=vorbis_book_decode(phrasebook,&vd->opb); + if(oggpack_eop(&vd->opb))goto eopbreak; /* this can be done quickly in assembly due to the quotient always being at most six bits */ @@ -150,11 +150,11 @@ int res_inverse(vorbis_block *vb,vorbis_info_residue *info, codebook *stagebook=ci->book_param+ info->stagebooks[(partword[j][i]<<3)+s]; if(info->type){ - if(vorbis_book_decodev_add(stagebook,in[j]+offset,&vb->opb, + if(vorbis_book_decodev_add(stagebook,in[j]+offset,&vd->opb, samples_per_partition,-8)==-1) goto eopbreak; }else{ - if(vorbis_book_decodevs_add(stagebook,in[j]+offset,&vb->opb, + if(vorbis_book_decodevs_add(stagebook,in[j]+offset,&vd->opb, samples_per_partition,-8)==-1) goto eopbreak; } @@ -184,8 +184,8 @@ int res_inverse(vorbis_block *vb,vorbis_info_residue *info, partword[i+k]=partword[i+k+1]*info->partitions; /* fetch the partition word */ - temp=vorbis_book_decode(phrasebook,&vb->opb); - if(oggpack_eop(&vb->opb))goto eopbreak; + temp=vorbis_book_decode(phrasebook,&vd->opb); + if(oggpack_eop(&vd->opb))goto eopbreak; /* this can be done quickly in assembly due to the quotient always being at most six bits */ @@ -203,7 +203,7 @@ int res_inverse(vorbis_block *vb,vorbis_info_residue *info, info->stagebooks[(partword[i]<<3)+s]; if(vorbis_book_decodevv_add(stagebook,in, i*samples_per_partition+beginoff,ch, - &vb->opb, + &vd->opb, samples_per_partition,-8)==-1) goto eopbreak; } diff --git a/synthesis.c b/synthesis.c deleted file mode 100644 index 1f3db9b..0000000 --- a/synthesis.c +++ /dev/null @@ -1,119 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * - * * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 * - * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * - * * - ******************************************************************** - - function: single-block PCM synthesis - last mod: $Id: synthesis.c,v 1.4.2.3 2003/04/14 01:13:44 xiphmont Exp $ - - ********************************************************************/ - -#include <stdio.h> -#include "ogg.h" -#include "ivorbiscodec.h" -#include "codec_internal.h" -#include "misc.h" -#include "os.h" - -static int ilog(unsigned int v){ - int ret=0; - if(v)--v; - while(v){ - ret++; - v>>=1; - } - return(ret); -} - -int vorbis_synthesis(vorbis_block *vb,ogg_packet *op,int decodep){ - vorbis_dsp_state *vd=vb->vd; - vorbis_info *vi=vd->vi; - codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; - oggpack_buffer *opb=&vb->opb; - int type,mode,i; - - /* first things first. Make sure decode is ready */ - _vorbis_block_ripcord(vb); - oggpack_readinit(opb,op->packet); - - /* Check the packet type */ - if(oggpack_read(opb,1)!=0){ - /* Oops. This is not an audio data packet */ - return(OV_ENOTAUDIO); - } - - /* read our mode and pre/post windowsize */ - mode=oggpack_read(opb,ilog(ci->modes)); - if(mode==-1)return(OV_EBADPACKET); - - vb->mode=mode; - vb->W=ci->mode_param[mode].blockflag; - if(vb->W){ - vb->lW=oggpack_read(opb,1); - vb->nW=oggpack_read(opb,1); - if(vb->nW==-1) return(OV_EBADPACKET); - }else{ - vb->lW=0; - vb->nW=0; - } - - /* more setup */ - vb->granulepos=op->granulepos; - vb->sequence=op->packetno-3; /* first block is third packet */ - vb->eofflag=op->e_o_s; - - if(decodep){ - /* alloc pcm passback storage */ - vb->pcmend=ci->blocksizes[vb->W]; - vb->pcm=(ogg_int32_t **)_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels); - for(i=0;i<vi->channels;i++) - vb->pcm[i]=(ogg_int32_t *)_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i])); - - /* unpack_header enforces range checking */ - return(mapping_inverse(vb,ci->map_param+ci->mode_param[mode].mapping)); - }else{ - /* no pcm */ - vb->pcmend=0; - vb->pcm=NULL; - - return 0; - } -} - -long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){ - codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; - oggpack_buffer opb; - int mode; - - oggpack_readinit(&opb,op->packet); - - /* Check the packet type */ - if(oggpack_read(&opb,1)!=0){ - /* Oops. This is not an audio data packet */ - return(OV_ENOTAUDIO); - } - - { - int modebits=0; - int v=ci->modes; - while(v>1){ - modebits++; - v>>=1; - } - - /* read our mode and pre/post windowsize */ - mode=oggpack_read(&opb,modebits); - } - if(mode==-1)return(OV_EBADPACKET); - return(ci->blocksizes[ci->mode_param[mode].blockflag]); -} - - diff --git a/vorbisfile.c b/vorbisfile.c index 93e681f..c517707 100644 --- a/vorbisfile.c +++ b/vorbisfile.c @@ -12,7 +12,7 @@ ******************************************************************** function: stdio-based convenience library for opening/seeking/decoding - last mod: $Id: vorbisfile.c,v 1.6.2.2 2003/04/14 06:40:51 xiphmont Exp $ + last mod: $Id: vorbisfile.c,v 1.6.2.3 2003/04/22 09:00:49 xiphmont Exp $ ********************************************************************/ @@ -22,7 +22,7 @@ #include <string.h> #include <math.h> -#include "ivorbiscodec.h" +#include "codec_internal.h" #include "ivorbisfile.h" #include "os.h" @@ -269,7 +269,7 @@ static int _fetch_headers(OggVorbis_File *vf, ret=OV_EBADHEADER; goto bail_header; } - if((ret=vorbis_synthesis_headerin(vi,vc,&op))){ + if((ret=vorbis_dsp_headerin(vi,vc,&op))){ goto bail_header; } i++; @@ -413,7 +413,6 @@ static void _make_decode_ready(OggVorbis_File *vf){ }else{ vf->vd=vorbis_dsp_create(vf->vi); } - vf->vb=vorbis_block_create(vf->vd); vf->ready_state=INITSET; vf->bittrack=0; vf->samptrack=0; @@ -462,9 +461,7 @@ static int _open_seekable2(OggVorbis_File *vf){ /* clear out the current logical bitstream decoder */ static void _decode_clear(OggVorbis_File *vf){ vorbis_dsp_destroy(vf->vd); - vorbis_block_destroy(vf->vb); vf->vd=0; - vf->vb=0; vf->ready_state=OPENED; } @@ -504,28 +501,16 @@ static int _fetch_and_process_packet(OggVorbis_File *vf, if(result>0){ /* got a packet. process it */ granulepos=op.granulepos; - if(!vorbis_synthesis(vf->vb,&op,1)){ /* lazy check for lazy + if(!vorbis_dsp_synthesis(vf->vd,&op,1)){ /* lazy check for lazy header handling. The header packets aren't audio, so if/when we submit them, vorbis_synthesis will reject them */ - - /* suck in the synthesis data and track bitrate */ - { - int oldsamples=vorbis_synthesis_pcmout(vf->vd,NULL); - /* for proper use of libvorbis within libvorbisfile, - oldsamples will always be zero. */ - if(oldsamples){ - ret=OV_EFAULT; - goto cleanup; - } - - vorbis_synthesis_blockin(vf->vd,vf->vb); - vf->samptrack+=vorbis_synthesis_pcmout(vf->vd,NULL)-oldsamples; - vf->bittrack+=op.bytes*8; - } + + vf->samptrack+=vorbis_dsp_pcmout(vf->vd,NULL,0); + vf->bittrack+=op.bytes*8; /* update the pcm offset. */ if(granulepos!=-1 && !op.e_o_s){ @@ -552,7 +537,7 @@ static int _fetch_and_process_packet(OggVorbis_File *vf, here unless the stream is very broken */ - samples=vorbis_synthesis_pcmout(vf->vd,NULL); + samples=vorbis_dsp_pcmout(vf->vd,NULL,0); granulepos-=samples; for(i=0;i<link;i++) @@ -728,10 +713,8 @@ static int _ov_open2(OggVorbis_File *vf){ /* clear out the OggVorbis_File struct */ int ov_clear(OggVorbis_File *vf){ if(vf){ - vorbis_block_destroy(vf->vb); vorbis_dsp_destroy(vf->vd); vf->vd=0; - vf->vb=0; ogg_stream_destroy(vf->os); if(vf->vi && vf->links){ @@ -974,7 +957,7 @@ int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){ vf->pcm_offset=-1; ogg_stream_reset_serialno(vf->os, vf->current_serialno); /* must set serialno */ - vorbis_synthesis_restart(vf->vd); + vorbis_dsp_restart(vf->vd); _seek_helper(vf,pos); @@ -1218,7 +1201,7 @@ int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){ vf->ready_state=STREAMSET; }else{ - vorbis_synthesis_restart(vf->vd); + vorbis_dsp_restart(vf->vd); } ogg_stream_reset_serialno(vf->os,vf->current_serialno); @@ -1313,10 +1296,9 @@ int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){ /* remove the packet from packet queue and track its granulepos */ ogg_stream_packetout(vf->os,NULL); - vorbis_synthesis(vf->vb,&op,0); /* set up a vb with - only tracking, no - pcm_decode */ - vorbis_synthesis_blockin(vf->vd,vf->vb); + vorbis_dsp_synthesis(vf->vd,&op,0); /* set up a vb with + only tracking, no + pcm_decode */ /* end of logical stream case is hard, especially with exact length positioning. */ @@ -1368,10 +1350,10 @@ int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){ logical bitstream boundary with abandon is OK. */ while(vf->pcm_offset<pos){ ogg_int64_t target=pos-vf->pcm_offset; - long samples=vorbis_synthesis_pcmout(vf->vd,NULL); + long samples=vorbis_dsp_pcmout(vf->vd,NULL,0); if(samples>target)samples=target; - vorbis_synthesis_read(vf->vd,samples); + vorbis_dsp_read(vf->vd,samples); vf->pcm_offset+=samples; if(samples<target) @@ -1543,18 +1525,27 @@ vorbis_comment *ov_comment(OggVorbis_File *vf,int link){ *section) set to the logical bitstream number */ -long ov_read(OggVorbis_File *vf,char *buffer,int bytes_req,int *bitstream){ +long ov_read(OggVorbis_File *vf,void *buffer,int bytes_req,int *bitstream){ int i,j; - ogg_int32_t **pcm; long samples; + long channels; if(vf->ready_state<OPENED)return(OV_EINVAL); while(1){ if(vf->ready_state==INITSET){ - samples=vorbis_synthesis_pcmout(vf->vd,&pcm); - if(samples)break; + channels=ov_info(vf,-1)->channels; + samples=vorbis_dsp_pcmout(vf->vd,buffer,(bytes_req>>1)/channels); + if(samples){ + if(samples>0){ + vorbis_dsp_read(vf->vd,samples); + vf->pcm_offset+=samples; + if(bitstream)*bitstream=vf->current_link; + return(samples*2*channels); + } + return(samples); + } } /* suck in another packet */ @@ -1567,35 +1558,4 @@ long ov_read(OggVorbis_File *vf,char *buffer,int bytes_req,int *bitstream){ } } - - if(samples>0){ - - /* yay! proceed to pack data into the byte buffer */ - - long channels=ov_info(vf,-1)->channels; - - if(channels==1){ - if(samples>(bytes_req/2)) - samples=bytes_req/2; - }else{ - if(samples>(bytes_req/4)) - samples=bytes_req/4; - } - - for(i=0;i<channels;i++) { /* It's faster in this order */ - ogg_int32_t *src=pcm[i]; - short *dest=((short *)buffer)+i; - for(j=0;j<samples;j++) { - *dest=CLIP_TO_15(src[j]>>9); - dest+=channels; - } - } - - vorbis_synthesis_read(vf->vd,samples); - vf->pcm_offset+=samples; - if(bitstream)*bitstream=vf->current_link; - return(samples*2*channels); - }else{ - return(samples); - } } |