summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty <xiphmont@xiph.org>2003-04-10 11:33:59 +0000
committerMonty <xiphmont@xiph.org>2003-04-10 11:33:59 +0000
commit76bb18a1854d9293bec36238481fb54735cdd473 (patch)
tree736d851faa73ad875b9066d4192f5d46ff9f7d68
parent7916a80caf5ce632a1aacd9418b76b719c3fb772 (diff)
downloadtremor-76bb18a1854d9293bec36238481fb54735cdd473.tar.gz
Initial work on floor memory usage reduction.
Floor 0 more or less complete; eliminated all lookups, reduced stack slightly *and* the code got faster :-) Monty git-svn-id: https://svn.xiph.org/branches/lowmem-branch/Tremor@4600 0101bb08-14d6-0310-b084-bc0e0c8e3800
-rw-r--r--backends.h13
-rw-r--r--codec_internal.h4
-rw-r--r--floor0.c208
-rw-r--r--floor1.c155
-rw-r--r--info.c12
-rw-r--r--mapping0.c13
6 files changed, 165 insertions, 240 deletions
diff --git a/backends.h b/backends.h
index 50c1c45..32657c2 100644
--- a/backends.h
+++ b/backends.h
@@ -33,10 +33,7 @@
/* Floor backend generic *****************************************/
typedef struct{
vorbis_info_floor *(*unpack)(vorbis_info *,oggpack_buffer *);
- vorbis_look_floor *(*look) (vorbis_dsp_state *,vorbis_info_mode *,
- vorbis_info_floor *);
void (*free_info) (vorbis_info_floor *);
- void (*free_look) (vorbis_look_floor *);
void *(*inverse1) (struct vorbis_block *,vorbis_look_floor *);
int (*inverse2) (struct vorbis_block *,vorbis_look_floor *,
void *buffer,ogg_int32_t *);
@@ -68,8 +65,14 @@ typedef struct{
int class_subbook[VIF_CLASS][8]; /* [VIF_CLASS][subs] */
- int mult; /* 1 2 3 or 4 */
- int postlist[VIF_POSIT+2]; /* first two implicit */
+ int mult; /* 1 2 3 or 4 */
+ ogg_uint16_t postlist[VIF_POSIT+2]; /* first two implicit */
+
+ /* useful, generated values */
+ char forward_index[VIF_POSIT+2];
+ char hineighbor[VIF_POSIT];
+ char loneighbor[VIF_POSIT];
+ int posts;
} vorbis_info_floor1;
diff --git a/codec_internal.h b/codec_internal.h
index ca4dd9c..4f12c93 100644
--- a/codec_internal.h
+++ b/codec_internal.h
@@ -78,8 +78,8 @@ typedef struct codec_setup_info {
int map_type[64];
vorbis_info_mapping *map_param[64];
int time_type[64];
- int floor_type[64];
- vorbis_info_floor *floor_param[64];
+ char *floor_type;
+ vorbis_info_floor **floor_param;
int residue_type[64];
vorbis_info_residue *residue_param[64];
codebook *book_param;
diff --git a/floor0.c b/floor0.c
index 0ee489d..b475a97 100644
--- a/floor0.c
+++ b/floor0.c
@@ -28,17 +28,6 @@
#define LSP_FRACBITS 14
-typedef struct {
- long n;
- int ln;
- int m;
- int *linearmap;
-
- vorbis_info_floor0 *vi;
- ogg_int32_t *lsp_look;
-
-} vorbis_look_floor0;
-
/*************** LSP decode ********************/
#include "lsp_lookup.h"
@@ -77,30 +66,34 @@ static inline ogg_int32_t vorbis_coslook_i(long a){
COS_LOOKUP_I_SHIFT);
}
-/* interpolated lookup based cos function */
+/* interpolated half-wave lookup based cos function */
/* a is in 0.16 format, where 0==0, 2^^16==PI, return .LSP_FRACBITS */
static inline ogg_int32_t vorbis_coslook2_i(long a){
- a=a&0x1ffff;
-
- if(a>0x10000)a=0x20000-a;
- {
- int i=a>>COS_LOOKUP_I_SHIFT;
- int d=a&COS_LOOKUP_I_MASK;
- a=((COS_LOOKUP_I[i]<<COS_LOOKUP_I_SHIFT)-
- d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>>
- (COS_LOOKUP_I_SHIFT-LSP_FRACBITS+14);
- }
-
- return(a);
+ int i=a>>COS_LOOKUP_I_SHIFT;
+ int d=a&COS_LOOKUP_I_MASK;
+ return ((COS_LOOKUP_I[i]<<COS_LOOKUP_I_SHIFT)-
+ d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>>
+ (COS_LOOKUP_I_SHIFT-LSP_FRACBITS+14);
}
-static const int barklook[28]={
+static const ogg_int32_t barklook[28]={
0,100,200,301, 405,516,635,766,
912,1077,1263,1476, 1720,2003,2333,2721,
3184,3742,4428,5285, 6376,7791,9662,12181,
15624,20397,27087,36554
};
+static const ogg_uint32_t barklook_igap[27]={
+ 21474836, 21474836, 21262214, 20648881,
+ 19346700, 18046081, 16393005, 14708792,
+ 13015052, 11545611, 10082083, 8801162,
+ 7588281, 6507526, 5534752, 4638194,
+ 3848537, 3130443, 2505815, 1968363,
+ 1517656, 1147773, 852514, 623725,
+ 449923, 320999, 226839
+};
+
+
/* used in init only; interpolate the long way */
static inline ogg_int32_t toBARK(int n){
int i;
@@ -110,10 +103,7 @@ static inline ogg_int32_t toBARK(int n){
if(i==27){
return 27<<15;
}else{
- int gap=barklook[i+1]-barklook[i];
- int del=n-barklook[i];
-
- return((i<<15)+((del<<15)/gap));
+ return (i<<15)+(((n-barklook[i])*barklook_igap[i])>>16);
}
}
@@ -133,11 +123,12 @@ static const unsigned char MLOOP_2[64]={
static const unsigned char MLOOP_3[8]={0,1,2,2,3,3,3,3};
-void vorbis_lsp_to_curve(ogg_int32_t *curve,int *map,int n,int ln,
+#include <stdio.h>
+void vorbis_lsp_to_curve(ogg_int32_t *curve,int n,int ln,
ogg_int32_t *lsp,int m,
ogg_int32_t amp,
ogg_int32_t ampoffset,
- ogg_int32_t *icos){
+ ogg_int32_t nyq){
/* 0 <= m < 256 */
@@ -146,6 +137,23 @@ void vorbis_lsp_to_curve(ogg_int32_t *curve,int *map,int n,int ln,
int ampoffseti=ampoffset*4096;
int ampi=amp;
ogg_int32_t *ilsp=(ogg_int32_t *)alloca(m*sizeof(*ilsp));
+
+ ogg_uint32_t inyq= (1UL<<31) / toBARK(nyq);
+ ogg_uint32_t imap= (1UL<<31) / ln;
+ ogg_uint32_t tBnyq1 = toBARK(nyq)<<1;
+
+ /* Besenham for frequency scale to avoid a division */
+ int f=0;
+ int fdx=n;
+ int fbase=nyq/fdx;
+ int ferr=0;
+ int fdy=nyq-fbase*fdx;
+ int map=0;
+
+ ogg_uint32_t nextbark=MULT31(imap>>1,toBARK(nyq));
+ int nextf=barklook[nextbark>>15]+(((nextbark&0x7fff)*
+ (barklook[(nextbark>>15)+1]-barklook[nextbark>>15]))>>15);
+
/* lsp is in 8.24, range 0 to PI; coslook wants it in .16 0 to 1*/
for(i=0;i<m;i++){
#ifndef _LOW_ACCURACY_
@@ -165,11 +173,14 @@ void vorbis_lsp_to_curve(ogg_int32_t *curve,int *map,int n,int ln,
i=0;
while(i<n){
- int j,k=map[i];
+ int j;
ogg_uint32_t pi=46341; /* 2**-.5 in 0.16 */
ogg_uint32_t qi=46341;
ogg_int32_t qexp=0,shift;
- ogg_int32_t wi=icos[k];
+ ogg_int32_t wi;
+
+ wi=vorbis_coslook2_i((map*imap)>>15);
+
#ifdef _V_LSP_MATH_ASM
lsp_loop_asm(&qi,&pi,&qexp,ilsp,wi,m);
@@ -202,8 +213,9 @@ void vorbis_lsp_to_curve(ogg_int32_t *curve,int *map,int n,int ln,
for(j=3;j<m;j+=2){
if(!(shift=MLOOP_1[(pi|qi)>>25]))
- if(!(shift=MLOOP_2[(pi|qi)>>19]))
- shift=MLOOP_3[(pi|qi)>>16];
+ if(!(shift=MLOOP_2[(pi|qi)>>19]))
+ shift=MLOOP_3[(pi|qi)>>16];
+
qi=(qi>>shift)*labs(ilsp[j-1]-wi);
pi=(pi>>shift)*labs(ilsp[j]-wi);
qexp+=shift;
@@ -211,7 +223,7 @@ void vorbis_lsp_to_curve(ogg_int32_t *curve,int *map,int n,int ln,
if(!(shift=MLOOP_1[(pi|qi)>>25]))
if(!(shift=MLOOP_2[(pi|qi)>>19]))
shift=MLOOP_3[(pi|qi)>>16];
-
+
/* pi,qi normalized collectively, both tracked using qexp */
if(m&1){
@@ -279,7 +291,33 @@ void vorbis_lsp_to_curve(ogg_int32_t *curve,int *map,int n,int ln,
amp>>=9;
#endif
curve[i]= MULT31_SHIFT15(curve[i],amp);
- while(map[++i]==k) curve[i]= MULT31_SHIFT15(curve[i],amp);
+
+ while(++i<n){
+
+ /* line plot to get new f */
+ ferr+=fdy;
+ if(ferr>=fdx){
+ ferr-=fdx;
+ f++;
+ }
+ f+=fbase;
+
+ if(f>=nextf)break;
+ curve[i]= MULT31_SHIFT15(curve[i],amp);
+ }
+
+ while(1){
+ map++;
+ nextbark=MULT31((map+1)*(imap>>1),tBnyq1);
+ nextf=barklook[nextbark>>15]+
+ (((nextbark&0x7fff)*
+ (barklook[(nextbark>>15)+1]-barklook[nextbark>>15]))>>15);
+ if(f<nextf)break;
+ }
+ if(map>=ln){
+ map=ln-1; /* guard against the approximation */
+ nextf=9999999;
+ }
}
}
@@ -287,21 +325,7 @@ void vorbis_lsp_to_curve(ogg_int32_t *curve,int *map,int n,int ln,
static void floor0_free_info(vorbis_info_floor *i){
vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
- if(info){
- memset(info,0,sizeof(*info));
- _ogg_free(info);
- }
-}
-
-static void floor0_free_look(vorbis_look_floor *i){
- vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
- if(look){
-
- if(look->linearmap)_ogg_free(look->linearmap);
- if(look->lsp_look)_ogg_free(look->lsp_look);
- memset(look,0,sizeof(*look));
- _ogg_free(look);
- }
+ if(info)_ogg_free(info);
}
static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){
@@ -319,12 +343,13 @@ static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){
if(info->order<1)goto err_out;
if(info->rate<1)goto err_out;
if(info->barkmap<1)goto err_out;
- if(info->numbooks<1)goto err_out;
for(j=0;j<info->numbooks;j++){
info->books[j]=oggpack_read(opb,8);
- if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out;
+ if(info->books[j]>=ci->books)goto err_out;
}
+
+ if(oggpack_eop(opb))goto err_out;
return(info);
err_out:
@@ -332,54 +357,8 @@ static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){
return(NULL);
}
-/* initialize Bark scale and normalization lookups. We could do this
- with static tables, but Vorbis allows a number of possible
- combinations, so it's best to do it computationally.
-
- The below is authoritative in terms of defining scale mapping.
- Note that the scale depends on the sampling rate as well as the
- linear block and mapping sizes */
-
-static vorbis_look_floor *floor0_look (vorbis_dsp_state *vd,vorbis_info_mode *mi,
- vorbis_info_floor *i){
- int j;
- ogg_int32_t scale;
- vorbis_info *vi=vd->vi;
- codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
+static void *floor0_inverse1(vorbis_block *vb,vorbis_info_floor *i){
vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
- vorbis_look_floor0 *look=(vorbis_look_floor0 *)_ogg_calloc(1,sizeof(*look));
- look->m=info->order;
- look->n=ci->blocksizes[mi->blockflag]/2;
- look->ln=info->barkmap;
- look->vi=info;
-
- /* the mapping from a linear scale to a smaller bark scale is
- straightforward. We do *not* make sure that the linear mapping
- does not skip bark-scale bins; the decoder simply skips them and
- the encoder may do what it wishes in filling them. They're
- necessary in some mapping combinations to keep the scale spacing
- accurate */
- look->linearmap=(int *)_ogg_malloc((look->n+1)*sizeof(*look->linearmap));
- for(j=0;j<look->n;j++){
-
- int val=(look->ln*
- ((toBARK(info->rate/2*j/look->n)<<11)/toBARK(info->rate/2)))>>11;
-
- if(val>=look->ln)val=look->ln-1; /* guard against the approximation */
- look->linearmap[j]=val;
- }
- look->linearmap[j]=-1;
-
- look->lsp_look=(ogg_int32_t *)_ogg_malloc(look->ln*sizeof(*look->lsp_look));
- for(j=0;j<look->ln;j++)
- look->lsp_look[j]=vorbis_coslook2_i(0x10000*j/look->ln);
-
- return look;
-}
-
-static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){
- vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
- vorbis_info_floor0 *info=look->vi;
int j,k;
int ampraw=oggpack_read(&vb->opb,info->ampbits);
@@ -392,16 +371,17 @@ static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){
codec_setup_info *ci=(codec_setup_info *)vb->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)*(look->m+1));
+ ogg_int32_t *lsp=
+ (ogg_int32_t *)_vorbis_block_alloc(vb,sizeof(*lsp)*(info->order+1));
- for(j=0;j<look->m;j+=b->dim)
+ 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;
- for(j=0;j<look->m;){
+ for(j=0;j<info->order;){
for(k=0;k<b->dim;k++,j++)lsp[j]+=last;
last=lsp[j-1];
}
- lsp[look->m]=amp;
+ lsp[info->order]=amp;
return(lsp);
}
}
@@ -409,28 +389,28 @@ static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){
return(NULL);
}
-static int floor0_inverse2(vorbis_block *vb,vorbis_look_floor *i,
+static int floor0_inverse2(vorbis_block *vb,vorbis_info_floor *i,
void *memo,ogg_int32_t *out){
- vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
- vorbis_info_floor0 *info=look->vi;
+ vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
if(memo){
ogg_int32_t *lsp=(ogg_int32_t *)memo;
- ogg_int32_t amp=lsp[look->m];
+ ogg_int32_t amp=lsp[info->order];
/* take the coefficients back to a spectral envelope curve */
- vorbis_lsp_to_curve(out,look->linearmap,look->n,look->ln,
- lsp,look->m,amp,info->ampdB,look->lsp_look);
+ vorbis_lsp_to_curve(out,vb->pcmend/2,info->barkmap,
+ lsp,info->order,amp,info->ampdB,
+ info->rate>>1);
return(1);
}
- memset(out,0,sizeof(*out)*look->n);
+ memset(out,0,sizeof(*out)*vb->pcmend/2);
return(0);
}
/* export hooks */
vorbis_func_floor floor0_exportbundle={
- &floor0_unpack,&floor0_look,&floor0_free_info,
- &floor0_free_look,&floor0_inverse1,&floor0_inverse2
+ &floor0_unpack,&floor0_free_info,
+ &floor0_inverse1,&floor0_inverse2
};
diff --git a/floor1.c b/floor1.c
index bc2de22..1943483 100644
--- a/floor1.c
+++ b/floor1.c
@@ -27,19 +27,6 @@
#define floor1_rangedB 140 /* floor 1 fixed at -140dB to 0dB range */
-typedef struct {
- int forward_index[VIF_POSIT+2];
-
- int hineighbor[VIF_POSIT];
- int loneighbor[VIF_POSIT];
- int posts;
-
- int n;
- int quant_q;
- vorbis_info_floor1 *vi;
-
-} vorbis_look_floor1;
-
/***********************************************/
static void floor1_free_info(vorbis_info_floor *i){
@@ -50,14 +37,6 @@ static void floor1_free_info(vorbis_info_floor *i){
}
}
-static void floor1_free_look(vorbis_look_floor *i){
- vorbis_look_floor1 *look=(vorbis_look_floor1 *)i;
- if(look){
- memset(look,0,sizeof(*look));
- _ogg_free(look);
- }
-}
-
static int ilog(unsigned int v){
int ret=0;
while(v){
@@ -67,9 +46,14 @@ static int ilog(unsigned int v){
return(ret);
}
+static int icomp(const void *a,const void *b){
+ return(**(int **)a-**(int **)b);
+}
+
static vorbis_info_floor *floor1_unpack (vorbis_info *vi,oggpack_buffer *opb){
codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
int j,k,count=0,maxclass=-1,rangebits;
+ ogg_uint16_t *sortpointer[VIF_POSIT+2];
vorbis_info_floor1 *info=(vorbis_info_floor1 *)_ogg_calloc(1,sizeof(*info));
/* read partitions */
@@ -96,7 +80,7 @@ static vorbis_info_floor *floor1_unpack (vorbis_info *vi,oggpack_buffer *opb){
}
/* read the post list */
- info->mult=oggpack_read(opb,2)+1; /* only 1,2,3,4 legal now */
+ info->mult=oggpack_read(opb,2); /* only 0,1,2,3 legal now */
rangebits=oggpack_read(opb,4);
for(j=0,k=0;j<info->partitions;j++){
@@ -109,87 +93,44 @@ static vorbis_info_floor *floor1_unpack (vorbis_info *vi,oggpack_buffer *opb){
}
info->postlist[0]=0;
info->postlist[1]=1<<rangebits;
-
- return(info);
-
- err_out:
- floor1_free_info(info);
- return(NULL);
-}
-
-static int icomp(const void *a,const void *b){
- return(**(int **)a-**(int **)b);
-}
-
-static vorbis_look_floor *floor1_look(vorbis_dsp_state *vd,vorbis_info_mode *mi,
- vorbis_info_floor *in){
-
- int *sortpointer[VIF_POSIT+2];
- vorbis_info_floor1 *info=(vorbis_info_floor1 *)in;
- vorbis_look_floor1 *look=(vorbis_look_floor1 *)_ogg_calloc(1,sizeof(*look));
- int i,j,n=0;
-
- look->vi=info;
- look->n=info->postlist[1];
-
- /* we drop each position value in-between already decoded values,
- and use linear interpolation to predict each new value past the
- edges. The positions are read in the order of the position
- list... we precompute the bounding positions in the lookup. Of
- course, the neighbors can change (if a position is declined), but
- this is an initial mapping */
-
- for(i=0;i<info->partitions;i++)n+=info->class_dim[info->partitionclass[i]];
- n+=2;
- look->posts=n;
+ info->posts=count+2;
/* also store a sorted position index */
- for(i=0;i<n;i++)sortpointer[i]=info->postlist+i;
- qsort(sortpointer,n,sizeof(*sortpointer),icomp);
+ for(j=0;j<info->posts;j++)sortpointer[j]=info->postlist+j;
+ qsort(sortpointer,info->posts,sizeof(*sortpointer),icomp);
/* points from sort order back to range number */
- for(i=0;i<n;i++)look->forward_index[i]=sortpointer[i]-info->postlist;
+ for(j=0;j<info->posts;j++)
+ info->forward_index[j]=sortpointer[j]-info->postlist;
- /* quantize values to multiplier spec */
- switch(info->mult){
- case 1: /* 1024 -> 256 */
- look->quant_q=256;
- break;
- case 2: /* 1024 -> 128 */
- look->quant_q=128;
- break;
- case 3: /* 1024 -> 86 */
- look->quant_q=86;
- break;
- case 4: /* 1024 -> 64 */
- look->quant_q=64;
- break;
- }
-
/* discover our neighbors for decode where we don't use fit flags
(that would push the neighbors outward) */
- for(i=0;i<n-2;i++){
+ for(j=0;j<info->posts-2;j++){
int lo=0;
int hi=1;
int lx=0;
- int hx=look->n;
- int currentx=info->postlist[i+2];
- for(j=0;j<i+2;j++){
- int x=info->postlist[j];
+ int hx=info->postlist[1];
+ int currentx=info->postlist[j+2];
+ for(k=0;k<j+2;k++){
+ int x=info->postlist[k];
if(x>lx && x<currentx){
- lo=j;
+ lo=k;
lx=x;
}
if(x<hx && x>currentx){
- hi=j;
+ hi=k;
hx=x;
}
}
- look->loneighbor[i]=lo;
- look->hineighbor[i]=hi;
+ info->loneighbor[j]=lo;
+ info->hineighbor[j]=hi;
}
- return(look);
+ return(info);
+
+ err_out:
+ floor1_free_info(info);
+ return(NULL);
}
static int render_point(int x0,int x1,int y0,int y1,int x){
@@ -307,20 +248,23 @@ static void render_line(int x0,int x1,int y0,int y1,ogg_int32_t *d){
}
}
-static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
- vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
- vorbis_info_floor1 *info=look->vi;
+static int quant_look[4]={256,128,86,64};
+
+static void *floor1_inverse1(vorbis_block *vb,vorbis_info_floor *in){
+ vorbis_info_floor1 *info=(vorbis_info_floor1 *)in;
codec_setup_info *ci=(codec_setup_info *)vb->vd->vi->codec_setup;
int i,j,k;
codebook *books=ci->book_param;
-
+ int quant_q=quant_look[info->mult];
+
/* unpack wrapped/predicted values from stream */
if(oggpack_read(&vb->opb,1)==1){
- int *fit_value=(int *)_vorbis_block_alloc(vb,(look->posts)*sizeof(*fit_value));
+ int *fit_value=
+ (int *)_vorbis_block_alloc(vb,(info->posts)*sizeof(*fit_value));
- fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
- fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
+ fit_value[0]=oggpack_read(&vb->opb,ilog(quant_q-1));
+ fit_value[1]=oggpack_read(&vb->opb,ilog(quant_q-1));
/* partition by partition */
/* partition by partition */
@@ -352,13 +296,13 @@ static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
}
/* unwrap positive values and reconsitute via linear interpolation */
- for(i=2;i<look->posts;i++){
- int predicted=render_point(info->postlist[look->loneighbor[i-2]],
- info->postlist[look->hineighbor[i-2]],
- fit_value[look->loneighbor[i-2]],
- fit_value[look->hineighbor[i-2]],
+ for(i=2;i<info->posts;i++){
+ int predicted=render_point(info->postlist[info->loneighbor[i-2]],
+ info->postlist[info->hineighbor[i-2]],
+ fit_value[info->loneighbor[i-2]],
+ fit_value[info->hineighbor[i-2]],
info->postlist[i]);
- int hiroom=look->quant_q-predicted;
+ int hiroom=quant_q-predicted;
int loroom=predicted;
int room=(hiroom<loroom?hiroom:loroom)<<1;
int val=fit_value[i];
@@ -379,8 +323,8 @@ static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
}
fit_value[i]=val+predicted;
- fit_value[look->loneighbor[i-2]]&=0x7fff;
- fit_value[look->hineighbor[i-2]]&=0x7fff;
+ fit_value[info->loneighbor[i-2]]&=0x7fff;
+ fit_value[info->hineighbor[i-2]]&=0x7fff;
}else{
fit_value[i]=predicted|0x8000;
@@ -394,10 +338,9 @@ static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
return(NULL);
}
-static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo,
+static int floor1_inverse2(vorbis_block *vb,vorbis_info_floor *in,void *memo,
ogg_int32_t *out){
- vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
- vorbis_info_floor1 *info=look->vi;
+ 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;
@@ -409,8 +352,8 @@ static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo,
int hx=0;
int lx=0;
int ly=fit_value[0]*info->mult;
- for(j=1;j<look->posts;j++){
- int current=look->forward_index[j];
+ for(j=1;j<info->posts;j++){
+ int current=info->forward_index[j];
int hy=fit_value[current]&0x7fff;
if(hy==fit_value[current]){
@@ -432,7 +375,7 @@ static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo,
/* export hooks */
vorbis_func_floor floor1_exportbundle={
- &floor1_unpack,&floor1_look,&floor1_free_info,
- &floor1_free_look,&floor1_inverse1,&floor1_inverse2
+ &floor1_unpack,&floor1_free_info,
+ &floor1_inverse1,&floor1_inverse2
};
diff --git a/info.c b/info.c
index 895a246..b985be9 100644
--- a/info.c
+++ b/info.c
@@ -126,9 +126,13 @@ void vorbis_info_clear(vorbis_info *vi){
for(i=0;i<ci->maps;i++) /* unpack does the range checking */
_mapping_P[ci->map_type[i]]->free_info(ci->map_param[i]);
- for(i=0;i<ci->floors;i++) /* unpack does the range checking */
- _floor_P[ci->floor_type[i]]->free_info(ci->floor_param[i]);
-
+ if(ci->floor_param){
+ for(i=0;i<ci->floors;i++) /* unpack does the range checking */
+ _floor_P[ci->floor_type[i]]->free_info(ci->floor_param[i]);
+ _ogg_free(ci->floor_param);
+ _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]);
@@ -226,6 +230,8 @@ static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){
/* floor backend settings */
ci->floors=oggpack_read(opb,6)+1;
+ ci->floor_param=_ogg_malloc(sizeof(*ci->floor_param)*ci->floors);
+ ci->floor_type=_ogg_malloc(sizeof(*ci->floor_type)*ci->floors);
for(i=0;i<ci->floors;i++){
ci->floor_type[i]=oggpack_read(opb,16);
if(ci->floor_type[i]<0 || ci->floor_type[i]>=VI_FLOORB)goto err_out;
diff --git a/mapping0.c b/mapping0.c
index b5f12f7..6222141 100644
--- a/mapping0.c
+++ b/mapping0.c
@@ -41,8 +41,6 @@ typedef struct {
vorbis_info_mode *mode;
vorbis_info_mapping0 *map;
- vorbis_look_floor **floor_look;
-
vorbis_look_residue **residue_look;
vorbis_func_floor **floor_func;
@@ -67,13 +65,11 @@ static void mapping0_free_look(vorbis_look_mapping *look){
if(l){
for(i=0;i<l->map->submaps;i++){
- l->floor_func[i]->free_look(l->floor_look[i]);
l->residue_func[i]->free_look(l->residue_look[i]);
}
_ogg_free(l->floor_func);
_ogg_free(l->residue_func);
- _ogg_free(l->floor_look);
_ogg_free(l->residue_look);
memset(l,0,sizeof(*l));
_ogg_free(l);
@@ -89,8 +85,6 @@ 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->floor_look=(vorbis_look_floor **)_ogg_calloc(info->submaps,sizeof(*look->floor_look));
-
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));
@@ -101,8 +95,6 @@ static vorbis_look_mapping *mapping0_look(vorbis_dsp_state *vd,vorbis_info_mode
int resnum=info->residuesubmap[i];
look->floor_func[i]=_floor_P[ci->floor_type[floornum]];
- look->floor_look[i]=look->floor_func[i]->
- look(vd,vm,ci->floor_param[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]);
@@ -198,7 +190,7 @@ static int mapping0_inverse(vorbis_block *vb,vorbis_look_mapping *l){
for(i=0;i<vi->channels;i++){
int submap=info->chmuxlist[i];
floormemo[i]=look->floor_func[submap]->
- inverse1(vb,look->floor_look[submap]);
+ inverse1(vb,ci->floor_param[info->floorsubmap[submap]]);
if(floormemo[i])
nonzero[i]=1;
else
@@ -271,7 +263,8 @@ static int mapping0_inverse(vorbis_block *vb,vorbis_look_mapping *l){
ogg_int32_t *pcm=vb->pcm[i];
int submap=info->chmuxlist[i];
look->floor_func[submap]->
- inverse2(vb,look->floor_look[submap],floormemo[i],pcm);
+ inverse2(vb,ci->floor_param[info->floorsubmap[submap]],
+ floormemo[i],pcm);
}
//for(j=0;j<vi->channels;j++)