diff options
author | Monty <xiphmont@xiph.org> | 2003-04-13 09:03:09 +0000 |
---|---|---|
committer | Monty <xiphmont@xiph.org> | 2003-04-13 09:03:09 +0000 |
commit | 337db8ef0bb7e64ad8fcffa341d298680b1f9d27 (patch) | |
tree | 3ae44372b0b63b5626c76758c06c9fa1b14bd432 | |
parent | e53ab577810533fdc0836bfb404f33fa26c603c4 (diff) | |
download | tremor-337db8ef0bb7e64ad8fcffa341d298680b1f9d27.tar.gz |
Continuing reduction work; res012.c completed
git-svn-id: https://svn.xiph.org/branches/lowmem-branch/Tremor@4607 0101bb08-14d6-0310-b084-bc0e0c8e3800
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | backends.h | 134 | ||||
-rw-r--r-- | block.c | 13 | ||||
-rw-r--r-- | codec_internal.h | 127 | ||||
-rw-r--r-- | floor0.c | 1 | ||||
-rw-r--r-- | floor1.c | 2 | ||||
-rw-r--r-- | info.c | 53 | ||||
-rw-r--r-- | mapping0.c | 25 | ||||
-rw-r--r-- | registry.c | 10 | ||||
-rw-r--r-- | registry.h | 40 | ||||
-rw-r--r-- | res012.c | 385 | ||||
-rw-r--r-- | synthesis.c | 11 |
12 files changed, 281 insertions, 522 deletions
diff --git a/Makefile.am b/Makefile.am index ab7b371..7321631 100644 --- a/Makefile.am +++ b/Makefile.am @@ -12,7 +12,7 @@ libvorbisidec_la_SOURCES = mdct.c block.c window.c \ codebook.h misc.h mdct_lookup.h\ os.h mdct.h ivorbisfile.h lsp_lookup.h\ registry.h window.h window_lookup.h\ - codec_internal.h backends.h ogg.h \ + codec_internal.h ogg.h \ asm_arm.h ivorbiscodec.h libvorbisidec_la_LDFLAGS = -version-info @V_LIB_CURRENT@:@V_LIB_REVISION@:@V_LIB_AGE@ diff --git a/backends.h b/backends.h deleted file mode 100644 index 1ed4063..0000000 --- a/backends.h +++ /dev/null @@ -1,134 +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: backend and mapping structures - - ********************************************************************/ - -/* this is exposed up here because we need it for static modes. - Lookups for each backend aren't exposed because there's no reason - to do so */ - -#ifndef _vorbis_backend_h_ -#define _vorbis_backend_h_ - -#include "codec_internal.h" - -/* this would all be simpler/shorter with templates, but.... */ -/* Transform backend generic *************************************/ - -/* only mdct right now. Flesh it out more if we ever transcend mdct - in the transform domain */ - -/* Floor backend generic *****************************************/ -typedef struct{ - vorbis_info_floor *(*unpack)(vorbis_info *,oggpack_buffer *); - void (*free_info) (vorbis_info_floor *); - void *(*inverse1) (struct vorbis_block *,vorbis_look_floor *); - int (*inverse2) (struct vorbis_block *,vorbis_look_floor *, - void *buffer,ogg_int32_t *); -} vorbis_func_floor; - -typedef struct{ - int order; - long rate; - long barkmap; - - int ampbits; - int ampdB; - - int numbooks; /* <= 16 */ - char books[16]; - -} vorbis_info_floor0; - -#define VIF_POSIT 63 -#define VIF_CLASS 16 -#define VIF_PARTS 31 - -typedef struct{ - char class_dim; /* 1 to 8 */ - char class_subs; /* 0,1,2,3 (bits: 1<<n poss) */ - unsigned char class_book; /* subs ^ dim entries */ - unsigned char class_subbook[8]; /* [VIF_CLASS][subs] */ -} floor1class; - -typedef struct{ - floor1class *class; /* [VIF_CLASS] */ - char *partitionclass; /* [VIF_PARTS]; 0 to 15 */ - ogg_uint16_t *postlist; /* [VIF_POSIT+2]; first two implicit */ - char *forward_index; /* [VIF_POSIT+2]; */ - char *hineighbor; /* [VIF_POSIT]; */ - char *loneighbor; /* [VIF_POSIT]; */ - - int partitions; /* 0 to 31 */ - int posts; - int mult; /* 1 2 3 or 4 */ - -} vorbis_info_floor1; - -/* Residue backend generic *****************************************/ -typedef struct{ - vorbis_info_residue *(*unpack)(vorbis_info *,oggpack_buffer *); - vorbis_look_residue *(*look) (vorbis_dsp_state *,vorbis_info_mode *, - vorbis_info_residue *); - void (*free_info) (vorbis_info_residue *); - void (*free_look) (vorbis_look_residue *); - int (*inverse) (struct vorbis_block *,vorbis_look_residue *, - ogg_int32_t **,int *,int); -} vorbis_func_residue; - -typedef struct vorbis_info_residue0{ -/* block-partitioned VQ coded straight residue */ - long begin; - long end; - - /* first stage (lossless partitioning) */ - int grouping; /* group n vectors per partition */ - int partitions; /* possible codebooks for a partition */ - int groupbook; /* huffbook for partitioning */ - int secondstages[64]; /* expanded out to pointers in lookup */ - int booklist[256]; /* list of second stage books */ -} vorbis_info_residue0; - -/* Mapping backend generic *****************************************/ -typedef struct{ - vorbis_info_mapping *(*unpack)(vorbis_info *,oggpack_buffer *); - vorbis_look_mapping *(*look) (vorbis_dsp_state *,vorbis_info_mode *, - vorbis_info_mapping *); - void (*free_info) (vorbis_info_mapping *); - void (*free_look) (vorbis_look_mapping *); - int (*inverse) (struct vorbis_block *vb,vorbis_look_mapping *); -} vorbis_func_mapping; - -typedef struct vorbis_info_mapping0{ - int submaps; /* <= 16 */ - int chmuxlist[256]; /* up to 256 channels in a Vorbis stream */ - - int floorsubmap[16]; /* [mux] submap to floors */ - int residuesubmap[16]; /* [mux] submap to residue */ - - int psy[2]; /* by blocktype; impulse/padding for short, - transition/normal for long */ - - int coupling_steps; - int coupling_mag[256]; - int coupling_ang[256]; -} vorbis_info_mapping0; - -#endif - - - - - @@ -23,7 +23,6 @@ #include "codec_internal.h" #include "window.h" -#include "registry.h" #include "misc.h" static int ilog(unsigned int v){ @@ -172,10 +171,9 @@ static int _vds_init(vorbis_dsp_state *v,vorbis_info *vi){ /* initialize all the mapping/backend lookups */ b->mode=(vorbis_look_mapping **)_ogg_calloc(ci->modes,sizeof(*b->mode)); for(i=0;i<ci->modes;i++){ - int mapnum=ci->mode_param[i]->mapping; - int maptype=ci->map_type[mapnum]; - b->mode[i]=_mapping_P[maptype]->look(v,ci->mode_param[i], - ci->map_param[mapnum]); + int mapnum=ci->mode_param[i].mapping; + b->mode[i]=_mapping_P[0]->look(v,ci->mode_param+i, + ci->map_param[mapnum]); } return(0); } @@ -224,9 +222,8 @@ void vorbis_dsp_clear(vorbis_dsp_state *v){ /* free mode lookups; these are actually vorbis_look_mapping structs */ if(ci){ for(i=0;i<ci->modes;i++){ - int mapnum=ci->mode_param[i]->mapping; - int maptype=ci->map_type[mapnum]; - if(b && b->mode)_mapping_P[maptype]->free_look(b->mode[i]); + int mapnum=ci->mode_param[i].mapping; + if(b && b->mode)_mapping_P[0]->free_look(b->mode[i]); } } diff --git a/codec_internal.h b/codec_internal.h index 4f12c93..8abbcc3 100644 --- a/codec_internal.h +++ b/codec_internal.h @@ -20,22 +20,116 @@ #include "codebook.h" -typedef void vorbis_look_mapping; -typedef void vorbis_look_floor; -typedef void vorbis_look_residue; -typedef void vorbis_look_transform; +#define VI_TRANSFORMB 1 +#define VI_WINDOWB 1 +#define VI_TIMEB 1 +#define VI_FLOORB 2 +#define VI_RESB 3 +#define VI_MAPB 1 + +typedef void vorbis_info_floor; +typedef void vorbis_info_mapping; + +/* Floor backend generic *****************************************/ +typedef struct{ + vorbis_info_floor *(*unpack)(vorbis_info *,oggpack_buffer *); + void (*free_info) (vorbis_info_floor *); + void *(*inverse1) (struct vorbis_block *,vorbis_info_floor *); + int (*inverse2) (struct vorbis_block *,vorbis_info_floor *, + void *buffer,ogg_int32_t *); +} vorbis_func_floor; + +typedef struct{ + int order; + long rate; + long barkmap; + + int ampbits; + int ampdB; + + int numbooks; /* <= 16 */ + char books[16]; + +} vorbis_info_floor0; + +typedef struct{ + char class_dim; /* 1 to 8 */ + char class_subs; /* 0,1,2,3 (bits: 1<<n poss) */ + unsigned char class_book; /* subs ^ dim entries */ + unsigned char class_subbook[8]; /* [VIF_CLASS][subs] */ +} floor1class; + +typedef struct{ + floor1class *class; /* [VIF_CLASS] */ + char *partitionclass; /* [VIF_PARTS]; 0 to 15 */ + ogg_uint16_t *postlist; /* [VIF_POSIT+2]; first two implicit */ + char *forward_index; /* [VIF_POSIT+2]; */ + char *hineighbor; /* [VIF_POSIT]; */ + char *loneighbor; /* [VIF_POSIT]; */ + + int partitions; /* 0 to 31 */ + int posts; + int mult; /* 1 2 3 or 4 */ + +} vorbis_info_floor1; + +/* Residue backend generic *****************************************/ + +typedef struct vorbis_info_residue{ + int type; + unsigned char *stagemasks; + unsigned char *stagebooks; + +/* block-partitioned VQ coded straight residue */ + long begin; + long end; + + /* first stage (lossless partitioning) */ + int grouping; /* group n vectors per partition */ + char partitions; /* possible codebooks for a partition */ + unsigned char groupbook; /* huffbook for partitioning */ + char stages; +} 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, + ogg_int32_t **in,int *nonzero,int ch); /* mode ************************************************************/ typedef struct { int blockflag; - int windowtype; - int transformtype; int mapping; } vorbis_info_mode; -typedef void vorbis_info_floor; -typedef void vorbis_info_residue; -typedef void vorbis_info_mapping; +/* Mapping backend generic *****************************************/ + +typedef void vorbis_look_mapping; + +typedef struct{ + vorbis_info_mapping *(*unpack)(vorbis_info *,oggpack_buffer *); + vorbis_look_mapping *(*look) (vorbis_dsp_state *,vorbis_info_mode *, + vorbis_info_mapping *); + void (*free_info) (vorbis_info_mapping *); + void (*free_look) (vorbis_look_mapping *); + int (*inverse) (struct vorbis_block *vb,vorbis_look_mapping *); +} vorbis_func_mapping; + +typedef struct vorbis_info_mapping0{ + int submaps; /* <= 16 */ + int chmuxlist[256]; /* up to 256 channels in a Vorbis stream */ + + int floorsubmap[16]; /* [mux] submap to floors */ + int residuesubmap[16]; /* [mux] submap to residue */ + + int psy[2]; /* by blocktype; impulse/padding for short, + transition/normal for long */ + + int coupling_steps; + int coupling_mag[256]; + int coupling_ang[256]; +} vorbis_info_mapping0; typedef struct private_state { /* local lookup storage */ @@ -69,23 +163,20 @@ typedef struct codec_setup_info { int modes; int maps; - int times; int floors; int residues; int books; - vorbis_info_mode *mode_param[64]; - int map_type[64]; + vorbis_info_mode *mode_param; vorbis_info_mapping *map_param[64]; - int time_type[64]; char *floor_type; - vorbis_info_floor **floor_param; - int residue_type[64]; - vorbis_info_residue *residue_param[64]; + vorbis_info_floor **floor_param; + vorbis_info_residue *residue_param; codebook *book_param; - int passlimit[32]; /* iteration limit per couple/quant pass */ - int coupling_passes; } codec_setup_info; +extern vorbis_func_floor *_floor_P[]; +extern vorbis_func_mapping *_mapping_P[]; + #endif @@ -21,7 +21,6 @@ #include "ogg.h" #include "ivorbiscodec.h" #include "codec_internal.h" -#include "registry.h" #include "codebook.h" #include "misc.h" #include "os.h" @@ -21,11 +21,11 @@ #include "ogg.h" #include "ivorbiscodec.h" #include "codec_internal.h" -#include "registry.h" #include "codebook.h" #include "misc.h" #define floor1_rangedB 140 /* floor 1 fixed at -140dB to 0dB range */ +#define VIF_POSIT 63 /***********************************************/ @@ -25,7 +25,6 @@ #include "ivorbiscodec.h" #include "codec_internal.h" #include "codebook.h" -#include "registry.h" #include "window.h" #include "misc.h" #include "os.h" @@ -120,11 +119,10 @@ void vorbis_info_clear(vorbis_info *vi){ if(ci){ - for(i=0;i<ci->modes;i++) - if(ci->mode_param[i])_ogg_free(ci->mode_param[i]); + if(ci->mode_param)_ogg_free(ci->mode_param); for(i=0;i<ci->maps;i++) /* unpack does the range checking */ - _mapping_P[ci->map_type[i]]->free_info(ci->map_param[i]); + _mapping_P[0]->free_info(ci->map_param[i]); if(ci->floor_param){ for(i=0;i<ci->floors;i++) /* unpack does the range checking */ @@ -133,8 +131,11 @@ void vorbis_info_clear(vorbis_info *vi){ _ogg_free(ci->floor_type); } - for(i=0;i<ci->residues;i++) /* unpack does the range checking */ - _residue_P[ci->residue_type[i]]->free_info(ci->residue_param[i]); + if(ci->residue_param){ + for(i=0;i<ci->residues;i++) /* unpack does the range checking */ + res_clear_info(ci->residue_param+i); + _ogg_free(ci->residue_param); + } if(ci->book_param){ for(i=0;i<ci->books;i++) @@ -221,12 +222,10 @@ static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){ for(i=0;i<ci->books;i++) if(vorbis_book_unpack(opb,ci->book_param+i))goto err_out; - /* time backend settings */ - ci->times=oggpack_read(opb,6)+1; - for(i=0;i<ci->times;i++){ - ci->time_type[i]=oggpack_read(opb,16); - if(ci->time_type[i]<0 || ci->time_type[i]>=VI_TIMEB)goto err_out; - } + /* time backend settings, not actually used */ + i=oggpack_read(opb,6); + for(;i>=0;i--) + if(oggpack_read(opb,16)!=0)goto err_out; /* floor backend settings */ ci->floors=oggpack_read(opb,6)+1; @@ -241,34 +240,28 @@ static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){ /* residue backend settings */ ci->residues=oggpack_read(opb,6)+1; - for(i=0;i<ci->residues;i++){ - ci->residue_type[i]=oggpack_read(opb,16); - if(ci->residue_type[i]<0 || ci->residue_type[i]>=VI_RESB)goto err_out; - ci->residue_param[i]=_residue_P[ci->residue_type[i]]->unpack(vi,opb); - if(!ci->residue_param[i])goto err_out; - } + ci->residue_param=_ogg_malloc(sizeof(*ci->residue_param)*ci->residues); + for(i=0;i<ci->residues;i++) + if(res_unpack(ci->residue_param+i,vi,opb))goto err_out; /* map backend settings */ ci->maps=oggpack_read(opb,6)+1; for(i=0;i<ci->maps;i++){ - ci->map_type[i]=oggpack_read(opb,16); - if(ci->map_type[i]<0 || ci->map_type[i]>=VI_MAPB)goto err_out; - ci->map_param[i]=_mapping_P[ci->map_type[i]]->unpack(vi,opb); + if(oggpack_read(opb,16)!=0)goto err_out; + ci->map_param[i]=_mapping_P[0]->unpack(vi,opb); if(!ci->map_param[i])goto err_out; } /* mode settings */ ci->modes=oggpack_read(opb,6)+1; + ci->mode_param= + (vorbis_info_mode *)_ogg_malloc(ci->modes*sizeof(*ci->mode_param)); for(i=0;i<ci->modes;i++){ - ci->mode_param[i]=(vorbis_info_mode *)_ogg_calloc(1,sizeof(*ci->mode_param[i])); - ci->mode_param[i]->blockflag=oggpack_read(opb,1); - ci->mode_param[i]->windowtype=oggpack_read(opb,16); - ci->mode_param[i]->transformtype=oggpack_read(opb,16); - ci->mode_param[i]->mapping=oggpack_read(opb,8); - - if(ci->mode_param[i]->windowtype>=VI_WINDOWB)goto err_out; - if(ci->mode_param[i]->transformtype>=VI_WINDOWB)goto err_out; - if(ci->mode_param[i]->mapping>=ci->maps)goto err_out; + ci->mode_param[i].blockflag=oggpack_read(opb,1); + if(oggpack_read(opb,16))goto err_out; + if(oggpack_read(opb,16))goto err_out; + ci->mode_param[i].mapping=oggpack_read(opb,8); + if(ci->mode_param[i].mapping>=ci->maps)goto err_out; } if(oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */ @@ -25,7 +25,6 @@ #include "codec_internal.h" #include "codebook.h" #include "window.h" -#include "registry.h" #include "misc.h" /* simplistic, wasteful way of doing this (unique lookup for each @@ -41,10 +40,8 @@ typedef struct { vorbis_info_mode *mode; vorbis_info_mapping0 *map; - vorbis_look_residue **residue_look; - vorbis_func_floor **floor_func; - vorbis_func_residue **residue_func; + int ch; long lastframe; /* if a different mode is called, we need to @@ -64,13 +61,7 @@ static void mapping0_free_look(vorbis_look_mapping *look){ vorbis_look_mapping0 *l=(vorbis_look_mapping0 *)look; if(l){ - for(i=0;i<l->map->submaps;i++){ - l->residue_func[i]->free_look(l->residue_look[i]); - } - _ogg_free(l->floor_func); - _ogg_free(l->residue_func); - _ogg_free(l->residue_look); memset(l,0,sizeof(*l)); _ogg_free(l); } @@ -85,20 +76,11 @@ static vorbis_look_mapping *mapping0_look(vorbis_dsp_state *vd,vorbis_info_mode vorbis_info_mapping0 *info=look->map=(vorbis_info_mapping0 *)m; look->mode=vm; - look->residue_look=(vorbis_look_residue **)_ogg_calloc(info->submaps,sizeof(*look->residue_look)); - look->floor_func=(vorbis_func_floor **)_ogg_calloc(info->submaps,sizeof(*look->floor_func)); - look->residue_func=(vorbis_func_residue **)_ogg_calloc(info->submaps,sizeof(*look->residue_func)); for(i=0;i<info->submaps;i++){ int floornum=info->floorsubmap[i]; - int resnum=info->residuesubmap[i]; - look->floor_func[i]=_floor_P[ci->floor_type[floornum]]; - look->residue_func[i]=_residue_P[ci->residue_type[resnum]]; - look->residue_look[i]=look->residue_func[i]-> - look(vd,vm,ci->residue_param[resnum]); - } look->ch=vi->channels; @@ -154,7 +136,6 @@ static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb) } for(i=0;i<info->submaps;i++){ int temp=oggpack_read(opb,8); - if(temp>=ci->times)goto err_out; info->floorsubmap[i]=oggpack_read(opb,8); if(info->floorsubmap[i]>=ci->floors)goto err_out; info->residuesubmap[i]=oggpack_read(opb,8); @@ -220,8 +201,8 @@ static int mapping0_inverse(vorbis_block *vb,vorbis_look_mapping *l){ } } - look->residue_func[i]->inverse(vb,look->residue_look[i], - pcmbundle,zerobundle,ch_in_bundle); + res_inverse(vb,ci->residue_param+info->residuesubmap[i], + pcmbundle,zerobundle,ch_in_bundle); } //for(j=0;j<vi->channels;j++) @@ -17,7 +17,6 @@ #include "ivorbiscodec.h" #include "codec_internal.h" -#include "registry.h" #include "misc.h" @@ -26,9 +25,6 @@ extern vorbis_func_floor floor0_exportbundle; extern vorbis_func_floor floor1_exportbundle; -extern vorbis_func_residue residue0_exportbundle; -extern vorbis_func_residue residue1_exportbundle; -extern vorbis_func_residue residue2_exportbundle; extern vorbis_func_mapping mapping0_exportbundle; vorbis_func_floor *_floor_P[]={ @@ -36,12 +32,6 @@ vorbis_func_floor *_floor_P[]={ &floor1_exportbundle, }; -vorbis_func_residue *_residue_P[]={ - &residue0_exportbundle, - &residue1_exportbundle, - &residue2_exportbundle, -}; - vorbis_func_mapping *_mapping_P[]={ &mapping0_exportbundle, }; diff --git a/registry.h b/registry.h deleted file mode 100644 index 2bc8068..0000000 --- a/registry.h +++ /dev/null @@ -1,40 +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-2002 * - * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * - * * - ******************************************************************** - - function: registry for time, floor, res backends and channel mappings - - ********************************************************************/ - -#ifndef _V_REG_H_ -#define _V_REG_H_ - -#define VI_TRANSFORMB 1 -#define VI_WINDOWB 1 -#define VI_TIMEB 1 -#define VI_FLOORB 2 -#define VI_RESB 3 -#define VI_MAPB 1 - -#include "backends.h" - -#if defined(_WIN32) && defined(VORBISDLL_IMPORT) -# define EXTERN __declspec(dllimport) extern -#else -# define EXTERN extern -#endif - -EXTERN vorbis_func_floor *_floor_P[]; -EXTERN vorbis_func_residue *_residue_P[]; -EXTERN vorbis_func_mapping *_mapping_P[]; - -#endif @@ -6,7 +6,7 @@ * 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-2002 * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 * * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * * * ******************************************************************** @@ -21,49 +21,15 @@ #include "ogg.h" #include "ivorbiscodec.h" #include "codec_internal.h" -#include "registry.h" #include "codebook.h" #include "misc.h" #include "os.h" -typedef struct { - vorbis_info_residue0 *info; - int map; - - int parts; - int stages; - codebook *fullbooks; - codebook *phrasebook; - codebook ***partbooks; - - int partvals; - int **decodemap; - -} vorbis_look_residue0; - -void res0_free_info(vorbis_info_residue *i){ - vorbis_info_residue0 *info=(vorbis_info_residue0 *)i; +void res_clear_info(vorbis_info_residue *info){ if(info){ + if(info->stagemasks)_ogg_free(info->stagemasks); + if(info->stagebooks)_ogg_free(info->stagebooks); memset(info,0,sizeof(*info)); - _ogg_free(info); - } -} - -void res0_free_look(vorbis_look_residue *i){ - int j; - if(i){ - - vorbis_look_residue0 *look=(vorbis_look_residue0 *)i; - - for(j=0;j<look->parts;j++) - if(look->partbooks[j])_ogg_free(look->partbooks[j]); - _ogg_free(look->partbooks); - for(j=0;j<look->partvals;j++) - _ogg_free(look->decodemap[j]); - _ogg_free(look->decodemap); - - memset(look,0,sizeof(*look)); - _ogg_free(look); } } @@ -76,259 +42,178 @@ static int ilog(unsigned int v){ return(ret); } -static int icount(unsigned int v){ - int ret=0; - while(v){ - ret+=v&1; - v>>=1; - } - return(ret); -} - /* vorbis_info is for range checking */ -vorbis_info_residue *res0_unpack(vorbis_info *vi,oggpack_buffer *opb){ - int j,acc=0; - vorbis_info_residue0 *info=(vorbis_info_residue0 *)_ogg_calloc(1,sizeof(*info)); +int res_unpack(vorbis_info_residue *info, + vorbis_info *vi,oggpack_buffer *opb){ + int j,k; codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; + memset(info,0,sizeof(*info)); + info->type=oggpack_read(opb,16); + if(info->type>2 || info->type<0)goto errout; info->begin=oggpack_read(opb,24); info->end=oggpack_read(opb,24); info->grouping=oggpack_read(opb,24)+1; info->partitions=oggpack_read(opb,6)+1; info->groupbook=oggpack_read(opb,8); + if(info->groupbook>=ci->books)goto errout; + + info->stagemasks=_ogg_malloc(info->partitions*sizeof(*info->stagemasks)); + info->stagebooks=_ogg_malloc(info->partitions*8*sizeof(*info->stagebooks)); for(j=0;j<info->partitions;j++){ int cascade=oggpack_read(opb,3); if(oggpack_read(opb,1)) cascade|=(oggpack_read(opb,5)<<3); - info->secondstages[j]=cascade; - - acc+=icount(cascade); + info->stagemasks[j]=cascade; } - for(j=0;j<acc;j++) - info->booklist[j]=oggpack_read(opb,8); - if(info->groupbook>=ci->books)goto errout; - for(j=0;j<acc;j++) - if(info->booklist[j]>=ci->books)goto errout; - - return(info); - errout: - res0_free_info(info); - return(NULL); -} - -vorbis_look_residue *res0_look(vorbis_dsp_state *vd,vorbis_info_mode *vm, - vorbis_info_residue *vr){ - vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr; - vorbis_look_residue0 *look=(vorbis_look_residue0 *)_ogg_calloc(1,sizeof(*look)); - codec_setup_info *ci=(codec_setup_info *)vd->vi->codec_setup; - - int j,k,acc=0; - int dim; - int maxstage=0; - look->info=info; - look->map=vm->mapping; - - look->parts=info->partitions; - look->fullbooks=ci->book_param; - look->phrasebook=ci->book_param+info->groupbook; - dim=look->phrasebook->dim; - - look->partbooks=(codebook ***)_ogg_calloc(look->parts,sizeof(*look->partbooks)); - - for(j=0;j<look->parts;j++){ - int stages=ilog(info->secondstages[j]); - if(stages){ - if(stages>maxstage)maxstage=stages; - look->partbooks[j]=(codebook **)_ogg_calloc(stages,sizeof(*look->partbooks[j])); - for(k=0;k<stages;k++) - if(info->secondstages[j]&(1<<k)){ - look->partbooks[j][k]=ci->book_param+info->booklist[acc++]; -#ifdef TRAIN_RES - look->training_data[k][j]=calloc(look->partbooks[j][k]->entries, - sizeof(***look->training_data)); -#endif - } + for(j=0;j<info->partitions;j++){ + for(k=0;k<8;k++){ + if((info->stagemasks[j]>>k)&1){ + unsigned char book=oggpack_read(opb,8); + if(book>=ci->books)goto errout; + info->stagebooks[j*8+k]=book; + if(k+1>info->stages)info->stages=k+1; + }else + info->stagebooks[j*8+k]=0xff; } } - look->partvals=look->parts; - for(j=1;j<dim;j++)look->partvals*=look->parts; - look->stages=maxstage; - look->decodemap=(int **)_ogg_malloc(look->partvals*sizeof(*look->decodemap)); - for(j=0;j<look->partvals;j++){ - long val=j; - long mult=look->partvals/look->parts; - look->decodemap[j]=(int *)_ogg_malloc(dim*sizeof(*look->decodemap[j])); - for(k=0;k<dim;k++){ - long deco=val/mult; - val-=deco*mult; - mult/=look->parts; - look->decodemap[j][k]=deco; - } - } + if(oggpack_eop(opb))goto errout; - return(look); + return 0; + errout: + res_clear_info(info); + return 1; } - -/* a truncated packet here just means 'stop working'; it's not an error */ -static int _01inverse(vorbis_block *vb,vorbis_look_residue *vl, - ogg_int32_t **in,int ch, - long (*decodepart)(codebook *, ogg_int32_t *, - oggpack_buffer *,int,int)){ - - long i,j,k,l,s; - vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; - vorbis_info_residue0 *info=look->info; - - /* move all this setup out later */ +int res_inverse(vorbis_block *vb,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; + codebook *phrasebook=ci->book_param+info->groupbook; int samples_per_partition=info->grouping; - int partitions_per_word=look->phrasebook->dim; + int partitions_per_word=phrasebook->dim; int n=info->end-info->begin; - int partvals=n/samples_per_partition; int partwords=(partvals+partitions_per_word-1)/partitions_per_word; - int ***partword=(int ***)alloca(ch*sizeof(*partword)); - for(j=0;j<ch;j++) - partword[j]=(int **)_vorbis_block_alloc(vb,partwords*sizeof(*partword[j])); + if(info->type<2){ + for(i=0;i<ch;i++) + if(nonzero[i]) + in[used++]=in[i]; + ch=used; - for(s=0;s<look->stages;s++){ - - /* each loop decodes on partition codeword containing - partitions_pre_word partitions */ - for(i=0,l=0;i<partvals;l++){ - if(s==0){ - /* fetch the partition word for each channel */ - for(j=0;j<ch;j++){ - int temp=vorbis_book_decode(look->phrasebook,&vb->opb); - if(temp==-1)goto eopbreak; - partword[j][l]=look->decodemap[temp]; - if(partword[j][l]==NULL)goto errout; - } - } + if(used){ - /* now we decode residual values for the partitions */ - for(k=0;k<partitions_per_word && i<partvals;k++,i++) - for(j=0;j<ch;j++){ - long offset=info->begin+i*samples_per_partition; - if(info->secondstages[partword[j][l][k]]&(1<<s)){ - codebook *stagebook=look->partbooks[partword[j][l][k]][s]; - if(stagebook){ - if(decodepart(stagebook,in[j]+offset,&vb->opb, - samples_per_partition,-8)==-1)goto eopbreak; + char **partword=(char **)alloca(ch*sizeof(*partword)); + for(j=0;j<ch;j++) + partword[j]=(char *)alloca(partwords*partitions_per_word* + sizeof(*partword[j])); + + for(s=0;s<info->stages;s++){ + + for(i=0;i<partvals;){ + if(s==0){ + /* fetch the partition word for each channel */ + + partword[0][i+partitions_per_word-1]=1; + for(k=partitions_per_word-2;k>=0;k--) + partword[0][i+k]=partword[0][i+k+1]*info->partitions; + + for(j=1;j<ch;j++) + for(k=partitions_per_word-1;k>=0;k--) + 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; + + /* this can be done quickly in assembly due to the quotient + always being at most six bits */ + for(k=0;k<partitions_per_word;k++){ + ogg_uint32_t div=partword[j][i+k]; + partword[j][i+k]=temp/div; + temp-=partword[j][i+k]*div; + } + } } + + /* now we decode residual values for the partitions */ + for(k=0;k<partitions_per_word && i<partvals;k++,i++) + for(j=0;j<ch;j++){ + long offset=info->begin+i*samples_per_partition; + if(info->stagemasks[partword[j][i]]&(1<<s)){ + 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, + samples_per_partition,-8)==-1) + goto eopbreak; + }else{ + if(vorbis_book_decodevs_add(stagebook,in[j]+offset,&vb->opb, + samples_per_partition,-8)==-1) + goto eopbreak; + } + } + } } - } - } - - errout: - eopbreak: - return(0); -} - -int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl, - ogg_int32_t **in,int *nonzero,int ch){ - int i,used=0; - for(i=0;i<ch;i++) - if(nonzero[i]) - in[used++]=in[i]; - if(used) - return(_01inverse(vb,vl,in,used,vorbis_book_decodevs_add)); - else - return(0); -} - -int res1_inverse(vorbis_block *vb,vorbis_look_residue *vl, - ogg_int32_t **in,int *nonzero,int ch){ - int i,used=0; - for(i=0;i<ch;i++) - if(nonzero[i]) - in[used++]=in[i]; - if(used) - return(_01inverse(vb,vl,in,used,vorbis_book_decodev_add)); - else - return(0); -} - -/* duplicate code here as speed is somewhat more important */ -int res2_inverse(vorbis_block *vb,vorbis_look_residue *vl, - ogg_int32_t **in,int *nonzero,int ch){ - long i,k,l,s; - vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; - vorbis_info_residue0 *info=look->info; - - /* move all this setup out later */ - int samples_per_partition=info->grouping; - int partitions_per_word=look->phrasebook->dim; - int n=info->end-info->begin; - - int partvals=n/samples_per_partition; - int partwords=(partvals+partitions_per_word-1)/partitions_per_word; - int **partword=(int **)_vorbis_block_alloc(vb,partwords*sizeof(*partword)); - int beginoff=info->begin/ch; - - for(i=0;i<ch;i++)if(nonzero[i])break; - if(i==ch)return(0); /* no nonzero vectors */ - - samples_per_partition/=ch; - - for(s=0;s<look->stages;s++){ - for(i=0,l=0;i<partvals;l++){ - - if(s==0){ - /* fetch the partition word */ - int temp=vorbis_book_decode(look->phrasebook,&vb->opb); - if(temp==-1)goto eopbreak; - partword[l]=look->decodemap[temp]; - if(partword[l]==NULL)goto errout; - } - - /* now we decode residual values for the partitions */ - for(k=0;k<partitions_per_word && i<partvals;k++,i++) - if(info->secondstages[partword[l][k]]&(1<<s)){ - codebook *stagebook=look->partbooks[partword[l][k]][s]; + } + } + }else{ + + char *partword= + (char *)alloca(partwords*partitions_per_word*sizeof(*partword)); + int beginoff=info->begin/ch; + + for(i=0;i<ch;i++)if(nonzero[i])break; + if(i==ch)return(0); /* no nonzero vectors */ + + samples_per_partition/=ch; + + for(s=0;s<info->stages;s++){ + for(i=0;i<partvals;){ + + if(s==0){ + int temp; + partword[i+partitions_per_word-1]=1; + for(k=partitions_per_word-2;k>=0;k--) + 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; - if(stagebook){ + /* this can be done quickly in assembly due to the quotient + always being at most six bits */ + for(k=0;k<partitions_per_word;k++){ + ogg_uint32_t div=partword[i+k]; + partword[i+k]=temp/div; + temp-=partword[i+k]*div; + } + } + + /* now we decode residual values for the partitions */ + for(k=0;k<partitions_per_word && i<partvals;k++,i++) + if(info->stagemasks[partword[i]]&(1<<s)){ + codebook *stagebook=ci->book_param+ + info->stagebooks[(partword[i]<<3)+s]; if(vorbis_book_decodevv_add(stagebook,in, i*samples_per_partition+beginoff,ch, &vb->opb, samples_per_partition,-8)==-1) goto eopbreak; } - } + } } } errout: eopbreak: - return(0); -} - - -vorbis_func_residue residue0_exportbundle={ - &res0_unpack, - &res0_look, - &res0_free_info, - &res0_free_look, - &res0_inverse -}; - -vorbis_func_residue residue1_exportbundle={ - &res0_unpack, - &res0_look, - &res0_free_info, - &res0_free_look, - &res1_inverse -}; + + return 0; +} -vorbis_func_residue residue2_exportbundle={ - &res0_unpack, - &res0_look, - &res0_free_info, - &res0_free_look, - &res2_inverse -}; diff --git a/synthesis.c b/synthesis.c index 5b04cb5..b62c5f1 100644 --- a/synthesis.c +++ b/synthesis.c @@ -12,7 +12,7 @@ ******************************************************************** function: single-block PCM synthesis - last mod: $Id: synthesis.c,v 1.4.2.1 2003/04/09 09:43:49 xiphmont Exp $ + last mod: $Id: synthesis.c,v 1.4.2.2 2003/04/13 09:03:09 xiphmont Exp $ ********************************************************************/ @@ -20,7 +20,6 @@ #include "ogg.h" #include "ivorbiscodec.h" #include "codec_internal.h" -#include "registry.h" #include "misc.h" #include "os.h" @@ -47,7 +46,7 @@ int vorbis_synthesis(vorbis_block *vb,ogg_packet *op,int decodep){ if(mode==-1)return(OV_EBADPACKET); vb->mode=mode; - vb->W=ci->mode_param[mode]->blockflag; + vb->W=ci->mode_param[mode].blockflag; if(vb->W){ vb->lW=oggpack_read(opb,1); vb->nW=oggpack_read(opb,1); @@ -70,9 +69,7 @@ int vorbis_synthesis(vorbis_block *vb,ogg_packet *op,int decodep){ vb->pcm[i]=(ogg_int32_t *)_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i])); /* unpack_header enforces range checking */ - type=ci->map_type[ci->mode_param[mode]->mapping]; - - return(_mapping_P[type]->inverse(vb,b->mode[mode])); + return(_mapping_P[0]->inverse(vb,b->mode[mode])); }else{ /* no pcm */ vb->pcmend=0; @@ -107,7 +104,7 @@ long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){ mode=oggpack_read(&opb,modebits); } if(mode==-1)return(OV_EBADPACKET); - return(ci->blocksizes[ci->mode_param[mode]->blockflag]); + return(ci->blocksizes[ci->mode_param[mode].blockflag]); } |