summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty <xiphmont@xiph.org>2003-04-14 01:13:44 +0000
committerMonty <xiphmont@xiph.org>2003-04-14 01:13:44 +0000
commit17a83fe7417ea1d074fd2bed178bbc931b294d00 (patch)
treee98d14caa02ac4fa10c8b324ed482f8c7cc2c2c4
parent337db8ef0bb7e64ad8fcffa341d298680b1f9d27 (diff)
downloadtremor-17a83fe7417ea1d074fd2bed178bbc931b294d00.tar.gz
Kill a floor0 bug; need to repair _LOW_ACCURACY_ for floor0 next
git-svn-id: https://svn.xiph.org/branches/lowmem-branch/Tremor@4608 0101bb08-14d6-0310-b084-bc0e0c8e3800
-rw-r--r--Makefile.am6
-rw-r--r--block.c64
-rw-r--r--codec_internal.h56
-rw-r--r--floor0.c55
-rw-r--r--floor1.c15
-rw-r--r--info.c22
-rw-r--r--ivorbiscodec.h6
-rw-r--r--mapping0.c153
-rw-r--r--registry.c40
-rw-r--r--synthesis.c17
-rw-r--r--window.c84
-rw-r--r--window.h27
12 files changed, 168 insertions, 377 deletions
diff --git a/Makefile.am b/Makefile.am
index 7321631..0c8b7af 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,14 +4,14 @@ INCLUDES = -I./
lib_LTLIBRARIES = libvorbisidec.la
-libvorbisidec_la_SOURCES = mdct.c block.c window.c \
+libvorbisidec_la_SOURCES = mdct.c block.c \
synthesis.c info.c misc.c \
floor1.c floor0.c vorbisfile.c \
- res012.c mapping0.c registry.c codebook.c \
+ res012.c mapping0.c codebook.c \
framing.c bitwise.c \
codebook.h misc.h mdct_lookup.h\
os.h mdct.h ivorbisfile.h lsp_lookup.h\
- registry.h window.h window_lookup.h\
+ window_lookup.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/block.c b/block.c
index 43eb7c8..6647149 100644
--- a/block.c
+++ b/block.c
@@ -21,20 +21,8 @@
#include "ogg.h"
#include "ivorbiscodec.h"
#include "codec_internal.h"
-
-#include "window.h"
#include "misc.h"
-static int ilog(unsigned int v){
- int ret=0;
- if(v)--v;
- while(v){
- ret++;
- v>>=1;
- }
- return(ret);
-}
-
/* pcm accumulator examples (not exhaustive):
<-------------- lW ---------------->
@@ -145,17 +133,9 @@ int vorbis_block_clear(vorbis_block *vb){
static int _vds_init(vorbis_dsp_state *v,vorbis_info *vi){
int i;
codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
- private_state *b=NULL;
-
memset(v,0,sizeof(*v));
- b=(private_state *)(v->backend_state=_ogg_calloc(1,sizeof(*b)));
v->vi=vi;
- b->modebits=ilog(ci->modes);
-
- /* Vorbis I uses only window type 0 */
- b->window[0]=_vorbis_window(0,ci->blocksizes[0]/2);
- b->window[1]=_vorbis_window(0,ci->blocksizes[1]/2);
v->pcm_storage=ci->blocksizes[1];
v->pcm=(ogg_int32_t **)_ogg_malloc(vi->channels*sizeof(*v->pcm));
@@ -168,13 +148,6 @@ static int _vds_init(vorbis_dsp_state *v,vorbis_info *vi){
v->lW=0; /* previous window size */
v->W=0; /* current window size */
- /* 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;
- b->mode[i]=_mapping_P[0]->look(v,ci->mode_param+i,
- ci->map_param[mapnum]);
- }
return(0);
}
@@ -182,7 +155,6 @@ int vorbis_synthesis_restart(vorbis_dsp_state *v){
vorbis_info *vi=v->vi;
codec_setup_info *ci;
- if(!v->backend_state)return -1;
if(!vi)return -1;
ci=vi->codec_setup;
if(!ci)return -1;
@@ -193,7 +165,7 @@ int vorbis_synthesis_restart(vorbis_dsp_state *v){
v->pcm_returned=-1;
v->granulepos=-1;
v->sequence=-1;
- ((private_state *)(v->backend_state))->sample_count=-1;
+ v->sample_count=-1;
return(0);
}
@@ -210,7 +182,6 @@ void vorbis_dsp_clear(vorbis_dsp_state *v){
if(v){
vorbis_info *vi=v->vi;
codec_setup_info *ci=(codec_setup_info *)(vi?vi->codec_setup:NULL);
- private_state *b=(private_state *)v->backend_state;
if(v->pcm){
for(i=0;i<vi->channels;i++)
@@ -219,19 +190,6 @@ void vorbis_dsp_clear(vorbis_dsp_state *v){
if(v->pcmret)_ogg_free(v->pcmret);
}
- /* 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;
- if(b && b->mode)_mapping_P[0]->free_look(b->mode[i]);
- }
- }
-
- if(b){
- if(b->mode)_ogg_free(b->mode);
- _ogg_free(b);
- }
-
memset(v,0,sizeof(*v));
}
}
@@ -243,7 +201,6 @@ void vorbis_dsp_clear(vorbis_dsp_state *v){
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;
- private_state *b=v->backend_state;
int i,j;
if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL);
@@ -255,7 +212,7 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
if((v->sequence==-1)||
(v->sequence+1 != vb->sequence)){
v->granulepos=-1; /* out of sequence; lose count */
- b->sample_count=-1;
+ v->sample_count=-1;
}
v->sequence=vb->sequence;
@@ -358,10 +315,10 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
is. For this reason, vorbisfile will always try to make sure
it reads the last two marked pages in proper sequence */
- if(b->sample_count==-1){
- b->sample_count=0;
+ if(v->sample_count==-1){
+ v->sample_count=0;
}else{
- b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
+ v->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
}
if(v->granulepos==-1){
@@ -370,7 +327,7 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
v->granulepos=vb->granulepos;
/* is this a short page? */
- if(b->sample_count>v->granulepos){
+ 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){
@@ -380,10 +337,10 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
/* granulepos could be -1 due to a seek, but that would result
in a long coun`t, not short count */
- v->pcm_current-=(b->sample_count-v->granulepos);
+ v->pcm_current-=(v->sample_count-v->granulepos);
}else{
/* trim the beginning */
- v->pcm_returned+=(b->sample_count-v->granulepos);
+ v->pcm_returned+=(v->sample_count-v->granulepos);
if(v->pcm_returned>v->pcm_current)
v->pcm_returned=v->pcm_current;
}
@@ -409,10 +366,7 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
v->granulepos=vb->granulepos;
}
}
-
- /* Update, cleanup */
-
- if(vb->eofflag)v->eofflag=1;
+
return(0);
}
diff --git a/codec_internal.h b/codec_internal.h
index 8abbcc3..67ce479 100644
--- a/codec_internal.h
+++ b/codec_internal.h
@@ -19,6 +19,7 @@
#define _V_CODECI_H_
#include "codebook.h"
+#include "ivorbiscodec.h"
#define VI_TRANSFORMB 1
#define VI_WINDOWB 1
@@ -28,16 +29,20 @@
#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;
+
+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 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 *);
typedef struct{
int order;
@@ -105,18 +110,7 @@ typedef struct {
/* 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{
+typedef struct vorbis_info_mapping{
int submaps; /* <= 16 */
int chmuxlist[256]; /* up to 256 channels in a Vorbis stream */
@@ -129,19 +123,12 @@ typedef struct vorbis_info_mapping0{
int coupling_steps;
int coupling_mag[256];
int coupling_ang[256];
-} vorbis_info_mapping0;
+} vorbis_info_mapping;
-typedef struct private_state {
- /* local lookup storage */
- const void *window[2];
-
- /* backend lookups are tied to the mode, not the backend or naked mapping */
- int modebits;
- vorbis_look_mapping **mode;
-
- ogg_int64_t sample_count;
-
-} private_state;
+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 *);
/* codec_setup_info contains all the setup information specific to the
specific compression/decompression mode in progress (eg,
@@ -168,7 +155,7 @@ typedef struct codec_setup_info {
int books;
vorbis_info_mode *mode_param;
- vorbis_info_mapping *map_param[64];
+ vorbis_info_mapping *map_param;
char *floor_type;
vorbis_info_floor **floor_param;
vorbis_info_residue *residue_param;
@@ -176,7 +163,4 @@ typedef struct codec_setup_info {
} codec_setup_info;
-extern vorbis_func_floor *_floor_P[];
-extern vorbis_func_mapping *_mapping_P[];
-
#endif
diff --git a/floor0.c b/floor0.c
index 6663a5c..028cb2c 100644
--- a/floor0.c
+++ b/floor0.c
@@ -75,24 +75,27 @@ static inline ogg_int32_t vorbis_coslook2_i(long a){
(COS_LOOKUP_I_SHIFT-LSP_FRACBITS+14);
}
-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_uint16_t barklook[54]={
+ 0,51,102,154, 206,258,311,365,
+ 420,477,535,594, 656,719,785,854,
+ 926,1002,1082,1166, 1256,1352,1454,1564,
+ 1683,1812,1953,2107, 2276,2463,2670,2900,
+ 3155,3440,3756,4106, 4493,4919,5387,5901,
+ 6466,7094,7798,8599, 9528,10623,11935,13524,
+ 15453,17775,20517,23667, 27183,31004
};
/* used in init only; interpolate the long way */
static inline ogg_int32_t toBARK(int n){
int i;
- for(i=0;i<27;i++)
+ for(i=0;i<54;i++)
if(n>=barklook[i] && n<barklook[i+1])break;
- if(i==27){
- return 27<<15;
+ if(i==54){
+ return 54<<14;
}else{
- return (i<<15)+(((n-barklook[i])*
- ((1<<31)/(barklook[i+1]-barklook[i])))>>16);
+ return (i<<14)+(((n-barklook[i])*
+ ((1UL<<31)/(barklook[i+1]-barklook[i])))>>17);
}
}
@@ -112,7 +115,6 @@ static const unsigned char MLOOP_2[64]={
static const unsigned char MLOOP_3[8]={0,1,2,2,3,3,3,3};
-#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,
@@ -139,9 +141,9 @@ void vorbis_lsp_to_curve(ogg_int32_t *curve,int n,int ln,
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);
+ ogg_uint32_t nextbark=MULT31(imap>>1,tBnyq1);
+ int nextf=barklook[nextbark>>14]+(((nextbark&0x3fff)*
+ (barklook[(nextbark>>14)+1]-barklook[nextbark>>14]))>>14);
/* lsp is in 8.24, range 0 to PI; coslook wants it in .16 0 to 1*/
for(i=0;i<m;i++){
@@ -292,16 +294,18 @@ void vorbis_lsp_to_curve(ogg_int32_t *curve,int n,int ln,
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;
+ nextf=barklook[nextbark>>14]+
+ (((nextbark&0x3fff)*
+ (barklook[(nextbark>>14)+1]-barklook[nextbark>>14]))>>14);
+ if(f<=nextf)break;
}
if(map>=ln){
map=ln-1; /* guard against the approximation */
@@ -312,12 +316,12 @@ void vorbis_lsp_to_curve(ogg_int32_t *curve,int n,int ln,
/*************** vorbis decode glue ************/
-static void floor0_free_info(vorbis_info_floor *i){
+void floor0_free_info(vorbis_info_floor *i){
vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
if(info)_ogg_free(info);
}
-static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){
+vorbis_info_floor *floor0_info_unpack (vorbis_info *vi,oggpack_buffer *opb){
codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
int j;
@@ -346,7 +350,7 @@ static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){
return(NULL);
}
-static void *floor0_inverse1(vorbis_block *vb,vorbis_info_floor *i){
+void *floor0_inverse1(vorbis_block *vb,vorbis_info_floor *i){
vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
int j,k;
@@ -378,7 +382,7 @@ static void *floor0_inverse1(vorbis_block *vb,vorbis_info_floor *i){
return(NULL);
}
-static int floor0_inverse2(vorbis_block *vb,vorbis_info_floor *i,
+int floor0_inverse2(vorbis_block *vb,vorbis_info_floor *i,
void *memo,ogg_int32_t *out){
vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
@@ -396,10 +400,3 @@ static int floor0_inverse2(vorbis_block *vb,vorbis_info_floor *i,
return(0);
}
-/* export hooks */
-vorbis_func_floor floor0_exportbundle={
- &floor0_unpack,&floor0_free_info,
- &floor0_inverse1,&floor0_inverse2
-};
-
-
diff --git a/floor1.c b/floor1.c
index 9e8e3fd..66e6f6b 100644
--- a/floor1.c
+++ b/floor1.c
@@ -29,7 +29,7 @@
/***********************************************/
-static void floor1_free_info(vorbis_info_floor *i){
+void floor1_free_info(vorbis_info_floor *i){
vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
if(info){
if(info->class)_ogg_free(info->class);
@@ -56,7 +56,7 @@ 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){
+vorbis_info_floor *floor1_info_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];
@@ -271,7 +271,7 @@ static void render_line(int x0,int x1,int y0,int y1,ogg_int32_t *d){
static int quant_look[4]={256,128,86,64};
-static void *floor1_inverse1(vorbis_block *vb,vorbis_info_floor *in){
+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;
@@ -359,7 +359,7 @@ static void *floor1_inverse1(vorbis_block *vb,vorbis_info_floor *in){
return(NULL);
}
-static int floor1_inverse2(vorbis_block *vb,vorbis_info_floor *in,void *memo,
+int floor1_inverse2(vorbis_block *vb,vorbis_info_floor *in,void *memo,
ogg_int32_t *out){
vorbis_info_floor1 *info=(vorbis_info_floor1 *)in;
@@ -393,10 +393,3 @@ static int floor1_inverse2(vorbis_block *vb,vorbis_info_floor *in,void *memo,
memset(out,0,sizeof(*out)*n);
return(0);
}
-
-/* export hooks */
-vorbis_func_floor floor1_exportbundle={
- &floor1_unpack,&floor1_free_info,
- &floor1_inverse1,&floor1_inverse2
-};
-
diff --git a/info.c b/info.c
index ccb8a40..97c81db 100644
--- a/info.c
+++ b/info.c
@@ -25,7 +25,6 @@
#include "ivorbiscodec.h"
#include "codec_internal.h"
#include "codebook.h"
-#include "window.h"
#include "misc.h"
#include "os.h"
@@ -121,12 +120,18 @@ void vorbis_info_clear(vorbis_info *vi){
if(ci->mode_param)_ogg_free(ci->mode_param);
- for(i=0;i<ci->maps;i++) /* unpack does the range checking */
- _mapping_P[0]->free_info(ci->map_param[i]);
+ if(ci->map_param){
+ for(i=0;i<ci->maps;i++) /* unpack does the range checking */
+ mapping_clear_info(ci->map_param+i);
+ _ogg_free(ci->map_param);
+ }
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]);
+ if(ci->floor_type[i])
+ floor1_free_info(ci->floor_param[i]);
+ else
+ floor0_free_info(ci->floor_param[i]);
_ogg_free(ci->floor_param);
_ogg_free(ci->floor_type);
}
@@ -234,7 +239,10 @@ static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){
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;
- ci->floor_param[i]=_floor_P[ci->floor_type[i]]->unpack(vi,opb);
+ if(ci->floor_type[i])
+ ci->floor_param[i]=floor1_info_unpack(vi,opb);
+ else
+ ci->floor_param[i]=floor0_info_unpack(vi,opb);
if(!ci->floor_param[i])goto err_out;
}
@@ -246,10 +254,10 @@ static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){
/* map backend settings */
ci->maps=oggpack_read(opb,6)+1;
+ ci->map_param=_ogg_malloc(sizeof(*ci->map_param)*ci->maps);
for(i=0;i<ci->maps;i++){
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;
+ if(mapping_info_unpack(ci->map_param+i,vi,opb))goto err_out;
}
/* mode settings */
diff --git a/ivorbiscodec.h b/ivorbiscodec.h
index d4de1fd..aaa3fb8 100644
--- a/ivorbiscodec.h
+++ b/ivorbiscodec.h
@@ -57,7 +57,6 @@ typedef struct vorbis_info{
analysis/synthesis state. The DSP state belongs to a specific
logical bitstream ****************************************************/
typedef struct vorbis_dsp_state{
- int analysisp;
vorbis_info *vi;
ogg_int32_t **pcm;
@@ -66,9 +65,6 @@ typedef struct vorbis_dsp_state{
int pcm_current;
int pcm_returned;
- int preextrapolate;
- int eofflag;
-
long lW;
long W;
long nW;
@@ -76,8 +72,8 @@ typedef struct vorbis_dsp_state{
ogg_int64_t granulepos;
ogg_int64_t sequence;
+ ogg_int64_t sample_count;
- void *backend_state;
} vorbis_dsp_state;
typedef struct vorbis_block{
diff --git a/mapping0.c b/mapping0.c
index 9d6c159..773e1ad 100644
--- a/mapping0.c
+++ b/mapping0.c
@@ -24,68 +24,69 @@
#include "mdct.h"
#include "codec_internal.h"
#include "codebook.h"
-#include "window.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);
+ }
+}
-/* simplistic, wasteful way of doing this (unique lookup for each
- mode/submapping); there should be a central repository for
- identical lookups. That will require minor work, so I'm putting it
- off as low priority.
+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];
- Why a lookup for each backend in a given mode? Because the
- blocksize is set by the mode, and low backend lookups may require
- parameters from other areas of the mode/mapping */
+ long leftbegin=n/4-ln/4;
+ long leftend=leftbegin+ln/2;
-typedef struct {
- vorbis_info_mode *mode;
- vorbis_info_mapping0 *map;
+ long rightbegin=n/2+n/4-rn/4;
+ long rightend=rightbegin+rn/2;
+
+ int i,p;
- vorbis_func_floor **floor_func;
+ window[0]=_vorbis_window(blocksizes[0]>>1);
+ window[1]=_vorbis_window(blocksizes[1]>>1);
+ for(i=0;i<leftbegin;i++)
+ d[i]=0;
- int ch;
- long lastframe; /* if a different mode is called, we need to
- invalidate decay */
-} vorbis_look_mapping0;
+ for(p=0;i<leftend;i++,p++)
+ d[i]=MULT31(d[i],window[lW][p]);
-static void mapping0_free_info(vorbis_info_mapping *i){
- vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)i;
- if(info){
- memset(info,0,sizeof(*info));
- _ogg_free(info);
- }
-}
-
-static void mapping0_free_look(vorbis_look_mapping *look){
- int i;
- vorbis_look_mapping0 *l=(vorbis_look_mapping0 *)look;
- if(l){
+ for(i=rightbegin,p=rn/2-1;i<rightend;i++,p--)
+ d[i]=MULT31(d[i],window[nW][p]);
- _ogg_free(l->floor_func);
- memset(l,0,sizeof(*l));
- _ogg_free(l);
- }
+ for(;i<n;i++)
+ d[i]=0;
}
-static vorbis_look_mapping *mapping0_look(vorbis_dsp_state *vd,vorbis_info_mode *vm,
- vorbis_info_mapping *m){
- int i;
- vorbis_info *vi=vd->vi;
- codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
- vorbis_look_mapping0 *look=(vorbis_look_mapping0 *)_ogg_calloc(1,sizeof(*look));
- vorbis_info_mapping0 *info=look->map=(vorbis_info_mapping0 *)m;
- look->mode=vm;
-
- look->floor_func=(vorbis_func_floor **)_ogg_calloc(info->submaps,sizeof(*look->floor_func));
-
- for(i=0;i<info->submaps;i++){
- int floornum=info->floorsubmap[i];
- look->floor_func[i]=_floor_P[ci->floor_type[floornum]];
+void mapping_clear_info(vorbis_info_mapping *info){
+ if(info){
+ memset(info,0,sizeof(*info));
}
-
- look->ch=vi->channels;
-
- return(look);
}
static int ilog(unsigned int v){
@@ -99,9 +100,9 @@ static int ilog(unsigned int v){
}
/* also responsible for range checking */
-static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb){
+int mapping_info_unpack(vorbis_info_mapping *info,vorbis_info *vi,
+ oggpack_buffer *opb){
int i;
- vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)_ogg_calloc(1,sizeof(*info));
codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
memset(info,0,sizeof(*info));
@@ -142,21 +143,17 @@ static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb)
if(info->residuesubmap[i]>=ci->residues)goto err_out;
}
- return info;
+ return 0;
err_out:
- mapping0_free_info(info);
- return(NULL);
+ mapping_clear_info(info);
+ return -1;
}
-static int seq=0;
-static int mapping0_inverse(vorbis_block *vb,vorbis_look_mapping *l){
+int mapping_inverse(vorbis_block *vb,vorbis_info_mapping *info){
vorbis_dsp_state *vd=vb->vd;
vorbis_info *vi=vd->vi;
codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
- private_state *b=(private_state *)vd->backend_state;
- vorbis_look_mapping0 *look=(vorbis_look_mapping0 *)l;
- vorbis_info_mapping0 *info=look->map;
int i,j;
long n=vb->pcmend=ci->blocksizes[vb->W];
@@ -170,8 +167,16 @@ static int mapping0_inverse(vorbis_block *vb,vorbis_look_mapping *l){
/* recover the spectral envelope; store it in the PCM vector for now */
for(i=0;i<vi->channels;i++){
int submap=info->chmuxlist[i];
- floormemo[i]=look->floor_func[submap]->
- inverse1(vb,ci->floor_param[info->floorsubmap[submap]]);
+ int floorno=info->floorsubmap[submap];
+
+ if(ci->floor_type[floorno]){
+ /* floor 1 */
+ floormemo[i]=floor1_inverse1(vb,ci->floor_param[floorno]);
+ }else{
+ /* floor 0 */
+ floormemo[i]=floor0_inverse1(vb,ci->floor_param[floorno]);
+ }
+
if(floormemo[i])
nonzero[i]=1;
else
@@ -243,9 +248,15 @@ static int mapping0_inverse(vorbis_block *vb,vorbis_look_mapping *l){
for(i=0;i<vi->channels;i++){
ogg_int32_t *pcm=vb->pcm[i];
int submap=info->chmuxlist[i];
- look->floor_func[submap]->
- inverse2(vb,ci->floor_param[info->floorsubmap[submap]],
- floormemo[i],pcm);
+ int floorno=info->floorsubmap[submap];
+
+ if(ci->floor_type[floorno]){
+ /* floor 1 */
+ floor1_inverse2(vb,ci->floor_param[floorno],floormemo[i],pcm);
+ }else{
+ /* floor 0 */
+ floor0_inverse2(vb,ci->floor_param[floorno],floormemo[i],pcm);
+ }
}
//for(j=0;j<vi->channels;j++)
@@ -265,7 +276,7 @@ static int mapping0_inverse(vorbis_block *vb,vorbis_look_mapping *l){
for(i=0;i<vi->channels;i++){
ogg_int32_t *pcm=vb->pcm[i];
if(nonzero[i])
- _vorbis_apply_window(pcm,b->window,ci->blocksizes,vb->lW,vb->W,vb->nW);
+ _vorbis_apply_window(pcm,ci->blocksizes,vb->lW,vb->W,vb->nW);
else
for(j=0;j<n;j++)
pcm[j]=0;
@@ -275,16 +286,6 @@ static int mapping0_inverse(vorbis_block *vb,vorbis_look_mapping *l){
//for(j=0;j<vi->channels;j++)
//_analysis_output("window",seq+j,vb->pcm[j],-24,n,0,0);
- seq+=vi->channels;
/* all done! */
return(0);
}
-
-/* export hooks */
-vorbis_func_mapping mapping0_exportbundle={
- &mapping0_unpack,
- &mapping0_look,
- &mapping0_free_info,
- &mapping0_free_look,
- &mapping0_inverse
-};
diff --git a/registry.c b/registry.c
deleted file mode 100644
index 5edd26f..0000000
--- a/registry.c
+++ /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 floor, res backends and channel mappings
-
- ********************************************************************/
-
-#include "ivorbiscodec.h"
-#include "codec_internal.h"
-#include "misc.h"
-
-
-/* seems like major overkill now; the backend numbers will grow into
- the infrastructure soon enough */
-
-extern vorbis_func_floor floor0_exportbundle;
-extern vorbis_func_floor floor1_exportbundle;
-extern vorbis_func_mapping mapping0_exportbundle;
-
-vorbis_func_floor *_floor_P[]={
- &floor0_exportbundle,
- &floor1_exportbundle,
-};
-
-vorbis_func_mapping *_mapping_P[]={
- &mapping0_exportbundle,
-};
-
-
-
diff --git a/synthesis.c b/synthesis.c
index b62c5f1..1f3db9b 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.2 2003/04/13 09:03:09 xiphmont Exp $
+ last mod: $Id: synthesis.c,v 1.4.2.3 2003/04/14 01:13:44 xiphmont Exp $
********************************************************************/
@@ -23,9 +23,18 @@
#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;
- private_state *b=(private_state *)vd->backend_state;
vorbis_info *vi=vd->vi;
codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
oggpack_buffer *opb=&vb->opb;
@@ -42,7 +51,7 @@ int vorbis_synthesis(vorbis_block *vb,ogg_packet *op,int decodep){
}
/* read our mode and pre/post windowsize */
- mode=oggpack_read(opb,b->modebits);
+ mode=oggpack_read(opb,ilog(ci->modes));
if(mode==-1)return(OV_EBADPACKET);
vb->mode=mode;
@@ -69,7 +78,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 */
- return(_mapping_P[0]->inverse(vb,b->mode[mode]));
+ return(mapping_inverse(vb,ci->map_param+ci->mode_param[mode].mapping));
}else{
/* no pcm */
vb->pcmend=0;
diff --git a/window.c b/window.c
deleted file mode 100644
index 4d6e79e..0000000
--- a/window.c
+++ /dev/null
@@ -1,84 +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: window functions
-
- ********************************************************************/
-
-#include <stdlib.h>
-#include <math.h>
-#include "os.h"
-#include "misc.h"
-#include "window.h"
-#include "window_lookup.h"
-
-const void *_vorbis_window(int type, int left){
-
- switch(type){
- case 0:
-
- 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);
- }
- break;
- default:
- return(0);
- }
-}
-
-void _vorbis_apply_window(ogg_int32_t *d,const void *window_p[2],
- long *blocksizes,
- int lW,int W,int nW){
-
- LOOKUP_T *window[2]={window_p[0],window_p[1]};
- 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;
-
- 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;
-}
diff --git a/window.h b/window.h
deleted file mode 100644
index 27647fe..0000000
--- a/window.h
+++ /dev/null
@@ -1,27 +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: window functions
-
- ********************************************************************/
-
-#ifndef _V_WINDOW_
-#define _V_WINDOW_
-
-extern const void *_vorbis_window(int type,int left);
-extern void _vorbis_apply_window(ogg_int32_t *d,const void *window[2],
- long *blocksizes,
- int lW,int W,int nW);
-
-
-#endif