From cab466d0585827812b4e562eb41a752dd56f1e53 Mon Sep 17 00:00:00 2001 From: Monty Date: Sat, 22 Jan 2000 13:28:37 +0000 Subject: [PATCH] It's all coming back together slowly. Incremental update. Monty svn path=/trunk/vorbis/; revision=240 --- examples/Makefile.in | 6 +- examples/decoder_example.c | 4 +- examples/encoder_example.c | 4 +- include/vorbis/backends.h | 74 +++------ include/vorbis/codec.h | 65 ++++++-- include/vorbis/internal.h | 6 +- lib/Makefile.in | 9 +- lib/analysis.c | 13 +- lib/block.c | 140 +++++++++++++---- lib/bookinternal.h | 14 +- lib/codebook.c | 176 +++++++++------------ lib/envelope.c | 12 +- lib/floor0.c | 110 +++++++++----- lib/floor0.h | 34 ----- lib/info.c | 147 ++++++------------ lib/lpc.h | 15 +- lib/mapping0.c | 370 +++++++-------------------------------------- lib/mapping0.h | 41 ----- lib/mdct.c | 29 ++-- lib/mdct.h | 8 +- lib/{time0.h => misc.h} | 19 +-- lib/psy.c | 12 +- lib/psy.h | 13 +- lib/registry.c | 85 ++--------- lib/registry.h | 46 +----- lib/res0.h | 34 ----- lib/smallft.h | 8 +- lib/synthesis.c | 35 ++++- lib/time0.c | 38 +++-- lib/window.c | 61 ++++---- lib/window.h | 5 +- 31 files changed, 631 insertions(+), 1002 deletions(-) delete mode 100644 lib/floor0.h delete mode 100644 lib/mapping0.h rename lib/{time0.h => misc.h} (65%) delete mode 100644 lib/res0.h diff --git a/examples/Makefile.in b/examples/Makefile.in index 76b67b4..1afcaae 100644 --- a/examples/Makefile.in +++ b/examples/Makefile.in @@ -1,6 +1,6 @@ # vorbis makefile configured for use with gcc on any platform -# $Id: Makefile.in,v 1.2 2000/01/05 03:10:23 xiphmont Exp $ +# $Id: Makefile.in,v 1.3 2000/01/22 13:28:07 xiphmont Exp $ ############################################################################### # # @@ -27,7 +27,9 @@ AR=@AR@ RANLIB=@RANLIB@ LIBS=@LIBS@ -lm -HFILES = ../include/vorbis/codec.h ../include/vorbis/vorbisfile.h +HFILES = ../include/vorbis/codec.h ../include/vorbis/vorbisfile.h \ + ../include/vorbis/internal.h ../include/vorbis/backend.h \ + ../include/vorbis/codebook.h OFILES = encoder_example.o decoder_example.o chaining_example.o BINFILES = encoder_example decoder_example chaining_example diff --git a/examples/decoder_example.c b/examples/decoder_example.c index 413c409..e2194b8 100644 --- a/examples/decoder_example.c +++ b/examples/decoder_example.c @@ -12,7 +12,7 @@ ******************************************************************** function: simple example decoder - last mod: $Id: decoder_example.c,v 1.3 2000/01/05 03:10:25 xiphmont Exp $ + last mod: $Id: decoder_example.c,v 1.4 2000/01/22 13:28:08 xiphmont Exp $ ********************************************************************/ @@ -259,8 +259,8 @@ int main(){ /* ogg_page and ogg_packet structs always point to storage in libvorbis. They're never freed or manipulated directly */ - vorbis_dsp_clear(&vd); vorbis_block_clear(&vb); + vorbis_dsp_clear(&vd); vorbis_info_clear(&vi); /* must be called last */ } diff --git a/examples/encoder_example.c b/examples/encoder_example.c index 53b09f7..d8c37d4 100644 --- a/examples/encoder_example.c +++ b/examples/encoder_example.c @@ -12,7 +12,7 @@ ******************************************************************** function: simple example encoder - last mod: $Id: encoder_example.c,v 1.3 2000/01/05 03:10:26 xiphmont Exp $ + last mod: $Id: encoder_example.c,v 1.4 2000/01/22 13:28:09 xiphmont Exp $ ********************************************************************/ @@ -148,8 +148,8 @@ int main(){ /* clean up and exit. vorbis_info_clear() must be called last */ ogg_stream_clear(&os); - vorbis_dsp_clear(&vd); vorbis_block_clear(&vb); + vorbis_dsp_clear(&vd); vorbis_info_clear(&vi); /* ogg_page and ogg_packet structs always point to storage in diff --git a/include/vorbis/backends.h b/include/vorbis/backends.h index 7147f0a..3728407 100644 --- a/include/vorbis/backends.h +++ b/include/vorbis/backends.h @@ -13,7 +13,7 @@ function: libvorbis backend and mapping structures; needed for static mode headers - last mod: $Id: backends.h,v 1.1 2000/01/22 10:40:36 xiphmont Exp $ + last mod: $Id: backends.h,v 1.2 2000/01/22 13:28:10 xiphmont Exp $ ********************************************************************/ @@ -25,36 +25,23 @@ #define _vorbis_time_backend_h_ /* this would all be simpler/shorter with templates, but.... */ -/* mode setup ******************************************************/ -typedef struct { - int blockflag; - int windowtype; - int transformtype; - int mapping; -} vorbis_info_mode; - /* Transform backend generic *************************************/ -typedef void vorbis_look_transform; -typedef struct{ - void (*forward)(vorbis_look_transform *,double *in,double *out); - void (*inverse)(vorbis_look_transform *,double *in,double *out); -} vorbis_func_transform; +/* only mdct right now. Flesh it out more if we ever transcend mdct + in the transform domain */ /* Time backend generic ******************************************/ - -typedef void vorbis_info_time; -typedef void vorbis_look_time; - typedef struct{ void (*pack) (vorbis_info_time *,oggpack_buffer *); - vorbis_info_time *(*unpack)(oggpack_buffer *); + vorbis_info_time *(*unpack)(vorbis_info *,oggpack_buffer *); vorbis_look_time *(*look) (vorbis_info *,vorbis_info_mode *, vorbis_info_time *); void (*free_info) (vorbis_info_time *); void (*free_look) (vorbis_look_time *); - void (*forward) (vorbis_info *,vorbis_look_time *,double *,double *); - void (*inverse) (vorbis_info *,vorbis_look_time *,double *,double *); + int (*forward) (struct vorbis_block *,vorbis_look_time *, + double *,double *); + int (*inverse) (struct vorbis_block *,vorbis_look_time *, + double *,double *); } vorbis_func_time; typedef struct{ @@ -62,19 +49,17 @@ typedef struct{ } vorbis_info_time0; /* Floor backend generic *****************************************/ - -typedef void vorbis_info_floor; -typedef void vorbis_look_floor; - typedef struct{ void (*pack) (vorbis_info_floor *,oggpack_buffer *); - vorbis_info_floor *(*unpack)(oggpack_buffer *); + vorbis_info_floor *(*unpack)(vorbis_info *,oggpack_buffer *); vorbis_look_floor *(*look) (vorbis_info *,vorbis_info_mode *, vorbis_info_floor *); void (*free_info) (vorbis_info_floor *); void (*free_look) (vorbis_look_floor *); - void (*forward) (vorbis_info *,vorbis_look_floor *,double *,double *); - void (*inverse) (vorbis_info *,vorbis_look_floor *,double *,double *); + int (*forward) (struct vorbis_block *,vorbis_look_floor *, + double *,double *); + int (*inverse) (struct vorbis_block *,vorbis_look_floor *, + double *,double *); } vorbis_func_floor; typedef struct{ @@ -86,21 +71,20 @@ typedef struct{ } vorbis_info_floor0; /* Residue backend generic *****************************************/ -typedef void vorbis_info_residue; -typedef void vorbis_look_residue; - typedef struct{ void (*pack) (vorbis_info_residue *,oggpack_buffer *); - vorbis_info_residue *(*unpack)(oggpack_buffer *); + vorbis_info_residue *(*unpack)(vorbis_info *,oggpack_buffer *); vorbis_look_residue *(*look) (vorbis_info *,vorbis_info_mode *, vorbis_info_residue *); void (*free_info) (vorbis_info_residue *); void (*free_look) (vorbis_look_residue *); - void (*forward) (vorbis_info *,vorbis_look_residue *,double *,double *); - void (*inverse) (vorbis_info *,vorbis_look_residue *,double *,double *); + int (*forward) (struct vorbis_block *,vorbis_look_residue *, + double *,double *); + int (*inverse) (struct vorbis_block *,vorbis_look_residue *, + double *,double *); } vorbis_func_residue; -typedef struct vorbis_info_res0{ +typedef struct vorbis_info_residue0{ /* block-partitioned VQ coded straight residue */ long begin; long end; @@ -108,29 +92,19 @@ typedef struct vorbis_info_res0{ /* way unfinished, just so you know while poking around CVS ;-) */ int stages; int *books; -} vorbis_info_res0; - -/* psychoacoustic setup ********************************************/ -typedef struct vorbis_info_psy{ - double maskthresh[MAX_BARK]; - double lrolldB; - double hrolldB; -} vorbis_info_psy; +} vorbis_info_residue0; /* Mapping backend generic *****************************************/ -typedef void vorbis_info_mapping; -typedef void vorbis_look_mapping; - typedef struct{ void (*pack) (vorbis_info_mapping *,oggpack_buffer *); - vorbis_info_mapping *(*unpack)(oggpack_buffer *); + vorbis_info_mapping *(*unpack)(vorbis_info *,oggpack_buffer *); vorbis_look_mapping *(*look) (vorbis_info *,vorbis_info_mode *, vorbis_info_mapping *); void (*free_info) (vorbis_info_mapping *); void (*free_look) (vorbis_look_mapping *); - void (*forward) (int mode,struct vorbis_block *vb); - void (*inverse) (int mode,struct vorbis_block *vb); -} vorbis_func_residue; + int (*forward) (struct vorbis_block *vb,vorbis_look_mapping *); + int (*inverse) (struct vorbis_block *vb,vorbis_look_mapping *); +} vorbis_func_mapping; typedef struct vorbis_info_mapping0{ int submaps; diff --git a/include/vorbis/codec.h b/include/vorbis/codec.h index 0ce37f5..bc0fe7b 100644 --- a/include/vorbis/codec.h +++ b/include/vorbis/codec.h @@ -12,7 +12,7 @@ ******************************************************************** function: libvorbis codec headers - last mod: $Id: codec.h,v 1.4 2000/01/22 10:40:37 xiphmont Exp $ + last mod: $Id: codec.h,v 1.5 2000/01/22 13:28:11 xiphmont Exp $ ********************************************************************/ @@ -24,12 +24,36 @@ #include #include "vorbis/codebook.h" #include "vorbis/internal.h" -#include "vorbis/backends.h" -/* vobis_info contains all the setup information specific to the +typedef void vorbis_look_transform; +typedef void vorbis_info_time; +typedef void vorbis_look_time; +typedef void vorbis_info_floor; +typedef void vorbis_look_floor; +typedef void vorbis_info_residue; +typedef void vorbis_look_residue; +typedef void vorbis_info_mapping; +typedef void vorbis_look_mapping; + +/* mode ************************************************************/ +typedef struct { + int blockflag; + int windowtype; + int transformtype; + int mapping; +} vorbis_info_mode; + +/* psychoacoustic setup ********************************************/ +typedef struct vorbis_info_psy{ + double maskthresh[MAX_BARK]; + double lrolldB; + double hrolldB; +} vorbis_info_psy; + +/* vorbis_info contains all the setup information specific to the specific compression/decompression mode in progress (eg, psychoacoustic settings, channel setup, options, codebook - etc). Substructures are in backends.h. + etc). *********************************************************************/ typedef struct vorbis_info{ @@ -82,7 +106,7 @@ typedef struct vorbis_info{ int *floor_type; vorbis_info_floor **floor_param; int *residue_type; - vorbis_info_res **residue_param; + vorbis_info_residue **residue_param; static_codebook **book_param; vorbis_info_psy **psy_param; /* encode only */ @@ -92,17 +116,6 @@ typedef struct vorbis_info{ double preecho_clamp; } vorbis_info; - -/* the comments are not part of vorbis_info so that vorbis_info can be - static storage */ -typedef struct vorbis_comments{ - /* unlimited user comment fields. libvorbis writes 'libvorbis' - whatever vendor is set to in encode */ - char **user_comments; - int comments; - char *vendor; - -} vorbis_comments; /* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/ @@ -271,6 +284,26 @@ typedef struct vorbis_block{ } vorbis_block; +#include "vorbis/backends.h" + +/* 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_comments{ + /* unlimited user comment fields. libvorbis writes 'libvorbis' + whatever vendor is set to in encode */ + char **user_comments; + int comments; + char *vendor; + +} vorbis_comments; + + /* 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 diff --git a/include/vorbis/internal.h b/include/vorbis/internal.h index 9a7ed7c..63f4ae5 100644 --- a/include/vorbis/internal.h +++ b/include/vorbis/internal.h @@ -13,7 +13,7 @@ function: libvorbis codec internal types. These structures are 'visible', but generally uninteresting to the developer - last mod: $Id: internal.h,v 1.3 2000/01/22 10:40:38 xiphmont Exp $ + last mod: $Id: internal.h,v 1.4 2000/01/22 13:28:12 xiphmont Exp $ ********************************************************************/ @@ -49,10 +49,6 @@ typedef struct { } oggpack_buffer; -/* internal use */ -extern void *_vorbis_block_alloc(vorbis_block *vb,long bytes); -extern void _vorbis_block_ripcord(vorbis_block *vb); - #endif diff --git a/lib/Makefile.in b/lib/Makefile.in index adc1ad7..eac125d 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -1,6 +1,6 @@ # vorbis makefile configured for use with gcc on any platform -# $Id: Makefile.in,v 1.22 2000/01/20 04:42:50 xiphmont Exp $ +# $Id: Makefile.in,v 1.23 2000/01/22 13:28:13 xiphmont Exp $ ############################################################################### # # @@ -28,9 +28,10 @@ RANLIB=@RANLIB@ LIBS=@LIBS@ -lm HFILES = ../include/vorbis/codec.h ../include/vorbis/vorbisfile.h \ - bitwise.h envelope.h lpc.h lsp.h bookinternal.h\ - psy.h smallft.h window.h scales.h os.h mdct.h\ - time0.h floor0.h res0.h mapping0.h registry.h + ../include/vorbis/internal.h ../include/vorbis/backend.h \ + ../include/vorbis/codebook.h \ + bitwise.h envelope.h lpc.h lsp.h bookinternal.h misc.h\ + psy.h smallft.h window.h scales.h os.h mdct.h registry.h LFILES = framing.o mdct.o smallft.o block.o envelope.o window.o\ lsp.o lpc.o analysis.o synthesis.o psy.o info.o bitwise.o\ time0.o floor0.o res0.o mapping0.o registry.o\ diff --git a/lib/analysis.c b/lib/analysis.c index c65967d..faceac3 100644 --- a/lib/analysis.c +++ b/lib/analysis.c @@ -12,7 +12,7 @@ ******************************************************************** function: single-block PCM analysis mode dispatch - last mod: $Id: analysis.c,v 1.21 2000/01/20 04:42:51 xiphmont Exp $ + last mod: $Id: analysis.c,v 1.22 2000/01/22 13:28:14 xiphmont Exp $ ********************************************************************/ @@ -43,11 +43,16 @@ int vorbis_analysis(vorbis_block *vb,ogg_packet *op){ /* currently lazy. Short block dispatches to 0, long to 1. */ if(vb->W &&vi->modes>1)mode=1; - type=vi->mappingtypes[mode]; + type=vi->map_type[vi->mode_param[mode]->mapping]; - /* Encode frame mode and dispatch */ + /* Encode frame mode, pre,post windowsize, then dispatch */ _oggpack_write(&vb->opb,mode,vd->modebits); - if(vorbis_map_analysis_P[type](vb,vi->modelist[mode],op)) + if(vb->W){ + _oggpack_write(&vb->opb,vb->lW,1); + _oggpack_write(&vb->opb,vb->nW,1); + } + + if(_mapping_P[type]->forward(vb,vd->mode[mode])) return(-1); /* set up the packet wrapper */ diff --git a/lib/block.c b/lib/block.c index 0a483e5..74a75cf 100644 --- a/lib/block.c +++ b/lib/block.c @@ -12,7 +12,7 @@ ******************************************************************** function: PCM data vector blocking, windowing and dis/reassembly - last mod: $Id: block.c,v 1.22 2000/01/20 04:42:52 xiphmont Exp $ + last mod: $Id: block.c,v 1.23 2000/01/22 13:28:15 xiphmont Exp $ Handle windowing, overlap-add, etc of the PCM vectors. This is made more amusing by Vorbis' current two allowed block sizes. @@ -33,8 +33,8 @@ #include "mdct.h" #include "lpc.h" #include "bitwise.h" -#include "psy.h" -#include "scales.h" +#include "registry.h" +#include "bookinternal.h" static int ilog2(unsigned int v){ int ret=0; @@ -92,8 +92,8 @@ static int ilog2(unsigned int v){ int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){ memset(vb,0,sizeof(vorbis_block)); vb->vd=v; - vb->localalloc=64*1024; - vb->localstore=malloc(vb->localalloc); + vb->localalloc=0; + vb->localstore=NULL; if(v->analysisp) _oggpack_writeinit(&vb->opb); @@ -103,21 +103,50 @@ int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){ void *_vorbis_block_alloc(vorbis_block *vb,long bytes){ bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1); if(bytes+vb->localtop>vb->localalloc){ - /* eh, conservative. After the first few frames, it won't grow */ - vb->localalloc+=bytes; - vb->localstore=realloc(vb->localstore,vb->localalloc); + /* can't just realloc... there are outstanding pointers */ + if(vb->localstore){ + struct alloc_chain *link=malloc(sizeof(struct alloc_chain)); + vb->totaluse+=vb->localtop; + link->next=vb->reap; + link->ptr=vb->localstore; + vb->reap=link; + } + /* highly conservative */ + vb->localalloc=bytes; + vb->localstore=malloc(vb->localalloc); + vb->localtop=0; } return(vb->localstore+vb->localtop); } +/* 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; + free(reap->ptr); + memset(reap,0,sizeof(struct alloc_chain)); + free(reap); + reap=next; + } + /* consolidate storage */ + if(vb->totaluse){ + vb->localstore=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_clear(vorbis_block *vb){ if(vb->vd) if(vb->vd->analysisp) _oggpack_writeclear(&vb->opb); + _vorbis_block_ripcord(vb); if(vb->localstore)free(vb->localstore); memset(vb,0,sizeof(vorbis_block)); @@ -129,28 +158,56 @@ int vorbis_block_clear(vorbis_block *vb){ The init is here because some of it is shared */ static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi){ + int i; memset(v,0,sizeof(vorbis_dsp_state)); v->vi=vi; v->modebits=ilog2(vi->modes); - mdct_init(&v->vm[0],vi->blocksizes[0]); - mdct_init(&v->vm[1],vi->blocksizes[1]); + v->transform[0]=calloc(VI_TRANSFORMB,sizeof(vorbis_look_transform *)); + v->transform[1]=calloc(VI_TRANSFORMB,sizeof(vorbis_look_transform *)); + + /* MDCT is tranform 0 */ - v->window[0][0][0]=_vorbis_window(vi->blocksizes[0], - vi->blocksizes[0]/2,vi->blocksizes[0]/2); + v->transform[0][0]=calloc(1,sizeof(mdct_lookup)); + v->transform[1][0]=calloc(1,sizeof(mdct_lookup)); + mdct_init(v->transform[0][0],vi->blocksizes[0]); + mdct_init(v->transform[1][0],vi->blocksizes[1]); + + v->window[0][0][0]=calloc(VI_WINDOWB,sizeof(double *)); v->window[0][0][1]=v->window[0][0][0]; v->window[0][1][0]=v->window[0][0][0]; v->window[0][1][1]=v->window[0][0][0]; + v->window[1][0][0]=calloc(VI_WINDOWB,sizeof(double *)); + v->window[1][0][1]=calloc(VI_WINDOWB,sizeof(double *)); + v->window[1][1][0]=calloc(VI_WINDOWB,sizeof(double *)); + v->window[1][1][1]=calloc(VI_WINDOWB,sizeof(double *)); + + for(i=0;iwindow[0][0][0][i]= + _vorbis_window(i,vi->blocksizes[0],vi->blocksizes[0]/2,vi->blocksizes[0]/2); + v->window[1][0][0][i]= + _vorbis_window(i,vi->blocksizes[1],vi->blocksizes[0]/2,vi->blocksizes[0]/2); + v->window[1][0][1][i]= + _vorbis_window(i,vi->blocksizes[1],vi->blocksizes[0]/2,vi->blocksizes[1]/2); + v->window[1][1][0][i]= + _vorbis_window(i,vi->blocksizes[1],vi->blocksizes[1]/2,vi->blocksizes[0]/2); + v->window[1][1][1][i]= + _vorbis_window(i,vi->blocksizes[1],vi->blocksizes[1]/2,vi->blocksizes[1]/2); + } - v->window[1][0][0]=_vorbis_window(vi->blocksizes[1], - vi->blocksizes[0]/2,vi->blocksizes[0]/2); - v->window[1][0][1]=_vorbis_window(vi->blocksizes[1], - vi->blocksizes[0]/2,vi->blocksizes[1]/2); - v->window[1][1][0]=_vorbis_window(vi->blocksizes[1], - vi->blocksizes[1]/2,vi->blocksizes[0]/2); - v->window[1][1][1]=_vorbis_window(vi->blocksizes[1], - vi->blocksizes[1]/2,vi->blocksizes[1]/2); + /* initialize all the mapping/backend lookups */ + v->mode=calloc(vi->modes,sizeof(vorbis_look_mapping *)); + for(i=0;imodes;i++){ + int maptype=vi->mode_param[i]->mapping; + v->mode[i]=_mapping_P[maptype]->look(vi,vi->mode_param[i], + vi->map_param[maptype]); + } + + /* finish the codebooks */ + v->fullbooks=calloc(vi->books,sizeof(codebook)); + for(i=0;ibooks;i++) + vorbis_book_finish(v->fullbooks+i,vi->book_param[i]); /* initialize the storage vectors to a decent size greater than the minimum */ @@ -180,6 +237,7 @@ static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi){ /* arbitrary settings and spec-mandated numbers get filled in here */ int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){ + _vds_shared_init(v,vi); /* Initialize the envelope multiplier storage */ @@ -200,10 +258,12 @@ void vorbis_dsp_clear(vorbis_dsp_state *v){ if(v){ vorbis_info *vi=v->vi; - if(v->window[0][0][0])free(v->window[0][0][0]); - for(j=0;j<2;j++) - for(k=0;k<2;k++) - if(v->window[1][j][k])free(v->window[1][j][k]); + for(i=0;iwindow[0][0][0][i])free(v->window[0][0][0][i]); + for(j=0;j<2;j++) + for(k=0;k<2;k++) + if(v->window[1][j][k][i])free(v->window[1][j][k][i]); + } if(v->pcm){ for(i=0;ichannels;i++) if(v->pcm[i])free(v->pcm[i]); @@ -213,8 +273,31 @@ void vorbis_dsp_clear(vorbis_dsp_state *v){ if(v->multipliers)free(v->multipliers); _ve_envelope_clear(&v->ve); - mdct_clear(&v->vm[0]); - mdct_clear(&v->vm[1]); + mdct_clear(v->transform[0][0]); + mdct_clear(v->transform[1][0]); + free(v->transform[0][0]); + free(v->transform[1][0]); + + free(v->transform[0]); + free(v->transform[1]); + + /* free mode lookups */ + for(i=0;imodes;i++){ + int maptype=vi->mode_param[i]->mapping; + _mapping_P[maptype]->free_look(v->mode[i]); + } + if(v->mode)free(v->mode); + + /* free codebooks */ + for(i=0;ibooks;i++) + vorbis_book_clear(v->fullbooks+i); + if(v->fullbooks)free(v->fullbooks); + + /* free header, header1, header2 */ + if(v->header)free(v->header); + if(v->header1)free(v->header1); + if(v->header2)free(v->header2); + memset(v,0,sizeof(vorbis_dsp_state)); } } @@ -223,6 +306,11 @@ double **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){ int i; vorbis_info *vi=v->vi; + /* free header, header1, header2 */ + if(v->header)free(v->header);v->header=NULL; + if(v->header1)free(v->header1);v->header1=NULL; + if(v->header2)free(v->header2);v->header2=NULL; + /* Do we have enough storage space for the requested buffer? If not, expand the PCM (and envelope) storage */ diff --git a/lib/bookinternal.h b/lib/bookinternal.h index 25e6789..0d74deb 100644 --- a/lib/bookinternal.h +++ b/lib/bookinternal.h @@ -12,7 +12,7 @@ ******************************************************************** function: basic codebook pack/unpack/code/decode operations - last mod: $Id: bookinternal.h,v 1.3 2000/01/20 04:42:54 xiphmont Exp $ + last mod: $Id: bookinternal.h,v 1.4 2000/01/22 13:28:16 xiphmont Exp $ ********************************************************************/ @@ -22,17 +22,7 @@ #include "vorbis/codebook.h" #include "bitwise.h" -/* some elements in the codebook structure are assumed to be pointers - to static/shared storage (the pointers are duped, and free below - does not touch them. The fields are unused by decode): - - quantlist, - lengthlist, - encode_tree - -*/ - -extern void vorbis_book_dup(codebook *dest,const codebook *source); +extern void vorbis_book_finish(codebook *dest,const static_codebook *source); extern void vorbis_book_clear(codebook *b); extern int vorbis_book_pack(codebook *c,oggpack_buffer *b); extern int vorbis_book_unpack(oggpack_buffer *b,codebook *c); diff --git a/lib/codebook.c b/lib/codebook.c index 89cd73e..0990591 100644 --- a/lib/codebook.c +++ b/lib/codebook.c @@ -12,7 +12,7 @@ ******************************************************************** function: basic codebook pack/unpack/code/decode operations - last mod: $Id: codebook.c,v 1.2 2000/01/12 11:16:34 xiphmont Exp $ + last mod: $Id: codebook.c,v 1.3 2000/01/22 13:28:17 xiphmont Exp $ ********************************************************************/ @@ -122,7 +122,7 @@ long *_make_words(long *l,long n){ } /* unpack the quantized list of values for encode/decode ***********/ -static double *_book_unquantize(codebook *b){ +static double *_book_unquantize(static_codebook *b){ long j,k; double mindel=_float24_unpack(b->q_min); double delta=_float24_unpack(b->q_delta); @@ -139,48 +139,8 @@ static double *_book_unquantize(codebook *b){ return(r); } -/**** Defend the abstraction ****************************************/ - -/* some elements in the codebook structure are assumed to be pointers - to static/shared storage (the pointers are duped, and free below - does not touch them. The fields are unused by decode): - - quantlist, - lengthlist, - encode_tree - -*/ - -void vorbis_book_dup(codebook *dest,const codebook *source){ - long entries=source->entries; - long dim=source->dim; - memcpy(dest,source,sizeof(codebook)); - - /* handle non-flat storage */ - if(source->valuelist){ - dest->valuelist=malloc(sizeof(double)*dim*entries); - memcpy(dest->valuelist,source->valuelist,sizeof(double)*dim*entries); - } - if(source->codelist){ - dest->codelist=malloc(sizeof(long)*entries); - memcpy(dest->codelist,source->codelist,sizeof(long)*entries); - } - - /* encode tree is assumed to be static storage; don't free it */ - - if(source->decode_tree){ - long aux=source->decode_tree->aux; - dest->decode_tree=malloc(sizeof(decode_aux)); - dest->decode_tree->aux=aux; - dest->decode_tree->ptr0=malloc(sizeof(long)*aux); - dest->decode_tree->ptr1=malloc(sizeof(long)*aux); - - memcpy(dest->decode_tree->ptr0,source->decode_tree->ptr0,sizeof(long)*aux); - memcpy(dest->decode_tree->ptr1,source->decode_tree->ptr1,sizeof(long)*aux); - } -} - void vorbis_book_clear(codebook *b){ + /* static book is not cleared. It exists only in encode */ if(b->decode_tree){ free(b->decode_tree->ptr0); free(b->decode_tree->ptr1); @@ -192,16 +152,26 @@ void vorbis_book_clear(codebook *b){ memset(b,0,sizeof(codebook)); } -/* packs the given codebook into the bitstream - side effects: populates the valuelist and codeword members ***********/ -int vorbis_book_pack(codebook *c,oggpack_buffer *b){ +int vorbis_book_finish(codebook *c, static_codebook *s){ + memset(c,0,sizeof(codebook)); + c->c=s; + c->elements=s->elements; + c->dim=s->dim; + c->codelist=_make_words(c->lengthlist,c->entries); + c->valuelist=_book_unquantize(c); + return(0); +} + +/* packs the given codebook into the bitstream **************************/ + +int vorbis_book_pack(static_codebook *c,oggpack_buffer *opb){ long i,j; int ordered=0; /* first the basic parameters */ - _oggpack_write(b,0x564342,24); - _oggpack_write(b,c->dim,16); - _oggpack_write(b,c->entries,24); + _oggpack_write(opb,0x564342,24); + _oggpack_write(opb,c->dim,16); + _oggpack_write(opb,c->entries,24); /* pack the codewords. There are two packings; length ordered and length random. Decide between the two now. */ @@ -216,93 +186,94 @@ int vorbis_book_pack(codebook *c,oggpack_buffer *b){ deterministically */ long count=0; - _oggpack_write(b,1,1); /* ordered */ - _oggpack_write(b,c->lengthlist[0]-1,5); /* 1 to 32 */ + _oggpack_write(opb,1,1); /* ordered */ + _oggpack_write(opb,c->lengthlist[0]-1,5); /* 1 to 32 */ for(i=1;ientries;i++){ long this=c->lengthlist[i]; long last=c->lengthlist[i-1]; if(this>last){ for(j=last;jentries-count)); + _oggpack_write(opb,i-count,ilog(c->entries-count)); count=i; } } } - _oggpack_write(b,i-count,ilog(c->entries-count)); + _oggpack_write(opb,i-count,ilog(c->entries-count)); }else{ /* length random. Again, we don't code the codeword itself, just the length. This time, though, we have to encode each length */ - _oggpack_write(b,0,1); /* unordered */ + _oggpack_write(opb,0,1); /* unordered */ for(i=0;ientries;i++) - _oggpack_write(b,c->lengthlist[i]-1,5); + _oggpack_write(opb,c->lengthlist[i]-1,5); } /* is the entry number the desired return value, or do we have a mapping? */ if(c->quantlist){ /* we have a mapping. bundle it out. */ - _oggpack_write(b,1,1); + _oggpack_write(opb,1,1); /* values that define the dequantization */ - _oggpack_write(b,c->q_min,24); - _oggpack_write(b,c->q_delta,24); - _oggpack_write(b,c->q_quant-1,4); - _oggpack_write(b,c->q_sequencep,1); + _oggpack_write(opb,c->q_min,24); + _oggpack_write(opb,c->q_delta,24); + _oggpack_write(opb,c->q_quant-1,4); + _oggpack_write(opb,c->q_sequencep,1); /* quantized values */ for(i=0;ientries*c->dim;i++) - _oggpack_write(b,c->quantlist[i],c->q_quant); + _oggpack_write(opb,c->quantlist[i],c->q_quant); }else{ /* no mapping. */ - _oggpack_write(b,0,1); + _oggpack_write(opb,0,1); } - - c->codelist=_make_words(c->lengthlist,c->entries); - c->valuelist=_book_unquantize(c); return(0); } /* unpacks a codebook from the packet buffer into the codebook struct, readies the codebook auxiliary structures for decode *************/ -int vorbis_book_unpack(oggpack_buffer *b,codebook *c){ +int vorbis_book_unpack(oggpack_buffer *opb,codebook *c){ long i,j; + long *lengthlist=NULL; + long *codelist=NULL; + static codebook s; memset(c,0,sizeof(codebook)); + memset(&s,0,sizeof(s)); /* make sure alignment is correct */ - if(_oggpack_read(b,24)!=0x564342)goto _eofout; + if(_oggpack_read(opb,24)!=0x564342)goto _eofout; /* first the basic parameters */ - c->dim=_oggpack_read(b,16); - c->entries=_oggpack_read(b,24); + c->dim=_oggpack_read(opb,16); + c->entries=_oggpack_read(opb,24); if(c->entries==-1)goto _eofout; /* codeword ordering.... length ordered or unordered? */ - switch(_oggpack_read(b,1)){ + switch(_oggpack_read(opb,1)){ case 0: /* unordered */ - c->lengthlist=malloc(sizeof(long)*c->entries); + lengthlist=malloc(sizeof(long)*c->entries); for(i=0;ientries;i++){ - long num=_oggpack_read(b,5); + long num=_oggpack_read(opb,5); if(num==-1)goto _eofout; - c->lengthlist[i]=num+1; + lengthlist[i]=num+1; } break; case 1: /* ordered */ { - long length=_oggpack_read(b,5)+1; - c->lengthlist=malloc(sizeof(long)*c->entries); + long length=_oggpack_read(opb,5)+1; + lengthlist=malloc(sizeof(long)*c->entries); for(i=0;ientries;){ - long num=_oggpack_read(b,ilog(c->entries-i)); + long num=_oggpack_read(opb,ilog(c->entries-i)); if(num==-1)goto _eofout; for(j=0;jlengthlist[i]=length; + lengthlist[i]=length; length++; } } @@ -313,8 +284,8 @@ int vorbis_book_unpack(oggpack_buffer *b,codebook *c){ } /* now we generate the codewords for the given lengths */ - c->codelist=_make_words(c->lengthlist,c->entries); - if(c->codelist==NULL)goto _errout; + codelist=_make_words(c->lengthlist,c->entries); + if(codelist==NULL)goto _errout; /* ...and the decode helper tree from the codewords */ { @@ -326,8 +297,8 @@ int vorbis_book_unpack(oggpack_buffer *b,codebook *c){ for(i=0;ientries;i++){ long ptr=0; - for(j=0;jlengthlist[i]-1;j++){ - int bit=(c->codelist[i]>>j)&1; + for(j=0;j>j)&1; if(!bit){ if(!ptr0[ptr]) ptr0[ptr]= ++top; @@ -338,32 +309,34 @@ int vorbis_book_unpack(oggpack_buffer *b,codebook *c){ ptr=ptr1[ptr]; } } - if(!((c->codelist[i]>>j)&1)) + if(!((codelist[i]>>j)&1)) ptr0[ptr]=-i; else ptr1[ptr]=-i; } } /* no longer needed */ - free(c->lengthlist);c->lengthlist=NULL; - free(c->codelist);c->codelist=NULL; + free(lengthlist); + free(codelist); /* Do we have a mapping to unpack? */ - if(_oggpack_read(b,1)){ + if(_oggpack_read(opb,1)){ /* values that define the dequantization */ - c->q_min=_oggpack_read(b,24); - c->q_delta=_oggpack_read(b,24); - c->q_quant=_oggpack_read(b,4)+1; - c->q_sequencep=_oggpack_read(b,1); + s.q_min=_oggpack_read(opb,24); + s.q_delta=_oggpack_read(opb,24); + s.q_quant=_oggpack_read(opb,4)+1; + s.q_sequencep=_oggpack_read(opb,1); + s.dim=c->dim; + s.entries=c->entries; /* quantized values */ - c->quantlist=malloc(sizeof(double)*c->entries*c->dim); + s.quantlist=malloc(sizeof(double)*c->entries*c->dim); for(i=0;ientries*c->dim;i++) - c->quantlist[i]=_oggpack_read(b,c->q_quant); - if(c->quantlist[i-1]==-1)goto _eofout; - c->valuelist=_book_unquantize(c); - free(c->quantlist);c->quantlist=NULL; + s.quantlist[i]=_oggpack_read(opb,s.q_quant); + if(s.quantlist[i-1]==-1)goto _eofout; + c->valuelist=_book_unquantize(&s); + free(s.quantlist);memset(&s,0,sizeof(s)); } /* all set */ @@ -371,8 +344,9 @@ int vorbis_book_unpack(oggpack_buffer *b,codebook *c){ _errout: _eofout: - if(c->lengthlist)free(c->lengthlist);c->lengthlist=NULL; - if(c->quantlist)free(c->quantlist);c->quantlist=NULL; + if(lengthlist)free(lengthlist); + if(s.quantlist)free(s.quantlist); + if(codelist)free(codelist); vorbis_book_clear(c); return(-1); @@ -380,13 +354,13 @@ int vorbis_book_unpack(oggpack_buffer *b,codebook *c){ /* returns the number of bits ***************************************/ int vorbis_book_encode(codebook *book, int a, oggpack_buffer *b){ - _oggpack_write(b,book->codelist[a],book->lengthlist[a]); - return(book->lengthlist[a]); + _oggpack_write(b,book->codelist[a],book->c->lengthlist[a]); + return(book->c->lengthlist[a]); } /* returns the number of bits and *modifies a* to the entry value *****/ int vorbis_book_encodev(codebook *book, double *a, oggpack_buffer *b){ - encode_aux *t=book->encode_tree; + encode_aux *t=book->c->encode_tree; int dim=book->dim; int ptr=0,k; @@ -552,7 +526,7 @@ double test2[40]={ 0.375124, }; -codebook *testlist[]={&_vq_book_lsp20_0,&_vq_book_lsp32_0,NULL}; +static_codebook *testlist[]={&_vq_book_lsp20_0,&_vq_book_lsp32_0,NULL}; double *testvec[]={test1,test2}; int main(){ @@ -573,7 +547,7 @@ int main(){ /* pack the codebook, write the testvector */ _oggpack_reset(&write); - vorbis_book_dup(&c,testlist[ptr]); /* get it into memory we can write */ + vorbis_book_finish(&c,testlist[ptr]); /* get it into memory we can write */ vorbis_book_pack(&c,&write); fprintf(stderr,"Codebook size %ld bytes... ",_oggpack_bytes(&write)); for(i=0;iorder,8); + _oggpack_write(opb,d->rate,16); + _oggpack_write(opb,d->barkmap,16); + _oggpack_write(opb,d->stages,8); + for(j=0;jstages;j++) + _oggpack_write(opb,d->books[j],8); +} + +static vorbis_info_floor *unpack (vorbis_info *vi,oggpack_buffer *opb){ + int j; vorbis_info_floor0 *d=malloc(sizeof(vorbis_info_floor0)); - memcpy(d,source,sizeof(vorbis_info_floor0)); - if(d->stages){ - d->books=malloc(sizeof(int)*d->stages); - memcpy(d->books,((vorbis_info_floor0 *)source)->books, - sizeof(int)*d->stages); + d->order=_oggpack_read(opb,8); + d->rate=_oggpack_read(opb,16); + d->barkmap=_oggpack_read(opb,16); + d->stages=_oggpack_read(opb,8); + + if(d->order<1)goto err_out; + if(d->rate<1)goto err_out; + if(d->barkmap<1)goto err_out; + if(d->stages<1)goto err_out; + + d->books=alloca(sizeof(int)*d->stages); + for(j=0;jstages;j++){ + d->books[j]=_oggpack_read(opb,8); + if(d->books[j]<0 || d->books[j]>=vi->books)goto err_out; } - return(d); + return(d); + err_out: + free_info(d); + return(NULL); } -extern void _vorbis_floor0_free(_vi_info_floor *i){ +static vorbis_look_floor *look (vorbis_info *vi,vorbis_info_mode *mi, + vorbis_info_floor *i){ + +} +static void free_info(vorbis_info_floor *i){ vorbis_info_floor0 *d=(vorbis_info_floor0 *)i; if(d){ if(d->books)free(d->books); memset(i,0,sizeof(vorbis_info_floor0)); } } - -extern void _vorbis_floor0_pack(oggpack_buffer *opb,_vi_info_floor *vi){ - vorbis_info_floor0 *d=(vorbis_info_floor0 *)vi; - int i; - _oggpack_write(opb,d->order,8); - _oggpack_write(opb,d->rate,16); - _oggpack_write(opb,d->barkmap,16); - _oggpack_write(opb,d->stages,8); - for(i=0;istages;i++) - _oggpack_write(opb,d->books[i],8); +static void free_look(vorbis_look_floor *i){ } -extern _vi_info_floor *_vorbis_floor0_unpack(vorbis_info *vi, - oggpack_buffer *opb){ - vorbis_info_floor0 d; - int i; - d.order=_oggpack_read(opb,8); - d.rate=_oggpack_read(opb,16); - d.barkmap=_oggpack_read(opb,16); - d.stages=_oggpack_read(opb,8); - - if(d.order<1)return(NULL); - if(d.rate<1)return(NULL); - if(d.barkmap<1)return(NULL); - if(d.stages<1)return(NULL); - - d.books=alloca(sizeof(int)*d.stages); - for(i=0;i=vi->books)return(NULL); - } - return(_vorbis_floor0_dup(&d)); +static void forward(vorbis_block *vb,vorbis_look_floor *i, + double *in,double *out){ + + + /* Convert our floor to a set of lpc coefficients + vb->amp[i]=sqrt(vorbis_curve_to_lpc(floor,lpc,vl)); + + LSP <-> LPC is orthogonal and LSP quantizes more stably + vorbis_lpc_to_lsp(lpc,lsp,vl->m); + + code the spectral envelope; mutates the lsp coeffs to reflect + what was actually encoded + _vs_spectrum_encode(vb,vb->amp[i],lsp); + + Generate residue from the decoded envelope, which will be + slightly different to the pre-encoding floor due to + quantization. Slow, yes, but perhaps more accurate + + vorbis_lsp_to_lpc(lsp,lpc,vl->m); + vorbis_lpc_to_curve(curve,lpc,vb->amp[i],vl);*/ + return(0); +} +static void inverse(vorbis_block *vb,vorbis_look_floor *i, + double *in,double *out){ + return(0); } + +/* export hooks */ +vorbis_func_floor floor0_exportbundle={ + &pack,&unpack,&look,&free_info,&free_look,&forward,&inverse +}; + + diff --git a/lib/floor0.h b/lib/floor0.h deleted file mode 100644 index bc2ee0a..0000000 --- a/lib/floor0.h +++ /dev/null @@ -1,34 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY * - * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. * - * PLEASE READ THESE TERMS DISTRIBUTING. * - * * - * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 * - * by Monty and The XIPHOPHORUS Company * - * http://www.xiph.org/ * - * * - ******************************************************************** - - function: floor backend 0 implementation - last mod: $Id: floor0.h,v 1.1 2000/01/20 04:42:55 xiphmont Exp $ - - ********************************************************************/ - -typedef struct vorbis_info_floor0{ - int order; - long rate; - long barkmap; - - int stages; - int *books; -} vorbis_info_floor0; - -extern _vi_info_floor *_vorbis_floor0_dup(_vi_info_floor *source); -extern void _vorbis_floor0_free(_vi_info_floor *vi); -extern void _vorbis_floor0_pack(oggpack_buffer *opb, - _vi_info_floor *vi); -extern _vi_info_floor *_vorbis_floor0_unpack(vorbis_info *vi, - oggpack_buffer *opb); - diff --git a/lib/info.c b/lib/info.c index 6f9c965..a423972 100644 --- a/lib/info.c +++ b/lib/info.c @@ -12,7 +12,7 @@ ******************************************************************** function: maintain the info structure, info <-> header packets - last mod: $Id: info.c,v 1.16 2000/01/20 04:42:55 xiphmont Exp $ + last mod: $Id: info.c,v 1.17 2000/01/22 13:28:21 xiphmont Exp $ ********************************************************************/ @@ -25,6 +25,7 @@ #include "bitwise.h" #include "bookinternal.h" #include "registry.h" +#include "window.h" #include "psy.h" /* helpers */ @@ -51,7 +52,8 @@ static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){ } /* convenience functions for the interface */ -int vorbis_info_addcomment(vorbis_info *vi,char *comment){ +int vorbis_dsp_addcomment(vorbis_dsp_state *v,char *comment){ + vorbis_info *vi=v->vi; vi->user_comments=realloc(vi->user_comments, (vi->comments+2)*sizeof(char *)); vi->user_comments[vi->comments]=strdup(comment); @@ -60,12 +62,9 @@ int vorbis_info_addcomment(vorbis_info *vi,char *comment){ return(0); } -int vorbis_info_addvendor(vorbis_info *vi,char *vendor){ - if(vi->vendor)free(vi->vendor); - vi->vendor=strdup(vendor); - return(0); -} - +/* used by analysis, which has a minimally replicated vi */ +void _vorbis_info_anrep(vorbis_info *dest, vorbis_info *source){ + /* libVorbis expects modes to be submitted in an already valid vorbis_info structure, but also expects some of the elements to be allocated storage. To make this easier, the Vorbis distribution @@ -87,65 +86,10 @@ int vorbis_info_dup(vorbis_info *dest,vorbis_info *source){ for(i=0;icomments;i++) dest->user_comments[i]=strdup(source->user_comments[i]); } - /* dup vendor */ - if(source->vendor) - dest->vendor=strdup(source->vendor); - - /* dup mode maps, blockflags and map types */ - if(source->modes){ - dest->blockflags=malloc(source->modes*sizeof(int)); - dest->windowtypes=malloc(source->modes*sizeof(int)); - dest->transformtypes=malloc(source->modes*sizeof(int)); - dest->mappingtypes=malloc(source->modes*sizeof(int)); - dest->modelist=calloc(source->modes,sizeof(void *)); - - memcpy(dest->blockflags,source->blockflags,sizeof(int)*dest->modes); - memcpy(dest->windowtypes,source->windowtypes,sizeof(int)*dest->modes); - memcpy(dest->transformtypes,source->transformtypes,sizeof(int)*dest->modes); - memcpy(dest->mappingtypes,source->mappingtypes,sizeof(int)*dest->modes); - for(i=0;imodes;i++){ - if(dest->mappingtypes[i]<0|| dest->mappingtypes[i]>=VI_MAPB)goto err_out; - dest->modelist[i]= - vorbis_map_dup_P[dest->mappingtypes[i]](source,source->modelist[i]); - } - } - - /* dup times */ - if(source->times){ - dest->timetypes=malloc(source->times*sizeof(int)); - dest->timelist=calloc(source->times,sizeof(void *)); - memcpy(dest->timetypes,source->timetypes,sizeof(int)*dest->times); - for(i=0;itimes;i++){ - if(dest->timetypes[i]<0|| dest->timetypes[i]>=VI_TIMEB)goto err_out; - dest->timelist[i]= - vorbis_time_dup_P[dest->timetypes[i]](source->timelist[i]); - } - } + dest->vendor=NULL; - /* dup floors */ - if(source->floors){ - dest->floortypes=malloc(source->floors*sizeof(int)); - dest->floorlist=calloc(source->floors,sizeof(void *)); - memcpy(dest->floortypes,source->floortypes,sizeof(int)*dest->floors); - for(i=0;ifloors;i++){ - if(dest->floortypes[i]<0|| dest->floortypes[i]>=VI_FLOORB)goto err_out; - dest->floorlist[i]= - vorbis_floor_dup_P[dest->floortypes[i]](source->floorlist[i]); - } - } - - /* dup residues */ - if(source->residues){ - dest->residuetypes=malloc(source->residues*sizeof(int)); - dest->residuelist=calloc(source->residues,sizeof(void *)); - memcpy(dest->residuetypes,source->residuetypes,sizeof(int)*dest->residues); - for(i=0;iresidues;i++){ - if(dest->residuetypes[i]<0|| dest->residuetypes[i]>=VI_RESB) - goto err_out; - dest->residuelist[i]= - vorbis_res_dup_P[dest->residuetypes[i]](source->residuelist[i]); - } - } + /* modes, maps, times, floors, residues, psychoacoustics are not + dupped; the pointer is just replicated by the above copy */ /* dup (partially) books */ if(source->books){ @@ -156,25 +100,27 @@ int vorbis_info_dup(vorbis_info *dest,vorbis_info *source){ } } - /* dup psychoacoustics (if any) */ - if(source->psys){ - dest->psylist=calloc(source->psys,sizeof(void *)); - for(i=0;ipsys;i++){ - dest->psylist[i]=_vi_psy_dup(source->psylist[i]); - } - } - - /* we do *not* dup local storage */ - dest->header=NULL; - dest->header1=NULL; - dest->header2=NULL; - return(0); err_out: vorbis_info_clear(dest); return(-1); } + + memset(vi,0,sizeof(vorbis_info)); +} + +void vorbis_info_anclear(vorbis_info *vi){ + memset(vi,0,sizeof(vorbis_info)); +} + + + +/* used by synthesis, which has a full, alloced vi */ +void vorbis_info_init(vorbis_info *vi){ + memset(vi,0,sizeof(vorbis_info)); +} + void vorbis_info_clear(vorbis_info *vi){ int i; if(vi->comments){ @@ -348,8 +294,8 @@ static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){ vi->windowtypes[i]=_oggpack_read(opb,16); vi->transformtypes[i]=_oggpack_read(opb,16); vi->mappingtypes[i]=_oggpack_read(opb,16); - if(vi->windowtypes[i]!=0)goto err_out; - if(vi->transformtypes[i]!=0)goto err_out; + if(vi->windowtypes[i]<0 || vi->windowtypes[i]>VI_WINDOWB)goto err_out; + if(vi->transformtypes[i]<0 || vi->transformtypes[i]>VI_TRANSFORMB)goto err_out; if(vi->mappingtypes[i]<0 || vi->mappingtypes[i]>VI_MAPB)goto err_out; vi->modelist[i]=vorbis_map_unpack_P[vi->mappingtypes[i]](vi,opb); if(!vi->modelist[i])goto err_out; @@ -368,11 +314,6 @@ err_out: with bitstream comments and a third packet that holds the codebook. */ -/* call before header in, or just to zero out uninitialized mem */ -void vorbis_info_init(vorbis_info *vi){ - memset(vi,0,sizeof(vorbis_info)); -} - int vorbis_info_headerin(vorbis_info *vi,ogg_packet *op){ oggpack_buffer opb; @@ -531,11 +472,11 @@ err_out: return(-1); } -int vorbis_info_headerout(vorbis_info *vi, - ogg_packet *op, - ogg_packet *op_comm, - ogg_packet *op_code){ - +int vorbis_analysis_headerout(vorbis_dsp_state *v, + ogg_packet *op, + ogg_packet *op_comm, + ogg_packet *op_code){ + vorbis_info *vi=v->vi; oggpack_buffer opb; /* first header packet **********************************************/ @@ -544,10 +485,10 @@ int vorbis_info_headerout(vorbis_info *vi, if(_vorbis_pack_info(&opb,vi))goto err_out; /* build the packet */ - if(vi->header)free(vi->header); - vi->header=malloc(_oggpack_bytes(&opb)); - memcpy(vi->header,opb.buffer,_oggpack_bytes(&opb)); - op->packet=vi->header; + if(v->header)free(v->header); + v->header=malloc(_oggpack_bytes(&opb)); + memcpy(v->header,opb.buffer,_oggpack_bytes(&opb)); + op->packet=v->header; op->bytes=_oggpack_bytes(&opb); op->b_o_s=1; op->e_o_s=0; @@ -560,10 +501,10 @@ int vorbis_info_headerout(vorbis_info *vi, _oggpack_write(&opb,0x81,8); if(_vorbis_pack_comments(&opb,vi))goto err_out; - if(vi->header1)free(vi->header1); - vi->header1=malloc(_oggpack_bytes(&opb)); - memcpy(vi->header1,opb.buffer,_oggpack_bytes(&opb)); - op_comm->packet=vi->header1; + if(v->header1)free(v->header1); + v->header1=malloc(_oggpack_bytes(&opb)); + memcpy(v->header1,opb.buffer,_oggpack_bytes(&opb)); + op_comm->packet=v->header1; op_comm->bytes=_oggpack_bytes(&opb); op_comm->b_o_s=0; op_comm->e_o_s=0; @@ -576,10 +517,10 @@ int vorbis_info_headerout(vorbis_info *vi, _oggpack_write(&opb,0x82,8); if(_vorbis_pack_books(&opb,vi))goto err_out; - if(vi->header2)free(vi->header2); - vi->header2=malloc(_oggpack_bytes(&opb)); - memcpy(vi->header2,opb.buffer,_oggpack_bytes(&opb)); - op_code->packet=vi->header2; + if(v->header2)free(v->header2); + v->header2=malloc(_oggpack_bytes(&opb)); + memcpy(v->header2,opb.buffer,_oggpack_bytes(&opb)); + op_code->packet=v->header2; op_code->bytes=_oggpack_bytes(&opb); op_code->b_o_s=0; op_code->e_o_s=0; diff --git a/lib/lpc.h b/lib/lpc.h index 0858d92..fe39ec8 100644 --- a/lib/lpc.h +++ b/lib/lpc.h @@ -12,7 +12,7 @@ ******************************************************************** function: LPC low level routines - last mod: $Id: lpc.h,v 1.7 2000/01/05 03:10:59 xiphmont Exp $ + last mod: $Id: lpc.h,v 1.8 2000/01/22 13:28:22 xiphmont Exp $ ********************************************************************/ @@ -20,6 +20,19 @@ #define _V_LPC_H_ #include "vorbis/codec.h" +#include "smallft.h" + +typedef struct lpclook{ + /* en/decode lookups */ + int *linearmap; + double *barknorm; + drft_lookup fft; + + int n; + int ln; + int m; + +} lpc_lookup; extern void lpc_init(lpc_lookup *l,int n, long mapped, long rate, int m); extern void lpc_clear(lpc_lookup *l); diff --git a/lib/mapping0.c b/lib/mapping0.c index 7d6d68d..6339190 100644 --- a/lib/mapping0.c +++ b/lib/mapping0.c @@ -12,7 +12,7 @@ ******************************************************************** function: channel mapping 0 implementation - last mod: $Id: mapping0.c,v 1.1 2000/01/20 04:43:02 xiphmont Exp $ + last mod: $Id: mapping0.c,v 1.2 2000/01/22 13:28:23 xiphmont Exp $ ********************************************************************/ @@ -25,7 +25,7 @@ #include "registry.h" #include "mapping0.h" -extern _vi_info_map *_vorbis_map0_dup(vi_info *vi,_vi_info_mapping *source){ +_vi_info_map *_vorbis_map0_dup(vorbis_info *vi,_vi_info_map *source){ vorbis_info_mapping0 *d=malloc(sizeof(vorbis_info_mapping0)); vorbis_info_mapping0 *s=(vorbis_info_mapping0 *)source; memcpy(d,s,sizeof(vorbis_info_mapping0)); @@ -40,7 +40,7 @@ extern _vi_info_map *_vorbis_map0_dup(vi_info *vi,_vi_info_mapping *source){ return(d); } -extern void _vorbis_map0_free(_vi_info_mapping *i){ +void _vorbis_map0_free(_vi_info_map *i){ vorbis_info_mapping0 *d=(vorbis_info_mapping0 *)i; if(d){ @@ -52,10 +52,10 @@ extern void _vorbis_map0_free(_vi_info_mapping *i){ } } -extern void _vorbis_map0_pack(vorbis_info *vi,oggpack_buffer *opb, - _vi_info_map *i){ +void _vorbis_map0_pack(vorbis_info *vi,oggpack_buffer *opb, + _vi_info_map *source){ int i; - vorbis_info_mapping0 *d=(vorbis_info_mapping0 *)i; + vorbis_info_mapping0 *d=(vorbis_info_mapping0 *)source; _oggpack_write(opb,d->timesubmap,8); @@ -88,7 +88,7 @@ extern void _vorbis_map0_pack(vorbis_info *vi,oggpack_buffer *opb, /* also responsible for range checking */ extern _vi_info_map *_vorbis_map0_unpack(vorbis_info *vi,oggpack_buffer *opb){ int i; - vorbis_info_mapping0 d=calloc(1,sizeof(vorbis_info_mapping0)); + vorbis_info_mapping0 *d=calloc(1,sizeof(vorbis_info_mapping0)); memset(d,0,sizeof(vorbis_info_mapping0)); d->timesubmap=_oggpack_read(opb,8); @@ -118,7 +118,7 @@ extern _vi_info_map *_vorbis_map0_unpack(vorbis_info *vi,oggpack_buffer *opb){ for(i=0;ichannels;i++){ if(d->floorsubmap[i]<0 || d->floorsubmap[i]>=vi->floors)goto err_out; - if(d->residuesubmap[i]<0 || d->residuesubmap[i]>=vi->residuess) + if(d->residuesubmap[i]<0 || d->residuesubmap[i]>=vi->residues) goto err_out; } @@ -140,286 +140,83 @@ extern _vi_info_map *_vorbis_map0_unpack(vorbis_info *vi,oggpack_buffer *opb){ #include "spectrum.h" /* no time mapping implementation for now */ -int *_vorbis_map0_analysis(vorbis_block *vb,vorbis_info_map *i, - ogg_packet *opb){ - int i; +int _vorbis_map0_analysis(int mode,vorbis_block *vb){ vorbis_dsp_state *vd=vb->vd; - double *window=vd->window[vb->W][vb->lW][vb->nW]; oggpack_buffer *opb=&vb->opb; - vorbis_info_mapping0 *vi=i; + vorbis_info *vi=vd->vi; + vorbis_info_mapping0 *map=(vorbis_info_mapping0 *)(vi->modelist[mode]); int n=vb->pcmend; + int i,j; /* time domain pre-window: NONE IMPLEMENTED */ /* window the PCM data: takes PCM vector, vb; modifies PCM vector */ + { + double *window=vd->window[vb->W][vb->lW][vb->nW][vi->windowtypes[mode]]; + for(i=0;ichannels;i++){ + double *pcm=vb->pcm[i]; + for(j=0;jvd->vp[vb->W]; - lpc_lookup *vl=&vb->vd->vl[vb->W]; - - - vb->gluebits=0; - vb->time_envelope_bits=0; - vb->spectral_envelope_bits=0; - vb->spectral_residue_bits=0; - - /*lpc_lookup *vbal=&vb->vd->vbal[vb->W]; - double balance_v[vbal->m]; - double balance_amp;*/ - - /* first things first. Make sure encode is ready*/ - _oggpack_reset(opb); - /* Encode the packet type */ - _oggpack_write(opb,0,1); - - /* Encode the block size */ - _oggpack_write(opb,vb->W,1); - if(vb->W){ - _oggpack_write(opb,vb->lW,1); - _oggpack_write(opb,vb->nW,1); - } - - /* No envelope encoding yet */ - _oggpack_write(opb,0,1); - - /* time domain PCM -> MDCT domain */ - for(i=0;ichannels;i++) - mdct_forward(&vd->vm[vb->W],vb->pcm[i],vb->pcm[i],window); - - /* no balance yet */ - - /* extract the spectral envelope and residue */ - /* just do by channel. No coupling yet */ + /* only MDCT right now.... */ { for(i=0;ichannels;i++){ - static int frameno=0; - int j; - double *floor=alloca(n/2*sizeof(double)); - double *curve=alloca(n/2*sizeof(double)); - double *lpc=vb->lpc[i]; - double *lsp=vb->lsp[i]; - - memset(floor,0,sizeof(double)*n/2); - -#ifdef ANALYSIS - { - FILE *out; - char buffer[80]; - - sprintf(buffer,"Aspectrum%d.m",vb->sequence); - out=fopen(buffer,"w+"); - for(j=0;jpcm[i][j]); - fclose(out); - - } -#endif - - _vp_mask_floor(vp,vb->pcm[i],floor); - -#ifdef ANALYSIS - { - FILE *out; - char buffer[80]; - - sprintf(buffer,"Apremask%d.m",vb->sequence); - out=fopen(buffer,"w+"); - for(j=0;jamp[i]=sqrt(vorbis_curve_to_lpc(floor,lpc,vl)); - - /* LSP <-> LPC is orthogonal and LSP quantizes more stably */ - vorbis_lpc_to_lsp(lpc,lsp,vl->m); - - /* code the spectral envelope; mutates the lsp coeffs to reflect - what was actually encoded */ - _vs_spectrum_encode(vb,vb->amp[i],lsp); - - /* Generate residue from the decoded envelope, which will be - slightly different to the pre-encoding floor due to - quantization. Slow, yes, but perhaps more accurate */ - - vorbis_lsp_to_lpc(lsp,lpc,vl->m); - vorbis_lpc_to_curve(curve,lpc,vb->amp[i],vl); - - /* this may do various interesting massaging too...*/ - if(vb->amp[i])_vs_residue_train(vb,vb->pcm[i],curve,n/2); - _vs_residue_quantize(vb->pcm[i],curve,vi,n/2); - -#ifdef ANALYSIS - { - FILE *out; - char buffer[80]; - - sprintf(buffer,"Alpc%d.m",vb->sequence); - out=fopen(buffer,"w+"); - for(j=0;jm;j++) - fprintf(out,"%g\n",lpc[j]); - fclose(out); - - sprintf(buffer,"Alsp%d.m",vb->sequence); - out=fopen(buffer,"w+"); - for(j=0;jm;j++) - fprintf(out,"%g\n",lsp[j]); - fclose(out); - - sprintf(buffer,"Amask%d.m",vb->sequence); - out=fopen(buffer,"w+"); - for(j=0;jsequence); - out=fopen(buffer,"w+"); - for(j=0;jpcm[i][j]); - fclose(out); - } -#endif - - /* encode the residue */ - _vs_residue_encode(vb,vb->pcm[i]); - + double *pcm=vb->pcm[i]; + mdct_forward(vd->transform[vb->W][0],pcm,pcm); } } - /* set up the packet wrapper */ + { + double *decfloor=_vorbis_block_alloc(vb,n*sizeof(double)/2); + double *floor=_vorbis_block_alloc(vb,n*sizeof(double)/2); + double *mask=_vorbis_block_alloc(vb,n*sizeof(double)/2); - op->packet=opb->buffer; - op->bytes=_oggpack_bytes(opb); - op->b_o_s=0; - op->e_o_s=vb->eofflag; - op->frameno=vb->frameno; - op->packetno=vb->sequence; /* for sake of completeness */ + for(i=0;ichannels;i++){ + double *pcm=vb->pcm[i]; + double *pcmaux=vb->pcm[i]+n/2; + int floorsub=map->floorsubmap[i]; + int ressub=map->residuesubmap[i]; + int psysub=map->psysubmap[i]; + + /* perform psychoacoustics; takes PCM vector; + returns two curves: the desired transform floor and the masking curve */ + memset(floor,0,sizeof(double)*n/2); + memset(mask,0,sizeof(double)*n/2); + _vp_mask_floor(&vd->psy[psysub],pcm,mask,floor); + + /* perform floor encoding; takes transform floor, returns decoded floor */ + vorbis_floor_encode_P[vi->floortypes[floorsub]] + (vi->floorlist[floorsub],vd->floor[floorsub],pcm,floor,decfloor); - return(0); -} + /* perform residue prequantization */ + _vp_quantize(&vd->psy[psysub],pcm,mask,decfloor,pcmaux); + } + } + /* perform residue encoding with residue mapping; this is multiplexed */ + /* multiplexing works like this: The first + vorbis_res_encode_P[vi->restypes[ressub]] + (vi->reslist[ressub],vd->residue[ressub],pcm,mask,decfloor); -/* commented out, relocated balance stuff */ - /*{ - double *C=vb->pcm[0]; - double *D=vb->pcm[1]; - - balance_amp=_vp_balance_compute(D,C,balance_v,vbal); - - { - FILE *out; - char buffer[80]; - - sprintf(buffer,"com%d.m",frameno); - out=fopen(buffer,"w+"); - for(i=0;ivd; - vorbis_info *vi=vd->vi; - oggpack_buffer *opb=&vb->opb; - lpc_lookup *vl; - int spectral_order; - int n,i; + return(0); +} - /* first things first. Make sure decode is ready */ - _oggpack_readinit(opb,op->packet,op->bytes); +int _vorbis_map0_synthesis(int mode,vorbis_block *vb){ - /* Check the packet type */ - if(_oggpack_read(opb,1)!=0){ - /* Oops. This is not an audio data packet */ - return(-1); - } - /* Decode the block size */ - vb->W=_oggpack_read(opb,1); - if(vb->W){ - vb->lW=_oggpack_read(opb,1); - vb->nW=_oggpack_read(opb,1); - }else{ - vb->lW=0; - vb->nW=0; - } window=vb->vd->window[vb->W][vb->lW][vb->nW]; - /* other random setup */ - vb->frameno=op->frameno; - vb->sequence=op->packetno-3; /* first block is third packet */ - - vb->eofflag=op->e_o_s; - vl=&vb->vd->vl[vb->W]; - spectral_order=vi->floororder[vb->W]; - - /* The storage vectors are large enough; set the use markers */ n=vb->pcmend=vi->blocksize[vb->W]; /* No envelope encoding yet */ @@ -435,69 +232,12 @@ int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){ /* recover the spectral residue */ if(_vs_residue_decode(vb,vb->pcm[i])<0)return(-1); -#ifdef ANALYSIS - { - int j; - FILE *out; - char buffer[80]; - - sprintf(buffer,"Sres%d.m",vb->sequence); - out=fopen(buffer,"w+"); - for(j=0;jpcm[i][j]); - fclose(out); - } -#endif - /* LSP->LPC */ vorbis_lsp_to_lpc(lsp,lpc,vl->m); /* apply envelope to residue */ -#ifdef ANALYSIS - { - int j; - FILE *out; - char buffer[80]; - double curve[n/2]; - vorbis_lpc_to_curve(curve,lpc,vb->amp[i],vl); - - - sprintf(buffer,"Smask%d.m",vb->sequence); - out=fopen(buffer,"w+"); - for(j=0;jsequence); - out=fopen(buffer,"w+"); - for(j=0;jm;j++) - fprintf(out,"%g\n",lsp[j]); - fclose(out); - - sprintf(buffer,"Slpc%d.m",vb->sequence); - out=fopen(buffer,"w+"); - for(j=0;jm;j++) - fprintf(out,"%g\n",lpc[j]); - fclose(out); - } -#endif - vorbis_lpc_apply(vb->pcm[i],lpc,vb->amp[i],vl); - -#ifdef ANALYSIS - { - int j; - FILE *out; - char buffer[80]; - - sprintf(buffer,"Sspectrum%d.m",vb->sequence); - out=fopen(buffer,"w+"); - for(j=0;jpcm[i][j]); - fclose(out); - } -#endif /* MDCT->time */ diff --git a/lib/mapping0.h b/lib/mapping0.h deleted file mode 100644 index 1c6dcaa..0000000 --- a/lib/mapping0.h +++ /dev/null @@ -1,41 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY * - * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. * - * PLEASE READ THESE TERMS DISTRIBUTING. * - * * - * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 * - * by Monty and The XIPHOPHORUS Company * - * http://www.xiph.org/ * - * * - ******************************************************************** - - function: channel mapping 0 implementation - last mod: $Id: mapping0.h,v 1.1 2000/01/20 04:43:02 xiphmont Exp $ - - ********************************************************************/ - -typedef struct vorbis_info_mapping0{ - int timesubmap; /* list position of the time backend/settings - we're using */ - - int *floorsubmap; /* for each floor map, which channels */ - int *residuesubmap; /* residue to use for each incoming channel */ - int *psysubmap; /* psychoacoustics to use for each incoming channel */ - -} vorbis_info_mapping0; - -extern _vi_info_map *_vorbis_map0_dup (vorbis_info *vi, - _vi_info_map *source); -extern void _vorbis_map0_free (_vi_info_map *i); -extern void _vorbis_map0_pack (vorbis_info *vi, - oggpack_buffer *opb, - _vi_info_map *i); -extern _vi_info_map *_vorbis_map0_unpack (vorbis_info *vi, - oggpack_buffer *opb); -extern int _vorbis_map0_analysis (vorbis_block *vb, - _vi_info_map *i,ogg_packet *); -extern int _vorbis_map0_synthesis(vorbis_block *vb, - _vi_info_map *i,ogg_packet *); - diff --git a/lib/mdct.c b/lib/mdct.c index 1755e40..194673e 100644 --- a/lib/mdct.c +++ b/lib/mdct.c @@ -13,7 +13,7 @@ function: modified discrete cosine transform power of two length transform only [16 <= n ] - last mod: $Id: mdct.c,v 1.13 1999/12/30 07:26:44 xiphmont Exp $ + last mod: $Id: mdct.c,v 1.14 2000/01/22 13:28:25 xiphmont Exp $ Algorithm adapted from _The use of multirate filter banks for coding of high quality digital audio_, by T. Sporer, K. Brandenburg and @@ -196,7 +196,7 @@ static double *_mdct_kernel(double *x, double *w, return(x); } -void mdct_forward(mdct_lookup *init, double *in, double *out, double *window){ +void mdct_forward(mdct_lookup *init, double *in, double *out){ int n=init->n; double *x=alloca(sizeof(double)*(n/2)); double *w=alloca(sizeof(double)*(n/2)); @@ -217,8 +217,8 @@ void mdct_forward(mdct_lookup *init, double *in, double *out, double *window){ for(i=0;in; double *x=alloca(sizeof(double)*(n/2)); double *w=alloca(sizeof(double)*(n/2)); @@ -275,7 +275,7 @@ void mdct_backward(mdct_lookup *init, double *in, double *out, double *window){ int n8=n>>3; int i; - /* window + rotate + step 1 */ + /* rotate + step 1 */ { double *inO=in+1; double *xO= x; @@ -312,10 +312,10 @@ void mdct_backward(mdct_lookup *init, double *in, double *out, double *window){ double temp1= (*xx * B[1] - *(xx+1) * B[0]); double temp2=-(*xx * B[0] + *(xx+1) * B[1]); - out[o1]=-temp1*window[o1]; - out[o2]= temp1*window[o2]; - out[o3]= temp2*window[o3]; - out[o4]= temp2*window[o4]; + out[o1]=-temp1; + out[o2]= temp1; + out[o3]= temp2; + out[o4]= temp2; o1++; o2--; @@ -330,4 +330,3 @@ void mdct_backward(mdct_lookup *init, double *in, double *out, double *window){ - diff --git a/lib/mdct.h b/lib/mdct.h index 9acde51..c08827c 100644 --- a/lib/mdct.h +++ b/lib/mdct.h @@ -12,7 +12,7 @@ ******************************************************************** function: modified discrete cosine transform prototypes - last mod: $Id: mdct.h,v 1.9 2000/01/05 03:11:00 xiphmont Exp $ + last mod: $Id: mdct.h,v 1.10 2000/01/22 13:28:26 xiphmont Exp $ ********************************************************************/ @@ -23,10 +23,8 @@ extern void mdct_init(mdct_lookup *lookup,int n); extern void mdct_clear(mdct_lookup *l); -extern void mdct_forward(mdct_lookup *init, double *in, - double *out, double *window); -extern void mdct_backward(mdct_lookup *init, double *in, - double *out, double *window); +extern void mdct_forward(mdct_lookup *init, double *in, double *out); +extern void mdct_backward(mdct_lookup *init, double *in, double *out); #endif diff --git a/lib/time0.h b/lib/misc.h similarity index 65% rename from lib/time0.h rename to lib/misc.h index a6713f7..26850bf 100644 --- a/lib/time0.h +++ b/lib/misc.h @@ -11,18 +11,15 @@ * * ******************************************************************** - function: time backend 0 (dummy) - last mod: $Id: time0.h,v 1.1 2000/01/20 04:43:05 xiphmont Exp $ + function: miscellaneous prototypes + last mod: $Id: misc.h,v 1.1 2000/01/22 13:28:27 xiphmont Exp $ ********************************************************************/ -typedef struct vorbis_info_time0{ - long dummy; -} vorbis_info_time0; +#ifndef _V_RANDOM_H_ +#define _V_RANDOM_H_ -extern _vi_info_time *_vorbis_time0_dup (_vi_info_time *source); -extern void _vorbis_time0_free (_vi_info_time *i); -extern void _vorbis_time0_pack (oggpack_buffer *opb, - _vi_info_time *i); -extern _vi_info_time *_vorbis_time0_unpack(vorbis_info *vi, - oggpack_buffer *opb); +extern void *_vorbis_block_alloc(vorbis_block *vb,long bytes); +extern void _vorbis_block_ripcord(vorbis_block *vb); + +#endif diff --git a/lib/psy.c b/lib/psy.c index 1212145..c138ec8 100644 --- a/lib/psy.c +++ b/lib/psy.c @@ -12,7 +12,7 @@ ******************************************************************** function: psychoacoustics not including preecho - last mod: $Id: psy.c,v 1.11 2000/01/20 04:43:02 xiphmont Exp $ + last mod: $Id: psy.c,v 1.12 2000/01/22 13:28:27 xiphmont Exp $ ********************************************************************/ @@ -84,8 +84,8 @@ void _vp_psy_clear(psy_lookup *p){ /* Masking curve: linear rolloff on a Bark/dB scale, attenuated by maskthresh */ - -void _vp_mask_floor(psy_lookup *p,double *f, double *m){ +/* right now, floor==mask */ +void _vp_mask_floor(psy_lookup *p,double *f, double *mask,double *floor){ int n=p->n; double hroll=p->vi->hrolldB; double lroll=p->vi->lrolldB; @@ -104,7 +104,8 @@ void _vp_mask_floor(psy_lookup *p,double *f, double *m){ curoc=newoc; } troll=fromdB(roll); - if(m[i]maskthresh[n-1]; @@ -119,7 +120,8 @@ void _vp_mask_floor(psy_lookup *p,double *f, double *m){ curoc=newoc; } troll=fromdB(roll); - if(m[i] and The XIPHOPHORUS Company * - * http://www.xiph.org/ * - * * - ******************************************************************** - - function: residue backend 0 implementation - last mod: $Id: res0.h,v 1.1 2000/01/20 04:43:04 xiphmont Exp $ - - ********************************************************************/ - -typedef struct vorbis_info_res0{ -/* block-partitioned VQ coded straight residue */ - long begin; - long end; - - /* way unfinished, just so you know while poking around CVS ;-) */ - int stages; - int *books; -} vorbis_info_res0; - -extern _vi_info_res *_vorbis_res0_dup (_vi_info_res *source); -extern void _vorbis_res0_free (_vi_info_res *i); -extern void _vorbis_res0_pack (oggpack_buffer *opb, - _vi_info_res *vi); -extern _vi_info_res *_vorbis_res0_unpack(vorbis_info *vi, - oggpack_buffer *opb); diff --git a/lib/smallft.h b/lib/smallft.h index c72011f..69e9b58 100644 --- a/lib/smallft.h +++ b/lib/smallft.h @@ -12,7 +12,7 @@ ******************************************************************** function: fft transform - last mod: $Id: smallft.h,v 1.5 2000/01/05 03:11:02 xiphmont Exp $ + last mod: $Id: smallft.h,v 1.6 2000/01/22 13:28:32 xiphmont Exp $ ********************************************************************/ @@ -21,6 +21,12 @@ #include "vorbis/codec.h" +typedef struct { + int n; + double *trigcache; + int *splitcache; +} drft_lookup; + extern void drft_forward(drft_lookup *l,double *data); extern void drft_backward(drft_lookup *l,double *data); extern void drft_init(drft_lookup *l,int n); diff --git a/lib/synthesis.c b/lib/synthesis.c index 8b226d9..3947f23 100644 --- a/lib/synthesis.c +++ b/lib/synthesis.c @@ -12,7 +12,7 @@ ******************************************************************** function: single-block PCM synthesis - last mod: $Id: synthesis.c,v 1.13 2000/01/20 04:43:04 xiphmont Exp $ + last mod: $Id: synthesis.c,v 1.14 2000/01/22 13:28:33 xiphmont Exp $ ********************************************************************/ @@ -20,13 +20,13 @@ #include "vorbis/codec.h" #include "registry.h" #include "bitwise.h" +#include "misc.h" int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){ vorbis_dsp_state *vd=vb->vd; vorbis_info *vi=vd->vi; oggpack_buffer *opb=&vb->opb; - int type; - int mode; + int type,mode,i; /* first things first. Make sure decode is ready */ _vorbis_block_ripcord(vb); @@ -38,11 +38,32 @@ int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){ return(-1); } - /* read our mode */ - mode=_oggpack_read(&vb->opb,vd->modebits); - type=vi->mappingtypes[mode]; /* unpack_header enforces range checking */ + /* read our mode and pre/post windowsize */ + mode=_oggpack_read(opb,vd->modebits); + vb->W=vi->mode_param[mode]->blockflag; + if(vb->W){ + vb->lW=_oggpack_read(opb,1); + vb->nW=_oggpack_read(opb,1); + }else{ + vb->lW=0; + vb->nW=0; + } + + /* more setup */ + vb->frameno=op->frameno; + vb->sequence=op->packetno-3; /* first block is third packet */ + vb->eofflag=op->e_o_s; + + /* alloc pcm passback storage */ + vb->pcmend=vi->blocksizes[vb->W]; + vb->pcm=_vorbis_block_alloc(vb,sizeof(double *)*vi->channels); + for(i=0;ichannels;i++) + vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(double)); + + /* unpack_header enforces range checking */ + type=vi->map_type[vi->mode_param[mode]->mapping]; - return(vorbis_map_synthesis_P[type](vb,vi->modelist[mode],op)); + return(_mapping_P[type]->inverse(vb,vd->mode[mode])); } diff --git a/lib/time0.c b/lib/time0.c index 5147160..8c1dc63 100644 --- a/lib/time0.c +++ b/lib/time0.c @@ -12,7 +12,7 @@ ******************************************************************** function: time backend 0 (dummy) - last mod: $Id: time0.c,v 1.1 2000/01/20 04:43:05 xiphmont Exp $ + last mod: $Id: time0.c,v 1.2 2000/01/22 13:28:34 xiphmont Exp $ ********************************************************************/ @@ -20,20 +20,30 @@ #include #include "vorbis/codec.h" #include "registry.h" -#include "time0.h" -extern _vi_info_time *_vorbis_time0_dup(_vi_info_time *source){ - return(calloc(1,sizeof(vorbis_info_time0))); +static void pack (vorbis_info_time *i,oggpack_buffer *opb){ } - -extern void _vorbis_time0_free(_vi_info_time *i){ - if(i)free(i); +static vorbis_info_time *unpack (vorbis_info *vi,oggpack_buffer *opb){ + return NULL; } - -extern void _vorbis_time0_pack(oggpack_buffer *opb,_vi_info_time *i){ -} - -extern _vi_info_time *_vorbis_time0_unpack(vorbis_info *vi, - oggpack_buffer *opb){ - return(_vorbis_time0_dup(NULL)); +static vorbis_look_time *look (vorbis_info *vi,vorbis_info_mode *mi, + vorbis_info_time *i){ + return NULL; +} +static void free_info(vorbis_info_time *i){ } +static void free_look(vorbis_look_time *i){ +} +static int forward(vorbis_block *vb,vorbis_look_time *i, + double *in,double *out){ + return(0); +} +static int inverse(vorbis_block *vb,vorbis_look_time *i, + double *in,double *out){ + return(0); +} + +/* export hooks */ +vorbis_func_time time0_exportbundle={ + &pack,&unpack,&look,&free_info,&free_look,&forward,&inverse +}; diff --git a/lib/window.c b/lib/window.c index ed2dc25..499d15b 100644 --- a/lib/window.c +++ b/lib/window.c @@ -12,7 +12,7 @@ ******************************************************************** function: window functions - last mod: $Id: window.c,v 1.3 1999/12/30 07:26:55 xiphmont Exp $ + last mod: $Id: window.c,v 1.4 2000/01/22 13:28:36 xiphmont Exp $ ********************************************************************/ @@ -20,35 +20,42 @@ #include #include "os.h" -/* The 'vorbis window' is sin(sin(x)*sin(x)*2pi) */ - -double *_vorbis_window(int window,int left,int right){ +double *vorbis_window(int type, int window,int left,int right){ double *ret=calloc(window,sizeof(double)); - int leftbegin=window/4-left/2; - int rightbegin=window-window/4-right/2; - int i; - - for(i=0;i